diff --git a/node_modules/.bin/acorn b/node_modules/.bin/acorn new file mode 120000 index 0000000..cf76760 --- /dev/null +++ b/node_modules/.bin/acorn @@ -0,0 +1 @@ +../acorn/bin/acorn \ No newline at end of file diff --git a/node_modules/.bin/semver b/node_modules/.bin/semver new file mode 120000 index 0000000..5aaadf4 --- /dev/null +++ b/node_modules/.bin/semver @@ -0,0 +1 @@ +../semver/bin/semver.js \ No newline at end of file diff --git a/node_modules/.bin/terser b/node_modules/.bin/terser new file mode 120000 index 0000000..0792ff4 --- /dev/null +++ b/node_modules/.bin/terser @@ -0,0 +1 @@ +../terser/bin/terser \ No newline at end of file diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json new file mode 100644 index 0000000..51ab421 --- /dev/null +++ b/node_modules/.package-lock.json @@ -0,0 +1,241 @@ +{ + "name": "workspace", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "node_modules/@img/colour": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", + "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.3.tgz", + "integrity": "sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.4.tgz", + "integrity": "sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.3" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.4.tgz", + "integrity": "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.0", + "semver": "^7.7.2" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.4", + "@img/sharp-darwin-x64": "0.34.4", + "@img/sharp-libvips-darwin-arm64": "1.2.3", + "@img/sharp-libvips-darwin-x64": "1.2.3", + "@img/sharp-libvips-linux-arm": "1.2.3", + "@img/sharp-libvips-linux-arm64": "1.2.3", + "@img/sharp-libvips-linux-ppc64": "1.2.3", + "@img/sharp-libvips-linux-s390x": "1.2.3", + "@img/sharp-libvips-linux-x64": "1.2.3", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", + "@img/sharp-libvips-linuxmusl-x64": "1.2.3", + "@img/sharp-linux-arm": "0.34.4", + "@img/sharp-linux-arm64": "0.34.4", + "@img/sharp-linux-ppc64": "0.34.4", + "@img/sharp-linux-s390x": "0.34.4", + "@img/sharp-linux-x64": "0.34.4", + "@img/sharp-linuxmusl-arm64": "0.34.4", + "@img/sharp-linuxmusl-x64": "0.34.4", + "@img/sharp-wasm32": "0.34.4", + "@img/sharp-win32-arm64": "0.34.4", + "@img/sharp-win32-ia32": "0.34.4", + "@img/sharp-win32-x64": "0.34.4" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/terser": { + "version": "5.44.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz", + "integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + } + } +} diff --git a/node_modules/@img/colour/LICENSE.md b/node_modules/@img/colour/LICENSE.md new file mode 100644 index 0000000..292c550 --- /dev/null +++ b/node_modules/@img/colour/LICENSE.md @@ -0,0 +1,82 @@ +# Licensing + +## color + +Copyright (c) 2012 Heather Arthur + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +## color-convert + +Copyright (c) 2011-2016 Heather Arthur . +Copyright (c) 2016-2021 Josh Junon . + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +## color-string + +Copyright (c) 2011 Heather Arthur + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +## color-name + +The MIT License (MIT) +Copyright (c) 2015 Dmitry Ivanov + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/@img/colour/README.md b/node_modules/@img/colour/README.md new file mode 100644 index 0000000..a33e4eb --- /dev/null +++ b/node_modules/@img/colour/README.md @@ -0,0 +1,15 @@ +# `@img/colour` + +The latest version of the +[color](https://www.npmjs.com/package/color) +package is now ESM-only, +however some JavaScript runtimes do not yet support this, +which includes versions of Node.js prior to 20.19.0. + +This package converts the `color` package and its dependencies, +all of which are MIT-licensed, to CommonJS. + +- [color](https://www.npmjs.com/package/color) +- [color-convert](https://www.npmjs.com/package/color-convert) +- [color-string](https://www.npmjs.com/package/color-string) +- [color-name](https://www.npmjs.com/package/color-name) diff --git a/node_modules/@img/colour/color.cjs b/node_modules/@img/colour/color.cjs new file mode 100644 index 0000000..ac055fa --- /dev/null +++ b/node_modules/@img/colour/color.cjs @@ -0,0 +1,1594 @@ +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// node_modules/color/index.js +var index_exports = {}; +__export(index_exports, { + default: () => index_default +}); +module.exports = __toCommonJS(index_exports); + +// node_modules/color-name/index.js +var color_name_default = { + aliceblue: [240, 248, 255], + antiquewhite: [250, 235, 215], + aqua: [0, 255, 255], + aquamarine: [127, 255, 212], + azure: [240, 255, 255], + beige: [245, 245, 220], + bisque: [255, 228, 196], + black: [0, 0, 0], + blanchedalmond: [255, 235, 205], + blue: [0, 0, 255], + blueviolet: [138, 43, 226], + brown: [165, 42, 42], + burlywood: [222, 184, 135], + cadetblue: [95, 158, 160], + chartreuse: [127, 255, 0], + chocolate: [210, 105, 30], + coral: [255, 127, 80], + cornflowerblue: [100, 149, 237], + cornsilk: [255, 248, 220], + crimson: [220, 20, 60], + cyan: [0, 255, 255], + darkblue: [0, 0, 139], + darkcyan: [0, 139, 139], + darkgoldenrod: [184, 134, 11], + darkgray: [169, 169, 169], + darkgreen: [0, 100, 0], + darkgrey: [169, 169, 169], + darkkhaki: [189, 183, 107], + darkmagenta: [139, 0, 139], + darkolivegreen: [85, 107, 47], + darkorange: [255, 140, 0], + darkorchid: [153, 50, 204], + darkred: [139, 0, 0], + darksalmon: [233, 150, 122], + darkseagreen: [143, 188, 143], + darkslateblue: [72, 61, 139], + darkslategray: [47, 79, 79], + darkslategrey: [47, 79, 79], + darkturquoise: [0, 206, 209], + darkviolet: [148, 0, 211], + deeppink: [255, 20, 147], + deepskyblue: [0, 191, 255], + dimgray: [105, 105, 105], + dimgrey: [105, 105, 105], + dodgerblue: [30, 144, 255], + firebrick: [178, 34, 34], + floralwhite: [255, 250, 240], + forestgreen: [34, 139, 34], + fuchsia: [255, 0, 255], + gainsboro: [220, 220, 220], + ghostwhite: [248, 248, 255], + gold: [255, 215, 0], + goldenrod: [218, 165, 32], + gray: [128, 128, 128], + green: [0, 128, 0], + greenyellow: [173, 255, 47], + grey: [128, 128, 128], + honeydew: [240, 255, 240], + hotpink: [255, 105, 180], + indianred: [205, 92, 92], + indigo: [75, 0, 130], + ivory: [255, 255, 240], + khaki: [240, 230, 140], + lavender: [230, 230, 250], + lavenderblush: [255, 240, 245], + lawngreen: [124, 252, 0], + lemonchiffon: [255, 250, 205], + lightblue: [173, 216, 230], + lightcoral: [240, 128, 128], + lightcyan: [224, 255, 255], + lightgoldenrodyellow: [250, 250, 210], + lightgray: [211, 211, 211], + lightgreen: [144, 238, 144], + lightgrey: [211, 211, 211], + lightpink: [255, 182, 193], + lightsalmon: [255, 160, 122], + lightseagreen: [32, 178, 170], + lightskyblue: [135, 206, 250], + lightslategray: [119, 136, 153], + lightslategrey: [119, 136, 153], + lightsteelblue: [176, 196, 222], + lightyellow: [255, 255, 224], + lime: [0, 255, 0], + limegreen: [50, 205, 50], + linen: [250, 240, 230], + magenta: [255, 0, 255], + maroon: [128, 0, 0], + mediumaquamarine: [102, 205, 170], + mediumblue: [0, 0, 205], + mediumorchid: [186, 85, 211], + mediumpurple: [147, 112, 219], + mediumseagreen: [60, 179, 113], + mediumslateblue: [123, 104, 238], + mediumspringgreen: [0, 250, 154], + mediumturquoise: [72, 209, 204], + mediumvioletred: [199, 21, 133], + midnightblue: [25, 25, 112], + mintcream: [245, 255, 250], + mistyrose: [255, 228, 225], + moccasin: [255, 228, 181], + navajowhite: [255, 222, 173], + navy: [0, 0, 128], + oldlace: [253, 245, 230], + olive: [128, 128, 0], + olivedrab: [107, 142, 35], + orange: [255, 165, 0], + orangered: [255, 69, 0], + orchid: [218, 112, 214], + palegoldenrod: [238, 232, 170], + palegreen: [152, 251, 152], + paleturquoise: [175, 238, 238], + palevioletred: [219, 112, 147], + papayawhip: [255, 239, 213], + peachpuff: [255, 218, 185], + peru: [205, 133, 63], + pink: [255, 192, 203], + plum: [221, 160, 221], + powderblue: [176, 224, 230], + purple: [128, 0, 128], + rebeccapurple: [102, 51, 153], + red: [255, 0, 0], + rosybrown: [188, 143, 143], + royalblue: [65, 105, 225], + saddlebrown: [139, 69, 19], + salmon: [250, 128, 114], + sandybrown: [244, 164, 96], + seagreen: [46, 139, 87], + seashell: [255, 245, 238], + sienna: [160, 82, 45], + silver: [192, 192, 192], + skyblue: [135, 206, 235], + slateblue: [106, 90, 205], + slategray: [112, 128, 144], + slategrey: [112, 128, 144], + snow: [255, 250, 250], + springgreen: [0, 255, 127], + steelblue: [70, 130, 180], + tan: [210, 180, 140], + teal: [0, 128, 128], + thistle: [216, 191, 216], + tomato: [255, 99, 71], + turquoise: [64, 224, 208], + violet: [238, 130, 238], + wheat: [245, 222, 179], + white: [255, 255, 255], + whitesmoke: [245, 245, 245], + yellow: [255, 255, 0], + yellowgreen: [154, 205, 50] +}; + +// node_modules/color-string/index.js +var reverseNames = /* @__PURE__ */ Object.create(null); +for (const name in color_name_default) { + if (Object.hasOwn(color_name_default, name)) { + reverseNames[color_name_default[name]] = name; + } +} +var cs = { + to: {}, + get: {} +}; +cs.get = function(string) { + const prefix = string.slice(0, 3).toLowerCase(); + let value; + let model; + switch (prefix) { + case "hsl": { + value = cs.get.hsl(string); + model = "hsl"; + break; + } + case "hwb": { + value = cs.get.hwb(string); + model = "hwb"; + break; + } + default: { + value = cs.get.rgb(string); + model = "rgb"; + break; + } + } + if (!value) { + return null; + } + return { model, value }; +}; +cs.get.rgb = function(string) { + if (!string) { + return null; + } + const abbr = /^#([a-f\d]{3,4})$/i; + const hex = /^#([a-f\d]{6})([a-f\d]{2})?$/i; + const rgba = /^rgba?\(\s*([+-]?\d+)(?=[\s,])\s*(?:,\s*)?([+-]?\d+)(?=[\s,])\s*(?:,\s*)?([+-]?\d+)\s*(?:[\s,|/]\s*([+-]?[\d.]+)(%?)\s*)?\)$/; + const per = /^rgba?\(\s*([+-]?[\d.]+)%\s*,?\s*([+-]?[\d.]+)%\s*,?\s*([+-]?[\d.]+)%\s*(?:[\s,|/]\s*([+-]?[\d.]+)(%?)\s*)?\)$/; + const keyword = /^(\w+)$/; + let rgb = [0, 0, 0, 1]; + let match; + let i; + let hexAlpha; + if (match = string.match(hex)) { + hexAlpha = match[2]; + match = match[1]; + for (i = 0; i < 3; i++) { + const i2 = i * 2; + rgb[i] = Number.parseInt(match.slice(i2, i2 + 2), 16); + } + if (hexAlpha) { + rgb[3] = Number.parseInt(hexAlpha, 16) / 255; + } + } else if (match = string.match(abbr)) { + match = match[1]; + hexAlpha = match[3]; + for (i = 0; i < 3; i++) { + rgb[i] = Number.parseInt(match[i] + match[i], 16); + } + if (hexAlpha) { + rgb[3] = Number.parseInt(hexAlpha + hexAlpha, 16) / 255; + } + } else if (match = string.match(rgba)) { + for (i = 0; i < 3; i++) { + rgb[i] = Number.parseInt(match[i + 1], 10); + } + if (match[4]) { + rgb[3] = match[5] ? Number.parseFloat(match[4]) * 0.01 : Number.parseFloat(match[4]); + } + } else if (match = string.match(per)) { + for (i = 0; i < 3; i++) { + rgb[i] = Math.round(Number.parseFloat(match[i + 1]) * 2.55); + } + if (match[4]) { + rgb[3] = match[5] ? Number.parseFloat(match[4]) * 0.01 : Number.parseFloat(match[4]); + } + } else if (match = string.match(keyword)) { + if (match[1] === "transparent") { + return [0, 0, 0, 0]; + } + if (!Object.hasOwn(color_name_default, match[1])) { + return null; + } + rgb = color_name_default[match[1]]; + rgb[3] = 1; + return rgb; + } else { + return null; + } + for (i = 0; i < 3; i++) { + rgb[i] = clamp(rgb[i], 0, 255); + } + rgb[3] = clamp(rgb[3], 0, 1); + return rgb; +}; +cs.get.hsl = function(string) { + if (!string) { + return null; + } + const hsl = /^hsla?\(\s*([+-]?(?:\d{0,3}\.)?\d+)(?:deg)?\s*,?\s*([+-]?[\d.]+)%\s*,?\s*([+-]?[\d.]+)%\s*(?:[,|/]\s*([+-]?(?=\.\d|\d)(?:0|[1-9]\d*)?(?:\.\d*)?(?:[eE][+-]?\d+)?)\s*)?\)$/; + const match = string.match(hsl); + if (match) { + const alpha = Number.parseFloat(match[4]); + const h = (Number.parseFloat(match[1]) % 360 + 360) % 360; + const s = clamp(Number.parseFloat(match[2]), 0, 100); + const l = clamp(Number.parseFloat(match[3]), 0, 100); + const a = clamp(Number.isNaN(alpha) ? 1 : alpha, 0, 1); + return [h, s, l, a]; + } + return null; +}; +cs.get.hwb = function(string) { + if (!string) { + return null; + } + const hwb = /^hwb\(\s*([+-]?\d{0,3}(?:\.\d+)?)(?:deg)?\s*[\s,]\s*([+-]?[\d.]+)%\s*[\s,]\s*([+-]?[\d.]+)%\s*(?:[\s,]\s*([+-]?(?=\.\d|\d)(?:0|[1-9]\d*)?(?:\.\d*)?(?:[eE][+-]?\d+)?)\s*)?\)$/; + const match = string.match(hwb); + if (match) { + const alpha = Number.parseFloat(match[4]); + const h = (Number.parseFloat(match[1]) % 360 + 360) % 360; + const w = clamp(Number.parseFloat(match[2]), 0, 100); + const b = clamp(Number.parseFloat(match[3]), 0, 100); + const a = clamp(Number.isNaN(alpha) ? 1 : alpha, 0, 1); + return [h, w, b, a]; + } + return null; +}; +cs.to.hex = function(...rgba) { + return "#" + hexDouble(rgba[0]) + hexDouble(rgba[1]) + hexDouble(rgba[2]) + (rgba[3] < 1 ? hexDouble(Math.round(rgba[3] * 255)) : ""); +}; +cs.to.rgb = function(...rgba) { + return rgba.length < 4 || rgba[3] === 1 ? "rgb(" + Math.round(rgba[0]) + ", " + Math.round(rgba[1]) + ", " + Math.round(rgba[2]) + ")" : "rgba(" + Math.round(rgba[0]) + ", " + Math.round(rgba[1]) + ", " + Math.round(rgba[2]) + ", " + rgba[3] + ")"; +}; +cs.to.rgb.percent = function(...rgba) { + const r = Math.round(rgba[0] / 255 * 100); + const g = Math.round(rgba[1] / 255 * 100); + const b = Math.round(rgba[2] / 255 * 100); + return rgba.length < 4 || rgba[3] === 1 ? "rgb(" + r + "%, " + g + "%, " + b + "%)" : "rgba(" + r + "%, " + g + "%, " + b + "%, " + rgba[3] + ")"; +}; +cs.to.hsl = function(...hsla) { + return hsla.length < 4 || hsla[3] === 1 ? "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)" : "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, " + hsla[3] + ")"; +}; +cs.to.hwb = function(...hwba) { + let a = ""; + if (hwba.length >= 4 && hwba[3] !== 1) { + a = ", " + hwba[3]; + } + return "hwb(" + hwba[0] + ", " + hwba[1] + "%, " + hwba[2] + "%" + a + ")"; +}; +cs.to.keyword = function(...rgb) { + return reverseNames[rgb.slice(0, 3)]; +}; +function clamp(number_, min, max) { + return Math.min(Math.max(min, number_), max); +} +function hexDouble(number_) { + const string_ = Math.round(number_).toString(16).toUpperCase(); + return string_.length < 2 ? "0" + string_ : string_; +} +var color_string_default = cs; + +// node_modules/color-convert/conversions.js +var reverseKeywords = {}; +for (const key of Object.keys(color_name_default)) { + reverseKeywords[color_name_default[key]] = key; +} +var convert = { + rgb: { channels: 3, labels: "rgb" }, + hsl: { channels: 3, labels: "hsl" }, + hsv: { channels: 3, labels: "hsv" }, + hwb: { channels: 3, labels: "hwb" }, + cmyk: { channels: 4, labels: "cmyk" }, + xyz: { channels: 3, labels: "xyz" }, + lab: { channels: 3, labels: "lab" }, + oklab: { channels: 3, labels: ["okl", "oka", "okb"] }, + lch: { channels: 3, labels: "lch" }, + oklch: { channels: 3, labels: ["okl", "okc", "okh"] }, + hex: { channels: 1, labels: ["hex"] }, + keyword: { channels: 1, labels: ["keyword"] }, + ansi16: { channels: 1, labels: ["ansi16"] }, + ansi256: { channels: 1, labels: ["ansi256"] }, + hcg: { channels: 3, labels: ["h", "c", "g"] }, + apple: { channels: 3, labels: ["r16", "g16", "b16"] }, + gray: { channels: 1, labels: ["gray"] } +}; +var conversions_default = convert; +var LAB_FT = (6 / 29) ** 3; +function srgbNonlinearTransform(c) { + const cc = c > 31308e-7 ? 1.055 * c ** (1 / 2.4) - 0.055 : c * 12.92; + return Math.min(Math.max(0, cc), 1); +} +function srgbNonlinearTransformInv(c) { + return c > 0.04045 ? ((c + 0.055) / 1.055) ** 2.4 : c / 12.92; +} +for (const model of Object.keys(convert)) { + if (!("channels" in convert[model])) { + throw new Error("missing channels property: " + model); + } + if (!("labels" in convert[model])) { + throw new Error("missing channel labels property: " + model); + } + if (convert[model].labels.length !== convert[model].channels) { + throw new Error("channel and label counts mismatch: " + model); + } + const { channels, labels } = convert[model]; + delete convert[model].channels; + delete convert[model].labels; + Object.defineProperty(convert[model], "channels", { value: channels }); + Object.defineProperty(convert[model], "labels", { value: labels }); +} +convert.rgb.hsl = function(rgb) { + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; + const min = Math.min(r, g, b); + const max = Math.max(r, g, b); + const delta = max - min; + let h; + let s; + switch (max) { + case min: { + h = 0; + break; + } + case r: { + h = (g - b) / delta; + break; + } + case g: { + h = 2 + (b - r) / delta; + break; + } + case b: { + h = 4 + (r - g) / delta; + break; + } + } + h = Math.min(h * 60, 360); + if (h < 0) { + h += 360; + } + const l = (min + max) / 2; + if (max === min) { + s = 0; + } else if (l <= 0.5) { + s = delta / (max + min); + } else { + s = delta / (2 - max - min); + } + return [h, s * 100, l * 100]; +}; +convert.rgb.hsv = function(rgb) { + let rdif; + let gdif; + let bdif; + let h; + let s; + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; + const v = Math.max(r, g, b); + const diff = v - Math.min(r, g, b); + const diffc = function(c) { + return (v - c) / 6 / diff + 1 / 2; + }; + if (diff === 0) { + h = 0; + s = 0; + } else { + s = diff / v; + rdif = diffc(r); + gdif = diffc(g); + bdif = diffc(b); + switch (v) { + case r: { + h = bdif - gdif; + break; + } + case g: { + h = 1 / 3 + rdif - bdif; + break; + } + case b: { + h = 2 / 3 + gdif - rdif; + break; + } + } + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } + } + return [ + h * 360, + s * 100, + v * 100 + ]; +}; +convert.rgb.hwb = function(rgb) { + const r = rgb[0]; + const g = rgb[1]; + let b = rgb[2]; + const h = convert.rgb.hsl(rgb)[0]; + const w = 1 / 255 * Math.min(r, Math.min(g, b)); + b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); + return [h, w * 100, b * 100]; +}; +convert.rgb.oklab = function(rgb) { + const r = srgbNonlinearTransformInv(rgb[0] / 255); + const g = srgbNonlinearTransformInv(rgb[1] / 255); + const b = srgbNonlinearTransformInv(rgb[2] / 255); + const lp = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b); + const mp = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b); + const sp = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b); + const l = 0.2104542553 * lp + 0.793617785 * mp - 0.0040720468 * sp; + const aa = 1.9779984951 * lp - 2.428592205 * mp + 0.4505937099 * sp; + const bb = 0.0259040371 * lp + 0.7827717662 * mp - 0.808675766 * sp; + return [l * 100, aa * 100, bb * 100]; +}; +convert.rgb.cmyk = function(rgb) { + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; + const k = Math.min(1 - r, 1 - g, 1 - b); + const c = (1 - r - k) / (1 - k) || 0; + const m = (1 - g - k) / (1 - k) || 0; + const y = (1 - b - k) / (1 - k) || 0; + return [c * 100, m * 100, y * 100, k * 100]; +}; +function comparativeDistance(x, y) { + return (x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2 + (x[2] - y[2]) ** 2; +} +convert.rgb.keyword = function(rgb) { + const reversed = reverseKeywords[rgb]; + if (reversed) { + return reversed; + } + let currentClosestDistance = Number.POSITIVE_INFINITY; + let currentClosestKeyword; + for (const keyword of Object.keys(color_name_default)) { + const value = color_name_default[keyword]; + const distance = comparativeDistance(rgb, value); + if (distance < currentClosestDistance) { + currentClosestDistance = distance; + currentClosestKeyword = keyword; + } + } + return currentClosestKeyword; +}; +convert.keyword.rgb = function(keyword) { + return color_name_default[keyword]; +}; +convert.rgb.xyz = function(rgb) { + const r = srgbNonlinearTransformInv(rgb[0] / 255); + const g = srgbNonlinearTransformInv(rgb[1] / 255); + const b = srgbNonlinearTransformInv(rgb[2] / 255); + const x = r * 0.4124564 + g * 0.3575761 + b * 0.1804375; + const y = r * 0.2126729 + g * 0.7151522 + b * 0.072175; + const z = r * 0.0193339 + g * 0.119192 + b * 0.9503041; + return [x * 100, y * 100, z * 100]; +}; +convert.rgb.lab = function(rgb) { + const xyz = convert.rgb.xyz(rgb); + let x = xyz[0]; + let y = xyz[1]; + let z = xyz[2]; + x /= 95.047; + y /= 100; + z /= 108.883; + x = x > LAB_FT ? x ** (1 / 3) : 7.787 * x + 16 / 116; + y = y > LAB_FT ? y ** (1 / 3) : 7.787 * y + 16 / 116; + z = z > LAB_FT ? z ** (1 / 3) : 7.787 * z + 16 / 116; + const l = 116 * y - 16; + const a = 500 * (x - y); + const b = 200 * (y - z); + return [l, a, b]; +}; +convert.hsl.rgb = function(hsl) { + const h = hsl[0] / 360; + const s = hsl[1] / 100; + const l = hsl[2] / 100; + let t3; + let value; + if (s === 0) { + value = l * 255; + return [value, value, value]; + } + const t2 = l < 0.5 ? l * (1 + s) : l + s - l * s; + const t1 = 2 * l - t2; + const rgb = [0, 0, 0]; + for (let i = 0; i < 3; i++) { + t3 = h + 1 / 3 * -(i - 1); + if (t3 < 0) { + t3++; + } + if (t3 > 1) { + t3--; + } + if (6 * t3 < 1) { + value = t1 + (t2 - t1) * 6 * t3; + } else if (2 * t3 < 1) { + value = t2; + } else if (3 * t3 < 2) { + value = t1 + (t2 - t1) * (2 / 3 - t3) * 6; + } else { + value = t1; + } + rgb[i] = value * 255; + } + return rgb; +}; +convert.hsl.hsv = function(hsl) { + const h = hsl[0]; + let s = hsl[1] / 100; + let l = hsl[2] / 100; + let smin = s; + const lmin = Math.max(l, 0.01); + l *= 2; + s *= l <= 1 ? l : 2 - l; + smin *= lmin <= 1 ? lmin : 2 - lmin; + const v = (l + s) / 2; + const sv = l === 0 ? 2 * smin / (lmin + smin) : 2 * s / (l + s); + return [h, sv * 100, v * 100]; +}; +convert.hsv.rgb = function(hsv) { + const h = hsv[0] / 60; + const s = hsv[1] / 100; + let v = hsv[2] / 100; + const hi = Math.floor(h) % 6; + const f = h - Math.floor(h); + const p = 255 * v * (1 - s); + const q = 255 * v * (1 - s * f); + const t = 255 * v * (1 - s * (1 - f)); + v *= 255; + switch (hi) { + case 0: { + return [v, t, p]; + } + case 1: { + return [q, v, p]; + } + case 2: { + return [p, v, t]; + } + case 3: { + return [p, q, v]; + } + case 4: { + return [t, p, v]; + } + case 5: { + return [v, p, q]; + } + } +}; +convert.hsv.hsl = function(hsv) { + const h = hsv[0]; + const s = hsv[1] / 100; + const v = hsv[2] / 100; + const vmin = Math.max(v, 0.01); + let sl; + let l; + l = (2 - s) * v; + const lmin = (2 - s) * vmin; + sl = s * vmin; + sl /= lmin <= 1 ? lmin : 2 - lmin; + sl = sl || 0; + l /= 2; + return [h, sl * 100, l * 100]; +}; +convert.hwb.rgb = function(hwb) { + const h = hwb[0] / 360; + let wh = hwb[1] / 100; + let bl = hwb[2] / 100; + const ratio = wh + bl; + let f; + if (ratio > 1) { + wh /= ratio; + bl /= ratio; + } + const i = Math.floor(6 * h); + const v = 1 - bl; + f = 6 * h - i; + if ((i & 1) !== 0) { + f = 1 - f; + } + const n = wh + f * (v - wh); + let r; + let g; + let b; + switch (i) { + default: + case 6: + case 0: { + r = v; + g = n; + b = wh; + break; + } + case 1: { + r = n; + g = v; + b = wh; + break; + } + case 2: { + r = wh; + g = v; + b = n; + break; + } + case 3: { + r = wh; + g = n; + b = v; + break; + } + case 4: { + r = n; + g = wh; + b = v; + break; + } + case 5: { + r = v; + g = wh; + b = n; + break; + } + } + return [r * 255, g * 255, b * 255]; +}; +convert.cmyk.rgb = function(cmyk) { + const c = cmyk[0] / 100; + const m = cmyk[1] / 100; + const y = cmyk[2] / 100; + const k = cmyk[3] / 100; + const r = 1 - Math.min(1, c * (1 - k) + k); + const g = 1 - Math.min(1, m * (1 - k) + k); + const b = 1 - Math.min(1, y * (1 - k) + k); + return [r * 255, g * 255, b * 255]; +}; +convert.xyz.rgb = function(xyz) { + const x = xyz[0] / 100; + const y = xyz[1] / 100; + const z = xyz[2] / 100; + let r; + let g; + let b; + r = x * 3.2404542 + y * -1.5371385 + z * -0.4985314; + g = x * -0.969266 + y * 1.8760108 + z * 0.041556; + b = x * 0.0556434 + y * -0.2040259 + z * 1.0572252; + r = srgbNonlinearTransform(r); + g = srgbNonlinearTransform(g); + b = srgbNonlinearTransform(b); + return [r * 255, g * 255, b * 255]; +}; +convert.xyz.lab = function(xyz) { + let x = xyz[0]; + let y = xyz[1]; + let z = xyz[2]; + x /= 95.047; + y /= 100; + z /= 108.883; + x = x > LAB_FT ? x ** (1 / 3) : 7.787 * x + 16 / 116; + y = y > LAB_FT ? y ** (1 / 3) : 7.787 * y + 16 / 116; + z = z > LAB_FT ? z ** (1 / 3) : 7.787 * z + 16 / 116; + const l = 116 * y - 16; + const a = 500 * (x - y); + const b = 200 * (y - z); + return [l, a, b]; +}; +convert.xyz.oklab = function(xyz) { + const x = xyz[0] / 100; + const y = xyz[1] / 100; + const z = xyz[2] / 100; + const lp = Math.cbrt(0.8189330101 * x + 0.3618667424 * y - 0.1288597137 * z); + const mp = Math.cbrt(0.0329845436 * x + 0.9293118715 * y + 0.0361456387 * z); + const sp = Math.cbrt(0.0482003018 * x + 0.2643662691 * y + 0.633851707 * z); + const l = 0.2104542553 * lp + 0.793617785 * mp - 0.0040720468 * sp; + const a = 1.9779984951 * lp - 2.428592205 * mp + 0.4505937099 * sp; + const b = 0.0259040371 * lp + 0.7827717662 * mp - 0.808675766 * sp; + return [l * 100, a * 100, b * 100]; +}; +convert.oklab.oklch = function(oklab) { + return convert.lab.lch(oklab); +}; +convert.oklab.xyz = function(oklab) { + const ll = oklab[0] / 100; + const a = oklab[1] / 100; + const b = oklab[2] / 100; + const l = (0.999999998 * ll + 0.396337792 * a + 0.215803758 * b) ** 3; + const m = (1.000000008 * ll - 0.105561342 * a - 0.063854175 * b) ** 3; + const s = (1.000000055 * ll - 0.089484182 * a - 1.291485538 * b) ** 3; + const x = 1.227013851 * l - 0.55779998 * m + 0.281256149 * s; + const y = -0.040580178 * l + 1.11225687 * m - 0.071676679 * s; + const z = -0.076381285 * l - 0.421481978 * m + 1.58616322 * s; + return [x * 100, y * 100, z * 100]; +}; +convert.oklab.rgb = function(oklab) { + const ll = oklab[0] / 100; + const aa = oklab[1] / 100; + const bb = oklab[2] / 100; + const l = (ll + 0.3963377774 * aa + 0.2158037573 * bb) ** 3; + const m = (ll - 0.1055613458 * aa - 0.0638541728 * bb) ** 3; + const s = (ll - 0.0894841775 * aa - 1.291485548 * bb) ** 3; + const r = srgbNonlinearTransform(4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s); + const g = srgbNonlinearTransform(-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s); + const b = srgbNonlinearTransform(-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s); + return [r * 255, g * 255, b * 255]; +}; +convert.oklch.oklab = function(oklch) { + return convert.lch.lab(oklch); +}; +convert.lab.xyz = function(lab) { + const l = lab[0]; + const a = lab[1]; + const b = lab[2]; + let x; + let y; + let z; + y = (l + 16) / 116; + x = a / 500 + y; + z = y - b / 200; + const y2 = y ** 3; + const x2 = x ** 3; + const z2 = z ** 3; + y = y2 > LAB_FT ? y2 : (y - 16 / 116) / 7.787; + x = x2 > LAB_FT ? x2 : (x - 16 / 116) / 7.787; + z = z2 > LAB_FT ? z2 : (z - 16 / 116) / 7.787; + x *= 95.047; + y *= 100; + z *= 108.883; + return [x, y, z]; +}; +convert.lab.lch = function(lab) { + const l = lab[0]; + const a = lab[1]; + const b = lab[2]; + let h; + const hr = Math.atan2(b, a); + h = hr * 360 / 2 / Math.PI; + if (h < 0) { + h += 360; + } + const c = Math.sqrt(a * a + b * b); + return [l, c, h]; +}; +convert.lch.lab = function(lch) { + const l = lch[0]; + const c = lch[1]; + const h = lch[2]; + const hr = h / 360 * 2 * Math.PI; + const a = c * Math.cos(hr); + const b = c * Math.sin(hr); + return [l, a, b]; +}; +convert.rgb.ansi16 = function(args, saturation = null) { + const [r, g, b] = args; + let value = saturation === null ? convert.rgb.hsv(args)[2] : saturation; + value = Math.round(value / 50); + if (value === 0) { + return 30; + } + let ansi = 30 + (Math.round(b / 255) << 2 | Math.round(g / 255) << 1 | Math.round(r / 255)); + if (value === 2) { + ansi += 60; + } + return ansi; +}; +convert.hsv.ansi16 = function(args) { + return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); +}; +convert.rgb.ansi256 = function(args) { + const r = args[0]; + const g = args[1]; + const b = args[2]; + if (r >> 4 === g >> 4 && g >> 4 === b >> 4) { + if (r < 8) { + return 16; + } + if (r > 248) { + return 231; + } + return Math.round((r - 8) / 247 * 24) + 232; + } + const ansi = 16 + 36 * Math.round(r / 255 * 5) + 6 * Math.round(g / 255 * 5) + Math.round(b / 255 * 5); + return ansi; +}; +convert.ansi16.rgb = function(args) { + args = args[0]; + let color = args % 10; + if (color === 0 || color === 7) { + if (args > 50) { + color += 3.5; + } + color = color / 10.5 * 255; + return [color, color, color]; + } + const mult = (Math.trunc(args > 50) + 1) * 0.5; + const r = (color & 1) * mult * 255; + const g = (color >> 1 & 1) * mult * 255; + const b = (color >> 2 & 1) * mult * 255; + return [r, g, b]; +}; +convert.ansi256.rgb = function(args) { + args = args[0]; + if (args >= 232) { + const c = (args - 232) * 10 + 8; + return [c, c, c]; + } + args -= 16; + let rem; + const r = Math.floor(args / 36) / 5 * 255; + const g = Math.floor((rem = args % 36) / 6) / 5 * 255; + const b = rem % 6 / 5 * 255; + return [r, g, b]; +}; +convert.rgb.hex = function(args) { + const integer = ((Math.round(args[0]) & 255) << 16) + ((Math.round(args[1]) & 255) << 8) + (Math.round(args[2]) & 255); + const string = integer.toString(16).toUpperCase(); + return "000000".slice(string.length) + string; +}; +convert.hex.rgb = function(args) { + const match = args.toString(16).match(/[a-f\d]{6}|[a-f\d]{3}/i); + if (!match) { + return [0, 0, 0]; + } + let colorString = match[0]; + if (match[0].length === 3) { + colorString = [...colorString].map((char) => char + char).join(""); + } + const integer = Number.parseInt(colorString, 16); + const r = integer >> 16 & 255; + const g = integer >> 8 & 255; + const b = integer & 255; + return [r, g, b]; +}; +convert.rgb.hcg = function(rgb) { + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; + const max = Math.max(Math.max(r, g), b); + const min = Math.min(Math.min(r, g), b); + const chroma = max - min; + let hue; + const grayscale = chroma < 1 ? min / (1 - chroma) : 0; + if (chroma <= 0) { + hue = 0; + } else if (max === r) { + hue = (g - b) / chroma % 6; + } else if (max === g) { + hue = 2 + (b - r) / chroma; + } else { + hue = 4 + (r - g) / chroma; + } + hue /= 6; + hue %= 1; + return [hue * 360, chroma * 100, grayscale * 100]; +}; +convert.hsl.hcg = function(hsl) { + const s = hsl[1] / 100; + const l = hsl[2] / 100; + const c = l < 0.5 ? 2 * s * l : 2 * s * (1 - l); + let f = 0; + if (c < 1) { + f = (l - 0.5 * c) / (1 - c); + } + return [hsl[0], c * 100, f * 100]; +}; +convert.hsv.hcg = function(hsv) { + const s = hsv[1] / 100; + const v = hsv[2] / 100; + const c = s * v; + let f = 0; + if (c < 1) { + f = (v - c) / (1 - c); + } + return [hsv[0], c * 100, f * 100]; +}; +convert.hcg.rgb = function(hcg) { + const h = hcg[0] / 360; + const c = hcg[1] / 100; + const g = hcg[2] / 100; + if (c === 0) { + return [g * 255, g * 255, g * 255]; + } + const pure = [0, 0, 0]; + const hi = h % 1 * 6; + const v = hi % 1; + const w = 1 - v; + let mg = 0; + switch (Math.floor(hi)) { + case 0: { + pure[0] = 1; + pure[1] = v; + pure[2] = 0; + break; + } + case 1: { + pure[0] = w; + pure[1] = 1; + pure[2] = 0; + break; + } + case 2: { + pure[0] = 0; + pure[1] = 1; + pure[2] = v; + break; + } + case 3: { + pure[0] = 0; + pure[1] = w; + pure[2] = 1; + break; + } + case 4: { + pure[0] = v; + pure[1] = 0; + pure[2] = 1; + break; + } + default: { + pure[0] = 1; + pure[1] = 0; + pure[2] = w; + } + } + mg = (1 - c) * g; + return [ + (c * pure[0] + mg) * 255, + (c * pure[1] + mg) * 255, + (c * pure[2] + mg) * 255 + ]; +}; +convert.hcg.hsv = function(hcg) { + const c = hcg[1] / 100; + const g = hcg[2] / 100; + const v = c + g * (1 - c); + let f = 0; + if (v > 0) { + f = c / v; + } + return [hcg[0], f * 100, v * 100]; +}; +convert.hcg.hsl = function(hcg) { + const c = hcg[1] / 100; + const g = hcg[2] / 100; + const l = g * (1 - c) + 0.5 * c; + let s = 0; + if (l > 0 && l < 0.5) { + s = c / (2 * l); + } else if (l >= 0.5 && l < 1) { + s = c / (2 * (1 - l)); + } + return [hcg[0], s * 100, l * 100]; +}; +convert.hcg.hwb = function(hcg) { + const c = hcg[1] / 100; + const g = hcg[2] / 100; + const v = c + g * (1 - c); + return [hcg[0], (v - c) * 100, (1 - v) * 100]; +}; +convert.hwb.hcg = function(hwb) { + const w = hwb[1] / 100; + const b = hwb[2] / 100; + const v = 1 - b; + const c = v - w; + let g = 0; + if (c < 1) { + g = (v - c) / (1 - c); + } + return [hwb[0], c * 100, g * 100]; +}; +convert.apple.rgb = function(apple) { + return [apple[0] / 65535 * 255, apple[1] / 65535 * 255, apple[2] / 65535 * 255]; +}; +convert.rgb.apple = function(rgb) { + return [rgb[0] / 255 * 65535, rgb[1] / 255 * 65535, rgb[2] / 255 * 65535]; +}; +convert.gray.rgb = function(args) { + return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; +}; +convert.gray.hsl = function(args) { + return [0, 0, args[0]]; +}; +convert.gray.hsv = convert.gray.hsl; +convert.gray.hwb = function(gray) { + return [0, 100, gray[0]]; +}; +convert.gray.cmyk = function(gray) { + return [0, 0, 0, gray[0]]; +}; +convert.gray.lab = function(gray) { + return [gray[0], 0, 0]; +}; +convert.gray.hex = function(gray) { + const value = Math.round(gray[0] / 100 * 255) & 255; + const integer = (value << 16) + (value << 8) + value; + const string = integer.toString(16).toUpperCase(); + return "000000".slice(string.length) + string; +}; +convert.rgb.gray = function(rgb) { + const value = (rgb[0] + rgb[1] + rgb[2]) / 3; + return [value / 255 * 100]; +}; + +// node_modules/color-convert/route.js +function buildGraph() { + const graph = {}; + const models2 = Object.keys(conversions_default); + for (let { length } = models2, i = 0; i < length; i++) { + graph[models2[i]] = { + // http://jsperf.com/1-vs-infinity + // micro-opt, but this is simple. + distance: -1, + parent: null + }; + } + return graph; +} +function deriveBFS(fromModel) { + const graph = buildGraph(); + const queue = [fromModel]; + graph[fromModel].distance = 0; + while (queue.length > 0) { + const current = queue.pop(); + const adjacents = Object.keys(conversions_default[current]); + for (let { length } = adjacents, i = 0; i < length; i++) { + const adjacent = adjacents[i]; + const node = graph[adjacent]; + if (node.distance === -1) { + node.distance = graph[current].distance + 1; + node.parent = current; + queue.unshift(adjacent); + } + } + } + return graph; +} +function link(from, to) { + return function(args) { + return to(from(args)); + }; +} +function wrapConversion(toModel, graph) { + const path = [graph[toModel].parent, toModel]; + let fn = conversions_default[graph[toModel].parent][toModel]; + let cur = graph[toModel].parent; + while (graph[cur].parent) { + path.unshift(graph[cur].parent); + fn = link(conversions_default[graph[cur].parent][cur], fn); + cur = graph[cur].parent; + } + fn.conversion = path; + return fn; +} +function route(fromModel) { + const graph = deriveBFS(fromModel); + const conversion = {}; + const models2 = Object.keys(graph); + for (let { length } = models2, i = 0; i < length; i++) { + const toModel = models2[i]; + const node = graph[toModel]; + if (node.parent === null) { + continue; + } + conversion[toModel] = wrapConversion(toModel, graph); + } + return conversion; +} +var route_default = route; + +// node_modules/color-convert/index.js +var convert2 = {}; +var models = Object.keys(conversions_default); +function wrapRaw(fn) { + const wrappedFn = function(...args) { + const arg0 = args[0]; + if (arg0 === void 0 || arg0 === null) { + return arg0; + } + if (arg0.length > 1) { + args = arg0; + } + return fn(args); + }; + if ("conversion" in fn) { + wrappedFn.conversion = fn.conversion; + } + return wrappedFn; +} +function wrapRounded(fn) { + const wrappedFn = function(...args) { + const arg0 = args[0]; + if (arg0 === void 0 || arg0 === null) { + return arg0; + } + if (arg0.length > 1) { + args = arg0; + } + const result = fn(args); + if (typeof result === "object") { + for (let { length } = result, i = 0; i < length; i++) { + result[i] = Math.round(result[i]); + } + } + return result; + }; + if ("conversion" in fn) { + wrappedFn.conversion = fn.conversion; + } + return wrappedFn; +} +for (const fromModel of models) { + convert2[fromModel] = {}; + Object.defineProperty(convert2[fromModel], "channels", { value: conversions_default[fromModel].channels }); + Object.defineProperty(convert2[fromModel], "labels", { value: conversions_default[fromModel].labels }); + const routes = route_default(fromModel); + const routeModels = Object.keys(routes); + for (const toModel of routeModels) { + const fn = routes[toModel]; + convert2[fromModel][toModel] = wrapRounded(fn); + convert2[fromModel][toModel].raw = wrapRaw(fn); + } +} +var color_convert_default = convert2; + +// node_modules/color/index.js +var skippedModels = [ + // To be honest, I don't really feel like keyword belongs in color convert, but eh. + "keyword", + // Gray conflicts with some method names, and has its own method defined. + "gray", + // Shouldn't really be in color-convert either... + "hex" +]; +var hashedModelKeys = {}; +for (const model of Object.keys(color_convert_default)) { + hashedModelKeys[[...color_convert_default[model].labels].sort().join("")] = model; +} +var limiters = {}; +function Color(object, model) { + if (!(this instanceof Color)) { + return new Color(object, model); + } + if (model && model in skippedModels) { + model = null; + } + if (model && !(model in color_convert_default)) { + throw new Error("Unknown model: " + model); + } + let i; + let channels; + if (object == null) { + this.model = "rgb"; + this.color = [0, 0, 0]; + this.valpha = 1; + } else if (object instanceof Color) { + this.model = object.model; + this.color = [...object.color]; + this.valpha = object.valpha; + } else if (typeof object === "string") { + const result = color_string_default.get(object); + if (result === null) { + throw new Error("Unable to parse color from string: " + object); + } + this.model = result.model; + channels = color_convert_default[this.model].channels; + this.color = result.value.slice(0, channels); + this.valpha = typeof result.value[channels] === "number" ? result.value[channels] : 1; + } else if (object.length > 0) { + this.model = model || "rgb"; + channels = color_convert_default[this.model].channels; + const newArray = Array.prototype.slice.call(object, 0, channels); + this.color = zeroArray(newArray, channels); + this.valpha = typeof object[channels] === "number" ? object[channels] : 1; + } else if (typeof object === "number") { + this.model = "rgb"; + this.color = [ + object >> 16 & 255, + object >> 8 & 255, + object & 255 + ]; + this.valpha = 1; + } else { + this.valpha = 1; + const keys = Object.keys(object); + if ("alpha" in object) { + keys.splice(keys.indexOf("alpha"), 1); + this.valpha = typeof object.alpha === "number" ? object.alpha : 0; + } + const hashedKeys = keys.sort().join(""); + if (!(hashedKeys in hashedModelKeys)) { + throw new Error("Unable to parse color from object: " + JSON.stringify(object)); + } + this.model = hashedModelKeys[hashedKeys]; + const { labels } = color_convert_default[this.model]; + const color = []; + for (i = 0; i < labels.length; i++) { + color.push(object[labels[i]]); + } + this.color = zeroArray(color); + } + if (limiters[this.model]) { + channels = color_convert_default[this.model].channels; + for (i = 0; i < channels; i++) { + const limit = limiters[this.model][i]; + if (limit) { + this.color[i] = limit(this.color[i]); + } + } + } + this.valpha = Math.max(0, Math.min(1, this.valpha)); + if (Object.freeze) { + Object.freeze(this); + } +} +Color.prototype = { + toString() { + return this.string(); + }, + toJSON() { + return this[this.model](); + }, + string(places) { + let self = this.model in color_string_default.to ? this : this.rgb(); + self = self.round(typeof places === "number" ? places : 1); + const arguments_ = self.valpha === 1 ? self.color : [...self.color, this.valpha]; + return color_string_default.to[self.model](...arguments_); + }, + percentString(places) { + const self = this.rgb().round(typeof places === "number" ? places : 1); + const arguments_ = self.valpha === 1 ? self.color : [...self.color, this.valpha]; + return color_string_default.to.rgb.percent(...arguments_); + }, + array() { + return this.valpha === 1 ? [...this.color] : [...this.color, this.valpha]; + }, + object() { + const result = {}; + const { channels } = color_convert_default[this.model]; + const { labels } = color_convert_default[this.model]; + for (let i = 0; i < channels; i++) { + result[labels[i]] = this.color[i]; + } + if (this.valpha !== 1) { + result.alpha = this.valpha; + } + return result; + }, + unitArray() { + const rgb = this.rgb().color; + rgb[0] /= 255; + rgb[1] /= 255; + rgb[2] /= 255; + if (this.valpha !== 1) { + rgb.push(this.valpha); + } + return rgb; + }, + unitObject() { + const rgb = this.rgb().object(); + rgb.r /= 255; + rgb.g /= 255; + rgb.b /= 255; + if (this.valpha !== 1) { + rgb.alpha = this.valpha; + } + return rgb; + }, + round(places) { + places = Math.max(places || 0, 0); + return new Color([...this.color.map(roundToPlace(places)), this.valpha], this.model); + }, + alpha(value) { + if (value !== void 0) { + return new Color([...this.color, Math.max(0, Math.min(1, value))], this.model); + } + return this.valpha; + }, + // Rgb + red: getset("rgb", 0, maxfn(255)), + green: getset("rgb", 1, maxfn(255)), + blue: getset("rgb", 2, maxfn(255)), + hue: getset(["hsl", "hsv", "hsl", "hwb", "hcg"], 0, (value) => (value % 360 + 360) % 360), + saturationl: getset("hsl", 1, maxfn(100)), + lightness: getset("hsl", 2, maxfn(100)), + saturationv: getset("hsv", 1, maxfn(100)), + value: getset("hsv", 2, maxfn(100)), + chroma: getset("hcg", 1, maxfn(100)), + gray: getset("hcg", 2, maxfn(100)), + white: getset("hwb", 1, maxfn(100)), + wblack: getset("hwb", 2, maxfn(100)), + cyan: getset("cmyk", 0, maxfn(100)), + magenta: getset("cmyk", 1, maxfn(100)), + yellow: getset("cmyk", 2, maxfn(100)), + black: getset("cmyk", 3, maxfn(100)), + x: getset("xyz", 0, maxfn(95.047)), + y: getset("xyz", 1, maxfn(100)), + z: getset("xyz", 2, maxfn(108.833)), + l: getset("lab", 0, maxfn(100)), + a: getset("lab", 1), + b: getset("lab", 2), + keyword(value) { + if (value !== void 0) { + return new Color(value); + } + return color_convert_default[this.model].keyword(this.color); + }, + hex(value) { + if (value !== void 0) { + return new Color(value); + } + return color_string_default.to.hex(...this.rgb().round().color); + }, + hexa(value) { + if (value !== void 0) { + return new Color(value); + } + const rgbArray = this.rgb().round().color; + let alphaHex = Math.round(this.valpha * 255).toString(16).toUpperCase(); + if (alphaHex.length === 1) { + alphaHex = "0" + alphaHex; + } + return color_string_default.to.hex(...rgbArray) + alphaHex; + }, + rgbNumber() { + const rgb = this.rgb().color; + return (rgb[0] & 255) << 16 | (rgb[1] & 255) << 8 | rgb[2] & 255; + }, + luminosity() { + const rgb = this.rgb().color; + const lum = []; + for (const [i, element] of rgb.entries()) { + const chan = element / 255; + lum[i] = chan <= 0.04045 ? chan / 12.92 : ((chan + 0.055) / 1.055) ** 2.4; + } + return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2]; + }, + contrast(color2) { + const lum1 = this.luminosity(); + const lum2 = color2.luminosity(); + if (lum1 > lum2) { + return (lum1 + 0.05) / (lum2 + 0.05); + } + return (lum2 + 0.05) / (lum1 + 0.05); + }, + level(color2) { + const contrastRatio = this.contrast(color2); + if (contrastRatio >= 7) { + return "AAA"; + } + return contrastRatio >= 4.5 ? "AA" : ""; + }, + isDark() { + const rgb = this.rgb().color; + const yiq = (rgb[0] * 2126 + rgb[1] * 7152 + rgb[2] * 722) / 1e4; + return yiq < 128; + }, + isLight() { + return !this.isDark(); + }, + negate() { + const rgb = this.rgb(); + for (let i = 0; i < 3; i++) { + rgb.color[i] = 255 - rgb.color[i]; + } + return rgb; + }, + lighten(ratio) { + const hsl = this.hsl(); + hsl.color[2] += hsl.color[2] * ratio; + return hsl; + }, + darken(ratio) { + const hsl = this.hsl(); + hsl.color[2] -= hsl.color[2] * ratio; + return hsl; + }, + saturate(ratio) { + const hsl = this.hsl(); + hsl.color[1] += hsl.color[1] * ratio; + return hsl; + }, + desaturate(ratio) { + const hsl = this.hsl(); + hsl.color[1] -= hsl.color[1] * ratio; + return hsl; + }, + whiten(ratio) { + const hwb = this.hwb(); + hwb.color[1] += hwb.color[1] * ratio; + return hwb; + }, + blacken(ratio) { + const hwb = this.hwb(); + hwb.color[2] += hwb.color[2] * ratio; + return hwb; + }, + grayscale() { + const rgb = this.rgb().color; + const value = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11; + return Color.rgb(value, value, value); + }, + fade(ratio) { + return this.alpha(this.valpha - this.valpha * ratio); + }, + opaquer(ratio) { + return this.alpha(this.valpha + this.valpha * ratio); + }, + rotate(degrees) { + const hsl = this.hsl(); + let hue = hsl.color[0]; + hue = (hue + degrees) % 360; + hue = hue < 0 ? 360 + hue : hue; + hsl.color[0] = hue; + return hsl; + }, + mix(mixinColor, weight) { + if (!mixinColor || !mixinColor.rgb) { + throw new Error('Argument to "mix" was not a Color instance, but rather an instance of ' + typeof mixinColor); + } + const color1 = mixinColor.rgb(); + const color2 = this.rgb(); + const p = weight === void 0 ? 0.5 : weight; + const w = 2 * p - 1; + const a = color1.alpha() - color2.alpha(); + const w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2; + const w2 = 1 - w1; + return Color.rgb( + w1 * color1.red() + w2 * color2.red(), + w1 * color1.green() + w2 * color2.green(), + w1 * color1.blue() + w2 * color2.blue(), + color1.alpha() * p + color2.alpha() * (1 - p) + ); + } +}; +for (const model of Object.keys(color_convert_default)) { + if (skippedModels.includes(model)) { + continue; + } + const { channels } = color_convert_default[model]; + Color.prototype[model] = function(...arguments_) { + if (this.model === model) { + return new Color(this); + } + if (arguments_.length > 0) { + return new Color(arguments_, model); + } + return new Color([...assertArray(color_convert_default[this.model][model].raw(this.color)), this.valpha], model); + }; + Color[model] = function(...arguments_) { + let color = arguments_[0]; + if (typeof color === "number") { + color = zeroArray(arguments_, channels); + } + return new Color(color, model); + }; +} +function roundTo(number, places) { + return Number(number.toFixed(places)); +} +function roundToPlace(places) { + return function(number) { + return roundTo(number, places); + }; +} +function getset(model, channel, modifier) { + model = Array.isArray(model) ? model : [model]; + for (const m of model) { + (limiters[m] ||= [])[channel] = modifier; + } + model = model[0]; + return function(value) { + let result; + if (value !== void 0) { + if (modifier) { + value = modifier(value); + } + result = this[model](); + result.color[channel] = value; + return result; + } + result = this[model]().color[channel]; + if (modifier) { + result = modifier(result); + } + return result; + }; +} +function maxfn(max) { + return function(v) { + return Math.max(0, Math.min(max, v)); + }; +} +function assertArray(value) { + return Array.isArray(value) ? value : [value]; +} +function zeroArray(array, length) { + for (let i = 0; i < length; i++) { + if (typeof array[i] !== "number") { + array[i] = 0; + } + } + return array; +} +var index_default = Color; diff --git a/node_modules/@img/colour/index.cjs b/node_modules/@img/colour/index.cjs new file mode 100644 index 0000000..25596b2 --- /dev/null +++ b/node_modules/@img/colour/index.cjs @@ -0,0 +1 @@ +module.exports = require("./color.cjs").default; diff --git a/node_modules/@img/colour/package.json b/node_modules/@img/colour/package.json new file mode 100644 index 0000000..dc991b2 --- /dev/null +++ b/node_modules/@img/colour/package.json @@ -0,0 +1,45 @@ +{ + "name": "@img/colour", + "version": "1.0.0", + "description": "The ESM-only 'color' package made compatible for use with CommonJS runtimes", + "license": "MIT", + "main": "index.cjs", + "authors": [ + "Heather Arthur ", + "Josh Junon ", + "Maxime Thirouin", + "Dyma Ywanov ", + "LitoMore (https://github.com/LitoMore)" + ], + "engines": { + "node": ">=18" + }, + "files": [ + "color.cjs" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/lovell/colour.git" + }, + "type": "commonjs", + "keywords": [ + "color", + "colour", + "cjs", + "commonjs" + ], + "scripts": { + "build": "esbuild node_modules/color/index.js --bundle --platform=node --outfile=color.cjs", + "test": "node --test" + }, + "devDependencies": { + "color": "5.0.0", + "color-convert": "3.1.0", + "color-name": "2.0.0", + "color-string": "2.1.0", + "esbuild": "^0.25.9" + } +} diff --git a/node_modules/@img/sharp-libvips-linux-x64/README.md b/node_modules/@img/sharp-libvips-linux-x64/README.md new file mode 100644 index 0000000..9b2ce93 --- /dev/null +++ b/node_modules/@img/sharp-libvips-linux-x64/README.md @@ -0,0 +1,46 @@ +# `@img/sharp-libvips-linux-x64` + +Prebuilt libvips and dependencies for use with sharp on Linux (glibc) x64. + +## Licensing + +This software contains third-party libraries +used under the terms of the following licences: + +| Library | Used under the terms of | +|---------------|-----------------------------------------------------------------------------------------------------------| +| aom | BSD 2-Clause + [Alliance for Open Media Patent License 1.0](https://aomedia.org/license/patent-license/) | +| cairo | Mozilla Public License 2.0 | +| cgif | MIT Licence | +| expat | MIT Licence | +| fontconfig | [fontconfig Licence](https://gitlab.freedesktop.org/fontconfig/fontconfig/blob/main/COPYING) (BSD-like) | +| freetype | [freetype Licence](https://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/docs/FTL.TXT) (BSD-like) | +| fribidi | LGPLv3 | +| glib | LGPLv3 | +| harfbuzz | MIT Licence | +| highway | Apache-2.0 License, BSD 3-Clause | +| lcms | MIT Licence | +| libarchive | BSD 2-Clause | +| libexif | LGPLv3 | +| libffi | MIT Licence | +| libheif | LGPLv3 | +| libimagequant | [BSD 2-Clause](https://github.com/lovell/libimagequant/blob/main/COPYRIGHT) | +| libnsgif | MIT Licence | +| libpng | [libpng License](https://github.com/pnggroup/libpng/blob/master/LICENSE) | +| librsvg | LGPLv3 | +| libspng | [BSD 2-Clause, libpng License](https://github.com/randy408/libspng/blob/master/LICENSE) | +| libtiff | [libtiff License](https://gitlab.com/libtiff/libtiff/blob/master/LICENSE.md) (BSD-like) | +| libvips | LGPLv3 | +| libwebp | New BSD License | +| libxml2 | MIT Licence | +| mozjpeg | [zlib License, IJG License, BSD-3-Clause](https://github.com/mozilla/mozjpeg/blob/master/LICENSE.md) | +| pango | LGPLv3 | +| pixman | MIT Licence | +| proxy-libintl | LGPLv3 | +| zlib-ng | [zlib Licence](https://github.com/zlib-ng/zlib-ng/blob/develop/LICENSE.md) | + +Use of libraries under the terms of the LGPLv3 is via the +"any later version" clause of the LGPLv2 or LGPLv2.1. + +Please report any errors or omissions via +https://github.com/lovell/sharp-libvips/issues/new diff --git a/node_modules/@img/sharp-libvips-linux-x64/lib/glib-2.0/include/glibconfig.h b/node_modules/@img/sharp-libvips-linux-x64/lib/glib-2.0/include/glibconfig.h new file mode 100644 index 0000000..17473b8 --- /dev/null +++ b/node_modules/@img/sharp-libvips-linux-x64/lib/glib-2.0/include/glibconfig.h @@ -0,0 +1,221 @@ +/* glibconfig.h + * + * This is a generated file. Please modify 'glibconfig.h.in' + */ + +#ifndef __GLIBCONFIG_H__ +#define __GLIBCONFIG_H__ + +#include + +#include +#include +#define GLIB_HAVE_ALLOCA_H + +#define GLIB_STATIC_COMPILATION 1 +#define GOBJECT_STATIC_COMPILATION 1 +#define GIO_STATIC_COMPILATION 1 +#define GMODULE_STATIC_COMPILATION 1 +#define GI_STATIC_COMPILATION 1 +#define G_INTL_STATIC_COMPILATION 1 +#define FFI_STATIC_BUILD 1 + +/* Specifies that GLib's g_print*() functions wrap the + * system printf functions. This is useful to know, for example, + * when using glibc's register_printf_function(). + */ +#define GLIB_USING_SYSTEM_PRINTF + +G_BEGIN_DECLS + +#define G_MINFLOAT FLT_MIN +#define G_MAXFLOAT FLT_MAX +#define G_MINDOUBLE DBL_MIN +#define G_MAXDOUBLE DBL_MAX +#define G_MINSHORT SHRT_MIN +#define G_MAXSHORT SHRT_MAX +#define G_MAXUSHORT USHRT_MAX +#define G_MININT INT_MIN +#define G_MAXINT INT_MAX +#define G_MAXUINT UINT_MAX +#define G_MINLONG LONG_MIN +#define G_MAXLONG LONG_MAX +#define G_MAXULONG ULONG_MAX + +typedef signed char gint8; +typedef unsigned char guint8; + +typedef signed short gint16; +typedef unsigned short guint16; + +#define G_GINT16_MODIFIER "h" +#define G_GINT16_FORMAT "hi" +#define G_GUINT16_FORMAT "hu" + + +typedef signed int gint32; +typedef unsigned int guint32; + +#define G_GINT32_MODIFIER "" +#define G_GINT32_FORMAT "i" +#define G_GUINT32_FORMAT "u" + + +#define G_HAVE_GINT64 1 /* deprecated, always true */ + +typedef signed long gint64; +typedef unsigned long guint64; + +#define G_GINT64_CONSTANT(val) (val##L) +#define G_GUINT64_CONSTANT(val) (val##UL) + +#define G_GINT64_MODIFIER "l" +#define G_GINT64_FORMAT "li" +#define G_GUINT64_FORMAT "lu" + + +#define GLIB_SIZEOF_VOID_P 8 +#define GLIB_SIZEOF_LONG 8 +#define GLIB_SIZEOF_SIZE_T 8 +#define GLIB_SIZEOF_SSIZE_T 8 + +typedef signed long gssize; +typedef unsigned long gsize; +#define G_GSIZE_MODIFIER "l" +#define G_GSSIZE_MODIFIER "l" +#define G_GSIZE_FORMAT "lu" +#define G_GSSIZE_FORMAT "li" + +#define G_MAXSIZE G_MAXULONG +#define G_MINSSIZE G_MINLONG +#define G_MAXSSIZE G_MAXLONG + +typedef gint64 goffset; +#define G_MINOFFSET G_MININT64 +#define G_MAXOFFSET G_MAXINT64 + +#define G_GOFFSET_MODIFIER G_GINT64_MODIFIER +#define G_GOFFSET_FORMAT G_GINT64_FORMAT +#define G_GOFFSET_CONSTANT(val) G_GINT64_CONSTANT(val) + +#define G_POLLFD_FORMAT "%d" + +#define GPOINTER_TO_INT(p) ((gint) (glong) (p)) +#define GPOINTER_TO_UINT(p) ((guint) (gulong) (p)) + +#define GINT_TO_POINTER(i) ((gpointer) (glong) (i)) +#define GUINT_TO_POINTER(u) ((gpointer) (gulong) (u)) + +typedef signed long gintptr; +typedef unsigned long guintptr; + +#define G_GINTPTR_MODIFIER "l" +#define G_GINTPTR_FORMAT "li" +#define G_GUINTPTR_FORMAT "lu" + +#define GLIB_MAJOR_VERSION 2 +#define GLIB_MINOR_VERSION 86 +#define GLIB_MICRO_VERSION 0 + +#define G_OS_UNIX + +#define G_VA_COPY va_copy + +#define G_VA_COPY_AS_ARRAY 1 + +#define G_HAVE_ISO_VARARGS 1 + +/* gcc-2.95.x supports both gnu style and ISO varargs, but if -ansi + * is passed ISO vararg support is turned off, and there is no work + * around to turn it on, so we unconditionally turn it off. + */ +#if __GNUC__ == 2 && __GNUC_MINOR__ == 95 +# undef G_HAVE_ISO_VARARGS +#endif + +#define G_HAVE_GROWING_STACK 0 + +#ifndef _MSC_VER +# define G_HAVE_GNUC_VARARGS 1 +#endif + +#if defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590) +#define G_GNUC_INTERNAL __attribute__((visibility("hidden"))) +#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) +#define G_GNUC_INTERNAL __hidden +#elif defined (__GNUC__) && defined (G_HAVE_GNUC_VISIBILITY) +#define G_GNUC_INTERNAL __attribute__((visibility("hidden"))) +#else +#define G_GNUC_INTERNAL +#endif + +#define G_THREADS_ENABLED +#define G_THREADS_IMPL_POSIX + +#define G_ATOMIC_LOCK_FREE + +#define GINT16_TO_LE(val) ((gint16) (val)) +#define GUINT16_TO_LE(val) ((guint16) (val)) +#define GINT16_TO_BE(val) ((gint16) GUINT16_SWAP_LE_BE (val)) +#define GUINT16_TO_BE(val) (GUINT16_SWAP_LE_BE (val)) + +#define GINT32_TO_LE(val) ((gint32) (val)) +#define GUINT32_TO_LE(val) ((guint32) (val)) +#define GINT32_TO_BE(val) ((gint32) GUINT32_SWAP_LE_BE (val)) +#define GUINT32_TO_BE(val) (GUINT32_SWAP_LE_BE (val)) + +#define GINT64_TO_LE(val) ((gint64) (val)) +#define GUINT64_TO_LE(val) ((guint64) (val)) +#define GINT64_TO_BE(val) ((gint64) GUINT64_SWAP_LE_BE (val)) +#define GUINT64_TO_BE(val) (GUINT64_SWAP_LE_BE (val)) + +#define GLONG_TO_LE(val) ((glong) GINT64_TO_LE (val)) +#define GULONG_TO_LE(val) ((gulong) GUINT64_TO_LE (val)) +#define GLONG_TO_BE(val) ((glong) GINT64_TO_BE (val)) +#define GULONG_TO_BE(val) ((gulong) GUINT64_TO_BE (val)) +#define GINT_TO_LE(val) ((gint) GINT32_TO_LE (val)) +#define GUINT_TO_LE(val) ((guint) GUINT32_TO_LE (val)) +#define GINT_TO_BE(val) ((gint) GINT32_TO_BE (val)) +#define GUINT_TO_BE(val) ((guint) GUINT32_TO_BE (val)) +#define GSIZE_TO_LE(val) ((gsize) GUINT64_TO_LE (val)) +#define GSSIZE_TO_LE(val) ((gssize) GINT64_TO_LE (val)) +#define GSIZE_TO_BE(val) ((gsize) GUINT64_TO_BE (val)) +#define GSSIZE_TO_BE(val) ((gssize) GINT64_TO_BE (val)) +#define G_BYTE_ORDER G_LITTLE_ENDIAN + +#define GLIB_SYSDEF_POLLIN =1 +#define GLIB_SYSDEF_POLLOUT =4 +#define GLIB_SYSDEF_POLLPRI =2 +#define GLIB_SYSDEF_POLLHUP =16 +#define GLIB_SYSDEF_POLLERR =8 +#define GLIB_SYSDEF_POLLNVAL =32 + +/* No way to disable deprecation warnings for macros, so only emit deprecation + * warnings on platforms where usage of this macro is broken */ +#if defined(__APPLE__) || defined(_MSC_VER) || defined(__CYGWIN__) +#define G_MODULE_SUFFIX "so" GLIB_DEPRECATED_MACRO_IN_2_76 +#else +#define G_MODULE_SUFFIX "so" +#endif + +typedef int GPid; +#define G_PID_FORMAT "i" + +#define GLIB_SYSDEF_AF_UNIX 1 +#define GLIB_SYSDEF_AF_INET 2 +#define GLIB_SYSDEF_AF_INET6 10 + +#define GLIB_SYSDEF_MSG_OOB 1 +#define GLIB_SYSDEF_MSG_PEEK 2 +#define GLIB_SYSDEF_MSG_DONTROUTE 4 + +#define G_DIR_SEPARATOR '/' +#define G_DIR_SEPARATOR_S "/" +#define G_SEARCHPATH_SEPARATOR ':' +#define G_SEARCHPATH_SEPARATOR_S ":" + +#undef G_HAVE_FREE_SIZED + +G_END_DECLS + +#endif /* __GLIBCONFIG_H__ */ diff --git a/node_modules/@img/sharp-libvips-linux-x64/lib/index.js b/node_modules/@img/sharp-libvips-linux-x64/lib/index.js new file mode 100644 index 0000000..5092b4d --- /dev/null +++ b/node_modules/@img/sharp-libvips-linux-x64/lib/index.js @@ -0,0 +1 @@ +module.exports = __dirname; diff --git a/node_modules/@img/sharp-libvips-linux-x64/lib/libvips-cpp.so.8.17.2 b/node_modules/@img/sharp-libvips-linux-x64/lib/libvips-cpp.so.8.17.2 new file mode 100644 index 0000000..fadfe3c Binary files /dev/null and b/node_modules/@img/sharp-libvips-linux-x64/lib/libvips-cpp.so.8.17.2 differ diff --git a/node_modules/@img/sharp-libvips-linux-x64/package.json b/node_modules/@img/sharp-libvips-linux-x64/package.json new file mode 100644 index 0000000..e20ce53 --- /dev/null +++ b/node_modules/@img/sharp-libvips-linux-x64/package.json @@ -0,0 +1,42 @@ +{ + "name": "@img/sharp-libvips-linux-x64", + "version": "1.2.3", + "description": "Prebuilt libvips and dependencies for use with sharp on Linux (glibc) x64", + "author": "Lovell Fuller ", + "homepage": "https://sharp.pixelplumbing.com", + "repository": { + "type": "git", + "url": "git+https://github.com/lovell/sharp-libvips.git", + "directory": "npm/linux-x64" + }, + "license": "LGPL-3.0-or-later", + "funding": { + "url": "https://opencollective.com/libvips" + }, + "preferUnplugged": true, + "publishConfig": { + "access": "public" + }, + "files": [ + "lib", + "versions.json" + ], + "type": "commonjs", + "exports": { + "./lib": "./lib/index.js", + "./package": "./package.json", + "./versions": "./versions.json" + }, + "config": { + "glibc": ">=2.26" + }, + "os": [ + "linux" + ], + "libc": [ + "glibc" + ], + "cpu": [ + "x64" + ] +} diff --git a/node_modules/@img/sharp-libvips-linux-x64/versions.json b/node_modules/@img/sharp-libvips-linux-x64/versions.json new file mode 100644 index 0000000..d9cced1 --- /dev/null +++ b/node_modules/@img/sharp-libvips-linux-x64/versions.json @@ -0,0 +1,30 @@ +{ + "aom": "3.13.1", + "archive": "3.8.1", + "cairo": "1.18.4", + "cgif": "0.5.0", + "exif": "0.6.25", + "expat": "2.7.2", + "ffi": "3.5.2", + "fontconfig": "2.17.1", + "freetype": "2.14.1", + "fribidi": "1.0.16", + "glib": "2.86.0", + "harfbuzz": "11.5.0", + "heif": "1.20.2", + "highway": "1.3.0", + "imagequant": "2.4.1", + "lcms": "2.17", + "mozjpeg": "4.1.5", + "pango": "1.57.0", + "pixman": "0.46.4", + "png": "1.6.50", + "proxy-libintl": "0.5", + "rsvg": "2.61.1", + "spng": "0.7.4", + "tiff": "4.7.0", + "vips": "8.17.2", + "webp": "1.6.0", + "xml2": "2.15.0", + "zlib-ng": "2.2.5" +} \ No newline at end of file diff --git a/node_modules/@img/sharp-linux-x64/LICENSE b/node_modules/@img/sharp-linux-x64/LICENSE new file mode 100644 index 0000000..37ec93a --- /dev/null +++ b/node_modules/@img/sharp-linux-x64/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/node_modules/@img/sharp-linux-x64/README.md b/node_modules/@img/sharp-linux-x64/README.md new file mode 100644 index 0000000..cae31de --- /dev/null +++ b/node_modules/@img/sharp-linux-x64/README.md @@ -0,0 +1,18 @@ +# `@img/sharp-linux-x64` + +Prebuilt sharp for use with Linux (glibc) x64. + +## Licensing + +Copyright 2013 Lovell Fuller and others. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0) + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/node_modules/@img/sharp-linux-x64/lib/sharp-linux-x64.node b/node_modules/@img/sharp-linux-x64/lib/sharp-linux-x64.node new file mode 100644 index 0000000..563aaef Binary files /dev/null and b/node_modules/@img/sharp-linux-x64/lib/sharp-linux-x64.node differ diff --git a/node_modules/@img/sharp-linux-x64/package.json b/node_modules/@img/sharp-linux-x64/package.json new file mode 100644 index 0000000..20996aa --- /dev/null +++ b/node_modules/@img/sharp-linux-x64/package.json @@ -0,0 +1,46 @@ +{ + "name": "@img/sharp-linux-x64", + "version": "0.34.4", + "description": "Prebuilt sharp for use with Linux (glibc) x64", + "author": "Lovell Fuller ", + "homepage": "https://sharp.pixelplumbing.com", + "repository": { + "type": "git", + "url": "git+https://github.com/lovell/sharp.git", + "directory": "npm/linux-x64" + }, + "license": "Apache-2.0", + "funding": { + "url": "https://opencollective.com/libvips" + }, + "preferUnplugged": true, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.3" + }, + "files": [ + "lib" + ], + "publishConfig": { + "access": "public" + }, + "type": "commonjs", + "exports": { + "./sharp.node": "./lib/sharp-linux-x64.node", + "./package": "./package.json" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "config": { + "glibc": ">=2.26" + }, + "os": [ + "linux" + ], + "libc": [ + "glibc" + ], + "cpu": [ + "x64" + ] +} diff --git a/node_modules/@jridgewell/gen-mapping/LICENSE b/node_modules/@jridgewell/gen-mapping/LICENSE new file mode 100644 index 0000000..1f6ce94 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/LICENSE @@ -0,0 +1,19 @@ +Copyright 2024 Justin Ridgewell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@jridgewell/gen-mapping/README.md b/node_modules/@jridgewell/gen-mapping/README.md new file mode 100644 index 0000000..93692b1 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/README.md @@ -0,0 +1,227 @@ +# @jridgewell/gen-mapping + +> Generate source maps + +`gen-mapping` allows you to generate a source map during transpilation or minification. +With a source map, you're able to trace the original location in the source file, either in Chrome's +DevTools or using a library like [`@jridgewell/trace-mapping`][trace-mapping]. + +You may already be familiar with the [`source-map`][source-map] package's `SourceMapGenerator`. This +provides the same `addMapping` and `setSourceContent` API. + +## Installation + +```sh +npm install @jridgewell/gen-mapping +``` + +## Usage + +```typescript +import { GenMapping, addMapping, setSourceContent, toEncodedMap, toDecodedMap } from '@jridgewell/gen-mapping'; + +const map = new GenMapping({ + file: 'output.js', + sourceRoot: 'https://example.com/', +}); + +setSourceContent(map, 'input.js', `function foo() {}`); + +addMapping(map, { + // Lines start at line 1, columns at column 0. + generated: { line: 1, column: 0 }, + source: 'input.js', + original: { line: 1, column: 0 }, +}); + +addMapping(map, { + generated: { line: 1, column: 9 }, + source: 'input.js', + original: { line: 1, column: 9 }, + name: 'foo', +}); + +assert.deepEqual(toDecodedMap(map), { + version: 3, + file: 'output.js', + names: ['foo'], + sourceRoot: 'https://example.com/', + sources: ['input.js'], + sourcesContent: ['function foo() {}'], + mappings: [ + [ [0, 0, 0, 0], [9, 0, 0, 9, 0] ] + ], +}); + +assert.deepEqual(toEncodedMap(map), { + version: 3, + file: 'output.js', + names: ['foo'], + sourceRoot: 'https://example.com/', + sources: ['input.js'], + sourcesContent: ['function foo() {}'], + mappings: 'AAAA,SAASA', +}); +``` + +### Smaller Sourcemaps + +Not everything needs to be added to a sourcemap, and needless markings can cause signficantly +larger file sizes. `gen-mapping` exposes `maybeAddSegment`/`maybeAddMapping` APIs that will +intelligently determine if this marking adds useful information. If not, the marking will be +skipped. + +```typescript +import { maybeAddMapping } from '@jridgewell/gen-mapping'; + +const map = new GenMapping(); + +// Adding a sourceless marking at the beginning of a line isn't useful. +maybeAddMapping(map, { + generated: { line: 1, column: 0 }, +}); + +// Adding a new source marking is useful. +maybeAddMapping(map, { + generated: { line: 1, column: 0 }, + source: 'input.js', + original: { line: 1, column: 0 }, +}); + +// But adding another marking pointing to the exact same original location isn't, even if the +// generated column changed. +maybeAddMapping(map, { + generated: { line: 1, column: 9 }, + source: 'input.js', + original: { line: 1, column: 0 }, +}); + +assert.deepEqual(toEncodedMap(map), { + version: 3, + names: [], + sources: ['input.js'], + sourcesContent: [null], + mappings: 'AAAA', +}); +``` + +## Benchmarks + +``` +node v18.0.0 + +amp.js.map +Memory Usage: +gen-mapping: addSegment 5852872 bytes +gen-mapping: addMapping 7716042 bytes +source-map-js 6143250 bytes +source-map-0.6.1 6124102 bytes +source-map-0.8.0 6121173 bytes +Smallest memory usage is gen-mapping: addSegment + +Adding speed: +gen-mapping: addSegment x 441 ops/sec ±2.07% (90 runs sampled) +gen-mapping: addMapping x 350 ops/sec ±2.40% (86 runs sampled) +source-map-js: addMapping x 169 ops/sec ±2.42% (80 runs sampled) +source-map-0.6.1: addMapping x 167 ops/sec ±2.56% (80 runs sampled) +source-map-0.8.0: addMapping x 168 ops/sec ±2.52% (80 runs sampled) +Fastest is gen-mapping: addSegment + +Generate speed: +gen-mapping: decoded output x 150,824,370 ops/sec ±0.07% (102 runs sampled) +gen-mapping: encoded output x 663 ops/sec ±0.22% (98 runs sampled) +source-map-js: encoded output x 197 ops/sec ±0.45% (84 runs sampled) +source-map-0.6.1: encoded output x 198 ops/sec ±0.33% (85 runs sampled) +source-map-0.8.0: encoded output x 197 ops/sec ±0.06% (93 runs sampled) +Fastest is gen-mapping: decoded output + + +*** + + +babel.min.js.map +Memory Usage: +gen-mapping: addSegment 37578063 bytes +gen-mapping: addMapping 37212897 bytes +source-map-js 47638527 bytes +source-map-0.6.1 47690503 bytes +source-map-0.8.0 47470188 bytes +Smallest memory usage is gen-mapping: addMapping + +Adding speed: +gen-mapping: addSegment x 31.05 ops/sec ±8.31% (43 runs sampled) +gen-mapping: addMapping x 29.83 ops/sec ±7.36% (51 runs sampled) +source-map-js: addMapping x 20.73 ops/sec ±6.22% (38 runs sampled) +source-map-0.6.1: addMapping x 20.03 ops/sec ±10.51% (38 runs sampled) +source-map-0.8.0: addMapping x 19.30 ops/sec ±8.27% (37 runs sampled) +Fastest is gen-mapping: addSegment + +Generate speed: +gen-mapping: decoded output x 381,379,234 ops/sec ±0.29% (96 runs sampled) +gen-mapping: encoded output x 95.15 ops/sec ±2.98% (72 runs sampled) +source-map-js: encoded output x 15.20 ops/sec ±7.41% (33 runs sampled) +source-map-0.6.1: encoded output x 16.36 ops/sec ±10.46% (31 runs sampled) +source-map-0.8.0: encoded output x 16.06 ops/sec ±6.45% (31 runs sampled) +Fastest is gen-mapping: decoded output + + +*** + + +preact.js.map +Memory Usage: +gen-mapping: addSegment 416247 bytes +gen-mapping: addMapping 419824 bytes +source-map-js 1024619 bytes +source-map-0.6.1 1146004 bytes +source-map-0.8.0 1113250 bytes +Smallest memory usage is gen-mapping: addSegment + +Adding speed: +gen-mapping: addSegment x 13,755 ops/sec ±0.15% (98 runs sampled) +gen-mapping: addMapping x 13,013 ops/sec ±0.11% (101 runs sampled) +source-map-js: addMapping x 4,564 ops/sec ±0.21% (98 runs sampled) +source-map-0.6.1: addMapping x 4,562 ops/sec ±0.11% (99 runs sampled) +source-map-0.8.0: addMapping x 4,593 ops/sec ±0.11% (100 runs sampled) +Fastest is gen-mapping: addSegment + +Generate speed: +gen-mapping: decoded output x 379,864,020 ops/sec ±0.23% (93 runs sampled) +gen-mapping: encoded output x 14,368 ops/sec ±4.07% (82 runs sampled) +source-map-js: encoded output x 5,261 ops/sec ±0.21% (99 runs sampled) +source-map-0.6.1: encoded output x 5,124 ops/sec ±0.58% (99 runs sampled) +source-map-0.8.0: encoded output x 5,434 ops/sec ±0.33% (96 runs sampled) +Fastest is gen-mapping: decoded output + + +*** + + +react.js.map +Memory Usage: +gen-mapping: addSegment 975096 bytes +gen-mapping: addMapping 1102981 bytes +source-map-js 2918836 bytes +source-map-0.6.1 2885435 bytes +source-map-0.8.0 2874336 bytes +Smallest memory usage is gen-mapping: addSegment + +Adding speed: +gen-mapping: addSegment x 4,772 ops/sec ±0.15% (100 runs sampled) +gen-mapping: addMapping x 4,456 ops/sec ±0.13% (97 runs sampled) +source-map-js: addMapping x 1,618 ops/sec ±0.24% (97 runs sampled) +source-map-0.6.1: addMapping x 1,622 ops/sec ±0.12% (99 runs sampled) +source-map-0.8.0: addMapping x 1,631 ops/sec ±0.12% (100 runs sampled) +Fastest is gen-mapping: addSegment + +Generate speed: +gen-mapping: decoded output x 379,107,695 ops/sec ±0.07% (99 runs sampled) +gen-mapping: encoded output x 5,421 ops/sec ±1.60% (89 runs sampled) +source-map-js: encoded output x 2,113 ops/sec ±1.81% (98 runs sampled) +source-map-0.6.1: encoded output x 2,126 ops/sec ±0.10% (100 runs sampled) +source-map-0.8.0: encoded output x 2,176 ops/sec ±0.39% (98 runs sampled) +Fastest is gen-mapping: decoded output +``` + +[source-map]: https://www.npmjs.com/package/source-map +[trace-mapping]: https://github.com/jridgewell/sourcemaps/tree/main/packages/trace-mapping diff --git a/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.mjs b/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.mjs new file mode 100644 index 0000000..bbb0cac --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.mjs @@ -0,0 +1,292 @@ +// src/set-array.ts +var SetArray = class { + constructor() { + this._indexes = { __proto__: null }; + this.array = []; + } +}; +function cast(set) { + return set; +} +function get(setarr, key) { + return cast(setarr)._indexes[key]; +} +function put(setarr, key) { + const index = get(setarr, key); + if (index !== void 0) return index; + const { array, _indexes: indexes } = cast(setarr); + const length = array.push(key); + return indexes[key] = length - 1; +} +function remove(setarr, key) { + const index = get(setarr, key); + if (index === void 0) return; + const { array, _indexes: indexes } = cast(setarr); + for (let i = index + 1; i < array.length; i++) { + const k = array[i]; + array[i - 1] = k; + indexes[k]--; + } + indexes[key] = void 0; + array.pop(); +} + +// src/gen-mapping.ts +import { + encode +} from "@jridgewell/sourcemap-codec"; +import { TraceMap, decodedMappings } from "@jridgewell/trace-mapping"; + +// src/sourcemap-segment.ts +var COLUMN = 0; +var SOURCES_INDEX = 1; +var SOURCE_LINE = 2; +var SOURCE_COLUMN = 3; +var NAMES_INDEX = 4; + +// src/gen-mapping.ts +var NO_NAME = -1; +var GenMapping = class { + constructor({ file, sourceRoot } = {}) { + this._names = new SetArray(); + this._sources = new SetArray(); + this._sourcesContent = []; + this._mappings = []; + this.file = file; + this.sourceRoot = sourceRoot; + this._ignoreList = new SetArray(); + } +}; +function cast2(map) { + return map; +} +function addSegment(map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) { + return addSegmentInternal( + false, + map, + genLine, + genColumn, + source, + sourceLine, + sourceColumn, + name, + content + ); +} +function addMapping(map, mapping) { + return addMappingInternal(false, map, mapping); +} +var maybeAddSegment = (map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) => { + return addSegmentInternal( + true, + map, + genLine, + genColumn, + source, + sourceLine, + sourceColumn, + name, + content + ); +}; +var maybeAddMapping = (map, mapping) => { + return addMappingInternal(true, map, mapping); +}; +function setSourceContent(map, source, content) { + const { + _sources: sources, + _sourcesContent: sourcesContent + // _originalScopes: originalScopes, + } = cast2(map); + const index = put(sources, source); + sourcesContent[index] = content; +} +function setIgnore(map, source, ignore = true) { + const { + _sources: sources, + _sourcesContent: sourcesContent, + _ignoreList: ignoreList + // _originalScopes: originalScopes, + } = cast2(map); + const index = put(sources, source); + if (index === sourcesContent.length) sourcesContent[index] = null; + if (ignore) put(ignoreList, index); + else remove(ignoreList, index); +} +function toDecodedMap(map) { + const { + _mappings: mappings, + _sources: sources, + _sourcesContent: sourcesContent, + _names: names, + _ignoreList: ignoreList + // _originalScopes: originalScopes, + // _generatedRanges: generatedRanges, + } = cast2(map); + removeEmptyFinalLines(mappings); + return { + version: 3, + file: map.file || void 0, + names: names.array, + sourceRoot: map.sourceRoot || void 0, + sources: sources.array, + sourcesContent, + mappings, + // originalScopes, + // generatedRanges, + ignoreList: ignoreList.array + }; +} +function toEncodedMap(map) { + const decoded = toDecodedMap(map); + return Object.assign({}, decoded, { + // originalScopes: decoded.originalScopes.map((os) => encodeOriginalScopes(os)), + // generatedRanges: encodeGeneratedRanges(decoded.generatedRanges as GeneratedRange[]), + mappings: encode(decoded.mappings) + }); +} +function fromMap(input) { + const map = new TraceMap(input); + const gen = new GenMapping({ file: map.file, sourceRoot: map.sourceRoot }); + putAll(cast2(gen)._names, map.names); + putAll(cast2(gen)._sources, map.sources); + cast2(gen)._sourcesContent = map.sourcesContent || map.sources.map(() => null); + cast2(gen)._mappings = decodedMappings(map); + if (map.ignoreList) putAll(cast2(gen)._ignoreList, map.ignoreList); + return gen; +} +function allMappings(map) { + const out = []; + const { _mappings: mappings, _sources: sources, _names: names } = cast2(map); + for (let i = 0; i < mappings.length; i++) { + const line = mappings[i]; + for (let j = 0; j < line.length; j++) { + const seg = line[j]; + const generated = { line: i + 1, column: seg[COLUMN] }; + let source = void 0; + let original = void 0; + let name = void 0; + if (seg.length !== 1) { + source = sources.array[seg[SOURCES_INDEX]]; + original = { line: seg[SOURCE_LINE] + 1, column: seg[SOURCE_COLUMN] }; + if (seg.length === 5) name = names.array[seg[NAMES_INDEX]]; + } + out.push({ generated, source, original, name }); + } + } + return out; +} +function addSegmentInternal(skipable, map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) { + const { + _mappings: mappings, + _sources: sources, + _sourcesContent: sourcesContent, + _names: names + // _originalScopes: originalScopes, + } = cast2(map); + const line = getIndex(mappings, genLine); + const index = getColumnIndex(line, genColumn); + if (!source) { + if (skipable && skipSourceless(line, index)) return; + return insert(line, index, [genColumn]); + } + assert(sourceLine); + assert(sourceColumn); + const sourcesIndex = put(sources, source); + const namesIndex = name ? put(names, name) : NO_NAME; + if (sourcesIndex === sourcesContent.length) sourcesContent[sourcesIndex] = content != null ? content : null; + if (skipable && skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIndex)) { + return; + } + return insert( + line, + index, + name ? [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex] : [genColumn, sourcesIndex, sourceLine, sourceColumn] + ); +} +function assert(_val) { +} +function getIndex(arr, index) { + for (let i = arr.length; i <= index; i++) { + arr[i] = []; + } + return arr[index]; +} +function getColumnIndex(line, genColumn) { + let index = line.length; + for (let i = index - 1; i >= 0; index = i--) { + const current = line[i]; + if (genColumn >= current[COLUMN]) break; + } + return index; +} +function insert(array, index, value) { + for (let i = array.length; i > index; i--) { + array[i] = array[i - 1]; + } + array[index] = value; +} +function removeEmptyFinalLines(mappings) { + const { length } = mappings; + let len = length; + for (let i = len - 1; i >= 0; len = i, i--) { + if (mappings[i].length > 0) break; + } + if (len < length) mappings.length = len; +} +function putAll(setarr, array) { + for (let i = 0; i < array.length; i++) put(setarr, array[i]); +} +function skipSourceless(line, index) { + if (index === 0) return true; + const prev = line[index - 1]; + return prev.length === 1; +} +function skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIndex) { + if (index === 0) return false; + const prev = line[index - 1]; + if (prev.length === 1) return false; + return sourcesIndex === prev[SOURCES_INDEX] && sourceLine === prev[SOURCE_LINE] && sourceColumn === prev[SOURCE_COLUMN] && namesIndex === (prev.length === 5 ? prev[NAMES_INDEX] : NO_NAME); +} +function addMappingInternal(skipable, map, mapping) { + const { generated, source, original, name, content } = mapping; + if (!source) { + return addSegmentInternal( + skipable, + map, + generated.line - 1, + generated.column, + null, + null, + null, + null, + null + ); + } + assert(original); + return addSegmentInternal( + skipable, + map, + generated.line - 1, + generated.column, + source, + original.line - 1, + original.column, + name, + content + ); +} +export { + GenMapping, + addMapping, + addSegment, + allMappings, + fromMap, + maybeAddMapping, + maybeAddSegment, + setIgnore, + setSourceContent, + toDecodedMap, + toEncodedMap +}; +//# sourceMappingURL=gen-mapping.mjs.map diff --git a/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.mjs.map b/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.mjs.map new file mode 100644 index 0000000..4e37e45 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.mjs.map @@ -0,0 +1,6 @@ +{ + "version": 3, + "sources": ["../src/set-array.ts", "../src/gen-mapping.ts", "../src/sourcemap-segment.ts"], + "mappings": ";AAUO,IAAM,WAAN,MAAoC;AAAA,EAIzC,cAAc;AACZ,SAAK,WAAW,EAAE,WAAW,KAAK;AAClC,SAAK,QAAQ,CAAC;AAAA,EAChB;AACF;AAWA,SAAS,KAAoB,KAAgC;AAC3D,SAAO;AACT;AAKO,SAAS,IAAmB,QAAqB,KAA4B;AAClF,SAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC;AAMO,SAAS,IAAmB,QAAqB,KAAgB;AAEtE,QAAM,QAAQ,IAAI,QAAQ,GAAG;AAC7B,MAAI,UAAU,OAAW,QAAO;AAEhC,QAAM,EAAE,OAAO,UAAU,QAAQ,IAAI,KAAK,MAAM;AAEhD,QAAM,SAAS,MAAM,KAAK,GAAG;AAC7B,SAAQ,QAAQ,GAAG,IAAI,SAAS;AAClC;AAgBO,SAAS,OAAsB,QAAqB,KAAc;AACvE,QAAM,QAAQ,IAAI,QAAQ,GAAG;AAC7B,MAAI,UAAU,OAAW;AAEzB,QAAM,EAAE,OAAO,UAAU,QAAQ,IAAI,KAAK,MAAM;AAChD,WAAS,IAAI,QAAQ,GAAG,IAAI,MAAM,QAAQ,KAAK;AAC7C,UAAM,IAAI,MAAM,CAAC;AACjB,UAAM,IAAI,CAAC,IAAI;AACf,YAAQ,CAAC;AAAA,EACX;AACA,UAAQ,GAAG,IAAI;AACf,QAAM,IAAI;AACZ;;;AChFA;AAAA,EACE;AAAA,OAGK;AACP,SAAS,UAAU,uBAAuB;;;ACKnC,IAAM,SAAS;AACf,IAAM,gBAAgB;AACtB,IAAM,cAAc;AACpB,IAAM,gBAAgB;AACtB,IAAM,cAAc;;;ADsB3B,IAAM,UAAU;AAKT,IAAM,aAAN,MAAiB;AAAA,EAWtB,YAAY,EAAE,MAAM,WAAW,IAAa,CAAC,GAAG;AAC9C,SAAK,SAAS,IAAI,SAAS;AAC3B,SAAK,WAAW,IAAI,SAAS;AAC7B,SAAK,kBAAkB,CAAC;AACxB,SAAK,YAAY,CAAC;AAGlB,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,cAAc,IAAI,SAAS;AAAA,EAClC;AACF;AAgBA,SAASA,MAAK,KAAyB;AACrC,SAAO;AACT;AAoCO,SAAS,WACd,KACA,SACA,WACA,QACA,YACA,cACA,MACA,SACM;AACN,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAoCO,SAAS,WACd,KACA,SAOM;AACN,SAAO,mBAAmB,OAAO,KAAK,OAAmD;AAC3F;AAOO,IAAM,kBAAqC,CAChD,KACA,SACA,WACA,QACA,YACA,cACA,MACA,YACG;AACH,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAOO,IAAM,kBAAqC,CAAC,KAAK,YAAY;AAClE,SAAO,mBAAmB,MAAM,KAAK,OAAmD;AAC1F;AAKO,SAAS,iBAAiB,KAAiB,QAAgB,SAA8B;AAC9F,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,iBAAiB;AAAA;AAAA,EAEnB,IAAIA,MAAK,GAAG;AACZ,QAAM,QAAQ,IAAI,SAAS,MAAM;AACjC,iBAAe,KAAK,IAAI;AAE1B;AAEO,SAAS,UAAU,KAAiB,QAAgB,SAAS,MAAM;AACxE,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,iBAAiB;AAAA,IACjB,aAAa;AAAA;AAAA,EAEf,IAAIA,MAAK,GAAG;AACZ,QAAM,QAAQ,IAAI,SAAS,MAAM;AACjC,MAAI,UAAU,eAAe,OAAQ,gBAAe,KAAK,IAAI;AAE7D,MAAI,OAAQ,KAAI,YAAY,KAAK;AAAA,MAC5B,QAAO,YAAY,KAAK;AAC/B;AAMO,SAAS,aAAa,KAAmC;AAC9D,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,UAAU;AAAA,IACV,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR,aAAa;AAAA;AAAA;AAAA,EAGf,IAAIA,MAAK,GAAG;AACZ,wBAAsB,QAAQ;AAE9B,SAAO;AAAA,IACL,SAAS;AAAA,IACT,MAAM,IAAI,QAAQ;AAAA,IAClB,OAAO,MAAM;AAAA,IACb,YAAY,IAAI,cAAc;AAAA,IAC9B,SAAS,QAAQ;AAAA,IACjB;AAAA,IACA;AAAA;AAAA;AAAA,IAGA,YAAY,WAAW;AAAA,EACzB;AACF;AAMO,SAAS,aAAa,KAAmC;AAC9D,QAAM,UAAU,aAAa,GAAG;AAChC,SAAO,OAAO,OAAO,CAAC,GAAG,SAAS;AAAA;AAAA;AAAA,IAGhC,UAAU,OAAO,QAAQ,QAAgC;AAAA,EAC3D,CAAC;AACH;AAKO,SAAS,QAAQ,OAAmC;AACzD,QAAM,MAAM,IAAI,SAAS,KAAK;AAC9B,QAAM,MAAM,IAAI,WAAW,EAAE,MAAM,IAAI,MAAM,YAAY,IAAI,WAAW,CAAC;AAEzE,SAAOA,MAAK,GAAG,EAAE,QAAQ,IAAI,KAAK;AAClC,SAAOA,MAAK,GAAG,EAAE,UAAU,IAAI,OAAmB;AAClD,EAAAA,MAAK,GAAG,EAAE,kBAAkB,IAAI,kBAAkB,IAAI,QAAQ,IAAI,MAAM,IAAI;AAC5E,EAAAA,MAAK,GAAG,EAAE,YAAY,gBAAgB,GAAG;AAEzC,MAAI,IAAI,WAAY,QAAOA,MAAK,GAAG,EAAE,aAAa,IAAI,UAAU;AAEhE,SAAO;AACT;AAMO,SAAS,YAAY,KAA4B;AACtD,QAAM,MAAiB,CAAC;AACxB,QAAM,EAAE,WAAW,UAAU,UAAU,SAAS,QAAQ,MAAM,IAAIA,MAAK,GAAG;AAE1E,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAM,OAAO,SAAS,CAAC;AACvB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,MAAM,KAAK,CAAC;AAElB,YAAM,YAAY,EAAE,MAAM,IAAI,GAAG,QAAQ,IAAI,MAAM,EAAE;AACrD,UAAI,SAA6B;AACjC,UAAI,WAA4B;AAChC,UAAI,OAA2B;AAE/B,UAAI,IAAI,WAAW,GAAG;AACpB,iBAAS,QAAQ,MAAM,IAAI,aAAa,CAAC;AACzC,mBAAW,EAAE,MAAM,IAAI,WAAW,IAAI,GAAG,QAAQ,IAAI,aAAa,EAAE;AAEpE,YAAI,IAAI,WAAW,EAAG,QAAO,MAAM,MAAM,IAAI,WAAW,CAAC;AAAA,MAC3D;AAEA,UAAI,KAAK,EAAE,WAAW,QAAQ,UAAU,KAAK,CAAY;AAAA,IAC3D;AAAA,EACF;AAEA,SAAO;AACT;AAGA,SAAS,mBACP,UACA,KACA,SACA,WACA,QACA,YACA,cACA,MACA,SACM;AACN,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,UAAU;AAAA,IACV,iBAAiB;AAAA,IACjB,QAAQ;AAAA;AAAA,EAEV,IAAIA,MAAK,GAAG;AACZ,QAAM,OAAO,SAAS,UAAU,OAAO;AACvC,QAAM,QAAQ,eAAe,MAAM,SAAS;AAE5C,MAAI,CAAC,QAAQ;AACX,QAAI,YAAY,eAAe,MAAM,KAAK,EAAG;AAC7C,WAAO,OAAO,MAAM,OAAO,CAAC,SAAS,CAAC;AAAA,EACxC;AAIA,SAAe,UAAU;AACzB,SAAe,YAAY;AAE3B,QAAM,eAAe,IAAI,SAAS,MAAM;AACxC,QAAM,aAAa,OAAO,IAAI,OAAO,IAAI,IAAI;AAC7C,MAAI,iBAAiB,eAAe,OAAQ,gBAAe,YAAY,IAAI,4BAAW;AAGtF,MAAI,YAAY,WAAW,MAAM,OAAO,cAAc,YAAY,cAAc,UAAU,GAAG;AAC3F;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OACI,CAAC,WAAW,cAAc,YAAY,cAAc,UAAU,IAC9D,CAAC,WAAW,cAAc,YAAY,YAAY;AAAA,EACxD;AACF;AAEA,SAAS,OAAU,MAAkC;AAErD;AAEA,SAAS,SAAY,KAAY,OAAoB;AACnD,WAAS,IAAI,IAAI,QAAQ,KAAK,OAAO,KAAK;AACxC,QAAI,CAAC,IAAI,CAAC;AAAA,EACZ;AACA,SAAO,IAAI,KAAK;AAClB;AAEA,SAAS,eAAe,MAA0B,WAA2B;AAC3E,MAAI,QAAQ,KAAK;AACjB,WAAS,IAAI,QAAQ,GAAG,KAAK,GAAG,QAAQ,KAAK;AAC3C,UAAM,UAAU,KAAK,CAAC;AACtB,QAAI,aAAa,QAAQ,MAAM,EAAG;AAAA,EACpC;AACA,SAAO;AACT;AAEA,SAAS,OAAU,OAAY,OAAe,OAAU;AACtD,WAAS,IAAI,MAAM,QAAQ,IAAI,OAAO,KAAK;AACzC,UAAM,CAAC,IAAI,MAAM,IAAI,CAAC;AAAA,EACxB;AACA,QAAM,KAAK,IAAI;AACjB;AAEA,SAAS,sBAAsB,UAAgC;AAC7D,QAAM,EAAE,OAAO,IAAI;AACnB,MAAI,MAAM;AACV,WAAS,IAAI,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK;AAC1C,QAAI,SAAS,CAAC,EAAE,SAAS,EAAG;AAAA,EAC9B;AACA,MAAI,MAAM,OAAQ,UAAS,SAAS;AACtC;AAEA,SAAS,OAAkC,QAAqB,OAAY;AAC1E,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,IAAK,KAAI,QAAQ,MAAM,CAAC,CAAC;AAC7D;AAEA,SAAS,eAAe,MAA0B,OAAwB;AAGxE,MAAI,UAAU,EAAG,QAAO;AAExB,QAAM,OAAO,KAAK,QAAQ,CAAC;AAI3B,SAAO,KAAK,WAAW;AACzB;AAEA,SAAS,WACP,MACA,OACA,cACA,YACA,cACA,YACS;AAET,MAAI,UAAU,EAAG,QAAO;AAExB,QAAM,OAAO,KAAK,QAAQ,CAAC;AAG3B,MAAI,KAAK,WAAW,EAAG,QAAO;AAI9B,SACE,iBAAiB,KAAK,aAAa,KACnC,eAAe,KAAK,WAAW,KAC/B,iBAAiB,KAAK,aAAa,KACnC,gBAAgB,KAAK,WAAW,IAAI,KAAK,WAAW,IAAI;AAE5D;AAEA,SAAS,mBACP,UACA,KACA,SAOA;AACA,QAAM,EAAE,WAAW,QAAQ,UAAU,MAAM,QAAQ,IAAI;AACvD,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAU,OAAO;AAAA,MACjB,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAY,QAAQ;AACpB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU,OAAO;AAAA,IACjB,UAAU;AAAA,IACV;AAAA,IACA,SAAS,OAAO;AAAA,IAChB,SAAS;AAAA,IACT;AAAA,IACA;AAAA,EACF;AACF;", + "names": ["cast"] +} diff --git a/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.umd.js b/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.umd.js new file mode 100644 index 0000000..cb84af5 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.umd.js @@ -0,0 +1,358 @@ +(function (global, factory) { + if (typeof exports === 'object' && typeof module !== 'undefined') { + factory(module, require('@jridgewell/sourcemap-codec'), require('@jridgewell/trace-mapping')); + module.exports = def(module); + } else if (typeof define === 'function' && define.amd) { + define(['module', '@jridgewell/sourcemap-codec', '@jridgewell/trace-mapping'], function(mod) { + factory.apply(this, arguments); + mod.exports = def(mod); + }); + } else { + const mod = { exports: {} }; + factory(mod, global.sourcemapCodec, global.traceMapping); + global = typeof globalThis !== 'undefined' ? globalThis : global || self; + global.genMapping = def(mod); + } + function def(m) { return 'default' in m.exports ? m.exports.default : m.exports; } +})(this, (function (module, require_sourcemapCodec, require_traceMapping) { +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// umd:@jridgewell/sourcemap-codec +var require_sourcemap_codec = __commonJS({ + "umd:@jridgewell/sourcemap-codec"(exports, module2) { + module2.exports = require_sourcemapCodec; + } +}); + +// umd:@jridgewell/trace-mapping +var require_trace_mapping = __commonJS({ + "umd:@jridgewell/trace-mapping"(exports, module2) { + module2.exports = require_traceMapping; + } +}); + +// src/gen-mapping.ts +var gen_mapping_exports = {}; +__export(gen_mapping_exports, { + GenMapping: () => GenMapping, + addMapping: () => addMapping, + addSegment: () => addSegment, + allMappings: () => allMappings, + fromMap: () => fromMap, + maybeAddMapping: () => maybeAddMapping, + maybeAddSegment: () => maybeAddSegment, + setIgnore: () => setIgnore, + setSourceContent: () => setSourceContent, + toDecodedMap: () => toDecodedMap, + toEncodedMap: () => toEncodedMap +}); +module.exports = __toCommonJS(gen_mapping_exports); + +// src/set-array.ts +var SetArray = class { + constructor() { + this._indexes = { __proto__: null }; + this.array = []; + } +}; +function cast(set) { + return set; +} +function get(setarr, key) { + return cast(setarr)._indexes[key]; +} +function put(setarr, key) { + const index = get(setarr, key); + if (index !== void 0) return index; + const { array, _indexes: indexes } = cast(setarr); + const length = array.push(key); + return indexes[key] = length - 1; +} +function remove(setarr, key) { + const index = get(setarr, key); + if (index === void 0) return; + const { array, _indexes: indexes } = cast(setarr); + for (let i = index + 1; i < array.length; i++) { + const k = array[i]; + array[i - 1] = k; + indexes[k]--; + } + indexes[key] = void 0; + array.pop(); +} + +// src/gen-mapping.ts +var import_sourcemap_codec = __toESM(require_sourcemap_codec()); +var import_trace_mapping = __toESM(require_trace_mapping()); + +// src/sourcemap-segment.ts +var COLUMN = 0; +var SOURCES_INDEX = 1; +var SOURCE_LINE = 2; +var SOURCE_COLUMN = 3; +var NAMES_INDEX = 4; + +// src/gen-mapping.ts +var NO_NAME = -1; +var GenMapping = class { + constructor({ file, sourceRoot } = {}) { + this._names = new SetArray(); + this._sources = new SetArray(); + this._sourcesContent = []; + this._mappings = []; + this.file = file; + this.sourceRoot = sourceRoot; + this._ignoreList = new SetArray(); + } +}; +function cast2(map) { + return map; +} +function addSegment(map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) { + return addSegmentInternal( + false, + map, + genLine, + genColumn, + source, + sourceLine, + sourceColumn, + name, + content + ); +} +function addMapping(map, mapping) { + return addMappingInternal(false, map, mapping); +} +var maybeAddSegment = (map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) => { + return addSegmentInternal( + true, + map, + genLine, + genColumn, + source, + sourceLine, + sourceColumn, + name, + content + ); +}; +var maybeAddMapping = (map, mapping) => { + return addMappingInternal(true, map, mapping); +}; +function setSourceContent(map, source, content) { + const { + _sources: sources, + _sourcesContent: sourcesContent + // _originalScopes: originalScopes, + } = cast2(map); + const index = put(sources, source); + sourcesContent[index] = content; +} +function setIgnore(map, source, ignore = true) { + const { + _sources: sources, + _sourcesContent: sourcesContent, + _ignoreList: ignoreList + // _originalScopes: originalScopes, + } = cast2(map); + const index = put(sources, source); + if (index === sourcesContent.length) sourcesContent[index] = null; + if (ignore) put(ignoreList, index); + else remove(ignoreList, index); +} +function toDecodedMap(map) { + const { + _mappings: mappings, + _sources: sources, + _sourcesContent: sourcesContent, + _names: names, + _ignoreList: ignoreList + // _originalScopes: originalScopes, + // _generatedRanges: generatedRanges, + } = cast2(map); + removeEmptyFinalLines(mappings); + return { + version: 3, + file: map.file || void 0, + names: names.array, + sourceRoot: map.sourceRoot || void 0, + sources: sources.array, + sourcesContent, + mappings, + // originalScopes, + // generatedRanges, + ignoreList: ignoreList.array + }; +} +function toEncodedMap(map) { + const decoded = toDecodedMap(map); + return Object.assign({}, decoded, { + // originalScopes: decoded.originalScopes.map((os) => encodeOriginalScopes(os)), + // generatedRanges: encodeGeneratedRanges(decoded.generatedRanges as GeneratedRange[]), + mappings: (0, import_sourcemap_codec.encode)(decoded.mappings) + }); +} +function fromMap(input) { + const map = new import_trace_mapping.TraceMap(input); + const gen = new GenMapping({ file: map.file, sourceRoot: map.sourceRoot }); + putAll(cast2(gen)._names, map.names); + putAll(cast2(gen)._sources, map.sources); + cast2(gen)._sourcesContent = map.sourcesContent || map.sources.map(() => null); + cast2(gen)._mappings = (0, import_trace_mapping.decodedMappings)(map); + if (map.ignoreList) putAll(cast2(gen)._ignoreList, map.ignoreList); + return gen; +} +function allMappings(map) { + const out = []; + const { _mappings: mappings, _sources: sources, _names: names } = cast2(map); + for (let i = 0; i < mappings.length; i++) { + const line = mappings[i]; + for (let j = 0; j < line.length; j++) { + const seg = line[j]; + const generated = { line: i + 1, column: seg[COLUMN] }; + let source = void 0; + let original = void 0; + let name = void 0; + if (seg.length !== 1) { + source = sources.array[seg[SOURCES_INDEX]]; + original = { line: seg[SOURCE_LINE] + 1, column: seg[SOURCE_COLUMN] }; + if (seg.length === 5) name = names.array[seg[NAMES_INDEX]]; + } + out.push({ generated, source, original, name }); + } + } + return out; +} +function addSegmentInternal(skipable, map, genLine, genColumn, source, sourceLine, sourceColumn, name, content) { + const { + _mappings: mappings, + _sources: sources, + _sourcesContent: sourcesContent, + _names: names + // _originalScopes: originalScopes, + } = cast2(map); + const line = getIndex(mappings, genLine); + const index = getColumnIndex(line, genColumn); + if (!source) { + if (skipable && skipSourceless(line, index)) return; + return insert(line, index, [genColumn]); + } + assert(sourceLine); + assert(sourceColumn); + const sourcesIndex = put(sources, source); + const namesIndex = name ? put(names, name) : NO_NAME; + if (sourcesIndex === sourcesContent.length) sourcesContent[sourcesIndex] = content != null ? content : null; + if (skipable && skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIndex)) { + return; + } + return insert( + line, + index, + name ? [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex] : [genColumn, sourcesIndex, sourceLine, sourceColumn] + ); +} +function assert(_val) { +} +function getIndex(arr, index) { + for (let i = arr.length; i <= index; i++) { + arr[i] = []; + } + return arr[index]; +} +function getColumnIndex(line, genColumn) { + let index = line.length; + for (let i = index - 1; i >= 0; index = i--) { + const current = line[i]; + if (genColumn >= current[COLUMN]) break; + } + return index; +} +function insert(array, index, value) { + for (let i = array.length; i > index; i--) { + array[i] = array[i - 1]; + } + array[index] = value; +} +function removeEmptyFinalLines(mappings) { + const { length } = mappings; + let len = length; + for (let i = len - 1; i >= 0; len = i, i--) { + if (mappings[i].length > 0) break; + } + if (len < length) mappings.length = len; +} +function putAll(setarr, array) { + for (let i = 0; i < array.length; i++) put(setarr, array[i]); +} +function skipSourceless(line, index) { + if (index === 0) return true; + const prev = line[index - 1]; + return prev.length === 1; +} +function skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIndex) { + if (index === 0) return false; + const prev = line[index - 1]; + if (prev.length === 1) return false; + return sourcesIndex === prev[SOURCES_INDEX] && sourceLine === prev[SOURCE_LINE] && sourceColumn === prev[SOURCE_COLUMN] && namesIndex === (prev.length === 5 ? prev[NAMES_INDEX] : NO_NAME); +} +function addMappingInternal(skipable, map, mapping) { + const { generated, source, original, name, content } = mapping; + if (!source) { + return addSegmentInternal( + skipable, + map, + generated.line - 1, + generated.column, + null, + null, + null, + null, + null + ); + } + assert(original); + return addSegmentInternal( + skipable, + map, + generated.line - 1, + generated.column, + source, + original.line - 1, + original.column, + name, + content + ); +} +})); +//# sourceMappingURL=gen-mapping.umd.js.map diff --git a/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.umd.js.map b/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.umd.js.map new file mode 100644 index 0000000..b13750b --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.umd.js.map @@ -0,0 +1,6 @@ +{ + "version": 3, + "sources": ["umd:@jridgewell/sourcemap-codec", "umd:@jridgewell/trace-mapping", "../src/gen-mapping.ts", "../src/set-array.ts", "../src/sourcemap-segment.ts"], + "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,6CAAAA,SAAA;AAAA,IAAAA,QAAO,UAAU;AAAA;AAAA;;;ACAjB;AAAA,2CAAAC,SAAA;AAAA,IAAAA,QAAO,UAAU;AAAA;AAAA;;;ACAjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACUO,IAAM,WAAN,MAAoC;AAAA,EAIzC,cAAc;AACZ,SAAK,WAAW,EAAE,WAAW,KAAK;AAClC,SAAK,QAAQ,CAAC;AAAA,EAChB;AACF;AAWA,SAAS,KAAoB,KAAgC;AAC3D,SAAO;AACT;AAKO,SAAS,IAAmB,QAAqB,KAA4B;AAClF,SAAO,KAAK,MAAM,EAAE,SAAS,GAAG;AAClC;AAMO,SAAS,IAAmB,QAAqB,KAAgB;AAEtE,QAAM,QAAQ,IAAI,QAAQ,GAAG;AAC7B,MAAI,UAAU,OAAW,QAAO;AAEhC,QAAM,EAAE,OAAO,UAAU,QAAQ,IAAI,KAAK,MAAM;AAEhD,QAAM,SAAS,MAAM,KAAK,GAAG;AAC7B,SAAQ,QAAQ,GAAG,IAAI,SAAS;AAClC;AAgBO,SAAS,OAAsB,QAAqB,KAAc;AACvE,QAAM,QAAQ,IAAI,QAAQ,GAAG;AAC7B,MAAI,UAAU,OAAW;AAEzB,QAAM,EAAE,OAAO,UAAU,QAAQ,IAAI,KAAK,MAAM;AAChD,WAAS,IAAI,QAAQ,GAAG,IAAI,MAAM,QAAQ,KAAK;AAC7C,UAAM,IAAI,MAAM,CAAC;AACjB,UAAM,IAAI,CAAC,IAAI;AACf,YAAQ,CAAC;AAAA,EACX;AACA,UAAQ,GAAG,IAAI;AACf,QAAM,IAAI;AACZ;;;ADhFA,6BAIO;AACP,2BAA0C;;;AEKnC,IAAM,SAAS;AACf,IAAM,gBAAgB;AACtB,IAAM,cAAc;AACpB,IAAM,gBAAgB;AACtB,IAAM,cAAc;;;AFsB3B,IAAM,UAAU;AAKT,IAAM,aAAN,MAAiB;AAAA,EAWtB,YAAY,EAAE,MAAM,WAAW,IAAa,CAAC,GAAG;AAC9C,SAAK,SAAS,IAAI,SAAS;AAC3B,SAAK,WAAW,IAAI,SAAS;AAC7B,SAAK,kBAAkB,CAAC;AACxB,SAAK,YAAY,CAAC;AAGlB,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,cAAc,IAAI,SAAS;AAAA,EAClC;AACF;AAgBA,SAASC,MAAK,KAAyB;AACrC,SAAO;AACT;AAoCO,SAAS,WACd,KACA,SACA,WACA,QACA,YACA,cACA,MACA,SACM;AACN,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAoCO,SAAS,WACd,KACA,SAOM;AACN,SAAO,mBAAmB,OAAO,KAAK,OAAmD;AAC3F;AAOO,IAAM,kBAAqC,CAChD,KACA,SACA,WACA,QACA,YACA,cACA,MACA,YACG;AACH,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAOO,IAAM,kBAAqC,CAAC,KAAK,YAAY;AAClE,SAAO,mBAAmB,MAAM,KAAK,OAAmD;AAC1F;AAKO,SAAS,iBAAiB,KAAiB,QAAgB,SAA8B;AAC9F,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,iBAAiB;AAAA;AAAA,EAEnB,IAAIA,MAAK,GAAG;AACZ,QAAM,QAAQ,IAAI,SAAS,MAAM;AACjC,iBAAe,KAAK,IAAI;AAE1B;AAEO,SAAS,UAAU,KAAiB,QAAgB,SAAS,MAAM;AACxE,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,iBAAiB;AAAA,IACjB,aAAa;AAAA;AAAA,EAEf,IAAIA,MAAK,GAAG;AACZ,QAAM,QAAQ,IAAI,SAAS,MAAM;AACjC,MAAI,UAAU,eAAe,OAAQ,gBAAe,KAAK,IAAI;AAE7D,MAAI,OAAQ,KAAI,YAAY,KAAK;AAAA,MAC5B,QAAO,YAAY,KAAK;AAC/B;AAMO,SAAS,aAAa,KAAmC;AAC9D,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,UAAU;AAAA,IACV,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR,aAAa;AAAA;AAAA;AAAA,EAGf,IAAIA,MAAK,GAAG;AACZ,wBAAsB,QAAQ;AAE9B,SAAO;AAAA,IACL,SAAS;AAAA,IACT,MAAM,IAAI,QAAQ;AAAA,IAClB,OAAO,MAAM;AAAA,IACb,YAAY,IAAI,cAAc;AAAA,IAC9B,SAAS,QAAQ;AAAA,IACjB;AAAA,IACA;AAAA;AAAA;AAAA,IAGA,YAAY,WAAW;AAAA,EACzB;AACF;AAMO,SAAS,aAAa,KAAmC;AAC9D,QAAM,UAAU,aAAa,GAAG;AAChC,SAAO,OAAO,OAAO,CAAC,GAAG,SAAS;AAAA;AAAA;AAAA,IAGhC,cAAU,+BAAO,QAAQ,QAAgC;AAAA,EAC3D,CAAC;AACH;AAKO,SAAS,QAAQ,OAAmC;AACzD,QAAM,MAAM,IAAI,8BAAS,KAAK;AAC9B,QAAM,MAAM,IAAI,WAAW,EAAE,MAAM,IAAI,MAAM,YAAY,IAAI,WAAW,CAAC;AAEzE,SAAOA,MAAK,GAAG,EAAE,QAAQ,IAAI,KAAK;AAClC,SAAOA,MAAK,GAAG,EAAE,UAAU,IAAI,OAAmB;AAClD,EAAAA,MAAK,GAAG,EAAE,kBAAkB,IAAI,kBAAkB,IAAI,QAAQ,IAAI,MAAM,IAAI;AAC5E,EAAAA,MAAK,GAAG,EAAE,gBAAY,sCAAgB,GAAG;AAEzC,MAAI,IAAI,WAAY,QAAOA,MAAK,GAAG,EAAE,aAAa,IAAI,UAAU;AAEhE,SAAO;AACT;AAMO,SAAS,YAAY,KAA4B;AACtD,QAAM,MAAiB,CAAC;AACxB,QAAM,EAAE,WAAW,UAAU,UAAU,SAAS,QAAQ,MAAM,IAAIA,MAAK,GAAG;AAE1E,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAM,OAAO,SAAS,CAAC;AACvB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,MAAM,KAAK,CAAC;AAElB,YAAM,YAAY,EAAE,MAAM,IAAI,GAAG,QAAQ,IAAI,MAAM,EAAE;AACrD,UAAI,SAA6B;AACjC,UAAI,WAA4B;AAChC,UAAI,OAA2B;AAE/B,UAAI,IAAI,WAAW,GAAG;AACpB,iBAAS,QAAQ,MAAM,IAAI,aAAa,CAAC;AACzC,mBAAW,EAAE,MAAM,IAAI,WAAW,IAAI,GAAG,QAAQ,IAAI,aAAa,EAAE;AAEpE,YAAI,IAAI,WAAW,EAAG,QAAO,MAAM,MAAM,IAAI,WAAW,CAAC;AAAA,MAC3D;AAEA,UAAI,KAAK,EAAE,WAAW,QAAQ,UAAU,KAAK,CAAY;AAAA,IAC3D;AAAA,EACF;AAEA,SAAO;AACT;AAGA,SAAS,mBACP,UACA,KACA,SACA,WACA,QACA,YACA,cACA,MACA,SACM;AACN,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,UAAU;AAAA,IACV,iBAAiB;AAAA,IACjB,QAAQ;AAAA;AAAA,EAEV,IAAIA,MAAK,GAAG;AACZ,QAAM,OAAO,SAAS,UAAU,OAAO;AACvC,QAAM,QAAQ,eAAe,MAAM,SAAS;AAE5C,MAAI,CAAC,QAAQ;AACX,QAAI,YAAY,eAAe,MAAM,KAAK,EAAG;AAC7C,WAAO,OAAO,MAAM,OAAO,CAAC,SAAS,CAAC;AAAA,EACxC;AAIA,SAAe,UAAU;AACzB,SAAe,YAAY;AAE3B,QAAM,eAAe,IAAI,SAAS,MAAM;AACxC,QAAM,aAAa,OAAO,IAAI,OAAO,IAAI,IAAI;AAC7C,MAAI,iBAAiB,eAAe,OAAQ,gBAAe,YAAY,IAAI,4BAAW;AAGtF,MAAI,YAAY,WAAW,MAAM,OAAO,cAAc,YAAY,cAAc,UAAU,GAAG;AAC3F;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OACI,CAAC,WAAW,cAAc,YAAY,cAAc,UAAU,IAC9D,CAAC,WAAW,cAAc,YAAY,YAAY;AAAA,EACxD;AACF;AAEA,SAAS,OAAU,MAAkC;AAErD;AAEA,SAAS,SAAY,KAAY,OAAoB;AACnD,WAAS,IAAI,IAAI,QAAQ,KAAK,OAAO,KAAK;AACxC,QAAI,CAAC,IAAI,CAAC;AAAA,EACZ;AACA,SAAO,IAAI,KAAK;AAClB;AAEA,SAAS,eAAe,MAA0B,WAA2B;AAC3E,MAAI,QAAQ,KAAK;AACjB,WAAS,IAAI,QAAQ,GAAG,KAAK,GAAG,QAAQ,KAAK;AAC3C,UAAM,UAAU,KAAK,CAAC;AACtB,QAAI,aAAa,QAAQ,MAAM,EAAG;AAAA,EACpC;AACA,SAAO;AACT;AAEA,SAAS,OAAU,OAAY,OAAe,OAAU;AACtD,WAAS,IAAI,MAAM,QAAQ,IAAI,OAAO,KAAK;AACzC,UAAM,CAAC,IAAI,MAAM,IAAI,CAAC;AAAA,EACxB;AACA,QAAM,KAAK,IAAI;AACjB;AAEA,SAAS,sBAAsB,UAAgC;AAC7D,QAAM,EAAE,OAAO,IAAI;AACnB,MAAI,MAAM;AACV,WAAS,IAAI,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK;AAC1C,QAAI,SAAS,CAAC,EAAE,SAAS,EAAG;AAAA,EAC9B;AACA,MAAI,MAAM,OAAQ,UAAS,SAAS;AACtC;AAEA,SAAS,OAAkC,QAAqB,OAAY;AAC1E,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,IAAK,KAAI,QAAQ,MAAM,CAAC,CAAC;AAC7D;AAEA,SAAS,eAAe,MAA0B,OAAwB;AAGxE,MAAI,UAAU,EAAG,QAAO;AAExB,QAAM,OAAO,KAAK,QAAQ,CAAC;AAI3B,SAAO,KAAK,WAAW;AACzB;AAEA,SAAS,WACP,MACA,OACA,cACA,YACA,cACA,YACS;AAET,MAAI,UAAU,EAAG,QAAO;AAExB,QAAM,OAAO,KAAK,QAAQ,CAAC;AAG3B,MAAI,KAAK,WAAW,EAAG,QAAO;AAI9B,SACE,iBAAiB,KAAK,aAAa,KACnC,eAAe,KAAK,WAAW,KAC/B,iBAAiB,KAAK,aAAa,KACnC,gBAAgB,KAAK,WAAW,IAAI,KAAK,WAAW,IAAI;AAE5D;AAEA,SAAS,mBACP,UACA,KACA,SAOA;AACA,QAAM,EAAE,WAAW,QAAQ,UAAU,MAAM,QAAQ,IAAI;AACvD,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAU,OAAO;AAAA,MACjB,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAY,QAAQ;AACpB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU,OAAO;AAAA,IACjB,UAAU;AAAA,IACV;AAAA,IACA,SAAS,OAAO;AAAA,IAChB,SAAS;AAAA,IACT;AAAA,IACA;AAAA,EACF;AACF;", + "names": ["module", "module", "cast"] +} diff --git a/node_modules/@jridgewell/gen-mapping/dist/types/gen-mapping.d.ts b/node_modules/@jridgewell/gen-mapping/dist/types/gen-mapping.d.ts new file mode 100644 index 0000000..9ba936e --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/dist/types/gen-mapping.d.ts @@ -0,0 +1,88 @@ +import type { SourceMapInput } from '@jridgewell/trace-mapping'; +import type { DecodedSourceMap, EncodedSourceMap, Pos, Mapping } from './types'; +export type { DecodedSourceMap, EncodedSourceMap, Mapping }; +export type Options = { + file?: string | null; + sourceRoot?: string | null; +}; +/** + * Provides the state to generate a sourcemap. + */ +export declare class GenMapping { + private _names; + private _sources; + private _sourcesContent; + private _mappings; + private _ignoreList; + file: string | null | undefined; + sourceRoot: string | null | undefined; + constructor({ file, sourceRoot }?: Options); +} +/** + * A low-level API to associate a generated position with an original source position. Line and + * column here are 0-based, unlike `addMapping`. + */ +export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source?: null, sourceLine?: null, sourceColumn?: null, name?: null, content?: null): void; +export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name?: null, content?: string | null): void; +export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name: string, content?: string | null): void; +/** + * A high-level API to associate a generated position with an original source position. Line is + * 1-based, but column is 0-based, due to legacy behavior in `source-map` library. + */ +export declare function addMapping(map: GenMapping, mapping: { + generated: Pos; + source?: null; + original?: null; + name?: null; + content?: null; +}): void; +export declare function addMapping(map: GenMapping, mapping: { + generated: Pos; + source: string; + original: Pos; + name?: null; + content?: string | null; +}): void; +export declare function addMapping(map: GenMapping, mapping: { + generated: Pos; + source: string; + original: Pos; + name: string; + content?: string | null; +}): void; +/** + * Same as `addSegment`, but will only add the segment if it generates useful information in the + * resulting map. This only works correctly if segments are added **in order**, meaning you should + * not add a segment with a lower generated line/column than one that came before. + */ +export declare const maybeAddSegment: typeof addSegment; +/** + * Same as `addMapping`, but will only add the mapping if it generates useful information in the + * resulting map. This only works correctly if mappings are added **in order**, meaning you should + * not add a mapping with a lower generated line/column than one that came before. + */ +export declare const maybeAddMapping: typeof addMapping; +/** + * Adds/removes the content of the source file to the source map. + */ +export declare function setSourceContent(map: GenMapping, source: string, content: string | null): void; +export declare function setIgnore(map: GenMapping, source: string, ignore?: boolean): void; +/** + * Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects + * a sourcemap, or to JSON.stringify. + */ +export declare function toDecodedMap(map: GenMapping): DecodedSourceMap; +/** + * Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects + * a sourcemap, or to JSON.stringify. + */ +export declare function toEncodedMap(map: GenMapping): EncodedSourceMap; +/** + * Constructs a new GenMapping, using the already present mappings of the input. + */ +export declare function fromMap(input: SourceMapInput): GenMapping; +/** + * Returns an array of high-level mapping objects for every recorded segment, which could then be + * passed to the `source-map` library. + */ +export declare function allMappings(map: GenMapping): Mapping[]; diff --git a/node_modules/@jridgewell/gen-mapping/dist/types/set-array.d.ts b/node_modules/@jridgewell/gen-mapping/dist/types/set-array.d.ts new file mode 100644 index 0000000..6ed4354 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/dist/types/set-array.d.ts @@ -0,0 +1,32 @@ +type Key = string | number | symbol; +/** + * SetArray acts like a `Set` (allowing only one occurrence of a string `key`), but provides the + * index of the `key` in the backing array. + * + * This is designed to allow synchronizing a second array with the contents of the backing array, + * like how in a sourcemap `sourcesContent[i]` is the source content associated with `source[i]`, + * and there are never duplicates. + */ +export declare class SetArray { + private _indexes; + array: readonly T[]; + constructor(); +} +/** + * Gets the index associated with `key` in the backing array, if it is already present. + */ +export declare function get(setarr: SetArray, key: T): number | undefined; +/** + * Puts `key` into the backing array, if it is not already present. Returns + * the index of the `key` in the backing array. + */ +export declare function put(setarr: SetArray, key: T): number; +/** + * Pops the last added item out of the SetArray. + */ +export declare function pop(setarr: SetArray): void; +/** + * Removes the key, if it exists in the set. + */ +export declare function remove(setarr: SetArray, key: T): void; +export {}; diff --git a/node_modules/@jridgewell/gen-mapping/dist/types/sourcemap-segment.d.ts b/node_modules/@jridgewell/gen-mapping/dist/types/sourcemap-segment.d.ts new file mode 100644 index 0000000..aa19fb5 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/dist/types/sourcemap-segment.d.ts @@ -0,0 +1,12 @@ +type GeneratedColumn = number; +type SourcesIndex = number; +type SourceLine = number; +type SourceColumn = number; +type NamesIndex = number; +export type SourceMapSegment = [GeneratedColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex]; +export declare const COLUMN = 0; +export declare const SOURCES_INDEX = 1; +export declare const SOURCE_LINE = 2; +export declare const SOURCE_COLUMN = 3; +export declare const NAMES_INDEX = 4; +export {}; diff --git a/node_modules/@jridgewell/gen-mapping/dist/types/types.d.ts b/node_modules/@jridgewell/gen-mapping/dist/types/types.d.ts new file mode 100644 index 0000000..8eb90fb --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/dist/types/types.d.ts @@ -0,0 +1,43 @@ +import type { SourceMapSegment } from './sourcemap-segment'; +export interface SourceMapV3 { + file?: string | null; + names: readonly string[]; + sourceRoot?: string; + sources: readonly (string | null)[]; + sourcesContent?: readonly (string | null)[]; + version: 3; + ignoreList?: readonly number[]; +} +export interface EncodedSourceMap extends SourceMapV3 { + mappings: string; +} +export interface DecodedSourceMap extends SourceMapV3 { + mappings: readonly SourceMapSegment[][]; +} +export interface Pos { + line: number; + column: number; +} +export interface OriginalPos extends Pos { + source: string; +} +export interface BindingExpressionRange { + start: Pos; + expression: string; +} +export type Mapping = { + generated: Pos; + source: undefined; + original: undefined; + name: undefined; +} | { + generated: Pos; + source: string; + original: Pos; + name: string; +} | { + generated: Pos; + source: string; + original: Pos; + name: undefined; +}; diff --git a/node_modules/@jridgewell/gen-mapping/package.json b/node_modules/@jridgewell/gen-mapping/package.json new file mode 100644 index 0000000..036f9b7 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/package.json @@ -0,0 +1,67 @@ +{ + "name": "@jridgewell/gen-mapping", + "version": "0.3.13", + "description": "Generate source maps", + "keywords": [ + "source", + "map" + ], + "main": "dist/gen-mapping.umd.js", + "module": "dist/gen-mapping.mjs", + "types": "types/gen-mapping.d.cts", + "files": [ + "dist", + "src", + "types" + ], + "exports": { + ".": [ + { + "import": { + "types": "./types/gen-mapping.d.mts", + "default": "./dist/gen-mapping.mjs" + }, + "default": { + "types": "./types/gen-mapping.d.cts", + "default": "./dist/gen-mapping.umd.js" + } + }, + "./dist/gen-mapping.umd.js" + ], + "./package.json": "./package.json" + }, + "scripts": { + "benchmark": "run-s build:code benchmark:*", + "benchmark:install": "cd benchmark && npm install", + "benchmark:only": "node --expose-gc benchmark/index.js", + "build": "run-s -n build:code build:types", + "build:code": "node ../../esbuild.mjs gen-mapping.ts", + "build:types": "run-s build:types:force build:types:emit build:types:mts", + "build:types:force": "rimraf tsconfig.build.tsbuildinfo", + "build:types:emit": "tsc --project tsconfig.build.json", + "build:types:mts": "node ../../mts-types.mjs", + "clean": "run-s -n clean:code clean:types", + "clean:code": "tsc --build --clean tsconfig.build.json", + "clean:types": "rimraf dist types", + "test": "run-s -n test:types test:only test:format", + "test:format": "prettier --check '{src,test}/**/*.ts'", + "test:only": "mocha", + "test:types": "eslint '{src,test}/**/*.ts'", + "lint": "run-s -n lint:types lint:format", + "lint:format": "npm run test:format -- --write", + "lint:types": "npm run test:types -- --fix", + "prepublishOnly": "npm run-s -n build test" + }, + "homepage": "https://github.com/jridgewell/sourcemaps/tree/main/packages/gen-mapping", + "repository": { + "type": "git", + "url": "git+https://github.com/jridgewell/sourcemaps.git", + "directory": "packages/gen-mapping" + }, + "author": "Justin Ridgewell ", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } +} diff --git a/node_modules/@jridgewell/gen-mapping/src/gen-mapping.ts b/node_modules/@jridgewell/gen-mapping/src/gen-mapping.ts new file mode 100644 index 0000000..ecc878c --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/src/gen-mapping.ts @@ -0,0 +1,614 @@ +import { SetArray, put, remove } from './set-array'; +import { + encode, + // encodeGeneratedRanges, + // encodeOriginalScopes +} from '@jridgewell/sourcemap-codec'; +import { TraceMap, decodedMappings } from '@jridgewell/trace-mapping'; + +import { + COLUMN, + SOURCES_INDEX, + SOURCE_LINE, + SOURCE_COLUMN, + NAMES_INDEX, +} from './sourcemap-segment'; + +import type { SourceMapInput } from '@jridgewell/trace-mapping'; +// import type { OriginalScope, GeneratedRange } from '@jridgewell/sourcemap-codec'; +import type { SourceMapSegment } from './sourcemap-segment'; +import type { + DecodedSourceMap, + EncodedSourceMap, + Pos, + Mapping, + // BindingExpressionRange, + // OriginalPos, + // OriginalScopeInfo, + // GeneratedRangeInfo, +} from './types'; + +export type { DecodedSourceMap, EncodedSourceMap, Mapping }; + +export type Options = { + file?: string | null; + sourceRoot?: string | null; +}; + +const NO_NAME = -1; + +/** + * Provides the state to generate a sourcemap. + */ +export class GenMapping { + declare private _names: SetArray; + declare private _sources: SetArray; + declare private _sourcesContent: (string | null)[]; + declare private _mappings: SourceMapSegment[][]; + // private declare _originalScopes: OriginalScope[][]; + // private declare _generatedRanges: GeneratedRange[]; + declare private _ignoreList: SetArray; + declare file: string | null | undefined; + declare sourceRoot: string | null | undefined; + + constructor({ file, sourceRoot }: Options = {}) { + this._names = new SetArray(); + this._sources = new SetArray(); + this._sourcesContent = []; + this._mappings = []; + // this._originalScopes = []; + // this._generatedRanges = []; + this.file = file; + this.sourceRoot = sourceRoot; + this._ignoreList = new SetArray(); + } +} + +interface PublicMap { + _names: GenMapping['_names']; + _sources: GenMapping['_sources']; + _sourcesContent: GenMapping['_sourcesContent']; + _mappings: GenMapping['_mappings']; + // _originalScopes: GenMapping['_originalScopes']; + // _generatedRanges: GenMapping['_generatedRanges']; + _ignoreList: GenMapping['_ignoreList']; +} + +/** + * Typescript doesn't allow friend access to private fields, so this just casts the map into a type + * with public access modifiers. + */ +function cast(map: unknown): PublicMap { + return map as any; +} + +/** + * A low-level API to associate a generated position with an original source position. Line and + * column here are 0-based, unlike `addMapping`. + */ +export function addSegment( + map: GenMapping, + genLine: number, + genColumn: number, + source?: null, + sourceLine?: null, + sourceColumn?: null, + name?: null, + content?: null, +): void; +export function addSegment( + map: GenMapping, + genLine: number, + genColumn: number, + source: string, + sourceLine: number, + sourceColumn: number, + name?: null, + content?: string | null, +): void; +export function addSegment( + map: GenMapping, + genLine: number, + genColumn: number, + source: string, + sourceLine: number, + sourceColumn: number, + name: string, + content?: string | null, +): void; +export function addSegment( + map: GenMapping, + genLine: number, + genColumn: number, + source?: string | null, + sourceLine?: number | null, + sourceColumn?: number | null, + name?: string | null, + content?: string | null, +): void { + return addSegmentInternal( + false, + map, + genLine, + genColumn, + source, + sourceLine, + sourceColumn, + name, + content, + ); +} + +/** + * A high-level API to associate a generated position with an original source position. Line is + * 1-based, but column is 0-based, due to legacy behavior in `source-map` library. + */ +export function addMapping( + map: GenMapping, + mapping: { + generated: Pos; + source?: null; + original?: null; + name?: null; + content?: null; + }, +): void; +export function addMapping( + map: GenMapping, + mapping: { + generated: Pos; + source: string; + original: Pos; + name?: null; + content?: string | null; + }, +): void; +export function addMapping( + map: GenMapping, + mapping: { + generated: Pos; + source: string; + original: Pos; + name: string; + content?: string | null; + }, +): void; +export function addMapping( + map: GenMapping, + mapping: { + generated: Pos; + source?: string | null; + original?: Pos | null; + name?: string | null; + content?: string | null; + }, +): void { + return addMappingInternal(false, map, mapping as Parameters[2]); +} + +/** + * Same as `addSegment`, but will only add the segment if it generates useful information in the + * resulting map. This only works correctly if segments are added **in order**, meaning you should + * not add a segment with a lower generated line/column than one that came before. + */ +export const maybeAddSegment: typeof addSegment = ( + map, + genLine, + genColumn, + source, + sourceLine, + sourceColumn, + name, + content, +) => { + return addSegmentInternal( + true, + map, + genLine, + genColumn, + source, + sourceLine, + sourceColumn, + name, + content, + ); +}; + +/** + * Same as `addMapping`, but will only add the mapping if it generates useful information in the + * resulting map. This only works correctly if mappings are added **in order**, meaning you should + * not add a mapping with a lower generated line/column than one that came before. + */ +export const maybeAddMapping: typeof addMapping = (map, mapping) => { + return addMappingInternal(true, map, mapping as Parameters[2]); +}; + +/** + * Adds/removes the content of the source file to the source map. + */ +export function setSourceContent(map: GenMapping, source: string, content: string | null): void { + const { + _sources: sources, + _sourcesContent: sourcesContent, + // _originalScopes: originalScopes, + } = cast(map); + const index = put(sources, source); + sourcesContent[index] = content; + // if (index === originalScopes.length) originalScopes[index] = []; +} + +export function setIgnore(map: GenMapping, source: string, ignore = true) { + const { + _sources: sources, + _sourcesContent: sourcesContent, + _ignoreList: ignoreList, + // _originalScopes: originalScopes, + } = cast(map); + const index = put(sources, source); + if (index === sourcesContent.length) sourcesContent[index] = null; + // if (index === originalScopes.length) originalScopes[index] = []; + if (ignore) put(ignoreList, index); + else remove(ignoreList, index); +} + +/** + * Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects + * a sourcemap, or to JSON.stringify. + */ +export function toDecodedMap(map: GenMapping): DecodedSourceMap { + const { + _mappings: mappings, + _sources: sources, + _sourcesContent: sourcesContent, + _names: names, + _ignoreList: ignoreList, + // _originalScopes: originalScopes, + // _generatedRanges: generatedRanges, + } = cast(map); + removeEmptyFinalLines(mappings); + + return { + version: 3, + file: map.file || undefined, + names: names.array, + sourceRoot: map.sourceRoot || undefined, + sources: sources.array, + sourcesContent, + mappings, + // originalScopes, + // generatedRanges, + ignoreList: ignoreList.array, + }; +} + +/** + * Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects + * a sourcemap, or to JSON.stringify. + */ +export function toEncodedMap(map: GenMapping): EncodedSourceMap { + const decoded = toDecodedMap(map); + return Object.assign({}, decoded, { + // originalScopes: decoded.originalScopes.map((os) => encodeOriginalScopes(os)), + // generatedRanges: encodeGeneratedRanges(decoded.generatedRanges as GeneratedRange[]), + mappings: encode(decoded.mappings as SourceMapSegment[][]), + }); +} + +/** + * Constructs a new GenMapping, using the already present mappings of the input. + */ +export function fromMap(input: SourceMapInput): GenMapping { + const map = new TraceMap(input); + const gen = new GenMapping({ file: map.file, sourceRoot: map.sourceRoot }); + + putAll(cast(gen)._names, map.names); + putAll(cast(gen)._sources, map.sources as string[]); + cast(gen)._sourcesContent = map.sourcesContent || map.sources.map(() => null); + cast(gen)._mappings = decodedMappings(map) as GenMapping['_mappings']; + // TODO: implement originalScopes/generatedRanges + if (map.ignoreList) putAll(cast(gen)._ignoreList, map.ignoreList); + + return gen; +} + +/** + * Returns an array of high-level mapping objects for every recorded segment, which could then be + * passed to the `source-map` library. + */ +export function allMappings(map: GenMapping): Mapping[] { + const out: Mapping[] = []; + const { _mappings: mappings, _sources: sources, _names: names } = cast(map); + + for (let i = 0; i < mappings.length; i++) { + const line = mappings[i]; + for (let j = 0; j < line.length; j++) { + const seg = line[j]; + + const generated = { line: i + 1, column: seg[COLUMN] }; + let source: string | undefined = undefined; + let original: Pos | undefined = undefined; + let name: string | undefined = undefined; + + if (seg.length !== 1) { + source = sources.array[seg[SOURCES_INDEX]]; + original = { line: seg[SOURCE_LINE] + 1, column: seg[SOURCE_COLUMN] }; + + if (seg.length === 5) name = names.array[seg[NAMES_INDEX]]; + } + + out.push({ generated, source, original, name } as Mapping); + } + } + + return out; +} + +// This split declaration is only so that terser can elminiate the static initialization block. +function addSegmentInternal( + skipable: boolean, + map: GenMapping, + genLine: number, + genColumn: number, + source: S, + sourceLine: S extends string ? number : null | undefined, + sourceColumn: S extends string ? number : null | undefined, + name: S extends string ? string | null | undefined : null | undefined, + content: S extends string ? string | null | undefined : null | undefined, +): void { + const { + _mappings: mappings, + _sources: sources, + _sourcesContent: sourcesContent, + _names: names, + // _originalScopes: originalScopes, + } = cast(map); + const line = getIndex(mappings, genLine); + const index = getColumnIndex(line, genColumn); + + if (!source) { + if (skipable && skipSourceless(line, index)) return; + return insert(line, index, [genColumn]); + } + + // Sigh, TypeScript can't figure out sourceLine and sourceColumn aren't nullish if source + // isn't nullish. + assert(sourceLine); + assert(sourceColumn); + + const sourcesIndex = put(sources, source); + const namesIndex = name ? put(names, name) : NO_NAME; + if (sourcesIndex === sourcesContent.length) sourcesContent[sourcesIndex] = content ?? null; + // if (sourcesIndex === originalScopes.length) originalScopes[sourcesIndex] = []; + + if (skipable && skipSource(line, index, sourcesIndex, sourceLine, sourceColumn, namesIndex)) { + return; + } + + return insert( + line, + index, + name + ? [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex] + : [genColumn, sourcesIndex, sourceLine, sourceColumn], + ); +} + +function assert(_val: unknown): asserts _val is T { + // noop. +} + +function getIndex(arr: T[][], index: number): T[] { + for (let i = arr.length; i <= index; i++) { + arr[i] = []; + } + return arr[index]; +} + +function getColumnIndex(line: SourceMapSegment[], genColumn: number): number { + let index = line.length; + for (let i = index - 1; i >= 0; index = i--) { + const current = line[i]; + if (genColumn >= current[COLUMN]) break; + } + return index; +} + +function insert(array: T[], index: number, value: T) { + for (let i = array.length; i > index; i--) { + array[i] = array[i - 1]; + } + array[index] = value; +} + +function removeEmptyFinalLines(mappings: SourceMapSegment[][]) { + const { length } = mappings; + let len = length; + for (let i = len - 1; i >= 0; len = i, i--) { + if (mappings[i].length > 0) break; + } + if (len < length) mappings.length = len; +} + +function putAll(setarr: SetArray, array: T[]) { + for (let i = 0; i < array.length; i++) put(setarr, array[i]); +} + +function skipSourceless(line: SourceMapSegment[], index: number): boolean { + // The start of a line is already sourceless, so adding a sourceless segment to the beginning + // doesn't generate any useful information. + if (index === 0) return true; + + const prev = line[index - 1]; + // If the previous segment is also sourceless, then adding another sourceless segment doesn't + // genrate any new information. Else, this segment will end the source/named segment and point to + // a sourceless position, which is useful. + return prev.length === 1; +} + +function skipSource( + line: SourceMapSegment[], + index: number, + sourcesIndex: number, + sourceLine: number, + sourceColumn: number, + namesIndex: number, +): boolean { + // A source/named segment at the start of a line gives position at that genColumn + if (index === 0) return false; + + const prev = line[index - 1]; + + // If the previous segment is sourceless, then we're transitioning to a source. + if (prev.length === 1) return false; + + // If the previous segment maps to the exact same source position, then this segment doesn't + // provide any new position information. + return ( + sourcesIndex === prev[SOURCES_INDEX] && + sourceLine === prev[SOURCE_LINE] && + sourceColumn === prev[SOURCE_COLUMN] && + namesIndex === (prev.length === 5 ? prev[NAMES_INDEX] : NO_NAME) + ); +} + +function addMappingInternal( + skipable: boolean, + map: GenMapping, + mapping: { + generated: Pos; + source: S; + original: S extends string ? Pos : null | undefined; + name: S extends string ? string | null | undefined : null | undefined; + content: S extends string ? string | null | undefined : null | undefined; + }, +) { + const { generated, source, original, name, content } = mapping; + if (!source) { + return addSegmentInternal( + skipable, + map, + generated.line - 1, + generated.column, + null, + null, + null, + null, + null, + ); + } + assert(original); + return addSegmentInternal( + skipable, + map, + generated.line - 1, + generated.column, + source as string, + original.line - 1, + original.column, + name, + content, + ); +} + +/* +export function addOriginalScope( + map: GenMapping, + data: { + start: Pos; + end: Pos; + source: string; + kind: string; + name?: string; + variables?: string[]; + }, +): OriginalScopeInfo { + const { start, end, source, kind, name, variables } = data; + const { + _sources: sources, + _sourcesContent: sourcesContent, + _originalScopes: originalScopes, + _names: names, + } = cast(map); + const index = put(sources, source); + if (index === sourcesContent.length) sourcesContent[index] = null; + if (index === originalScopes.length) originalScopes[index] = []; + + const kindIndex = put(names, kind); + const scope: OriginalScope = name + ? [start.line - 1, start.column, end.line - 1, end.column, kindIndex, put(names, name)] + : [start.line - 1, start.column, end.line - 1, end.column, kindIndex]; + if (variables) { + scope.vars = variables.map((v) => put(names, v)); + } + const len = originalScopes[index].push(scope); + return [index, len - 1, variables]; +} +*/ + +// Generated Ranges +/* +export function addGeneratedRange( + map: GenMapping, + data: { + start: Pos; + isScope: boolean; + originalScope?: OriginalScopeInfo; + callsite?: OriginalPos; + }, +): GeneratedRangeInfo { + const { start, isScope, originalScope, callsite } = data; + const { + _originalScopes: originalScopes, + _sources: sources, + _sourcesContent: sourcesContent, + _generatedRanges: generatedRanges, + } = cast(map); + + const range: GeneratedRange = [ + start.line - 1, + start.column, + 0, + 0, + originalScope ? originalScope[0] : -1, + originalScope ? originalScope[1] : -1, + ]; + if (originalScope?.[2]) { + range.bindings = originalScope[2].map(() => [[-1]]); + } + if (callsite) { + const index = put(sources, callsite.source); + if (index === sourcesContent.length) sourcesContent[index] = null; + if (index === originalScopes.length) originalScopes[index] = []; + range.callsite = [index, callsite.line - 1, callsite.column]; + } + if (isScope) range.isScope = true; + generatedRanges.push(range); + + return [range, originalScope?.[2]]; +} + +export function setEndPosition(range: GeneratedRangeInfo, pos: Pos) { + range[0][2] = pos.line - 1; + range[0][3] = pos.column; +} + +export function addBinding( + map: GenMapping, + range: GeneratedRangeInfo, + variable: string, + expression: string | BindingExpressionRange, +) { + const { _names: names } = cast(map); + const bindings = (range[0].bindings ||= []); + const vars = range[1]; + + const index = vars!.indexOf(variable); + const binding = getIndex(bindings, index); + + if (typeof expression === 'string') binding[0] = [put(names, expression)]; + else { + const { start } = expression; + binding.push([put(names, expression.expression), start.line - 1, start.column]); + } +} +*/ diff --git a/node_modules/@jridgewell/gen-mapping/src/set-array.ts b/node_modules/@jridgewell/gen-mapping/src/set-array.ts new file mode 100644 index 0000000..a2a73a5 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/src/set-array.ts @@ -0,0 +1,82 @@ +type Key = string | number | symbol; + +/** + * SetArray acts like a `Set` (allowing only one occurrence of a string `key`), but provides the + * index of the `key` in the backing array. + * + * This is designed to allow synchronizing a second array with the contents of the backing array, + * like how in a sourcemap `sourcesContent[i]` is the source content associated with `source[i]`, + * and there are never duplicates. + */ +export class SetArray { + declare private _indexes: Record; + declare array: readonly T[]; + + constructor() { + this._indexes = { __proto__: null } as any; + this.array = []; + } +} + +interface PublicSet { + array: T[]; + _indexes: SetArray['_indexes']; +} + +/** + * Typescript doesn't allow friend access to private fields, so this just casts the set into a type + * with public access modifiers. + */ +function cast(set: SetArray): PublicSet { + return set as any; +} + +/** + * Gets the index associated with `key` in the backing array, if it is already present. + */ +export function get(setarr: SetArray, key: T): number | undefined { + return cast(setarr)._indexes[key]; +} + +/** + * Puts `key` into the backing array, if it is not already present. Returns + * the index of the `key` in the backing array. + */ +export function put(setarr: SetArray, key: T): number { + // The key may or may not be present. If it is present, it's a number. + const index = get(setarr, key); + if (index !== undefined) return index; + + const { array, _indexes: indexes } = cast(setarr); + + const length = array.push(key); + return (indexes[key] = length - 1); +} + +/** + * Pops the last added item out of the SetArray. + */ +export function pop(setarr: SetArray): void { + const { array, _indexes: indexes } = cast(setarr); + if (array.length === 0) return; + + const last = array.pop()!; + indexes[last] = undefined; +} + +/** + * Removes the key, if it exists in the set. + */ +export function remove(setarr: SetArray, key: T): void { + const index = get(setarr, key); + if (index === undefined) return; + + const { array, _indexes: indexes } = cast(setarr); + for (let i = index + 1; i < array.length; i++) { + const k = array[i]; + array[i - 1] = k; + indexes[k]!--; + } + indexes[key] = undefined; + array.pop(); +} diff --git a/node_modules/@jridgewell/gen-mapping/src/sourcemap-segment.ts b/node_modules/@jridgewell/gen-mapping/src/sourcemap-segment.ts new file mode 100644 index 0000000..fb296dd --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/src/sourcemap-segment.ts @@ -0,0 +1,16 @@ +type GeneratedColumn = number; +type SourcesIndex = number; +type SourceLine = number; +type SourceColumn = number; +type NamesIndex = number; + +export type SourceMapSegment = + | [GeneratedColumn] + | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn] + | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex]; + +export const COLUMN = 0; +export const SOURCES_INDEX = 1; +export const SOURCE_LINE = 2; +export const SOURCE_COLUMN = 3; +export const NAMES_INDEX = 4; diff --git a/node_modules/@jridgewell/gen-mapping/src/types.ts b/node_modules/@jridgewell/gen-mapping/src/types.ts new file mode 100644 index 0000000..b087f70 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/src/types.ts @@ -0,0 +1,61 @@ +// import type { GeneratedRange, OriginalScope } from '@jridgewell/sourcemap-codec'; +import type { SourceMapSegment } from './sourcemap-segment'; + +export interface SourceMapV3 { + file?: string | null; + names: readonly string[]; + sourceRoot?: string; + sources: readonly (string | null)[]; + sourcesContent?: readonly (string | null)[]; + version: 3; + ignoreList?: readonly number[]; +} + +export interface EncodedSourceMap extends SourceMapV3 { + mappings: string; + // originalScopes: string[]; + // generatedRanges: string; +} + +export interface DecodedSourceMap extends SourceMapV3 { + mappings: readonly SourceMapSegment[][]; + // originalScopes: readonly OriginalScope[][]; + // generatedRanges: readonly GeneratedRange[]; +} + +export interface Pos { + line: number; // 1-based + column: number; // 0-based +} + +export interface OriginalPos extends Pos { + source: string; +} + +export interface BindingExpressionRange { + start: Pos; + expression: string; +} + +// export type OriginalScopeInfo = [number, number, string[] | undefined]; +// export type GeneratedRangeInfo = [GeneratedRange, string[] | undefined]; + +export type Mapping = + | { + generated: Pos; + source: undefined; + original: undefined; + name: undefined; + } + | { + generated: Pos; + source: string; + original: Pos; + name: string; + } + | { + generated: Pos; + source: string; + original: Pos; + name: undefined; + }; diff --git a/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.cts b/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.cts new file mode 100644 index 0000000..7618d85 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.cts @@ -0,0 +1,89 @@ +import type { SourceMapInput } from '@jridgewell/trace-mapping'; +import type { DecodedSourceMap, EncodedSourceMap, Pos, Mapping } from './types.cts'; +export type { DecodedSourceMap, EncodedSourceMap, Mapping }; +export type Options = { + file?: string | null; + sourceRoot?: string | null; +}; +/** + * Provides the state to generate a sourcemap. + */ +export declare class GenMapping { + private _names; + private _sources; + private _sourcesContent; + private _mappings; + private _ignoreList; + file: string | null | undefined; + sourceRoot: string | null | undefined; + constructor({ file, sourceRoot }?: Options); +} +/** + * A low-level API to associate a generated position with an original source position. Line and + * column here are 0-based, unlike `addMapping`. + */ +export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source?: null, sourceLine?: null, sourceColumn?: null, name?: null, content?: null): void; +export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name?: null, content?: string | null): void; +export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name: string, content?: string | null): void; +/** + * A high-level API to associate a generated position with an original source position. Line is + * 1-based, but column is 0-based, due to legacy behavior in `source-map` library. + */ +export declare function addMapping(map: GenMapping, mapping: { + generated: Pos; + source?: null; + original?: null; + name?: null; + content?: null; +}): void; +export declare function addMapping(map: GenMapping, mapping: { + generated: Pos; + source: string; + original: Pos; + name?: null; + content?: string | null; +}): void; +export declare function addMapping(map: GenMapping, mapping: { + generated: Pos; + source: string; + original: Pos; + name: string; + content?: string | null; +}): void; +/** + * Same as `addSegment`, but will only add the segment if it generates useful information in the + * resulting map. This only works correctly if segments are added **in order**, meaning you should + * not add a segment with a lower generated line/column than one that came before. + */ +export declare const maybeAddSegment: typeof addSegment; +/** + * Same as `addMapping`, but will only add the mapping if it generates useful information in the + * resulting map. This only works correctly if mappings are added **in order**, meaning you should + * not add a mapping with a lower generated line/column than one that came before. + */ +export declare const maybeAddMapping: typeof addMapping; +/** + * Adds/removes the content of the source file to the source map. + */ +export declare function setSourceContent(map: GenMapping, source: string, content: string | null): void; +export declare function setIgnore(map: GenMapping, source: string, ignore?: boolean): void; +/** + * Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects + * a sourcemap, or to JSON.stringify. + */ +export declare function toDecodedMap(map: GenMapping): DecodedSourceMap; +/** + * Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects + * a sourcemap, or to JSON.stringify. + */ +export declare function toEncodedMap(map: GenMapping): EncodedSourceMap; +/** + * Constructs a new GenMapping, using the already present mappings of the input. + */ +export declare function fromMap(input: SourceMapInput): GenMapping; +/** + * Returns an array of high-level mapping objects for every recorded segment, which could then be + * passed to the `source-map` library. + */ +export declare function allMappings(map: GenMapping): Mapping[]; +//# sourceMappingURL=gen-mapping.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.cts.map b/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.cts.map new file mode 100644 index 0000000..8a2b183 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"gen-mapping.d.ts","sourceRoot":"","sources":["../src/gen-mapping.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,GAAG,EACH,OAAO,EAKR,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;AAE5D,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAIF;;GAEG;AACH,qBAAa,UAAU;IACrB,QAAgB,MAAM,CAAmB;IACzC,QAAgB,QAAQ,CAAmB;IAC3C,QAAgB,eAAe,CAAoB;IACnD,QAAgB,SAAS,CAAuB;IAGhD,QAAgB,WAAW,CAAmB;IACtC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;gBAElC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAE,OAAY;CAW/C;AAoBD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,IAAI,EACb,UAAU,CAAC,EAAE,IAAI,EACjB,YAAY,CAAC,EAAE,IAAI,EACnB,IAAI,CAAC,EAAE,IAAI,EACX,OAAO,CAAC,EAAE,IAAI,GACb,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,IAAI,EACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI,CAAC;AAwBR;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,IAAI,CAAC;CAChB,GACA,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,IAAI,CAAC;AAcR;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,UAqBpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,UAEpC,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAS9F;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAO,QAYvE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAwB9D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAO9D;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU,CAYzD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,EAAE,CA0BtD"} \ No newline at end of file diff --git a/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.mts b/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.mts new file mode 100644 index 0000000..bbc0d89 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.mts @@ -0,0 +1,89 @@ +import type { SourceMapInput } from '@jridgewell/trace-mapping'; +import type { DecodedSourceMap, EncodedSourceMap, Pos, Mapping } from './types.mts'; +export type { DecodedSourceMap, EncodedSourceMap, Mapping }; +export type Options = { + file?: string | null; + sourceRoot?: string | null; +}; +/** + * Provides the state to generate a sourcemap. + */ +export declare class GenMapping { + private _names; + private _sources; + private _sourcesContent; + private _mappings; + private _ignoreList; + file: string | null | undefined; + sourceRoot: string | null | undefined; + constructor({ file, sourceRoot }?: Options); +} +/** + * A low-level API to associate a generated position with an original source position. Line and + * column here are 0-based, unlike `addMapping`. + */ +export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source?: null, sourceLine?: null, sourceColumn?: null, name?: null, content?: null): void; +export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name?: null, content?: string | null): void; +export declare function addSegment(map: GenMapping, genLine: number, genColumn: number, source: string, sourceLine: number, sourceColumn: number, name: string, content?: string | null): void; +/** + * A high-level API to associate a generated position with an original source position. Line is + * 1-based, but column is 0-based, due to legacy behavior in `source-map` library. + */ +export declare function addMapping(map: GenMapping, mapping: { + generated: Pos; + source?: null; + original?: null; + name?: null; + content?: null; +}): void; +export declare function addMapping(map: GenMapping, mapping: { + generated: Pos; + source: string; + original: Pos; + name?: null; + content?: string | null; +}): void; +export declare function addMapping(map: GenMapping, mapping: { + generated: Pos; + source: string; + original: Pos; + name: string; + content?: string | null; +}): void; +/** + * Same as `addSegment`, but will only add the segment if it generates useful information in the + * resulting map. This only works correctly if segments are added **in order**, meaning you should + * not add a segment with a lower generated line/column than one that came before. + */ +export declare const maybeAddSegment: typeof addSegment; +/** + * Same as `addMapping`, but will only add the mapping if it generates useful information in the + * resulting map. This only works correctly if mappings are added **in order**, meaning you should + * not add a mapping with a lower generated line/column than one that came before. + */ +export declare const maybeAddMapping: typeof addMapping; +/** + * Adds/removes the content of the source file to the source map. + */ +export declare function setSourceContent(map: GenMapping, source: string, content: string | null): void; +export declare function setIgnore(map: GenMapping, source: string, ignore?: boolean): void; +/** + * Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects + * a sourcemap, or to JSON.stringify. + */ +export declare function toDecodedMap(map: GenMapping): DecodedSourceMap; +/** + * Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects + * a sourcemap, or to JSON.stringify. + */ +export declare function toEncodedMap(map: GenMapping): EncodedSourceMap; +/** + * Constructs a new GenMapping, using the already present mappings of the input. + */ +export declare function fromMap(input: SourceMapInput): GenMapping; +/** + * Returns an array of high-level mapping objects for every recorded segment, which could then be + * passed to the `source-map` library. + */ +export declare function allMappings(map: GenMapping): Mapping[]; +//# sourceMappingURL=gen-mapping.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.mts.map b/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.mts.map new file mode 100644 index 0000000..8a2b183 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/types/gen-mapping.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"gen-mapping.d.ts","sourceRoot":"","sources":["../src/gen-mapping.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,GAAG,EACH,OAAO,EAKR,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC;AAE5D,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAIF;;GAEG;AACH,qBAAa,UAAU;IACrB,QAAgB,MAAM,CAAmB;IACzC,QAAgB,QAAQ,CAAmB;IAC3C,QAAgB,eAAe,CAAoB;IACnD,QAAgB,SAAS,CAAuB;IAGhD,QAAgB,WAAW,CAAmB;IACtC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;gBAElC,EAAE,IAAI,EAAE,UAAU,EAAE,GAAE,OAAY;CAW/C;AAoBD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,IAAI,EACb,UAAU,CAAC,EAAE,IAAI,EACjB,YAAY,CAAC,EAAE,IAAI,EACnB,IAAI,CAAC,EAAE,IAAI,EACX,OAAO,CAAC,EAAE,IAAI,GACb,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,IAAI,EACX,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI,CAAC;AAwBR;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,IAAI,CAAC;CAChB,GACA,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,IAAI,CAAC;AACR,wBAAgB,UAAU,CACxB,GAAG,EAAE,UAAU,EACf,OAAO,EAAE;IACP,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,GACA,IAAI,CAAC;AAcR;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,UAqBpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,OAAO,UAEpC,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAS9F;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAO,QAYvE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAwB9D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,gBAAgB,CAO9D;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU,CAYzD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,EAAE,CA0BtD"} \ No newline at end of file diff --git a/node_modules/@jridgewell/gen-mapping/types/set-array.d.cts b/node_modules/@jridgewell/gen-mapping/types/set-array.d.cts new file mode 100644 index 0000000..5d8cda3 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/types/set-array.d.cts @@ -0,0 +1,33 @@ +type Key = string | number | symbol; +/** + * SetArray acts like a `Set` (allowing only one occurrence of a string `key`), but provides the + * index of the `key` in the backing array. + * + * This is designed to allow synchronizing a second array with the contents of the backing array, + * like how in a sourcemap `sourcesContent[i]` is the source content associated with `source[i]`, + * and there are never duplicates. + */ +export declare class SetArray { + private _indexes; + array: readonly T[]; + constructor(); +} +/** + * Gets the index associated with `key` in the backing array, if it is already present. + */ +export declare function get(setarr: SetArray, key: T): number | undefined; +/** + * Puts `key` into the backing array, if it is not already present. Returns + * the index of the `key` in the backing array. + */ +export declare function put(setarr: SetArray, key: T): number; +/** + * Pops the last added item out of the SetArray. + */ +export declare function pop(setarr: SetArray): void; +/** + * Removes the key, if it exists in the set. + */ +export declare function remove(setarr: SetArray, key: T): void; +export {}; +//# sourceMappingURL=set-array.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/gen-mapping/types/set-array.d.cts.map b/node_modules/@jridgewell/gen-mapping/types/set-array.d.cts.map new file mode 100644 index 0000000..c52b8bc --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/types/set-array.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"set-array.d.ts","sourceRoot":"","sources":["../src/set-array.ts"],"names":[],"mappings":"AAAA,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpC;;;;;;;GAOG;AACH,qBAAa,QAAQ,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG;IACvC,QAAgB,QAAQ,CAAgC;IAChD,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;;CAM7B;AAeD;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,SAAS,CAElF;AAED;;;GAGG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,CAStE;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAM5D;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAYvE"} \ No newline at end of file diff --git a/node_modules/@jridgewell/gen-mapping/types/set-array.d.mts b/node_modules/@jridgewell/gen-mapping/types/set-array.d.mts new file mode 100644 index 0000000..5d8cda3 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/types/set-array.d.mts @@ -0,0 +1,33 @@ +type Key = string | number | symbol; +/** + * SetArray acts like a `Set` (allowing only one occurrence of a string `key`), but provides the + * index of the `key` in the backing array. + * + * This is designed to allow synchronizing a second array with the contents of the backing array, + * like how in a sourcemap `sourcesContent[i]` is the source content associated with `source[i]`, + * and there are never duplicates. + */ +export declare class SetArray { + private _indexes; + array: readonly T[]; + constructor(); +} +/** + * Gets the index associated with `key` in the backing array, if it is already present. + */ +export declare function get(setarr: SetArray, key: T): number | undefined; +/** + * Puts `key` into the backing array, if it is not already present. Returns + * the index of the `key` in the backing array. + */ +export declare function put(setarr: SetArray, key: T): number; +/** + * Pops the last added item out of the SetArray. + */ +export declare function pop(setarr: SetArray): void; +/** + * Removes the key, if it exists in the set. + */ +export declare function remove(setarr: SetArray, key: T): void; +export {}; +//# sourceMappingURL=set-array.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/gen-mapping/types/set-array.d.mts.map b/node_modules/@jridgewell/gen-mapping/types/set-array.d.mts.map new file mode 100644 index 0000000..c52b8bc --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/types/set-array.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"set-array.d.ts","sourceRoot":"","sources":["../src/set-array.ts"],"names":[],"mappings":"AAAA,KAAK,GAAG,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpC;;;;;;;GAOG;AACH,qBAAa,QAAQ,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG;IACvC,QAAgB,QAAQ,CAAgC;IAChD,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;;CAM7B;AAeD;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,GAAG,SAAS,CAElF;AAED;;;GAGG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,CAStE;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAM5D;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAYvE"} \ No newline at end of file diff --git a/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.cts b/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.cts new file mode 100644 index 0000000..6886295 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.cts @@ -0,0 +1,13 @@ +type GeneratedColumn = number; +type SourcesIndex = number; +type SourceLine = number; +type SourceColumn = number; +type NamesIndex = number; +export type SourceMapSegment = [GeneratedColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex]; +export declare const COLUMN = 0; +export declare const SOURCES_INDEX = 1; +export declare const SOURCE_LINE = 2; +export declare const SOURCE_COLUMN = 3; +export declare const NAMES_INDEX = 4; +export {}; +//# sourceMappingURL=sourcemap-segment.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.cts.map b/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.cts.map new file mode 100644 index 0000000..23cdc45 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"sourcemap-segment.d.ts","sourceRoot":"","sources":["../src/sourcemap-segment.ts"],"names":[],"mappings":"AAAA,KAAK,eAAe,GAAG,MAAM,CAAC;AAC9B,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,UAAU,GAAG,MAAM,CAAC;AACzB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,UAAU,GAAG,MAAM,CAAC;AAEzB,MAAM,MAAM,gBAAgB,GACxB,CAAC,eAAe,CAAC,GACjB,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,GACzD,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;AAE1E,eAAO,MAAM,MAAM,IAAI,CAAC;AACxB,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,WAAW,IAAI,CAAC"} \ No newline at end of file diff --git a/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.mts b/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.mts new file mode 100644 index 0000000..6886295 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.mts @@ -0,0 +1,13 @@ +type GeneratedColumn = number; +type SourcesIndex = number; +type SourceLine = number; +type SourceColumn = number; +type NamesIndex = number; +export type SourceMapSegment = [GeneratedColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex]; +export declare const COLUMN = 0; +export declare const SOURCES_INDEX = 1; +export declare const SOURCE_LINE = 2; +export declare const SOURCE_COLUMN = 3; +export declare const NAMES_INDEX = 4; +export {}; +//# sourceMappingURL=sourcemap-segment.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.mts.map b/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.mts.map new file mode 100644 index 0000000..23cdc45 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/types/sourcemap-segment.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"sourcemap-segment.d.ts","sourceRoot":"","sources":["../src/sourcemap-segment.ts"],"names":[],"mappings":"AAAA,KAAK,eAAe,GAAG,MAAM,CAAC;AAC9B,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,UAAU,GAAG,MAAM,CAAC;AACzB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,UAAU,GAAG,MAAM,CAAC;AAEzB,MAAM,MAAM,gBAAgB,GACxB,CAAC,eAAe,CAAC,GACjB,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,GACzD,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;AAE1E,eAAO,MAAM,MAAM,IAAI,CAAC;AACxB,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,WAAW,IAAI,CAAC"} \ No newline at end of file diff --git a/node_modules/@jridgewell/gen-mapping/types/types.d.cts b/node_modules/@jridgewell/gen-mapping/types/types.d.cts new file mode 100644 index 0000000..58da00a --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/types/types.d.cts @@ -0,0 +1,44 @@ +import type { SourceMapSegment } from './sourcemap-segment.cts'; +export interface SourceMapV3 { + file?: string | null; + names: readonly string[]; + sourceRoot?: string; + sources: readonly (string | null)[]; + sourcesContent?: readonly (string | null)[]; + version: 3; + ignoreList?: readonly number[]; +} +export interface EncodedSourceMap extends SourceMapV3 { + mappings: string; +} +export interface DecodedSourceMap extends SourceMapV3 { + mappings: readonly SourceMapSegment[][]; +} +export interface Pos { + line: number; + column: number; +} +export interface OriginalPos extends Pos { + source: string; +} +export interface BindingExpressionRange { + start: Pos; + expression: string; +} +export type Mapping = { + generated: Pos; + source: undefined; + original: undefined; + name: undefined; +} | { + generated: Pos; + source: string; + original: Pos; + name: string; +} | { + generated: Pos; + source: string; + original: Pos; + name: undefined; +}; +//# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/gen-mapping/types/types.d.cts.map b/node_modules/@jridgewell/gen-mapping/types/types.d.cts.map new file mode 100644 index 0000000..159e734 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/types/types.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IACpC,cAAc,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAC5C,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,MAAM,CAAC;CAGlB;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EAAE,CAAC;CAGzC;AAED,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAY,SAAQ,GAAG;IACtC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,GAAG,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;CACpB;AAKD,MAAM,MAAM,OAAO,GACf;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;CACjB,GACD;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;CACjB,CAAC"} \ No newline at end of file diff --git a/node_modules/@jridgewell/gen-mapping/types/types.d.mts b/node_modules/@jridgewell/gen-mapping/types/types.d.mts new file mode 100644 index 0000000..e9837eb --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/types/types.d.mts @@ -0,0 +1,44 @@ +import type { SourceMapSegment } from './sourcemap-segment.mts'; +export interface SourceMapV3 { + file?: string | null; + names: readonly string[]; + sourceRoot?: string; + sources: readonly (string | null)[]; + sourcesContent?: readonly (string | null)[]; + version: 3; + ignoreList?: readonly number[]; +} +export interface EncodedSourceMap extends SourceMapV3 { + mappings: string; +} +export interface DecodedSourceMap extends SourceMapV3 { + mappings: readonly SourceMapSegment[][]; +} +export interface Pos { + line: number; + column: number; +} +export interface OriginalPos extends Pos { + source: string; +} +export interface BindingExpressionRange { + start: Pos; + expression: string; +} +export type Mapping = { + generated: Pos; + source: undefined; + original: undefined; + name: undefined; +} | { + generated: Pos; + source: string; + original: Pos; + name: string; +} | { + generated: Pos; + source: string; + original: Pos; + name: undefined; +}; +//# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/gen-mapping/types/types.d.mts.map b/node_modules/@jridgewell/gen-mapping/types/types.d.mts.map new file mode 100644 index 0000000..159e734 --- /dev/null +++ b/node_modules/@jridgewell/gen-mapping/types/types.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IACpC,cAAc,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAC5C,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,MAAM,CAAC;CAGlB;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EAAE,CAAC;CAGzC;AAED,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAY,SAAQ,GAAG;IACtC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,GAAG,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;CACpB;AAKD,MAAM,MAAM,OAAO,GACf;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;CACjB,GACD;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,GACD;IACE,SAAS,EAAE,GAAG,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;CACjB,CAAC"} \ No newline at end of file diff --git a/node_modules/@jridgewell/resolve-uri/LICENSE b/node_modules/@jridgewell/resolve-uri/LICENSE new file mode 100644 index 0000000..0a81b2a --- /dev/null +++ b/node_modules/@jridgewell/resolve-uri/LICENSE @@ -0,0 +1,19 @@ +Copyright 2019 Justin Ridgewell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/node_modules/@jridgewell/resolve-uri/README.md b/node_modules/@jridgewell/resolve-uri/README.md new file mode 100644 index 0000000..2fe70df --- /dev/null +++ b/node_modules/@jridgewell/resolve-uri/README.md @@ -0,0 +1,40 @@ +# @jridgewell/resolve-uri + +> Resolve a URI relative to an optional base URI + +Resolve any combination of absolute URIs, protocol-realtive URIs, absolute paths, or relative paths. + +## Installation + +```sh +npm install @jridgewell/resolve-uri +``` + +## Usage + +```typescript +function resolve(input: string, base?: string): string; +``` + +```js +import resolve from '@jridgewell/resolve-uri'; + +resolve('foo', 'https://example.com'); // => 'https://example.com/foo' +``` + +| Input | Base | Resolution | Explanation | +|-----------------------|-------------------------|--------------------------------|--------------------------------------------------------------| +| `https://example.com` | _any_ | `https://example.com/` | Input is normalized only | +| `//example.com` | `https://base.com/` | `https://example.com/` | Input inherits the base's protocol | +| `//example.com` | _rest_ | `//example.com/` | Input is normalized only | +| `/example` | `https://base.com/` | `https://base.com/example` | Input inherits the base's origin | +| `/example` | `//base.com/` | `//base.com/example` | Input inherits the base's host and remains protocol relative | +| `/example` | _rest_ | `/example` | Input is normalized only | +| `example` | `https://base.com/dir/` | `https://base.com/dir/example` | Input is joined with the base | +| `example` | `https://base.com/file` | `https://base.com/example` | Input is joined with the base without its file | +| `example` | `//base.com/dir/` | `//base.com/dir/example` | Input is joined with the base's last directory | +| `example` | `//base.com/file` | `//base.com/example` | Input is joined with the base without its file | +| `example` | `/base/dir/` | `/base/dir/example` | Input is joined with the base's last directory | +| `example` | `/base/file` | `/base/example` | Input is joined with the base without its file | +| `example` | `base/dir/` | `base/dir/example` | Input is joined with the base's last directory | +| `example` | `base/file` | `base/example` | Input is joined with the base without its file | diff --git a/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs b/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs new file mode 100644 index 0000000..e958e88 --- /dev/null +++ b/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs @@ -0,0 +1,232 @@ +// Matches the scheme of a URL, eg "http://" +const schemeRegex = /^[\w+.-]+:\/\//; +/** + * Matches the parts of a URL: + * 1. Scheme, including ":", guaranteed. + * 2. User/password, including "@", optional. + * 3. Host, guaranteed. + * 4. Port, including ":", optional. + * 5. Path, including "/", optional. + * 6. Query, including "?", optional. + * 7. Hash, including "#", optional. + */ +const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/; +/** + * File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start + * with a leading `/`, they can have a domain (but only if they don't start with a Windows drive). + * + * 1. Host, optional. + * 2. Path, which may include "/", guaranteed. + * 3. Query, including "?", optional. + * 4. Hash, including "#", optional. + */ +const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i; +function isAbsoluteUrl(input) { + return schemeRegex.test(input); +} +function isSchemeRelativeUrl(input) { + return input.startsWith('//'); +} +function isAbsolutePath(input) { + return input.startsWith('/'); +} +function isFileUrl(input) { + return input.startsWith('file:'); +} +function isRelative(input) { + return /^[.?#]/.test(input); +} +function parseAbsoluteUrl(input) { + const match = urlRegex.exec(input); + return makeUrl(match[1], match[2] || '', match[3], match[4] || '', match[5] || '/', match[6] || '', match[7] || ''); +} +function parseFileUrl(input) { + const match = fileRegex.exec(input); + const path = match[2]; + return makeUrl('file:', '', match[1] || '', '', isAbsolutePath(path) ? path : '/' + path, match[3] || '', match[4] || ''); +} +function makeUrl(scheme, user, host, port, path, query, hash) { + return { + scheme, + user, + host, + port, + path, + query, + hash, + type: 7 /* Absolute */, + }; +} +function parseUrl(input) { + if (isSchemeRelativeUrl(input)) { + const url = parseAbsoluteUrl('http:' + input); + url.scheme = ''; + url.type = 6 /* SchemeRelative */; + return url; + } + if (isAbsolutePath(input)) { + const url = parseAbsoluteUrl('http://foo.com' + input); + url.scheme = ''; + url.host = ''; + url.type = 5 /* AbsolutePath */; + return url; + } + if (isFileUrl(input)) + return parseFileUrl(input); + if (isAbsoluteUrl(input)) + return parseAbsoluteUrl(input); + const url = parseAbsoluteUrl('http://foo.com/' + input); + url.scheme = ''; + url.host = ''; + url.type = input + ? input.startsWith('?') + ? 3 /* Query */ + : input.startsWith('#') + ? 2 /* Hash */ + : 4 /* RelativePath */ + : 1 /* Empty */; + return url; +} +function stripPathFilename(path) { + // If a path ends with a parent directory "..", then it's a relative path with excess parent + // paths. It's not a file, so we can't strip it. + if (path.endsWith('/..')) + return path; + const index = path.lastIndexOf('/'); + return path.slice(0, index + 1); +} +function mergePaths(url, base) { + normalizePath(base, base.type); + // If the path is just a "/", then it was an empty path to begin with (remember, we're a relative + // path). + if (url.path === '/') { + url.path = base.path; + } + else { + // Resolution happens relative to the base path's directory, not the file. + url.path = stripPathFilename(base.path) + url.path; + } +} +/** + * The path can have empty directories "//", unneeded parents "foo/..", or current directory + * "foo/.". We need to normalize to a standard representation. + */ +function normalizePath(url, type) { + const rel = type <= 4 /* RelativePath */; + const pieces = url.path.split('/'); + // We need to preserve the first piece always, so that we output a leading slash. The item at + // pieces[0] is an empty string. + let pointer = 1; + // Positive is the number of real directories we've output, used for popping a parent directory. + // Eg, "foo/bar/.." will have a positive 2, and we can decrement to be left with just "foo". + let positive = 0; + // We need to keep a trailing slash if we encounter an empty directory (eg, splitting "foo/" will + // generate `["foo", ""]` pieces). And, if we pop a parent directory. But once we encounter a + // real directory, we won't need to append, unless the other conditions happen again. + let addTrailingSlash = false; + for (let i = 1; i < pieces.length; i++) { + const piece = pieces[i]; + // An empty directory, could be a trailing slash, or just a double "//" in the path. + if (!piece) { + addTrailingSlash = true; + continue; + } + // If we encounter a real directory, then we don't need to append anymore. + addTrailingSlash = false; + // A current directory, which we can always drop. + if (piece === '.') + continue; + // A parent directory, we need to see if there are any real directories we can pop. Else, we + // have an excess of parents, and we'll need to keep the "..". + if (piece === '..') { + if (positive) { + addTrailingSlash = true; + positive--; + pointer--; + } + else if (rel) { + // If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute + // URL, protocol relative URL, or an absolute path, we don't need to keep excess. + pieces[pointer++] = piece; + } + continue; + } + // We've encountered a real directory. Move it to the next insertion pointer, which accounts for + // any popped or dropped directories. + pieces[pointer++] = piece; + positive++; + } + let path = ''; + for (let i = 1; i < pointer; i++) { + path += '/' + pieces[i]; + } + if (!path || (addTrailingSlash && !path.endsWith('/..'))) { + path += '/'; + } + url.path = path; +} +/** + * Attempts to resolve `input` URL/path relative to `base`. + */ +function resolve(input, base) { + if (!input && !base) + return ''; + const url = parseUrl(input); + let inputType = url.type; + if (base && inputType !== 7 /* Absolute */) { + const baseUrl = parseUrl(base); + const baseType = baseUrl.type; + switch (inputType) { + case 1 /* Empty */: + url.hash = baseUrl.hash; + // fall through + case 2 /* Hash */: + url.query = baseUrl.query; + // fall through + case 3 /* Query */: + case 4 /* RelativePath */: + mergePaths(url, baseUrl); + // fall through + case 5 /* AbsolutePath */: + // The host, user, and port are joined, you can't copy one without the others. + url.user = baseUrl.user; + url.host = baseUrl.host; + url.port = baseUrl.port; + // fall through + case 6 /* SchemeRelative */: + // The input doesn't have a schema at least, so we need to copy at least that over. + url.scheme = baseUrl.scheme; + } + if (baseType > inputType) + inputType = baseType; + } + normalizePath(url, inputType); + const queryHash = url.query + url.hash; + switch (inputType) { + // This is impossible, because of the empty checks at the start of the function. + // case UrlType.Empty: + case 2 /* Hash */: + case 3 /* Query */: + return queryHash; + case 4 /* RelativePath */: { + // The first char is always a "/", and we need it to be relative. + const path = url.path.slice(1); + if (!path) + return queryHash || '.'; + if (isRelative(base || input) && !isRelative(path)) { + // If base started with a leading ".", or there is no base and input started with a ".", + // then we need to ensure that the relative path starts with a ".". We don't know if + // relative starts with a "..", though, so check before prepending. + return './' + path + queryHash; + } + return path + queryHash; + } + case 5 /* AbsolutePath */: + return url.path + queryHash; + default: + return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash; + } +} + +export { resolve as default }; +//# sourceMappingURL=resolve-uri.mjs.map diff --git a/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs.map b/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs.map new file mode 100644 index 0000000..1de97d0 --- /dev/null +++ b/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs.map @@ -0,0 +1 @@ +{"version":3,"file":"resolve-uri.mjs","sources":["../src/resolve-uri.ts"],"sourcesContent":["// Matches the scheme of a URL, eg \"http://\"\nconst schemeRegex = /^[\\w+.-]+:\\/\\//;\n\n/**\n * Matches the parts of a URL:\n * 1. Scheme, including \":\", guaranteed.\n * 2. User/password, including \"@\", optional.\n * 3. Host, guaranteed.\n * 4. Port, including \":\", optional.\n * 5. Path, including \"/\", optional.\n * 6. Query, including \"?\", optional.\n * 7. Hash, including \"#\", optional.\n */\nconst urlRegex = /^([\\w+.-]+:)\\/\\/([^@/#?]*@)?([^:/#?]*)(:\\d+)?(\\/[^#?]*)?(\\?[^#]*)?(#.*)?/;\n\n/**\n * File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start\n * with a leading `/`, they can have a domain (but only if they don't start with a Windows drive).\n *\n * 1. Host, optional.\n * 2. Path, which may include \"/\", guaranteed.\n * 3. Query, including \"?\", optional.\n * 4. Hash, including \"#\", optional.\n */\nconst fileRegex = /^file:(?:\\/\\/((?![a-z]:)[^/#?]*)?)?(\\/?[^#?]*)(\\?[^#]*)?(#.*)?/i;\n\ntype Url = {\n scheme: string;\n user: string;\n host: string;\n port: string;\n path: string;\n query: string;\n hash: string;\n type: UrlType;\n};\n\nconst enum UrlType {\n Empty = 1,\n Hash = 2,\n Query = 3,\n RelativePath = 4,\n AbsolutePath = 5,\n SchemeRelative = 6,\n Absolute = 7,\n}\n\nfunction isAbsoluteUrl(input: string): boolean {\n return schemeRegex.test(input);\n}\n\nfunction isSchemeRelativeUrl(input: string): boolean {\n return input.startsWith('//');\n}\n\nfunction isAbsolutePath(input: string): boolean {\n return input.startsWith('/');\n}\n\nfunction isFileUrl(input: string): boolean {\n return input.startsWith('file:');\n}\n\nfunction isRelative(input: string): boolean {\n return /^[.?#]/.test(input);\n}\n\nfunction parseAbsoluteUrl(input: string): Url {\n const match = urlRegex.exec(input)!;\n return makeUrl(\n match[1],\n match[2] || '',\n match[3],\n match[4] || '',\n match[5] || '/',\n match[6] || '',\n match[7] || '',\n );\n}\n\nfunction parseFileUrl(input: string): Url {\n const match = fileRegex.exec(input)!;\n const path = match[2];\n return makeUrl(\n 'file:',\n '',\n match[1] || '',\n '',\n isAbsolutePath(path) ? path : '/' + path,\n match[3] || '',\n match[4] || '',\n );\n}\n\nfunction makeUrl(\n scheme: string,\n user: string,\n host: string,\n port: string,\n path: string,\n query: string,\n hash: string,\n): Url {\n return {\n scheme,\n user,\n host,\n port,\n path,\n query,\n hash,\n type: UrlType.Absolute,\n };\n}\n\nfunction parseUrl(input: string): Url {\n if (isSchemeRelativeUrl(input)) {\n const url = parseAbsoluteUrl('http:' + input);\n url.scheme = '';\n url.type = UrlType.SchemeRelative;\n return url;\n }\n\n if (isAbsolutePath(input)) {\n const url = parseAbsoluteUrl('http://foo.com' + input);\n url.scheme = '';\n url.host = '';\n url.type = UrlType.AbsolutePath;\n return url;\n }\n\n if (isFileUrl(input)) return parseFileUrl(input);\n\n if (isAbsoluteUrl(input)) return parseAbsoluteUrl(input);\n\n const url = parseAbsoluteUrl('http://foo.com/' + input);\n url.scheme = '';\n url.host = '';\n url.type = input\n ? input.startsWith('?')\n ? UrlType.Query\n : input.startsWith('#')\n ? UrlType.Hash\n : UrlType.RelativePath\n : UrlType.Empty;\n return url;\n}\n\nfunction stripPathFilename(path: string): string {\n // If a path ends with a parent directory \"..\", then it's a relative path with excess parent\n // paths. It's not a file, so we can't strip it.\n if (path.endsWith('/..')) return path;\n const index = path.lastIndexOf('/');\n return path.slice(0, index + 1);\n}\n\nfunction mergePaths(url: Url, base: Url) {\n normalizePath(base, base.type);\n\n // If the path is just a \"/\", then it was an empty path to begin with (remember, we're a relative\n // path).\n if (url.path === '/') {\n url.path = base.path;\n } else {\n // Resolution happens relative to the base path's directory, not the file.\n url.path = stripPathFilename(base.path) + url.path;\n }\n}\n\n/**\n * The path can have empty directories \"//\", unneeded parents \"foo/..\", or current directory\n * \"foo/.\". We need to normalize to a standard representation.\n */\nfunction normalizePath(url: Url, type: UrlType) {\n const rel = type <= UrlType.RelativePath;\n const pieces = url.path.split('/');\n\n // We need to preserve the first piece always, so that we output a leading slash. The item at\n // pieces[0] is an empty string.\n let pointer = 1;\n\n // Positive is the number of real directories we've output, used for popping a parent directory.\n // Eg, \"foo/bar/..\" will have a positive 2, and we can decrement to be left with just \"foo\".\n let positive = 0;\n\n // We need to keep a trailing slash if we encounter an empty directory (eg, splitting \"foo/\" will\n // generate `[\"foo\", \"\"]` pieces). And, if we pop a parent directory. But once we encounter a\n // real directory, we won't need to append, unless the other conditions happen again.\n let addTrailingSlash = false;\n\n for (let i = 1; i < pieces.length; i++) {\n const piece = pieces[i];\n\n // An empty directory, could be a trailing slash, or just a double \"//\" in the path.\n if (!piece) {\n addTrailingSlash = true;\n continue;\n }\n\n // If we encounter a real directory, then we don't need to append anymore.\n addTrailingSlash = false;\n\n // A current directory, which we can always drop.\n if (piece === '.') continue;\n\n // A parent directory, we need to see if there are any real directories we can pop. Else, we\n // have an excess of parents, and we'll need to keep the \"..\".\n if (piece === '..') {\n if (positive) {\n addTrailingSlash = true;\n positive--;\n pointer--;\n } else if (rel) {\n // If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute\n // URL, protocol relative URL, or an absolute path, we don't need to keep excess.\n pieces[pointer++] = piece;\n }\n continue;\n }\n\n // We've encountered a real directory. Move it to the next insertion pointer, which accounts for\n // any popped or dropped directories.\n pieces[pointer++] = piece;\n positive++;\n }\n\n let path = '';\n for (let i = 1; i < pointer; i++) {\n path += '/' + pieces[i];\n }\n if (!path || (addTrailingSlash && !path.endsWith('/..'))) {\n path += '/';\n }\n url.path = path;\n}\n\n/**\n * Attempts to resolve `input` URL/path relative to `base`.\n */\nexport default function resolve(input: string, base: string | undefined): string {\n if (!input && !base) return '';\n\n const url = parseUrl(input);\n let inputType = url.type;\n\n if (base && inputType !== UrlType.Absolute) {\n const baseUrl = parseUrl(base);\n const baseType = baseUrl.type;\n\n switch (inputType) {\n case UrlType.Empty:\n url.hash = baseUrl.hash;\n // fall through\n\n case UrlType.Hash:\n url.query = baseUrl.query;\n // fall through\n\n case UrlType.Query:\n case UrlType.RelativePath:\n mergePaths(url, baseUrl);\n // fall through\n\n case UrlType.AbsolutePath:\n // The host, user, and port are joined, you can't copy one without the others.\n url.user = baseUrl.user;\n url.host = baseUrl.host;\n url.port = baseUrl.port;\n // fall through\n\n case UrlType.SchemeRelative:\n // The input doesn't have a schema at least, so we need to copy at least that over.\n url.scheme = baseUrl.scheme;\n }\n if (baseType > inputType) inputType = baseType;\n }\n\n normalizePath(url, inputType);\n\n const queryHash = url.query + url.hash;\n switch (inputType) {\n // This is impossible, because of the empty checks at the start of the function.\n // case UrlType.Empty:\n\n case UrlType.Hash:\n case UrlType.Query:\n return queryHash;\n\n case UrlType.RelativePath: {\n // The first char is always a \"/\", and we need it to be relative.\n const path = url.path.slice(1);\n\n if (!path) return queryHash || '.';\n\n if (isRelative(base || input) && !isRelative(path)) {\n // If base started with a leading \".\", or there is no base and input started with a \".\",\n // then we need to ensure that the relative path starts with a \".\". We don't know if\n // relative starts with a \"..\", though, so check before prepending.\n return './' + path + queryHash;\n }\n\n return path + queryHash;\n }\n\n case UrlType.AbsolutePath:\n return url.path + queryHash;\n\n default:\n return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash;\n }\n}\n"],"names":[],"mappings":"AAAA;AACA,MAAM,WAAW,GAAG,gBAAgB,CAAC;AAErC;;;;;;;;;;AAUA,MAAM,QAAQ,GAAG,0EAA0E,CAAC;AAE5F;;;;;;;;;AASA,MAAM,SAAS,GAAG,iEAAiE,CAAC;AAuBpF,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,cAAc,CAAC,KAAa;IACnC,OAAO,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AACnC,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAa;IACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAE,CAAC;IACpC,OAAO,OAAO,CACZ,KAAK,CAAC,CAAC,CAAC,EACR,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EACd,KAAK,CAAC,CAAC,CAAC,EACR,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EACd,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EACf,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EACd,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CACf,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAE,CAAC;IACrC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACtB,OAAO,OAAO,CACZ,OAAO,EACP,EAAE,EACF,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EACd,EAAE,EACF,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,EACxC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EACd,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CACf,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CACd,MAAc,EACd,IAAY,EACZ,IAAY,EACZ,IAAY,EACZ,IAAY,EACZ,KAAa,EACb,IAAY;IAEZ,OAAO;QACL,MAAM;QACN,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,KAAK;QACL,IAAI;QACJ,IAAI;KACL,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa;IAC7B,IAAI,mBAAmB,CAAC,KAAK,CAAC,EAAE;QAC9B,MAAM,GAAG,GAAG,gBAAgB,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC;QAC9C,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC;QAChB,GAAG,CAAC,IAAI,0BAA0B;QAClC,OAAO,GAAG,CAAC;KACZ;IAED,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE;QACzB,MAAM,GAAG,GAAG,gBAAgB,CAAC,gBAAgB,GAAG,KAAK,CAAC,CAAC;QACvD,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC;QAChB,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;QACd,GAAG,CAAC,IAAI,wBAAwB;QAChC,OAAO,GAAG,CAAC;KACZ;IAED,IAAI,SAAS,CAAC,KAAK,CAAC;QAAE,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;IAEjD,IAAI,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAEzD,MAAM,GAAG,GAAG,gBAAgB,CAAC,iBAAiB,GAAG,KAAK,CAAC,CAAC;IACxD,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC;IAChB,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;IACd,GAAG,CAAC,IAAI,GAAG,KAAK;UACZ,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;;cAEnB,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;;;wBAGT;IAClB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY;;;IAGrC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,UAAU,CAAC,GAAQ,EAAE,IAAS;IACrC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;;;IAI/B,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE;QACpB,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;KACtB;SAAM;;QAEL,GAAG,CAAC,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;KACpD;AACH,CAAC;AAED;;;;AAIA,SAAS,aAAa,CAAC,GAAQ,EAAE,IAAa;IAC5C,MAAM,GAAG,GAAG,IAAI,yBAAyB;IACzC,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;;;IAInC,IAAI,OAAO,GAAG,CAAC,CAAC;;;IAIhB,IAAI,QAAQ,GAAG,CAAC,CAAC;;;;IAKjB,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACtC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;;QAGxB,IAAI,CAAC,KAAK,EAAE;YACV,gBAAgB,GAAG,IAAI,CAAC;YACxB,SAAS;SACV;;QAGD,gBAAgB,GAAG,KAAK,CAAC;;QAGzB,IAAI,KAAK,KAAK,GAAG;YAAE,SAAS;;;QAI5B,IAAI,KAAK,KAAK,IAAI,EAAE;YAClB,IAAI,QAAQ,EAAE;gBACZ,gBAAgB,GAAG,IAAI,CAAC;gBACxB,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,CAAC;aACX;iBAAM,IAAI,GAAG,EAAE;;;gBAGd,MAAM,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC;aAC3B;YACD,SAAS;SACV;;;QAID,MAAM,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC;QAC1B,QAAQ,EAAE,CAAC;KACZ;IAED,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE;QAChC,IAAI,IAAI,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;KACzB;IACD,IAAI,CAAC,IAAI,KAAK,gBAAgB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE;QACxD,IAAI,IAAI,GAAG,CAAC;KACb;IACD,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;AAClB,CAAC;AAED;;;SAGwB,OAAO,CAAC,KAAa,EAAE,IAAwB;IACrE,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IAE/B,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5B,IAAI,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC;IAEzB,IAAI,IAAI,IAAI,SAAS,uBAAuB;QAC1C,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;QAE9B,QAAQ,SAAS;YACf;gBACE,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;;YAG1B;gBACE,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;;YAG5B,mBAAmB;YACnB;gBACE,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;;YAG3B;;gBAEE,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;gBACxB,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;gBACxB,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;;YAG1B;;gBAEE,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;SAC/B;QACD,IAAI,QAAQ,GAAG,SAAS;YAAE,SAAS,GAAG,QAAQ,CAAC;KAChD;IAED,aAAa,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAE9B,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC;IACvC,QAAQ,SAAS;;;QAIf,kBAAkB;QAClB;YACE,OAAO,SAAS,CAAC;QAEnB,2BAA2B;;YAEzB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAE/B,IAAI,CAAC,IAAI;gBAAE,OAAO,SAAS,IAAI,GAAG,CAAC;YAEnC,IAAI,UAAU,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;;;;gBAIlD,OAAO,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;aAChC;YAED,OAAO,IAAI,GAAG,SAAS,CAAC;SACzB;QAED;YACE,OAAO,GAAG,CAAC,IAAI,GAAG,SAAS,CAAC;QAE9B;YACE,OAAO,GAAG,CAAC,MAAM,GAAG,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,SAAS,CAAC;KACpF;AACH;;;;"} \ No newline at end of file diff --git a/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js b/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js new file mode 100644 index 0000000..a783049 --- /dev/null +++ b/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js @@ -0,0 +1,240 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.resolveURI = factory()); +})(this, (function () { 'use strict'; + + // Matches the scheme of a URL, eg "http://" + const schemeRegex = /^[\w+.-]+:\/\//; + /** + * Matches the parts of a URL: + * 1. Scheme, including ":", guaranteed. + * 2. User/password, including "@", optional. + * 3. Host, guaranteed. + * 4. Port, including ":", optional. + * 5. Path, including "/", optional. + * 6. Query, including "?", optional. + * 7. Hash, including "#", optional. + */ + const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/; + /** + * File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start + * with a leading `/`, they can have a domain (but only if they don't start with a Windows drive). + * + * 1. Host, optional. + * 2. Path, which may include "/", guaranteed. + * 3. Query, including "?", optional. + * 4. Hash, including "#", optional. + */ + const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i; + function isAbsoluteUrl(input) { + return schemeRegex.test(input); + } + function isSchemeRelativeUrl(input) { + return input.startsWith('//'); + } + function isAbsolutePath(input) { + return input.startsWith('/'); + } + function isFileUrl(input) { + return input.startsWith('file:'); + } + function isRelative(input) { + return /^[.?#]/.test(input); + } + function parseAbsoluteUrl(input) { + const match = urlRegex.exec(input); + return makeUrl(match[1], match[2] || '', match[3], match[4] || '', match[5] || '/', match[6] || '', match[7] || ''); + } + function parseFileUrl(input) { + const match = fileRegex.exec(input); + const path = match[2]; + return makeUrl('file:', '', match[1] || '', '', isAbsolutePath(path) ? path : '/' + path, match[3] || '', match[4] || ''); + } + function makeUrl(scheme, user, host, port, path, query, hash) { + return { + scheme, + user, + host, + port, + path, + query, + hash, + type: 7 /* Absolute */, + }; + } + function parseUrl(input) { + if (isSchemeRelativeUrl(input)) { + const url = parseAbsoluteUrl('http:' + input); + url.scheme = ''; + url.type = 6 /* SchemeRelative */; + return url; + } + if (isAbsolutePath(input)) { + const url = parseAbsoluteUrl('http://foo.com' + input); + url.scheme = ''; + url.host = ''; + url.type = 5 /* AbsolutePath */; + return url; + } + if (isFileUrl(input)) + return parseFileUrl(input); + if (isAbsoluteUrl(input)) + return parseAbsoluteUrl(input); + const url = parseAbsoluteUrl('http://foo.com/' + input); + url.scheme = ''; + url.host = ''; + url.type = input + ? input.startsWith('?') + ? 3 /* Query */ + : input.startsWith('#') + ? 2 /* Hash */ + : 4 /* RelativePath */ + : 1 /* Empty */; + return url; + } + function stripPathFilename(path) { + // If a path ends with a parent directory "..", then it's a relative path with excess parent + // paths. It's not a file, so we can't strip it. + if (path.endsWith('/..')) + return path; + const index = path.lastIndexOf('/'); + return path.slice(0, index + 1); + } + function mergePaths(url, base) { + normalizePath(base, base.type); + // If the path is just a "/", then it was an empty path to begin with (remember, we're a relative + // path). + if (url.path === '/') { + url.path = base.path; + } + else { + // Resolution happens relative to the base path's directory, not the file. + url.path = stripPathFilename(base.path) + url.path; + } + } + /** + * The path can have empty directories "//", unneeded parents "foo/..", or current directory + * "foo/.". We need to normalize to a standard representation. + */ + function normalizePath(url, type) { + const rel = type <= 4 /* RelativePath */; + const pieces = url.path.split('/'); + // We need to preserve the first piece always, so that we output a leading slash. The item at + // pieces[0] is an empty string. + let pointer = 1; + // Positive is the number of real directories we've output, used for popping a parent directory. + // Eg, "foo/bar/.." will have a positive 2, and we can decrement to be left with just "foo". + let positive = 0; + // We need to keep a trailing slash if we encounter an empty directory (eg, splitting "foo/" will + // generate `["foo", ""]` pieces). And, if we pop a parent directory. But once we encounter a + // real directory, we won't need to append, unless the other conditions happen again. + let addTrailingSlash = false; + for (let i = 1; i < pieces.length; i++) { + const piece = pieces[i]; + // An empty directory, could be a trailing slash, or just a double "//" in the path. + if (!piece) { + addTrailingSlash = true; + continue; + } + // If we encounter a real directory, then we don't need to append anymore. + addTrailingSlash = false; + // A current directory, which we can always drop. + if (piece === '.') + continue; + // A parent directory, we need to see if there are any real directories we can pop. Else, we + // have an excess of parents, and we'll need to keep the "..". + if (piece === '..') { + if (positive) { + addTrailingSlash = true; + positive--; + pointer--; + } + else if (rel) { + // If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute + // URL, protocol relative URL, or an absolute path, we don't need to keep excess. + pieces[pointer++] = piece; + } + continue; + } + // We've encountered a real directory. Move it to the next insertion pointer, which accounts for + // any popped or dropped directories. + pieces[pointer++] = piece; + positive++; + } + let path = ''; + for (let i = 1; i < pointer; i++) { + path += '/' + pieces[i]; + } + if (!path || (addTrailingSlash && !path.endsWith('/..'))) { + path += '/'; + } + url.path = path; + } + /** + * Attempts to resolve `input` URL/path relative to `base`. + */ + function resolve(input, base) { + if (!input && !base) + return ''; + const url = parseUrl(input); + let inputType = url.type; + if (base && inputType !== 7 /* Absolute */) { + const baseUrl = parseUrl(base); + const baseType = baseUrl.type; + switch (inputType) { + case 1 /* Empty */: + url.hash = baseUrl.hash; + // fall through + case 2 /* Hash */: + url.query = baseUrl.query; + // fall through + case 3 /* Query */: + case 4 /* RelativePath */: + mergePaths(url, baseUrl); + // fall through + case 5 /* AbsolutePath */: + // The host, user, and port are joined, you can't copy one without the others. + url.user = baseUrl.user; + url.host = baseUrl.host; + url.port = baseUrl.port; + // fall through + case 6 /* SchemeRelative */: + // The input doesn't have a schema at least, so we need to copy at least that over. + url.scheme = baseUrl.scheme; + } + if (baseType > inputType) + inputType = baseType; + } + normalizePath(url, inputType); + const queryHash = url.query + url.hash; + switch (inputType) { + // This is impossible, because of the empty checks at the start of the function. + // case UrlType.Empty: + case 2 /* Hash */: + case 3 /* Query */: + return queryHash; + case 4 /* RelativePath */: { + // The first char is always a "/", and we need it to be relative. + const path = url.path.slice(1); + if (!path) + return queryHash || '.'; + if (isRelative(base || input) && !isRelative(path)) { + // If base started with a leading ".", or there is no base and input started with a ".", + // then we need to ensure that the relative path starts with a ".". We don't know if + // relative starts with a "..", though, so check before prepending. + return './' + path + queryHash; + } + return path + queryHash; + } + case 5 /* AbsolutePath */: + return url.path + queryHash; + default: + return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash; + } + } + + return resolve; + +})); +//# sourceMappingURL=resolve-uri.umd.js.map diff --git a/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js.map b/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js.map new file mode 100644 index 0000000..70a37f2 --- /dev/null +++ b/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js.map @@ -0,0 +1 @@ +{"version":3,"file":"resolve-uri.umd.js","sources":["../src/resolve-uri.ts"],"sourcesContent":["// Matches the scheme of a URL, eg \"http://\"\nconst schemeRegex = /^[\\w+.-]+:\\/\\//;\n\n/**\n * Matches the parts of a URL:\n * 1. Scheme, including \":\", guaranteed.\n * 2. User/password, including \"@\", optional.\n * 3. Host, guaranteed.\n * 4. Port, including \":\", optional.\n * 5. Path, including \"/\", optional.\n * 6. Query, including \"?\", optional.\n * 7. Hash, including \"#\", optional.\n */\nconst urlRegex = /^([\\w+.-]+:)\\/\\/([^@/#?]*@)?([^:/#?]*)(:\\d+)?(\\/[^#?]*)?(\\?[^#]*)?(#.*)?/;\n\n/**\n * File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start\n * with a leading `/`, they can have a domain (but only if they don't start with a Windows drive).\n *\n * 1. Host, optional.\n * 2. Path, which may include \"/\", guaranteed.\n * 3. Query, including \"?\", optional.\n * 4. Hash, including \"#\", optional.\n */\nconst fileRegex = /^file:(?:\\/\\/((?![a-z]:)[^/#?]*)?)?(\\/?[^#?]*)(\\?[^#]*)?(#.*)?/i;\n\ntype Url = {\n scheme: string;\n user: string;\n host: string;\n port: string;\n path: string;\n query: string;\n hash: string;\n type: UrlType;\n};\n\nconst enum UrlType {\n Empty = 1,\n Hash = 2,\n Query = 3,\n RelativePath = 4,\n AbsolutePath = 5,\n SchemeRelative = 6,\n Absolute = 7,\n}\n\nfunction isAbsoluteUrl(input: string): boolean {\n return schemeRegex.test(input);\n}\n\nfunction isSchemeRelativeUrl(input: string): boolean {\n return input.startsWith('//');\n}\n\nfunction isAbsolutePath(input: string): boolean {\n return input.startsWith('/');\n}\n\nfunction isFileUrl(input: string): boolean {\n return input.startsWith('file:');\n}\n\nfunction isRelative(input: string): boolean {\n return /^[.?#]/.test(input);\n}\n\nfunction parseAbsoluteUrl(input: string): Url {\n const match = urlRegex.exec(input)!;\n return makeUrl(\n match[1],\n match[2] || '',\n match[3],\n match[4] || '',\n match[5] || '/',\n match[6] || '',\n match[7] || '',\n );\n}\n\nfunction parseFileUrl(input: string): Url {\n const match = fileRegex.exec(input)!;\n const path = match[2];\n return makeUrl(\n 'file:',\n '',\n match[1] || '',\n '',\n isAbsolutePath(path) ? path : '/' + path,\n match[3] || '',\n match[4] || '',\n );\n}\n\nfunction makeUrl(\n scheme: string,\n user: string,\n host: string,\n port: string,\n path: string,\n query: string,\n hash: string,\n): Url {\n return {\n scheme,\n user,\n host,\n port,\n path,\n query,\n hash,\n type: UrlType.Absolute,\n };\n}\n\nfunction parseUrl(input: string): Url {\n if (isSchemeRelativeUrl(input)) {\n const url = parseAbsoluteUrl('http:' + input);\n url.scheme = '';\n url.type = UrlType.SchemeRelative;\n return url;\n }\n\n if (isAbsolutePath(input)) {\n const url = parseAbsoluteUrl('http://foo.com' + input);\n url.scheme = '';\n url.host = '';\n url.type = UrlType.AbsolutePath;\n return url;\n }\n\n if (isFileUrl(input)) return parseFileUrl(input);\n\n if (isAbsoluteUrl(input)) return parseAbsoluteUrl(input);\n\n const url = parseAbsoluteUrl('http://foo.com/' + input);\n url.scheme = '';\n url.host = '';\n url.type = input\n ? input.startsWith('?')\n ? UrlType.Query\n : input.startsWith('#')\n ? UrlType.Hash\n : UrlType.RelativePath\n : UrlType.Empty;\n return url;\n}\n\nfunction stripPathFilename(path: string): string {\n // If a path ends with a parent directory \"..\", then it's a relative path with excess parent\n // paths. It's not a file, so we can't strip it.\n if (path.endsWith('/..')) return path;\n const index = path.lastIndexOf('/');\n return path.slice(0, index + 1);\n}\n\nfunction mergePaths(url: Url, base: Url) {\n normalizePath(base, base.type);\n\n // If the path is just a \"/\", then it was an empty path to begin with (remember, we're a relative\n // path).\n if (url.path === '/') {\n url.path = base.path;\n } else {\n // Resolution happens relative to the base path's directory, not the file.\n url.path = stripPathFilename(base.path) + url.path;\n }\n}\n\n/**\n * The path can have empty directories \"//\", unneeded parents \"foo/..\", or current directory\n * \"foo/.\". We need to normalize to a standard representation.\n */\nfunction normalizePath(url: Url, type: UrlType) {\n const rel = type <= UrlType.RelativePath;\n const pieces = url.path.split('/');\n\n // We need to preserve the first piece always, so that we output a leading slash. The item at\n // pieces[0] is an empty string.\n let pointer = 1;\n\n // Positive is the number of real directories we've output, used for popping a parent directory.\n // Eg, \"foo/bar/..\" will have a positive 2, and we can decrement to be left with just \"foo\".\n let positive = 0;\n\n // We need to keep a trailing slash if we encounter an empty directory (eg, splitting \"foo/\" will\n // generate `[\"foo\", \"\"]` pieces). And, if we pop a parent directory. But once we encounter a\n // real directory, we won't need to append, unless the other conditions happen again.\n let addTrailingSlash = false;\n\n for (let i = 1; i < pieces.length; i++) {\n const piece = pieces[i];\n\n // An empty directory, could be a trailing slash, or just a double \"//\" in the path.\n if (!piece) {\n addTrailingSlash = true;\n continue;\n }\n\n // If we encounter a real directory, then we don't need to append anymore.\n addTrailingSlash = false;\n\n // A current directory, which we can always drop.\n if (piece === '.') continue;\n\n // A parent directory, we need to see if there are any real directories we can pop. Else, we\n // have an excess of parents, and we'll need to keep the \"..\".\n if (piece === '..') {\n if (positive) {\n addTrailingSlash = true;\n positive--;\n pointer--;\n } else if (rel) {\n // If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute\n // URL, protocol relative URL, or an absolute path, we don't need to keep excess.\n pieces[pointer++] = piece;\n }\n continue;\n }\n\n // We've encountered a real directory. Move it to the next insertion pointer, which accounts for\n // any popped or dropped directories.\n pieces[pointer++] = piece;\n positive++;\n }\n\n let path = '';\n for (let i = 1; i < pointer; i++) {\n path += '/' + pieces[i];\n }\n if (!path || (addTrailingSlash && !path.endsWith('/..'))) {\n path += '/';\n }\n url.path = path;\n}\n\n/**\n * Attempts to resolve `input` URL/path relative to `base`.\n */\nexport default function resolve(input: string, base: string | undefined): string {\n if (!input && !base) return '';\n\n const url = parseUrl(input);\n let inputType = url.type;\n\n if (base && inputType !== UrlType.Absolute) {\n const baseUrl = parseUrl(base);\n const baseType = baseUrl.type;\n\n switch (inputType) {\n case UrlType.Empty:\n url.hash = baseUrl.hash;\n // fall through\n\n case UrlType.Hash:\n url.query = baseUrl.query;\n // fall through\n\n case UrlType.Query:\n case UrlType.RelativePath:\n mergePaths(url, baseUrl);\n // fall through\n\n case UrlType.AbsolutePath:\n // The host, user, and port are joined, you can't copy one without the others.\n url.user = baseUrl.user;\n url.host = baseUrl.host;\n url.port = baseUrl.port;\n // fall through\n\n case UrlType.SchemeRelative:\n // The input doesn't have a schema at least, so we need to copy at least that over.\n url.scheme = baseUrl.scheme;\n }\n if (baseType > inputType) inputType = baseType;\n }\n\n normalizePath(url, inputType);\n\n const queryHash = url.query + url.hash;\n switch (inputType) {\n // This is impossible, because of the empty checks at the start of the function.\n // case UrlType.Empty:\n\n case UrlType.Hash:\n case UrlType.Query:\n return queryHash;\n\n case UrlType.RelativePath: {\n // The first char is always a \"/\", and we need it to be relative.\n const path = url.path.slice(1);\n\n if (!path) return queryHash || '.';\n\n if (isRelative(base || input) && !isRelative(path)) {\n // If base started with a leading \".\", or there is no base and input started with a \".\",\n // then we need to ensure that the relative path starts with a \".\". We don't know if\n // relative starts with a \"..\", though, so check before prepending.\n return './' + path + queryHash;\n }\n\n return path + queryHash;\n }\n\n case UrlType.AbsolutePath:\n return url.path + queryHash;\n\n default:\n return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash;\n }\n}\n"],"names":[],"mappings":";;;;;;IAAA;IACA,MAAM,WAAW,GAAG,gBAAgB,CAAC;IAErC;;;;;;;;;;IAUA,MAAM,QAAQ,GAAG,0EAA0E,CAAC;IAE5F;;;;;;;;;IASA,MAAM,SAAS,GAAG,iEAAiE,CAAC;IAuBpF,SAAS,aAAa,CAAC,KAAa;QAClC,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,SAAS,mBAAmB,CAAC,KAAa;QACxC,OAAO,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,SAAS,cAAc,CAAC,KAAa;QACnC,OAAO,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED,SAAS,SAAS,CAAC,KAAa;QAC9B,OAAO,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,SAAS,UAAU,CAAC,KAAa;QAC/B,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,SAAS,gBAAgB,CAAC,KAAa;QACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAE,CAAC;QACpC,OAAO,OAAO,CACZ,KAAK,CAAC,CAAC,CAAC,EACR,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EACd,KAAK,CAAC,CAAC,CAAC,EACR,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EACd,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EACf,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EACd,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CACf,CAAC;IACJ,CAAC;IAED,SAAS,YAAY,CAAC,KAAa;QACjC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAE,CAAC;QACrC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,OAAO,OAAO,CACZ,OAAO,EACP,EAAE,EACF,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EACd,EAAE,EACF,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,EACxC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,EACd,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CACf,CAAC;IACJ,CAAC;IAED,SAAS,OAAO,CACd,MAAc,EACd,IAAY,EACZ,IAAY,EACZ,IAAY,EACZ,IAAY,EACZ,KAAa,EACb,IAAY;QAEZ,OAAO;YACL,MAAM;YACN,IAAI;YACJ,IAAI;YACJ,IAAI;YACJ,IAAI;YACJ,KAAK;YACL,IAAI;YACJ,IAAI;SACL,CAAC;IACJ,CAAC;IAED,SAAS,QAAQ,CAAC,KAAa;QAC7B,IAAI,mBAAmB,CAAC,KAAK,CAAC,EAAE;YAC9B,MAAM,GAAG,GAAG,gBAAgB,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC;YAC9C,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC;YAChB,GAAG,CAAC,IAAI,0BAA0B;YAClC,OAAO,GAAG,CAAC;SACZ;QAED,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE;YACzB,MAAM,GAAG,GAAG,gBAAgB,CAAC,gBAAgB,GAAG,KAAK,CAAC,CAAC;YACvD,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC;YAChB,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;YACd,GAAG,CAAC,IAAI,wBAAwB;YAChC,OAAO,GAAG,CAAC;SACZ;QAED,IAAI,SAAS,CAAC,KAAK,CAAC;YAAE,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC;QAEjD,IAAI,aAAa,CAAC,KAAK,CAAC;YAAE,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAEzD,MAAM,GAAG,GAAG,gBAAgB,CAAC,iBAAiB,GAAG,KAAK,CAAC,CAAC;QACxD,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC;QAChB,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;QACd,GAAG,CAAC,IAAI,GAAG,KAAK;cACZ,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;;kBAEnB,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;;;4BAGT;QAClB,OAAO,GAAG,CAAC;IACb,CAAC;IAED,SAAS,iBAAiB,CAAC,IAAY;;;QAGrC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IAClC,CAAC;IAED,SAAS,UAAU,CAAC,GAAQ,EAAE,IAAS;QACrC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;;;QAI/B,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE;YACpB,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;SACtB;aAAM;;YAEL,GAAG,CAAC,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;SACpD;IACH,CAAC;IAED;;;;IAIA,SAAS,aAAa,CAAC,GAAQ,EAAE,IAAa;QAC5C,MAAM,GAAG,GAAG,IAAI,yBAAyB;QACzC,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;;;QAInC,IAAI,OAAO,GAAG,CAAC,CAAC;;;QAIhB,IAAI,QAAQ,GAAG,CAAC,CAAC;;;;QAKjB,IAAI,gBAAgB,GAAG,KAAK,CAAC;QAE7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACtC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;;YAGxB,IAAI,CAAC,KAAK,EAAE;gBACV,gBAAgB,GAAG,IAAI,CAAC;gBACxB,SAAS;aACV;;YAGD,gBAAgB,GAAG,KAAK,CAAC;;YAGzB,IAAI,KAAK,KAAK,GAAG;gBAAE,SAAS;;;YAI5B,IAAI,KAAK,KAAK,IAAI,EAAE;gBAClB,IAAI,QAAQ,EAAE;oBACZ,gBAAgB,GAAG,IAAI,CAAC;oBACxB,QAAQ,EAAE,CAAC;oBACX,OAAO,EAAE,CAAC;iBACX;qBAAM,IAAI,GAAG,EAAE;;;oBAGd,MAAM,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC;iBAC3B;gBACD,SAAS;aACV;;;YAID,MAAM,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC;YAC1B,QAAQ,EAAE,CAAC;SACZ;QAED,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE;YAChC,IAAI,IAAI,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;SACzB;QACD,IAAI,CAAC,IAAI,KAAK,gBAAgB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE;YACxD,IAAI,IAAI,GAAG,CAAC;SACb;QACD,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;IAClB,CAAC;IAED;;;aAGwB,OAAO,CAAC,KAAa,EAAE,IAAwB;QACrE,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QAE/B,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC;QAEzB,IAAI,IAAI,IAAI,SAAS,uBAAuB;YAC1C,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;YAE9B,QAAQ,SAAS;gBACf;oBACE,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;;gBAG1B;oBACE,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;;gBAG5B,mBAAmB;gBACnB;oBACE,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;;gBAG3B;;oBAEE,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;oBACxB,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;oBACxB,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;;gBAG1B;;oBAEE,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;aAC/B;YACD,IAAI,QAAQ,GAAG,SAAS;gBAAE,SAAS,GAAG,QAAQ,CAAC;SAChD;QAED,aAAa,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAE9B,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC;QACvC,QAAQ,SAAS;;;YAIf,kBAAkB;YAClB;gBACE,OAAO,SAAS,CAAC;YAEnB,2BAA2B;;gBAEzB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAE/B,IAAI,CAAC,IAAI;oBAAE,OAAO,SAAS,IAAI,GAAG,CAAC;gBAEnC,IAAI,UAAU,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;;;;oBAIlD,OAAO,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;iBAChC;gBAED,OAAO,IAAI,GAAG,SAAS,CAAC;aACzB;YAED;gBACE,OAAO,GAAG,CAAC,IAAI,GAAG,SAAS,CAAC;YAE9B;gBACE,OAAO,GAAG,CAAC,MAAM,GAAG,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,SAAS,CAAC;SACpF;IACH;;;;;;;;"} \ No newline at end of file diff --git a/node_modules/@jridgewell/resolve-uri/dist/types/resolve-uri.d.ts b/node_modules/@jridgewell/resolve-uri/dist/types/resolve-uri.d.ts new file mode 100644 index 0000000..b7f0b3b --- /dev/null +++ b/node_modules/@jridgewell/resolve-uri/dist/types/resolve-uri.d.ts @@ -0,0 +1,4 @@ +/** + * Attempts to resolve `input` URL/path relative to `base`. + */ +export default function resolve(input: string, base: string | undefined): string; diff --git a/node_modules/@jridgewell/resolve-uri/package.json b/node_modules/@jridgewell/resolve-uri/package.json new file mode 100644 index 0000000..02a4c51 --- /dev/null +++ b/node_modules/@jridgewell/resolve-uri/package.json @@ -0,0 +1,69 @@ +{ + "name": "@jridgewell/resolve-uri", + "version": "3.1.2", + "description": "Resolve a URI relative to an optional base URI", + "keywords": [ + "resolve", + "uri", + "url", + "path" + ], + "author": "Justin Ridgewell ", + "license": "MIT", + "repository": "https://github.com/jridgewell/resolve-uri", + "main": "dist/resolve-uri.umd.js", + "module": "dist/resolve-uri.mjs", + "types": "dist/types/resolve-uri.d.ts", + "exports": { + ".": [ + { + "types": "./dist/types/resolve-uri.d.ts", + "browser": "./dist/resolve-uri.umd.js", + "require": "./dist/resolve-uri.umd.js", + "import": "./dist/resolve-uri.mjs" + }, + "./dist/resolve-uri.umd.js" + ], + "./package.json": "./package.json" + }, + "files": [ + "dist" + ], + "engines": { + "node": ">=6.0.0" + }, + "scripts": { + "prebuild": "rm -rf dist", + "build": "run-s -n build:*", + "build:rollup": "rollup -c rollup.config.js", + "build:ts": "tsc --project tsconfig.build.json", + "lint": "run-s -n lint:*", + "lint:prettier": "npm run test:lint:prettier -- --write", + "lint:ts": "npm run test:lint:ts -- --fix", + "pretest": "run-s build:rollup", + "test": "run-s -n test:lint test:only", + "test:debug": "mocha --inspect-brk", + "test:lint": "run-s -n test:lint:*", + "test:lint:prettier": "prettier --check '{src,test}/**/*.ts'", + "test:lint:ts": "eslint '{src,test}/**/*.ts'", + "test:only": "mocha", + "test:coverage": "c8 mocha", + "test:watch": "mocha --watch", + "prepublishOnly": "npm run preversion", + "preversion": "run-s test build" + }, + "devDependencies": { + "@jridgewell/resolve-uri-latest": "npm:@jridgewell/resolve-uri@*", + "@rollup/plugin-typescript": "8.3.0", + "@typescript-eslint/eslint-plugin": "5.10.0", + "@typescript-eslint/parser": "5.10.0", + "c8": "7.11.0", + "eslint": "8.7.0", + "eslint-config-prettier": "8.3.0", + "mocha": "9.2.0", + "npm-run-all": "4.1.5", + "prettier": "2.5.1", + "rollup": "2.66.0", + "typescript": "4.5.5" + } +} diff --git a/node_modules/@jridgewell/source-map/LICENSE b/node_modules/@jridgewell/source-map/LICENSE new file mode 100644 index 0000000..1f6ce94 --- /dev/null +++ b/node_modules/@jridgewell/source-map/LICENSE @@ -0,0 +1,19 @@ +Copyright 2024 Justin Ridgewell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@jridgewell/source-map/README.md b/node_modules/@jridgewell/source-map/README.md new file mode 100644 index 0000000..f73a326 --- /dev/null +++ b/node_modules/@jridgewell/source-map/README.md @@ -0,0 +1,184 @@ +# @jridgewell/source-map + +> Packages `@jridgewell/trace-mapping` and `@jridgewell/gen-mapping` into the familiar source-map API + +This isn't the full API, but it's the core functionality. This wraps +[@jridgewell/trace-mapping][trace-mapping] and [@jridgewell/gen-mapping][gen-mapping] +implementations. + +## Installation + +```sh +npm install @jridgewell/source-map +``` + +## Usage + +TODO + +### SourceMapConsumer + +```typescript +import { SourceMapConsumer } from '@jridgewell/source-map'; +const smc = new SourceMapConsumer({ + version: 3, + names: ['foo'], + sources: ['input.js'], + mappings: 'AAAAA', +}); +``` + +#### SourceMapConsumer.fromSourceMap(mapGenerator[, mapUrl]) + +Transforms a `SourceMapGenerator` into a `SourceMapConsumer`. + +```typescript +const smg = new SourceMapGenerator(); + +const smc = SourceMapConsumer.fromSourceMap(map); +smc.originalPositionFor({ line: 1, column: 0 }); +``` + +#### SourceMapConsumer.prototype.originalPositionFor(generatedPosition) + +```typescript +const smc = new SourceMapConsumer(map); +smc.originalPositionFor({ line: 1, column: 0 }); +``` + +#### SourceMapConsumer.prototype.mappings + +```typescript +const smc = new SourceMapConsumer(map); +smc.mappings; // AAAA +``` + +#### SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition) + +```typescript +const smc = new SourceMapConsumer(map); +smc.allGeneratedpositionsfor({ line: 1, column: 5, source: "baz.ts" }); +// [ +// { line: 2, column: 8 } +// ] +``` + +#### SourceMapConsumer.prototype.eachMapping(callback[, context[, order]]) + +> This implementation currently does not support the "order" parameter. +> This function can only iterate in Generated order. + +```typescript +const smc = new SourceMapConsumer(map); +smc.eachMapping((mapping) => { +// { source: 'baz.ts', +// generatedLine: 4, +// generatedColumn: 5, +// originalLine: 4, +// originalColumn: 5, +// name: null } +}); +``` + +#### SourceMapConsumer.prototype.generatedPositionFor(originalPosition) + +```typescript +const smc = new SourceMapConsumer(map); +smc.generatedPositionFor({ line: 1, column: 5, source: "baz.ts" }); +// { line: 2, column: 8 } +``` + +#### SourceMapConsumer.prototype.hasContentsOfAllSources() + +```typescript +const smc = new SourceMapConsumer(map); +smc.hasContentsOfAllSources(); +// true +``` + +#### SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing]) + +```typescript +const smc = new SourceMapConsumer(map); +smc.generatedPositionFor("baz.ts"); +// "export default ..." +``` + +#### SourceMapConsumer.prototype.version + +Returns the source map's version + +### SourceMapGenerator + +```typescript +import { SourceMapGenerator } from '@jridgewell/source-map'; +const smg = new SourceMapGenerator({ + file: 'output.js', + sourceRoot: 'https://example.com/', +}); +``` + +#### SourceMapGenerator.fromSourceMap(map) + +Transform a `SourceMapConsumer` into a `SourceMapGenerator`. + +```typescript +const smc = new SourceMapConsumer(); +const smg = SourceMapGenerator.fromSourceMap(smc); +``` + +#### SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]]) + +> This method is not implemented yet + +#### SourceMapGenerator.prototype.addMapping(mapping) + +```typescript +const smg = new SourceMapGenerator(); +smg.addMapping({ + generated: { line: 1, column: 0 }, + source: 'input.js', + original: { line: 1, column: 0 }, + name: 'foo', +}); +``` + +#### SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent) + +```typescript +const smg = new SourceMapGenerator(); +smg.setSourceContent('input.js', 'foobar'); +``` + +#### SourceMapGenerator.prototype.toJSON() + +```typescript +const smg = new SourceMapGenerator(); +smg.toJSON(); // { version: 3, names: [], sources: [], mappings: '' } +``` + +#### SourceMapGenerator.prototype.toString() + +```typescript +const smg = new SourceMapGenerator(); +smg.toJSON(); // "{version:3,names:[],sources:[],mappings:''}" +``` + +#### SourceMapGenerator.prototype.toDecodedMap() + +```typescript +const smg = new SourceMapGenerator(); +smg.toDecodedMap(); // { version: 3, names: [], sources: [], mappings: [] } +``` + +## Known differences with other implementations + +This implementation has some differences with `source-map` and `source-map-js`. + +- `SourceMapConsumer.prototype.eachMapping()` + - Does not support the `order` argument +- `SourceMapGenerator.prototype.applySourceMap()` + - Not implemented + +[trace-mapping]: https://github.com/jridgewell/sourcemaps/tree/main/packages/trace-mapping/ +[gen-mapping]: https://github.com/jridgewell/sourcemaps/tree/main/packages/gen-mapping/ diff --git a/node_modules/@jridgewell/source-map/dist/source-map.mjs b/node_modules/@jridgewell/source-map/dist/source-map.mjs new file mode 100644 index 0000000..f08ae5c --- /dev/null +++ b/node_modules/@jridgewell/source-map/dist/source-map.mjs @@ -0,0 +1,101 @@ +// src/source-map.ts +import { + AnyMap, + originalPositionFor, + generatedPositionFor, + allGeneratedPositionsFor, + eachMapping, + encodedMappings, + sourceContentFor +} from "@jridgewell/trace-mapping"; +import { + GenMapping, + maybeAddMapping, + toDecodedMap, + toEncodedMap, + setSourceContent, + fromMap +} from "@jridgewell/gen-mapping"; +var SourceMapConsumer = class _SourceMapConsumer { + constructor(map, mapUrl) { + const trace = this._map = new AnyMap(map, mapUrl); + this.file = trace.file; + this.names = trace.names; + this.sourceRoot = trace.sourceRoot; + this.sources = trace.resolvedSources; + this.sourcesContent = trace.sourcesContent; + this.version = trace.version; + } + static fromSourceMap(map, mapUrl) { + if (map.toDecodedMap) { + return new _SourceMapConsumer(map.toDecodedMap(), mapUrl); + } + return new _SourceMapConsumer(map.toJSON(), mapUrl); + } + get mappings() { + return encodedMappings(this._map); + } + originalPositionFor(needle) { + return originalPositionFor(this._map, needle); + } + generatedPositionFor(originalPosition) { + return generatedPositionFor(this._map, originalPosition); + } + allGeneratedPositionsFor(originalPosition) { + return allGeneratedPositionsFor(this._map, originalPosition); + } + hasContentsOfAllSources() { + if (!this.sourcesContent || this.sourcesContent.length !== this.sources.length) { + return false; + } + for (const content of this.sourcesContent) { + if (content == null) { + return false; + } + } + return true; + } + sourceContentFor(source, nullOnMissing) { + const sourceContent = sourceContentFor(this._map, source); + if (sourceContent != null) { + return sourceContent; + } + if (nullOnMissing) { + return null; + } + throw new Error(`"${source}" is not in the SourceMap.`); + } + eachMapping(callback, context) { + eachMapping(this._map, context ? callback.bind(context) : callback); + } + destroy() { + } +}; +var SourceMapGenerator = class _SourceMapGenerator { + constructor(opts) { + this._map = opts instanceof GenMapping ? opts : new GenMapping(opts); + } + static fromSourceMap(consumer) { + return new _SourceMapGenerator(fromMap(consumer)); + } + addMapping(mapping) { + maybeAddMapping(this._map, mapping); + } + setSourceContent(source, content) { + setSourceContent(this._map, source, content); + } + toJSON() { + return toEncodedMap(this._map); + } + toString() { + return JSON.stringify(this.toJSON()); + } + toDecodedMap() { + return toDecodedMap(this._map); + } +}; +export { + SourceMapConsumer, + SourceMapGenerator +}; +//# sourceMappingURL=source-map.mjs.map diff --git a/node_modules/@jridgewell/source-map/dist/source-map.mjs.map b/node_modules/@jridgewell/source-map/dist/source-map.mjs.map new file mode 100644 index 0000000..b8a9e16 --- /dev/null +++ b/node_modules/@jridgewell/source-map/dist/source-map.mjs.map @@ -0,0 +1,6 @@ +{ + "version": 3, + "sources": ["../src/source-map.ts"], + "mappings": ";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAaA,IAAM,oBAAN,MAAM,mBAAkB;AAAA,EAS7B,YACE,KACA,QACA;AACA,UAAM,QAAS,KAAK,OAAO,IAAI,OAAO,KAAK,MAAM;AAEjD,SAAK,OAAO,MAAM;AAClB,SAAK,QAAQ,MAAM;AACnB,SAAK,aAAa,MAAM;AACxB,SAAK,UAAU,MAAM;AACrB,SAAK,iBAAiB,MAAM;AAC5B,SAAK,UAAU,MAAM;AAAA,EACvB;AAAA,EAEA,OAAO,cAAc,KAAyB,QAAuC;AAGnF,QAAI,IAAI,cAAc;AACpB,aAAO,IAAI,mBAAkB,IAAI,aAAa,GAA8B,MAAM;AAAA,IACpF;AAGA,WAAO,IAAI,mBAAkB,IAAI,OAAO,GAA8B,MAAM;AAAA,EAC9E;AAAA,EAEA,IAAI,WAAmB;AACrB,WAAO,gBAAgB,KAAK,IAAI;AAAA,EAClC;AAAA,EAEA,oBACE,QACwC;AACxC,WAAO,oBAAoB,KAAK,MAAM,MAAM;AAAA,EAC9C;AAAA,EAEA,qBACE,kBACyC;AACzC,WAAO,qBAAqB,KAAK,MAAM,gBAAgB;AAAA,EACzD;AAAA,EAEA,yBACE,kBAC2C;AAC3C,WAAO,yBAAyB,KAAK,MAAM,gBAAgB;AAAA,EAC7D;AAAA,EAEA,0BAAmC;AACjC,QAAI,CAAC,KAAK,kBAAkB,KAAK,eAAe,WAAW,KAAK,QAAQ,QAAQ;AAC9E,aAAO;AAAA,IACT;AAEA,eAAW,WAAW,KAAK,gBAAgB;AACzC,UAAI,WAAW,MAAM;AACnB,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,iBAAiB,QAAgB,eAAwC;AACvE,UAAM,gBAAgB,iBAAiB,KAAK,MAAM,MAAM;AACxD,QAAI,iBAAiB,MAAM;AACzB,aAAO;AAAA,IACT;AAEA,QAAI,eAAe;AACjB,aAAO;AAAA,IACT;AACA,UAAM,IAAI,MAAM,IAAI,MAAM,4BAA4B;AAAA,EACxD;AAAA,EAEA,YACE,UACA,SACM;AAEN,gBAAY,KAAK,MAAM,UAAU,SAAS,KAAK,OAAO,IAAI,QAAQ;AAAA,EACpE;AAAA,EAEA,UAAU;AAAA,EAEV;AACF;AAEO,IAAM,qBAAN,MAAM,oBAAmB;AAAA,EAG9B,YAAY,MAAgE;AAE1E,SAAK,OAAO,gBAAgB,aAAa,OAAO,IAAI,WAAW,IAAI;AAAA,EACrE;AAAA,EAEA,OAAO,cAAc,UAA6B;AAChD,WAAO,IAAI,oBAAmB,QAAQ,QAAQ,CAAC;AAAA,EACjD;AAAA,EAEA,WAAW,SAAoF;AAC7F,oBAAgB,KAAK,MAAM,OAAO;AAAA,EACpC;AAAA,EAEA,iBACE,QACA,SACqC;AACrC,qBAAiB,KAAK,MAAM,QAAQ,OAAO;AAAA,EAC7C;AAAA,EAEA,SAA0C;AACxC,WAAO,aAAa,KAAK,IAAI;AAAA,EAC/B;AAAA,EAEA,WAAmB;AACjB,WAAO,KAAK,UAAU,KAAK,OAAO,CAAC;AAAA,EACrC;AAAA,EAEA,eAAgD;AAC9C,WAAO,aAAa,KAAK,IAAI;AAAA,EAC/B;AACF;", + "names": [] +} diff --git a/node_modules/@jridgewell/source-map/dist/source-map.umd.js b/node_modules/@jridgewell/source-map/dist/source-map.umd.js new file mode 100644 index 0000000..bdac85b --- /dev/null +++ b/node_modules/@jridgewell/source-map/dist/source-map.umd.js @@ -0,0 +1,152 @@ +(function (global, factory) { + if (typeof exports === 'object' && typeof module !== 'undefined') { + factory(module, require('@jridgewell/gen-mapping'), require('@jridgewell/trace-mapping')); + module.exports = def(module); + } else if (typeof define === 'function' && define.amd) { + define(['module', '@jridgewell/gen-mapping', '@jridgewell/trace-mapping'], function(mod) { + factory.apply(this, arguments); + mod.exports = def(mod); + }); + } else { + const mod = { exports: {} }; + factory(mod, global.genMapping, global.traceMapping); + global = typeof globalThis !== 'undefined' ? globalThis : global || self; + global.sourceMap = def(mod); + } + function def(m) { return 'default' in m.exports ? m.exports.default : m.exports; } +})(this, (function (module, require_genMapping, require_traceMapping) { +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// umd:@jridgewell/trace-mapping +var require_trace_mapping = __commonJS({ + "umd:@jridgewell/trace-mapping"(exports, module2) { + module2.exports = require_traceMapping; + } +}); + +// umd:@jridgewell/gen-mapping +var require_gen_mapping = __commonJS({ + "umd:@jridgewell/gen-mapping"(exports, module2) { + module2.exports = require_genMapping; + } +}); + +// src/source-map.ts +var source_map_exports = {}; +__export(source_map_exports, { + SourceMapConsumer: () => SourceMapConsumer, + SourceMapGenerator: () => SourceMapGenerator +}); +module.exports = __toCommonJS(source_map_exports); +var import_trace_mapping = __toESM(require_trace_mapping()); +var import_gen_mapping = __toESM(require_gen_mapping()); +var SourceMapConsumer = class _SourceMapConsumer { + constructor(map, mapUrl) { + const trace = this._map = new import_trace_mapping.AnyMap(map, mapUrl); + this.file = trace.file; + this.names = trace.names; + this.sourceRoot = trace.sourceRoot; + this.sources = trace.resolvedSources; + this.sourcesContent = trace.sourcesContent; + this.version = trace.version; + } + static fromSourceMap(map, mapUrl) { + if (map.toDecodedMap) { + return new _SourceMapConsumer(map.toDecodedMap(), mapUrl); + } + return new _SourceMapConsumer(map.toJSON(), mapUrl); + } + get mappings() { + return (0, import_trace_mapping.encodedMappings)(this._map); + } + originalPositionFor(needle) { + return (0, import_trace_mapping.originalPositionFor)(this._map, needle); + } + generatedPositionFor(originalPosition) { + return (0, import_trace_mapping.generatedPositionFor)(this._map, originalPosition); + } + allGeneratedPositionsFor(originalPosition) { + return (0, import_trace_mapping.allGeneratedPositionsFor)(this._map, originalPosition); + } + hasContentsOfAllSources() { + if (!this.sourcesContent || this.sourcesContent.length !== this.sources.length) { + return false; + } + for (const content of this.sourcesContent) { + if (content == null) { + return false; + } + } + return true; + } + sourceContentFor(source, nullOnMissing) { + const sourceContent = (0, import_trace_mapping.sourceContentFor)(this._map, source); + if (sourceContent != null) { + return sourceContent; + } + if (nullOnMissing) { + return null; + } + throw new Error(`"${source}" is not in the SourceMap.`); + } + eachMapping(callback, context) { + (0, import_trace_mapping.eachMapping)(this._map, context ? callback.bind(context) : callback); + } + destroy() { + } +}; +var SourceMapGenerator = class _SourceMapGenerator { + constructor(opts) { + this._map = opts instanceof import_gen_mapping.GenMapping ? opts : new import_gen_mapping.GenMapping(opts); + } + static fromSourceMap(consumer) { + return new _SourceMapGenerator((0, import_gen_mapping.fromMap)(consumer)); + } + addMapping(mapping) { + (0, import_gen_mapping.maybeAddMapping)(this._map, mapping); + } + setSourceContent(source, content) { + (0, import_gen_mapping.setSourceContent)(this._map, source, content); + } + toJSON() { + return (0, import_gen_mapping.toEncodedMap)(this._map); + } + toString() { + return JSON.stringify(this.toJSON()); + } + toDecodedMap() { + return (0, import_gen_mapping.toDecodedMap)(this._map); + } +}; +})); +//# sourceMappingURL=source-map.umd.js.map diff --git a/node_modules/@jridgewell/source-map/dist/source-map.umd.js.map b/node_modules/@jridgewell/source-map/dist/source-map.umd.js.map new file mode 100644 index 0000000..bc3f1c5 --- /dev/null +++ b/node_modules/@jridgewell/source-map/dist/source-map.umd.js.map @@ -0,0 +1,6 @@ +{ + "version": 3, + "sources": ["umd:@jridgewell/trace-mapping", "umd:@jridgewell/gen-mapping", "../src/source-map.ts"], + "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,2CAAAA,SAAA;AAAA,IAAAA,QAAO,UAAU;AAAA;AAAA;;;ACAjB;AAAA,yCAAAC,SAAA;AAAA,IAAAA,QAAO,UAAU;AAAA;AAAA;;;ACAjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BAQO;AACP,yBAOO;AAaA,IAAM,oBAAN,MAAM,mBAAkB;AAAA,EAS7B,YACE,KACA,QACA;AACA,UAAM,QAAS,KAAK,OAAO,IAAI,4BAAO,KAAK,MAAM;AAEjD,SAAK,OAAO,MAAM;AAClB,SAAK,QAAQ,MAAM;AACnB,SAAK,aAAa,MAAM;AACxB,SAAK,UAAU,MAAM;AACrB,SAAK,iBAAiB,MAAM;AAC5B,SAAK,UAAU,MAAM;AAAA,EACvB;AAAA,EAEA,OAAO,cAAc,KAAyB,QAAuC;AAGnF,QAAI,IAAI,cAAc;AACpB,aAAO,IAAI,mBAAkB,IAAI,aAAa,GAA8B,MAAM;AAAA,IACpF;AAGA,WAAO,IAAI,mBAAkB,IAAI,OAAO,GAA8B,MAAM;AAAA,EAC9E;AAAA,EAEA,IAAI,WAAmB;AACrB,eAAO,sCAAgB,KAAK,IAAI;AAAA,EAClC;AAAA,EAEA,oBACE,QACwC;AACxC,eAAO,0CAAoB,KAAK,MAAM,MAAM;AAAA,EAC9C;AAAA,EAEA,qBACE,kBACyC;AACzC,eAAO,2CAAqB,KAAK,MAAM,gBAAgB;AAAA,EACzD;AAAA,EAEA,yBACE,kBAC2C;AAC3C,eAAO,+CAAyB,KAAK,MAAM,gBAAgB;AAAA,EAC7D;AAAA,EAEA,0BAAmC;AACjC,QAAI,CAAC,KAAK,kBAAkB,KAAK,eAAe,WAAW,KAAK,QAAQ,QAAQ;AAC9E,aAAO;AAAA,IACT;AAEA,eAAW,WAAW,KAAK,gBAAgB;AACzC,UAAI,WAAW,MAAM;AACnB,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,iBAAiB,QAAgB,eAAwC;AACvE,UAAM,oBAAgB,uCAAiB,KAAK,MAAM,MAAM;AACxD,QAAI,iBAAiB,MAAM;AACzB,aAAO;AAAA,IACT;AAEA,QAAI,eAAe;AACjB,aAAO;AAAA,IACT;AACA,UAAM,IAAI,MAAM,IAAI,MAAM,4BAA4B;AAAA,EACxD;AAAA,EAEA,YACE,UACA,SACM;AAEN,0CAAY,KAAK,MAAM,UAAU,SAAS,KAAK,OAAO,IAAI,QAAQ;AAAA,EACpE;AAAA,EAEA,UAAU;AAAA,EAEV;AACF;AAEO,IAAM,qBAAN,MAAM,oBAAmB;AAAA,EAG9B,YAAY,MAAgE;AAE1E,SAAK,OAAO,gBAAgB,gCAAa,OAAO,IAAI,8BAAW,IAAI;AAAA,EACrE;AAAA,EAEA,OAAO,cAAc,UAA6B;AAChD,WAAO,IAAI,wBAAmB,4BAAQ,QAAQ,CAAC;AAAA,EACjD;AAAA,EAEA,WAAW,SAAoF;AAC7F,4CAAgB,KAAK,MAAM,OAAO;AAAA,EACpC;AAAA,EAEA,iBACE,QACA,SACqC;AACrC,6CAAiB,KAAK,MAAM,QAAQ,OAAO;AAAA,EAC7C;AAAA,EAEA,SAA0C;AACxC,eAAO,iCAAa,KAAK,IAAI;AAAA,EAC/B;AAAA,EAEA,WAAmB;AACjB,WAAO,KAAK,UAAU,KAAK,OAAO,CAAC;AAAA,EACrC;AAAA,EAEA,eAAgD;AAC9C,eAAO,iCAAa,KAAK,IAAI;AAAA,EAC/B;AACF;", + "names": ["module", "module"] +} diff --git a/node_modules/@jridgewell/source-map/package.json b/node_modules/@jridgewell/source-map/package.json new file mode 100644 index 0000000..03ca7df --- /dev/null +++ b/node_modules/@jridgewell/source-map/package.json @@ -0,0 +1,68 @@ +{ + "name": "@jridgewell/source-map", + "version": "0.3.11", + "description": "Packages @jridgewell/trace-mapping and @jridgewell/gen-mapping into the familiar source-map API", + "keywords": [ + "sourcemap", + "source", + "map" + ], + "main": "dist/source-map.umd.js", + "module": "dist/source-map.mjs", + "types": "types/source-map.d.cts", + "files": [ + "dist", + "src", + "types" + ], + "exports": { + ".": [ + { + "import": { + "types": "./types/source-map.d.mts", + "default": "./dist/source-map.mjs" + }, + "default": { + "types": "./types/source-map.d.cts", + "default": "./dist/source-map.umd.js" + } + }, + "./dist/source-map.umd.js" + ], + "./package.json": "./package.json" + }, + "scripts": { + "benchmark": "run-s build:code benchmark:*", + "benchmark:install": "cd benchmark && npm install", + "benchmark:only": "node --expose-gc benchmark/index.js", + "build": "run-s -n build:code build:types", + "build:code": "node ../../esbuild.mjs source-map.ts", + "build:types": "run-s build:types:force build:types:emit build:types:mts", + "build:types:force": "rimraf tsconfig.build.tsbuildinfo", + "build:types:emit": "tsc --project tsconfig.build.json", + "build:types:mts": "node ../../mts-types.mjs", + "clean": "run-s -n clean:code clean:types", + "clean:code": "tsc --build --clean tsconfig.build.json", + "clean:types": "rimraf dist types", + "test": "run-s -n test:types test:only test:format", + "test:format": "prettier --check '{src,test}/**/*.ts'", + "test:only": "mocha", + "test:types": "eslint '{src,test}/**/*.ts'", + "lint": "run-s -n lint:types lint:format", + "lint:format": "npm run test:format -- --write", + "lint:types": "npm run test:types -- --fix", + "prepublishOnly": "npm run-s -n build test" + }, + "homepage": "https://github.com/jridgewell/sourcemaps/tree/main/packages/source-map", + "repository": { + "type": "git", + "url": "git+https://github.com/jridgewell/sourcemaps.git", + "directory": "packages/source-map" + }, + "author": "Justin Ridgewell ", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } +} diff --git a/node_modules/@jridgewell/source-map/src/source-map.ts b/node_modules/@jridgewell/source-map/src/source-map.ts new file mode 100644 index 0000000..67a18ad --- /dev/null +++ b/node_modules/@jridgewell/source-map/src/source-map.ts @@ -0,0 +1,159 @@ +import { + AnyMap, + originalPositionFor, + generatedPositionFor, + allGeneratedPositionsFor, + eachMapping, + encodedMappings, + sourceContentFor, +} from '@jridgewell/trace-mapping'; +import { + GenMapping, + maybeAddMapping, + toDecodedMap, + toEncodedMap, + setSourceContent, + fromMap, +} from '@jridgewell/gen-mapping'; + +import type { + TraceMap, + SourceMapInput, + SectionedSourceMapInput, + DecodedSourceMap, +} from '@jridgewell/trace-mapping'; +export type { TraceMap, SourceMapInput, SectionedSourceMapInput, DecodedSourceMap }; + +import type { Mapping, EncodedSourceMap } from '@jridgewell/gen-mapping'; +export type { Mapping, EncodedSourceMap }; + +export class SourceMapConsumer { + declare private _map: TraceMap; + declare file: TraceMap['file']; + declare names: TraceMap['names']; + declare sourceRoot: TraceMap['sourceRoot']; + declare sources: TraceMap['sources']; + declare sourcesContent: TraceMap['sourcesContent']; + declare version: TraceMap['version']; + + constructor( + map: ConstructorParameters[0], + mapUrl?: ConstructorParameters[1], + ) { + const trace = (this._map = new AnyMap(map, mapUrl)); + + this.file = trace.file; + this.names = trace.names; + this.sourceRoot = trace.sourceRoot; + this.sources = trace.resolvedSources; + this.sourcesContent = trace.sourcesContent; + this.version = trace.version; + } + + static fromSourceMap(map: SourceMapGenerator, mapUrl?: Parameters[1]) { + // This is more performant if we receive + // a @jridgewell/source-map SourceMapGenerator + if (map.toDecodedMap) { + return new SourceMapConsumer(map.toDecodedMap() as SectionedSourceMapInput, mapUrl); + } + + // This is a fallback for `source-map` and `source-map-js` + return new SourceMapConsumer(map.toJSON() as SectionedSourceMapInput, mapUrl); + } + + get mappings(): string { + return encodedMappings(this._map); + } + + originalPositionFor( + needle: Parameters[1], + ): ReturnType { + return originalPositionFor(this._map, needle); + } + + generatedPositionFor( + originalPosition: Parameters[1], + ): ReturnType { + return generatedPositionFor(this._map, originalPosition); + } + + allGeneratedPositionsFor( + originalPosition: Parameters[1], + ): ReturnType[] { + return allGeneratedPositionsFor(this._map, originalPosition); + } + + hasContentsOfAllSources(): boolean { + if (!this.sourcesContent || this.sourcesContent.length !== this.sources.length) { + return false; + } + + for (const content of this.sourcesContent) { + if (content == null) { + return false; + } + } + + return true; + } + + sourceContentFor(source: string, nullOnMissing?: boolean): string | null { + const sourceContent = sourceContentFor(this._map, source); + if (sourceContent != null) { + return sourceContent; + } + + if (nullOnMissing) { + return null; + } + throw new Error(`"${source}" is not in the SourceMap.`); + } + + eachMapping( + callback: Parameters[1], + context?: any /*, order?: number*/, + ): void { + // order is ignored as @jridgewell/trace-map doesn't implement it + eachMapping(this._map, context ? callback.bind(context) : callback); + } + + destroy() { + // noop. + } +} + +export class SourceMapGenerator { + declare private _map: GenMapping; + + constructor(opts: ConstructorParameters[0] | GenMapping) { + // TODO :: should this be duck-typed ? + this._map = opts instanceof GenMapping ? opts : new GenMapping(opts); + } + + static fromSourceMap(consumer: SourceMapConsumer) { + return new SourceMapGenerator(fromMap(consumer)); + } + + addMapping(mapping: Parameters[1]): ReturnType { + maybeAddMapping(this._map, mapping); + } + + setSourceContent( + source: Parameters[1], + content: Parameters[2], + ): ReturnType { + setSourceContent(this._map, source, content); + } + + toJSON(): ReturnType { + return toEncodedMap(this._map); + } + + toString(): string { + return JSON.stringify(this.toJSON()); + } + + toDecodedMap(): ReturnType { + return toDecodedMap(this._map); + } +} diff --git a/node_modules/@jridgewell/source-map/types/source-map.d.cts b/node_modules/@jridgewell/source-map/types/source-map.d.cts new file mode 100644 index 0000000..f8c3d20 --- /dev/null +++ b/node_modules/@jridgewell/source-map/types/source-map.d.cts @@ -0,0 +1,36 @@ +import { AnyMap, originalPositionFor, generatedPositionFor, eachMapping } from '@jridgewell/trace-mapping'; +import { GenMapping, maybeAddMapping, toDecodedMap, toEncodedMap, setSourceContent } from '@jridgewell/gen-mapping'; +import type { TraceMap, SourceMapInput, SectionedSourceMapInput, DecodedSourceMap } from '@jridgewell/trace-mapping'; +export type { TraceMap, SourceMapInput, SectionedSourceMapInput, DecodedSourceMap }; +import type { Mapping, EncodedSourceMap } from '@jridgewell/gen-mapping'; +export type { Mapping, EncodedSourceMap }; +export declare class SourceMapConsumer { + private _map; + file: TraceMap['file']; + names: TraceMap['names']; + sourceRoot: TraceMap['sourceRoot']; + sources: TraceMap['sources']; + sourcesContent: TraceMap['sourcesContent']; + version: TraceMap['version']; + constructor(map: ConstructorParameters[0], mapUrl?: ConstructorParameters[1]); + static fromSourceMap(map: SourceMapGenerator, mapUrl?: Parameters[1]): SourceMapConsumer; + get mappings(): string; + originalPositionFor(needle: Parameters[1]): ReturnType; + generatedPositionFor(originalPosition: Parameters[1]): ReturnType; + allGeneratedPositionsFor(originalPosition: Parameters[1]): ReturnType[]; + hasContentsOfAllSources(): boolean; + sourceContentFor(source: string, nullOnMissing?: boolean): string | null; + eachMapping(callback: Parameters[1], context?: any): void; + destroy(): void; +} +export declare class SourceMapGenerator { + private _map; + constructor(opts: ConstructorParameters[0] | GenMapping); + static fromSourceMap(consumer: SourceMapConsumer): SourceMapGenerator; + addMapping(mapping: Parameters[1]): ReturnType; + setSourceContent(source: Parameters[1], content: Parameters[2]): ReturnType; + toJSON(): ReturnType; + toString(): string; + toDecodedMap(): ReturnType; +} +//# sourceMappingURL=source-map.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/source-map/types/source-map.d.cts.map b/node_modules/@jridgewell/source-map/types/source-map.d.cts.map new file mode 100644 index 0000000..50289f9 --- /dev/null +++ b/node_modules/@jridgewell/source-map/types/source-map.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"source-map.d.ts","sourceRoot":"","sources":["../src/source-map.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,mBAAmB,EACnB,oBAAoB,EAEpB,WAAW,EAGZ,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,UAAU,EACV,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAEjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EACV,QAAQ,EACR,cAAc,EACd,uBAAuB,EACvB,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,CAAC;AAEpF,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACzE,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAE1C,qBAAa,iBAAiB;IAC5B,QAAgB,IAAI,CAAW;IACvB,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvB,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACzB,UAAU,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;IACnC,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC7B,cAAc,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IAC3C,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;gBAGnC,GAAG,EAAE,qBAAqB,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,EAC5C,MAAM,CAAC,EAAE,qBAAqB,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAYlD,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,kBAAkB,EAAE,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAWnF,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,mBAAmB,CACjB,MAAM,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,GAChD,UAAU,CAAC,OAAO,mBAAmB,CAAC;IAIzC,oBAAoB,CAClB,gBAAgB,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,GAC3D,UAAU,CAAC,OAAO,oBAAoB,CAAC;IAI1C,wBAAwB,CACtB,gBAAgB,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,GAC3D,UAAU,CAAC,OAAO,oBAAoB,CAAC,EAAE;IAI5C,uBAAuB,IAAI,OAAO;IAclC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IAYxE,WAAW,CACT,QAAQ,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EAC3C,OAAO,CAAC,EAAE,GAAG,GACZ,IAAI;IAKP,OAAO;CAGR;AAED,qBAAa,kBAAkB;IAC7B,QAAgB,IAAI,CAAa;gBAErB,IAAI,EAAE,qBAAqB,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU;IAK1E,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,iBAAiB;IAIhD,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC;IAI9F,gBAAgB,CACd,MAAM,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAC9C,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAC9C,UAAU,CAAC,OAAO,gBAAgB,CAAC;IAItC,MAAM,IAAI,UAAU,CAAC,OAAO,YAAY,CAAC;IAIzC,QAAQ,IAAI,MAAM;IAIlB,YAAY,IAAI,UAAU,CAAC,OAAO,YAAY,CAAC;CAGhD"} \ No newline at end of file diff --git a/node_modules/@jridgewell/source-map/types/source-map.d.mts b/node_modules/@jridgewell/source-map/types/source-map.d.mts new file mode 100644 index 0000000..f8c3d20 --- /dev/null +++ b/node_modules/@jridgewell/source-map/types/source-map.d.mts @@ -0,0 +1,36 @@ +import { AnyMap, originalPositionFor, generatedPositionFor, eachMapping } from '@jridgewell/trace-mapping'; +import { GenMapping, maybeAddMapping, toDecodedMap, toEncodedMap, setSourceContent } from '@jridgewell/gen-mapping'; +import type { TraceMap, SourceMapInput, SectionedSourceMapInput, DecodedSourceMap } from '@jridgewell/trace-mapping'; +export type { TraceMap, SourceMapInput, SectionedSourceMapInput, DecodedSourceMap }; +import type { Mapping, EncodedSourceMap } from '@jridgewell/gen-mapping'; +export type { Mapping, EncodedSourceMap }; +export declare class SourceMapConsumer { + private _map; + file: TraceMap['file']; + names: TraceMap['names']; + sourceRoot: TraceMap['sourceRoot']; + sources: TraceMap['sources']; + sourcesContent: TraceMap['sourcesContent']; + version: TraceMap['version']; + constructor(map: ConstructorParameters[0], mapUrl?: ConstructorParameters[1]); + static fromSourceMap(map: SourceMapGenerator, mapUrl?: Parameters[1]): SourceMapConsumer; + get mappings(): string; + originalPositionFor(needle: Parameters[1]): ReturnType; + generatedPositionFor(originalPosition: Parameters[1]): ReturnType; + allGeneratedPositionsFor(originalPosition: Parameters[1]): ReturnType[]; + hasContentsOfAllSources(): boolean; + sourceContentFor(source: string, nullOnMissing?: boolean): string | null; + eachMapping(callback: Parameters[1], context?: any): void; + destroy(): void; +} +export declare class SourceMapGenerator { + private _map; + constructor(opts: ConstructorParameters[0] | GenMapping); + static fromSourceMap(consumer: SourceMapConsumer): SourceMapGenerator; + addMapping(mapping: Parameters[1]): ReturnType; + setSourceContent(source: Parameters[1], content: Parameters[2]): ReturnType; + toJSON(): ReturnType; + toString(): string; + toDecodedMap(): ReturnType; +} +//# sourceMappingURL=source-map.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/source-map/types/source-map.d.mts.map b/node_modules/@jridgewell/source-map/types/source-map.d.mts.map new file mode 100644 index 0000000..50289f9 --- /dev/null +++ b/node_modules/@jridgewell/source-map/types/source-map.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"source-map.d.ts","sourceRoot":"","sources":["../src/source-map.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,mBAAmB,EACnB,oBAAoB,EAEpB,WAAW,EAGZ,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,UAAU,EACV,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAEjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EACV,QAAQ,EACR,cAAc,EACd,uBAAuB,EACvB,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,CAAC;AAEpF,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACzE,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAE1C,qBAAa,iBAAiB;IAC5B,QAAgB,IAAI,CAAW;IACvB,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvB,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IACzB,UAAU,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;IACnC,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC7B,cAAc,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IAC3C,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;gBAGnC,GAAG,EAAE,qBAAqB,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,EAC5C,MAAM,CAAC,EAAE,qBAAqB,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAYlD,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,kBAAkB,EAAE,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAWnF,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,mBAAmB,CACjB,MAAM,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,GAChD,UAAU,CAAC,OAAO,mBAAmB,CAAC;IAIzC,oBAAoB,CAClB,gBAAgB,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,GAC3D,UAAU,CAAC,OAAO,oBAAoB,CAAC;IAI1C,wBAAwB,CACtB,gBAAgB,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,GAC3D,UAAU,CAAC,OAAO,oBAAoB,CAAC,EAAE;IAI5C,uBAAuB,IAAI,OAAO;IAclC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IAYxE,WAAW,CACT,QAAQ,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EAC3C,OAAO,CAAC,EAAE,GAAG,GACZ,IAAI;IAKP,OAAO;CAGR;AAED,qBAAa,kBAAkB;IAC7B,QAAgB,IAAI,CAAa;gBAErB,IAAI,EAAE,qBAAqB,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU;IAK1E,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,iBAAiB;IAIhD,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC;IAI9F,gBAAgB,CACd,MAAM,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAC9C,OAAO,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAC9C,UAAU,CAAC,OAAO,gBAAgB,CAAC;IAItC,MAAM,IAAI,UAAU,CAAC,OAAO,YAAY,CAAC;IAIzC,QAAQ,IAAI,MAAM;IAIlB,YAAY,IAAI,UAAU,CAAC,OAAO,YAAY,CAAC;CAGhD"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/LICENSE b/node_modules/@jridgewell/sourcemap-codec/LICENSE new file mode 100644 index 0000000..1f6ce94 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/LICENSE @@ -0,0 +1,19 @@ +Copyright 2024 Justin Ridgewell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@jridgewell/sourcemap-codec/README.md b/node_modules/@jridgewell/sourcemap-codec/README.md new file mode 100644 index 0000000..b3e0708 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/README.md @@ -0,0 +1,264 @@ +# @jridgewell/sourcemap-codec + +Encode/decode the `mappings` property of a [sourcemap](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit). + + +## Why? + +Sourcemaps are difficult to generate and manipulate, because the `mappings` property – the part that actually links the generated code back to the original source – is encoded using an obscure method called [Variable-length quantity](https://en.wikipedia.org/wiki/Variable-length_quantity). On top of that, each segment in the mapping contains offsets rather than absolute indices, which means that you can't look at a segment in isolation – you have to understand the whole sourcemap. + +This package makes the process slightly easier. + + +## Installation + +```bash +npm install @jridgewell/sourcemap-codec +``` + + +## Usage + +```js +import { encode, decode } from '@jridgewell/sourcemap-codec'; + +var decoded = decode( ';EAEEA,EAAE,EAAC,CAAE;ECQY,UACC' ); + +assert.deepEqual( decoded, [ + // the first line (of the generated code) has no mappings, + // as shown by the starting semi-colon (which separates lines) + [], + + // the second line contains four (comma-separated) segments + [ + // segments are encoded as you'd expect: + // [ generatedCodeColumn, sourceIndex, sourceCodeLine, sourceCodeColumn, nameIndex ] + + // i.e. the first segment begins at column 2, and maps back to the second column + // of the second line (both zero-based) of the 0th source, and uses the 0th + // name in the `map.names` array + [ 2, 0, 2, 2, 0 ], + + // the remaining segments are 4-length rather than 5-length, + // because they don't map a name + [ 4, 0, 2, 4 ], + [ 6, 0, 2, 5 ], + [ 7, 0, 2, 7 ] + ], + + // the final line contains two segments + [ + [ 2, 1, 10, 19 ], + [ 12, 1, 11, 20 ] + ] +]); + +var encoded = encode( decoded ); +assert.equal( encoded, ';EAEEA,EAAE,EAAC,CAAE;ECQY,UACC' ); +``` + +## Benchmarks + +``` +node v20.10.0 + +amp.js.map - 45120 segments + +Decode Memory Usage: +local code 5815135 bytes +@jridgewell/sourcemap-codec 1.4.15 5868160 bytes +sourcemap-codec 5492584 bytes +source-map-0.6.1 13569984 bytes +source-map-0.8.0 6390584 bytes +chrome dev tools 8011136 bytes +Smallest memory usage is sourcemap-codec + +Decode speed: +decode: local code x 492 ops/sec ±1.22% (90 runs sampled) +decode: @jridgewell/sourcemap-codec 1.4.15 x 499 ops/sec ±1.16% (89 runs sampled) +decode: sourcemap-codec x 376 ops/sec ±1.66% (89 runs sampled) +decode: source-map-0.6.1 x 34.99 ops/sec ±0.94% (48 runs sampled) +decode: source-map-0.8.0 x 351 ops/sec ±0.07% (95 runs sampled) +chrome dev tools x 165 ops/sec ±0.91% (86 runs sampled) +Fastest is decode: @jridgewell/sourcemap-codec 1.4.15 + +Encode Memory Usage: +local code 444248 bytes +@jridgewell/sourcemap-codec 1.4.15 623024 bytes +sourcemap-codec 8696280 bytes +source-map-0.6.1 8745176 bytes +source-map-0.8.0 8736624 bytes +Smallest memory usage is local code + +Encode speed: +encode: local code x 796 ops/sec ±0.11% (97 runs sampled) +encode: @jridgewell/sourcemap-codec 1.4.15 x 795 ops/sec ±0.25% (98 runs sampled) +encode: sourcemap-codec x 231 ops/sec ±0.83% (86 runs sampled) +encode: source-map-0.6.1 x 166 ops/sec ±0.57% (86 runs sampled) +encode: source-map-0.8.0 x 203 ops/sec ±0.45% (88 runs sampled) +Fastest is encode: local code,encode: @jridgewell/sourcemap-codec 1.4.15 + + +*** + + +babel.min.js.map - 347793 segments + +Decode Memory Usage: +local code 35424960 bytes +@jridgewell/sourcemap-codec 1.4.15 35424696 bytes +sourcemap-codec 36033464 bytes +source-map-0.6.1 62253704 bytes +source-map-0.8.0 43843920 bytes +chrome dev tools 45111400 bytes +Smallest memory usage is @jridgewell/sourcemap-codec 1.4.15 + +Decode speed: +decode: local code x 38.18 ops/sec ±5.44% (52 runs sampled) +decode: @jridgewell/sourcemap-codec 1.4.15 x 38.36 ops/sec ±5.02% (52 runs sampled) +decode: sourcemap-codec x 34.05 ops/sec ±4.45% (47 runs sampled) +decode: source-map-0.6.1 x 4.31 ops/sec ±2.76% (15 runs sampled) +decode: source-map-0.8.0 x 55.60 ops/sec ±0.13% (73 runs sampled) +chrome dev tools x 16.94 ops/sec ±3.78% (46 runs sampled) +Fastest is decode: source-map-0.8.0 + +Encode Memory Usage: +local code 2606016 bytes +@jridgewell/sourcemap-codec 1.4.15 2626440 bytes +sourcemap-codec 21152576 bytes +source-map-0.6.1 25023928 bytes +source-map-0.8.0 25256448 bytes +Smallest memory usage is local code + +Encode speed: +encode: local code x 127 ops/sec ±0.18% (83 runs sampled) +encode: @jridgewell/sourcemap-codec 1.4.15 x 128 ops/sec ±0.26% (83 runs sampled) +encode: sourcemap-codec x 29.31 ops/sec ±2.55% (53 runs sampled) +encode: source-map-0.6.1 x 18.85 ops/sec ±3.19% (36 runs sampled) +encode: source-map-0.8.0 x 19.34 ops/sec ±1.97% (36 runs sampled) +Fastest is encode: @jridgewell/sourcemap-codec 1.4.15 + + +*** + + +preact.js.map - 1992 segments + +Decode Memory Usage: +local code 261696 bytes +@jridgewell/sourcemap-codec 1.4.15 244296 bytes +sourcemap-codec 302816 bytes +source-map-0.6.1 939176 bytes +source-map-0.8.0 336 bytes +chrome dev tools 587368 bytes +Smallest memory usage is source-map-0.8.0 + +Decode speed: +decode: local code x 17,782 ops/sec ±0.32% (97 runs sampled) +decode: @jridgewell/sourcemap-codec 1.4.15 x 17,863 ops/sec ±0.40% (100 runs sampled) +decode: sourcemap-codec x 12,453 ops/sec ±0.27% (101 runs sampled) +decode: source-map-0.6.1 x 1,288 ops/sec ±1.05% (96 runs sampled) +decode: source-map-0.8.0 x 9,289 ops/sec ±0.27% (101 runs sampled) +chrome dev tools x 4,769 ops/sec ±0.18% (100 runs sampled) +Fastest is decode: @jridgewell/sourcemap-codec 1.4.15 + +Encode Memory Usage: +local code 262944 bytes +@jridgewell/sourcemap-codec 1.4.15 25544 bytes +sourcemap-codec 323048 bytes +source-map-0.6.1 507808 bytes +source-map-0.8.0 507480 bytes +Smallest memory usage is @jridgewell/sourcemap-codec 1.4.15 + +Encode speed: +encode: local code x 24,207 ops/sec ±0.79% (95 runs sampled) +encode: @jridgewell/sourcemap-codec 1.4.15 x 24,288 ops/sec ±0.48% (96 runs sampled) +encode: sourcemap-codec x 6,761 ops/sec ±0.21% (100 runs sampled) +encode: source-map-0.6.1 x 5,374 ops/sec ±0.17% (99 runs sampled) +encode: source-map-0.8.0 x 5,633 ops/sec ±0.32% (99 runs sampled) +Fastest is encode: @jridgewell/sourcemap-codec 1.4.15,encode: local code + + +*** + + +react.js.map - 5726 segments + +Decode Memory Usage: +local code 678816 bytes +@jridgewell/sourcemap-codec 1.4.15 678816 bytes +sourcemap-codec 816400 bytes +source-map-0.6.1 2288864 bytes +source-map-0.8.0 721360 bytes +chrome dev tools 1012512 bytes +Smallest memory usage is local code + +Decode speed: +decode: local code x 6,178 ops/sec ±0.19% (98 runs sampled) +decode: @jridgewell/sourcemap-codec 1.4.15 x 6,261 ops/sec ±0.22% (100 runs sampled) +decode: sourcemap-codec x 4,472 ops/sec ±0.90% (99 runs sampled) +decode: source-map-0.6.1 x 449 ops/sec ±0.31% (95 runs sampled) +decode: source-map-0.8.0 x 3,219 ops/sec ±0.13% (100 runs sampled) +chrome dev tools x 1,743 ops/sec ±0.20% (99 runs sampled) +Fastest is decode: @jridgewell/sourcemap-codec 1.4.15 + +Encode Memory Usage: +local code 140960 bytes +@jridgewell/sourcemap-codec 1.4.15 159808 bytes +sourcemap-codec 969304 bytes +source-map-0.6.1 930520 bytes +source-map-0.8.0 930248 bytes +Smallest memory usage is local code + +Encode speed: +encode: local code x 8,013 ops/sec ±0.19% (100 runs sampled) +encode: @jridgewell/sourcemap-codec 1.4.15 x 7,989 ops/sec ±0.20% (101 runs sampled) +encode: sourcemap-codec x 2,472 ops/sec ±0.21% (99 runs sampled) +encode: source-map-0.6.1 x 2,200 ops/sec ±0.17% (99 runs sampled) +encode: source-map-0.8.0 x 2,220 ops/sec ±0.37% (99 runs sampled) +Fastest is encode: local code + + +*** + + +vscode.map - 2141001 segments + +Decode Memory Usage: +local code 198955264 bytes +@jridgewell/sourcemap-codec 1.4.15 199175352 bytes +sourcemap-codec 199102688 bytes +source-map-0.6.1 386323432 bytes +source-map-0.8.0 244116432 bytes +chrome dev tools 293734280 bytes +Smallest memory usage is local code + +Decode speed: +decode: local code x 3.90 ops/sec ±22.21% (15 runs sampled) +decode: @jridgewell/sourcemap-codec 1.4.15 x 3.95 ops/sec ±23.53% (15 runs sampled) +decode: sourcemap-codec x 3.82 ops/sec ±17.94% (14 runs sampled) +decode: source-map-0.6.1 x 0.61 ops/sec ±7.81% (6 runs sampled) +decode: source-map-0.8.0 x 9.54 ops/sec ±0.28% (28 runs sampled) +chrome dev tools x 2.18 ops/sec ±10.58% (10 runs sampled) +Fastest is decode: source-map-0.8.0 + +Encode Memory Usage: +local code 13509880 bytes +@jridgewell/sourcemap-codec 1.4.15 13537648 bytes +sourcemap-codec 32540104 bytes +source-map-0.6.1 127531040 bytes +source-map-0.8.0 127535312 bytes +Smallest memory usage is local code + +Encode speed: +encode: local code x 20.10 ops/sec ±0.19% (38 runs sampled) +encode: @jridgewell/sourcemap-codec 1.4.15 x 20.26 ops/sec ±0.32% (38 runs sampled) +encode: sourcemap-codec x 5.44 ops/sec ±1.64% (18 runs sampled) +encode: source-map-0.6.1 x 2.30 ops/sec ±4.79% (10 runs sampled) +encode: source-map-0.8.0 x 2.46 ops/sec ±6.53% (10 runs sampled) +Fastest is encode: @jridgewell/sourcemap-codec 1.4.15 +``` + +# License + +MIT diff --git a/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs new file mode 100644 index 0000000..532bab3 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs @@ -0,0 +1,423 @@ +// src/vlq.ts +var comma = ",".charCodeAt(0); +var semicolon = ";".charCodeAt(0); +var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var intToChar = new Uint8Array(64); +var charToInt = new Uint8Array(128); +for (let i = 0; i < chars.length; i++) { + const c = chars.charCodeAt(i); + intToChar[i] = c; + charToInt[c] = i; +} +function decodeInteger(reader, relative) { + let value = 0; + let shift = 0; + let integer = 0; + do { + const c = reader.next(); + integer = charToInt[c]; + value |= (integer & 31) << shift; + shift += 5; + } while (integer & 32); + const shouldNegate = value & 1; + value >>>= 1; + if (shouldNegate) { + value = -2147483648 | -value; + } + return relative + value; +} +function encodeInteger(builder, num, relative) { + let delta = num - relative; + delta = delta < 0 ? -delta << 1 | 1 : delta << 1; + do { + let clamped = delta & 31; + delta >>>= 5; + if (delta > 0) clamped |= 32; + builder.write(intToChar[clamped]); + } while (delta > 0); + return num; +} +function hasMoreVlq(reader, max) { + if (reader.pos >= max) return false; + return reader.peek() !== comma; +} + +// src/strings.ts +var bufLength = 1024 * 16; +var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? { + decode(buf) { + const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength); + return out.toString(); + } +} : { + decode(buf) { + let out = ""; + for (let i = 0; i < buf.length; i++) { + out += String.fromCharCode(buf[i]); + } + return out; + } +}; +var StringWriter = class { + constructor() { + this.pos = 0; + this.out = ""; + this.buffer = new Uint8Array(bufLength); + } + write(v) { + const { buffer } = this; + buffer[this.pos++] = v; + if (this.pos === bufLength) { + this.out += td.decode(buffer); + this.pos = 0; + } + } + flush() { + const { buffer, out, pos } = this; + return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out; + } +}; +var StringReader = class { + constructor(buffer) { + this.pos = 0; + this.buffer = buffer; + } + next() { + return this.buffer.charCodeAt(this.pos++); + } + peek() { + return this.buffer.charCodeAt(this.pos); + } + indexOf(char) { + const { buffer, pos } = this; + const idx = buffer.indexOf(char, pos); + return idx === -1 ? buffer.length : idx; + } +}; + +// src/scopes.ts +var EMPTY = []; +function decodeOriginalScopes(input) { + const { length } = input; + const reader = new StringReader(input); + const scopes = []; + const stack = []; + let line = 0; + for (; reader.pos < length; reader.pos++) { + line = decodeInteger(reader, line); + const column = decodeInteger(reader, 0); + if (!hasMoreVlq(reader, length)) { + const last = stack.pop(); + last[2] = line; + last[3] = column; + continue; + } + const kind = decodeInteger(reader, 0); + const fields = decodeInteger(reader, 0); + const hasName = fields & 1; + const scope = hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind]; + let vars = EMPTY; + if (hasMoreVlq(reader, length)) { + vars = []; + do { + const varsIndex = decodeInteger(reader, 0); + vars.push(varsIndex); + } while (hasMoreVlq(reader, length)); + } + scope.vars = vars; + scopes.push(scope); + stack.push(scope); + } + return scopes; +} +function encodeOriginalScopes(scopes) { + const writer = new StringWriter(); + for (let i = 0; i < scopes.length; ) { + i = _encodeOriginalScopes(scopes, i, writer, [0]); + } + return writer.flush(); +} +function _encodeOriginalScopes(scopes, index, writer, state) { + const scope = scopes[index]; + const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope; + if (index > 0) writer.write(comma); + state[0] = encodeInteger(writer, startLine, state[0]); + encodeInteger(writer, startColumn, 0); + encodeInteger(writer, kind, 0); + const fields = scope.length === 6 ? 1 : 0; + encodeInteger(writer, fields, 0); + if (scope.length === 6) encodeInteger(writer, scope[5], 0); + for (const v of vars) { + encodeInteger(writer, v, 0); + } + for (index++; index < scopes.length; ) { + const next = scopes[index]; + const { 0: l, 1: c } = next; + if (l > endLine || l === endLine && c >= endColumn) { + break; + } + index = _encodeOriginalScopes(scopes, index, writer, state); + } + writer.write(comma); + state[0] = encodeInteger(writer, endLine, state[0]); + encodeInteger(writer, endColumn, 0); + return index; +} +function decodeGeneratedRanges(input) { + const { length } = input; + const reader = new StringReader(input); + const ranges = []; + const stack = []; + let genLine = 0; + let definitionSourcesIndex = 0; + let definitionScopeIndex = 0; + let callsiteSourcesIndex = 0; + let callsiteLine = 0; + let callsiteColumn = 0; + let bindingLine = 0; + let bindingColumn = 0; + do { + const semi = reader.indexOf(";"); + let genColumn = 0; + for (; reader.pos < semi; reader.pos++) { + genColumn = decodeInteger(reader, genColumn); + if (!hasMoreVlq(reader, semi)) { + const last = stack.pop(); + last[2] = genLine; + last[3] = genColumn; + continue; + } + const fields = decodeInteger(reader, 0); + const hasDefinition = fields & 1; + const hasCallsite = fields & 2; + const hasScope = fields & 4; + let callsite = null; + let bindings = EMPTY; + let range; + if (hasDefinition) { + const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex); + definitionScopeIndex = decodeInteger( + reader, + definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0 + ); + definitionSourcesIndex = defSourcesIndex; + range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex]; + } else { + range = [genLine, genColumn, 0, 0]; + } + range.isScope = !!hasScope; + if (hasCallsite) { + const prevCsi = callsiteSourcesIndex; + const prevLine = callsiteLine; + callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex); + const sameSource = prevCsi === callsiteSourcesIndex; + callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0); + callsiteColumn = decodeInteger( + reader, + sameSource && prevLine === callsiteLine ? callsiteColumn : 0 + ); + callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn]; + } + range.callsite = callsite; + if (hasMoreVlq(reader, semi)) { + bindings = []; + do { + bindingLine = genLine; + bindingColumn = genColumn; + const expressionsCount = decodeInteger(reader, 0); + let expressionRanges; + if (expressionsCount < -1) { + expressionRanges = [[decodeInteger(reader, 0)]]; + for (let i = -1; i > expressionsCount; i--) { + const prevBl = bindingLine; + bindingLine = decodeInteger(reader, bindingLine); + bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0); + const expression = decodeInteger(reader, 0); + expressionRanges.push([expression, bindingLine, bindingColumn]); + } + } else { + expressionRanges = [[expressionsCount]]; + } + bindings.push(expressionRanges); + } while (hasMoreVlq(reader, semi)); + } + range.bindings = bindings; + ranges.push(range); + stack.push(range); + } + genLine++; + reader.pos = semi + 1; + } while (reader.pos < length); + return ranges; +} +function encodeGeneratedRanges(ranges) { + if (ranges.length === 0) return ""; + const writer = new StringWriter(); + for (let i = 0; i < ranges.length; ) { + i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]); + } + return writer.flush(); +} +function _encodeGeneratedRanges(ranges, index, writer, state) { + const range = ranges[index]; + const { + 0: startLine, + 1: startColumn, + 2: endLine, + 3: endColumn, + isScope, + callsite, + bindings + } = range; + if (state[0] < startLine) { + catchupLine(writer, state[0], startLine); + state[0] = startLine; + state[1] = 0; + } else if (index > 0) { + writer.write(comma); + } + state[1] = encodeInteger(writer, range[1], state[1]); + const fields = (range.length === 6 ? 1 : 0) | (callsite ? 2 : 0) | (isScope ? 4 : 0); + encodeInteger(writer, fields, 0); + if (range.length === 6) { + const { 4: sourcesIndex, 5: scopesIndex } = range; + if (sourcesIndex !== state[2]) { + state[3] = 0; + } + state[2] = encodeInteger(writer, sourcesIndex, state[2]); + state[3] = encodeInteger(writer, scopesIndex, state[3]); + } + if (callsite) { + const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite; + if (sourcesIndex !== state[4]) { + state[5] = 0; + state[6] = 0; + } else if (callLine !== state[5]) { + state[6] = 0; + } + state[4] = encodeInteger(writer, sourcesIndex, state[4]); + state[5] = encodeInteger(writer, callLine, state[5]); + state[6] = encodeInteger(writer, callColumn, state[6]); + } + if (bindings) { + for (const binding of bindings) { + if (binding.length > 1) encodeInteger(writer, -binding.length, 0); + const expression = binding[0][0]; + encodeInteger(writer, expression, 0); + let bindingStartLine = startLine; + let bindingStartColumn = startColumn; + for (let i = 1; i < binding.length; i++) { + const expRange = binding[i]; + bindingStartLine = encodeInteger(writer, expRange[1], bindingStartLine); + bindingStartColumn = encodeInteger(writer, expRange[2], bindingStartColumn); + encodeInteger(writer, expRange[0], 0); + } + } + } + for (index++; index < ranges.length; ) { + const next = ranges[index]; + const { 0: l, 1: c } = next; + if (l > endLine || l === endLine && c >= endColumn) { + break; + } + index = _encodeGeneratedRanges(ranges, index, writer, state); + } + if (state[0] < endLine) { + catchupLine(writer, state[0], endLine); + state[0] = endLine; + state[1] = 0; + } else { + writer.write(comma); + } + state[1] = encodeInteger(writer, endColumn, state[1]); + return index; +} +function catchupLine(writer, lastLine, line) { + do { + writer.write(semicolon); + } while (++lastLine < line); +} + +// src/sourcemap-codec.ts +function decode(mappings) { + const { length } = mappings; + const reader = new StringReader(mappings); + const decoded = []; + let genColumn = 0; + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + do { + const semi = reader.indexOf(";"); + const line = []; + let sorted = true; + let lastCol = 0; + genColumn = 0; + while (reader.pos < semi) { + let seg; + genColumn = decodeInteger(reader, genColumn); + if (genColumn < lastCol) sorted = false; + lastCol = genColumn; + if (hasMoreVlq(reader, semi)) { + sourcesIndex = decodeInteger(reader, sourcesIndex); + sourceLine = decodeInteger(reader, sourceLine); + sourceColumn = decodeInteger(reader, sourceColumn); + if (hasMoreVlq(reader, semi)) { + namesIndex = decodeInteger(reader, namesIndex); + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex]; + } else { + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn]; + } + } else { + seg = [genColumn]; + } + line.push(seg); + reader.pos++; + } + if (!sorted) sort(line); + decoded.push(line); + reader.pos = semi + 1; + } while (reader.pos <= length); + return decoded; +} +function sort(line) { + line.sort(sortComparator); +} +function sortComparator(a, b) { + return a[0] - b[0]; +} +function encode(decoded) { + const writer = new StringWriter(); + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + if (i > 0) writer.write(semicolon); + if (line.length === 0) continue; + let genColumn = 0; + for (let j = 0; j < line.length; j++) { + const segment = line[j]; + if (j > 0) writer.write(comma); + genColumn = encodeInteger(writer, segment[0], genColumn); + if (segment.length === 1) continue; + sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex); + sourceLine = encodeInteger(writer, segment[2], sourceLine); + sourceColumn = encodeInteger(writer, segment[3], sourceColumn); + if (segment.length === 4) continue; + namesIndex = encodeInteger(writer, segment[4], namesIndex); + } + } + return writer.flush(); +} +export { + decode, + decodeGeneratedRanges, + decodeOriginalScopes, + encode, + encodeGeneratedRanges, + encodeOriginalScopes +}; +//# sourceMappingURL=sourcemap-codec.mjs.map diff --git a/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map new file mode 100644 index 0000000..c276844 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map @@ -0,0 +1,6 @@ +{ + "version": 3, + "sources": ["../src/vlq.ts", "../src/strings.ts", "../src/scopes.ts", "../src/sourcemap-codec.ts"], + "mappings": ";AAEO,IAAM,QAAQ,IAAI,WAAW,CAAC;AAC9B,IAAM,YAAY,IAAI,WAAW,CAAC;AAEzC,IAAM,QAAQ;AACd,IAAM,YAAY,IAAI,WAAW,EAAE;AACnC,IAAM,YAAY,IAAI,WAAW,GAAG;AAEpC,SAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,QAAM,IAAI,MAAM,WAAW,CAAC;AAC5B,YAAU,CAAC,IAAI;AACf,YAAU,CAAC,IAAI;AACjB;AAEO,SAAS,cAAc,QAAsB,UAA0B;AAC5E,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,MAAI,UAAU;AAEd,KAAG;AACD,UAAM,IAAI,OAAO,KAAK;AACtB,cAAU,UAAU,CAAC;AACrB,cAAU,UAAU,OAAO;AAC3B,aAAS;AAAA,EACX,SAAS,UAAU;AAEnB,QAAM,eAAe,QAAQ;AAC7B,aAAW;AAEX,MAAI,cAAc;AAChB,YAAQ,cAAc,CAAC;AAAA,EACzB;AAEA,SAAO,WAAW;AACpB;AAEO,SAAS,cAAc,SAAuB,KAAa,UAA0B;AAC1F,MAAI,QAAQ,MAAM;AAElB,UAAQ,QAAQ,IAAK,CAAC,SAAS,IAAK,IAAI,SAAS;AACjD,KAAG;AACD,QAAI,UAAU,QAAQ;AACtB,eAAW;AACX,QAAI,QAAQ,EAAG,YAAW;AAC1B,YAAQ,MAAM,UAAU,OAAO,CAAC;AAAA,EAClC,SAAS,QAAQ;AAEjB,SAAO;AACT;AAEO,SAAS,WAAW,QAAsB,KAAa;AAC5D,MAAI,OAAO,OAAO,IAAK,QAAO;AAC9B,SAAO,OAAO,KAAK,MAAM;AAC3B;;;ACtDA,IAAM,YAAY,OAAO;AAGzB,IAAM,KACJ,OAAO,gBAAgB,cACH,oBAAI,YAAY,IAChC,OAAO,WAAW,cAChB;AAAA,EACE,OAAO,KAAyB;AAC9B,UAAM,MAAM,OAAO,KAAK,IAAI,QAAQ,IAAI,YAAY,IAAI,UAAU;AAClE,WAAO,IAAI,SAAS;AAAA,EACtB;AACF,IACA;AAAA,EACE,OAAO,KAAyB;AAC9B,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,aAAO,OAAO,aAAa,IAAI,CAAC,CAAC;AAAA,IACnC;AACA,WAAO;AAAA,EACT;AACF;AAED,IAAM,eAAN,MAAmB;AAAA,EAAnB;AACL,eAAM;AACN,SAAQ,MAAM;AACd,SAAQ,SAAS,IAAI,WAAW,SAAS;AAAA;AAAA,EAEzC,MAAM,GAAiB;AACrB,UAAM,EAAE,OAAO,IAAI;AACnB,WAAO,KAAK,KAAK,IAAI;AACrB,QAAI,KAAK,QAAQ,WAAW;AAC1B,WAAK,OAAO,GAAG,OAAO,MAAM;AAC5B,WAAK,MAAM;AAAA,IACb;AAAA,EACF;AAAA,EAEA,QAAgB;AACd,UAAM,EAAE,QAAQ,KAAK,IAAI,IAAI;AAC7B,WAAO,MAAM,IAAI,MAAM,GAAG,OAAO,OAAO,SAAS,GAAG,GAAG,CAAC,IAAI;AAAA,EAC9D;AACF;AAEO,IAAM,eAAN,MAAmB;AAAA,EAIxB,YAAY,QAAgB;AAH5B,eAAM;AAIJ,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,OAAe;AACb,WAAO,KAAK,OAAO,WAAW,KAAK,KAAK;AAAA,EAC1C;AAAA,EAEA,OAAe;AACb,WAAO,KAAK,OAAO,WAAW,KAAK,GAAG;AAAA,EACxC;AAAA,EAEA,QAAQ,MAAsB;AAC5B,UAAM,EAAE,QAAQ,IAAI,IAAI;AACxB,UAAM,MAAM,OAAO,QAAQ,MAAM,GAAG;AACpC,WAAO,QAAQ,KAAK,OAAO,SAAS;AAAA,EACtC;AACF;;;AC7DA,IAAM,QAAe,CAAC;AA+Bf,SAAS,qBAAqB,OAAgC;AACnE,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,SAAS,IAAI,aAAa,KAAK;AACrC,QAAM,SAA0B,CAAC;AACjC,QAAM,QAAyB,CAAC;AAChC,MAAI,OAAO;AAEX,SAAO,OAAO,MAAM,QAAQ,OAAO,OAAO;AACxC,WAAO,cAAc,QAAQ,IAAI;AACjC,UAAM,SAAS,cAAc,QAAQ,CAAC;AAEtC,QAAI,CAAC,WAAW,QAAQ,MAAM,GAAG;AAC/B,YAAM,OAAO,MAAM,IAAI;AACvB,WAAK,CAAC,IAAI;AACV,WAAK,CAAC,IAAI;AACV;AAAA,IACF;AAEA,UAAM,OAAO,cAAc,QAAQ,CAAC;AACpC,UAAM,SAAS,cAAc,QAAQ,CAAC;AACtC,UAAM,UAAU,SAAS;AAEzB,UAAM,QACJ,UAAU,CAAC,MAAM,QAAQ,GAAG,GAAG,MAAM,cAAc,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,QAAQ,GAAG,GAAG,IAAI;AAG5F,QAAI,OAAc;AAClB,QAAI,WAAW,QAAQ,MAAM,GAAG;AAC9B,aAAO,CAAC;AACR,SAAG;AACD,cAAM,YAAY,cAAc,QAAQ,CAAC;AACzC,aAAK,KAAK,SAAS;AAAA,MACrB,SAAS,WAAW,QAAQ,MAAM;AAAA,IACpC;AACA,UAAM,OAAO;AAEb,WAAO,KAAK,KAAK;AACjB,UAAM,KAAK,KAAK;AAAA,EAClB;AAEA,SAAO;AACT;AAEO,SAAS,qBAAqB,QAAiC;AACpE,QAAM,SAAS,IAAI,aAAa;AAEhC,WAAS,IAAI,GAAG,IAAI,OAAO,UAAU;AACnC,QAAI,sBAAsB,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC;AAAA,EAClD;AAEA,SAAO,OAAO,MAAM;AACtB;AAEA,SAAS,sBACP,QACA,OACA,QACA,OAGQ;AACR,QAAM,QAAQ,OAAO,KAAK;AAC1B,QAAM,EAAE,GAAG,WAAW,GAAG,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,KAAK,IAAI;AAElF,MAAI,QAAQ,EAAG,QAAO,MAAM,KAAK;AAEjC,QAAM,CAAC,IAAI,cAAc,QAAQ,WAAW,MAAM,CAAC,CAAC;AACpD,gBAAc,QAAQ,aAAa,CAAC;AACpC,gBAAc,QAAQ,MAAM,CAAC;AAE7B,QAAM,SAAS,MAAM,WAAW,IAAI,IAAS;AAC7C,gBAAc,QAAQ,QAAQ,CAAC;AAC/B,MAAI,MAAM,WAAW,EAAG,eAAc,QAAQ,MAAM,CAAC,GAAG,CAAC;AAEzD,aAAW,KAAK,MAAM;AACpB,kBAAc,QAAQ,GAAG,CAAC;AAAA,EAC5B;AAEA,OAAK,SAAS,QAAQ,OAAO,UAAU;AACrC,UAAM,OAAO,OAAO,KAAK;AACzB,UAAM,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI;AACvB,QAAI,IAAI,WAAY,MAAM,WAAW,KAAK,WAAY;AACpD;AAAA,IACF;AACA,YAAQ,sBAAsB,QAAQ,OAAO,QAAQ,KAAK;AAAA,EAC5D;AAEA,SAAO,MAAM,KAAK;AAClB,QAAM,CAAC,IAAI,cAAc,QAAQ,SAAS,MAAM,CAAC,CAAC;AAClD,gBAAc,QAAQ,WAAW,CAAC;AAElC,SAAO;AACT;AAEO,SAAS,sBAAsB,OAAiC;AACrE,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,SAAS,IAAI,aAAa,KAAK;AACrC,QAAM,SAA2B,CAAC;AAClC,QAAM,QAA0B,CAAC;AAEjC,MAAI,UAAU;AACd,MAAI,yBAAyB;AAC7B,MAAI,uBAAuB;AAC3B,MAAI,uBAAuB;AAC3B,MAAI,eAAe;AACnB,MAAI,iBAAiB;AACrB,MAAI,cAAc;AAClB,MAAI,gBAAgB;AAEpB,KAAG;AACD,UAAM,OAAO,OAAO,QAAQ,GAAG;AAC/B,QAAI,YAAY;AAEhB,WAAO,OAAO,MAAM,MAAM,OAAO,OAAO;AACtC,kBAAY,cAAc,QAAQ,SAAS;AAE3C,UAAI,CAAC,WAAW,QAAQ,IAAI,GAAG;AAC7B,cAAM,OAAO,MAAM,IAAI;AACvB,aAAK,CAAC,IAAI;AACV,aAAK,CAAC,IAAI;AACV;AAAA,MACF;AAEA,YAAM,SAAS,cAAc,QAAQ,CAAC;AACtC,YAAM,gBAAgB,SAAS;AAC/B,YAAM,cAAc,SAAS;AAC7B,YAAM,WAAW,SAAS;AAE1B,UAAI,WAA4B;AAChC,UAAI,WAAsB;AAC1B,UAAI;AACJ,UAAI,eAAe;AACjB,cAAM,kBAAkB,cAAc,QAAQ,sBAAsB;AACpE,+BAAuB;AAAA,UACrB;AAAA,UACA,2BAA2B,kBAAkB,uBAAuB;AAAA,QACtE;AAEA,iCAAyB;AACzB,gBAAQ,CAAC,SAAS,WAAW,GAAG,GAAG,iBAAiB,oBAAoB;AAAA,MAC1E,OAAO;AACL,gBAAQ,CAAC,SAAS,WAAW,GAAG,CAAC;AAAA,MACnC;AAEA,YAAM,UAAU,CAAC,CAAC;AAElB,UAAI,aAAa;AACf,cAAM,UAAU;AAChB,cAAM,WAAW;AACjB,+BAAuB,cAAc,QAAQ,oBAAoB;AACjE,cAAM,aAAa,YAAY;AAC/B,uBAAe,cAAc,QAAQ,aAAa,eAAe,CAAC;AAClE,yBAAiB;AAAA,UACf;AAAA,UACA,cAAc,aAAa,eAAe,iBAAiB;AAAA,QAC7D;AAEA,mBAAW,CAAC,sBAAsB,cAAc,cAAc;AAAA,MAChE;AACA,YAAM,WAAW;AAEjB,UAAI,WAAW,QAAQ,IAAI,GAAG;AAC5B,mBAAW,CAAC;AACZ,WAAG;AACD,wBAAc;AACd,0BAAgB;AAChB,gBAAM,mBAAmB,cAAc,QAAQ,CAAC;AAChD,cAAI;AACJ,cAAI,mBAAmB,IAAI;AACzB,+BAAmB,CAAC,CAAC,cAAc,QAAQ,CAAC,CAAC,CAAC;AAC9C,qBAAS,IAAI,IAAI,IAAI,kBAAkB,KAAK;AAC1C,oBAAM,SAAS;AACf,4BAAc,cAAc,QAAQ,WAAW;AAC/C,8BAAgB,cAAc,QAAQ,gBAAgB,SAAS,gBAAgB,CAAC;AAChF,oBAAM,aAAa,cAAc,QAAQ,CAAC;AAC1C,+BAAiB,KAAK,CAAC,YAAY,aAAa,aAAa,CAAC;AAAA,YAChE;AAAA,UACF,OAAO;AACL,+BAAmB,CAAC,CAAC,gBAAgB,CAAC;AAAA,UACxC;AACA,mBAAS,KAAK,gBAAgB;AAAA,QAChC,SAAS,WAAW,QAAQ,IAAI;AAAA,MAClC;AACA,YAAM,WAAW;AAEjB,aAAO,KAAK,KAAK;AACjB,YAAM,KAAK,KAAK;AAAA,IAClB;AAEA;AACA,WAAO,MAAM,OAAO;AAAA,EACtB,SAAS,OAAO,MAAM;AAEtB,SAAO;AACT;AAEO,SAAS,sBAAsB,QAAkC;AACtE,MAAI,OAAO,WAAW,EAAG,QAAO;AAEhC,QAAM,SAAS,IAAI,aAAa;AAEhC,WAAS,IAAI,GAAG,IAAI,OAAO,UAAU;AACnC,QAAI,uBAAuB,QAAQ,GAAG,QAAQ,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;AAAA,EACrE;AAEA,SAAO,OAAO,MAAM;AACtB;AAEA,SAAS,uBACP,QACA,OACA,QACA,OASQ;AACR,QAAM,QAAQ,OAAO,KAAK;AAC1B,QAAM;AAAA,IACJ,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,MAAI,MAAM,CAAC,IAAI,WAAW;AACxB,gBAAY,QAAQ,MAAM,CAAC,GAAG,SAAS;AACvC,UAAM,CAAC,IAAI;AACX,UAAM,CAAC,IAAI;AAAA,EACb,WAAW,QAAQ,GAAG;AACpB,WAAO,MAAM,KAAK;AAAA,EACpB;AAEA,QAAM,CAAC,IAAI,cAAc,QAAQ,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;AAEnD,QAAM,UACH,MAAM,WAAW,IAAI,IAAS,MAAM,WAAW,IAAS,MAAM,UAAU,IAAS;AACpF,gBAAc,QAAQ,QAAQ,CAAC;AAE/B,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,EAAE,GAAG,cAAc,GAAG,YAAY,IAAI;AAC5C,QAAI,iBAAiB,MAAM,CAAC,GAAG;AAC7B,YAAM,CAAC,IAAI;AAAA,IACb;AACA,UAAM,CAAC,IAAI,cAAc,QAAQ,cAAc,MAAM,CAAC,CAAC;AACvD,UAAM,CAAC,IAAI,cAAc,QAAQ,aAAa,MAAM,CAAC,CAAC;AAAA,EACxD;AAEA,MAAI,UAAU;AACZ,UAAM,EAAE,GAAG,cAAc,GAAG,UAAU,GAAG,WAAW,IAAI,MAAM;AAC9D,QAAI,iBAAiB,MAAM,CAAC,GAAG;AAC7B,YAAM,CAAC,IAAI;AACX,YAAM,CAAC,IAAI;AAAA,IACb,WAAW,aAAa,MAAM,CAAC,GAAG;AAChC,YAAM,CAAC,IAAI;AAAA,IACb;AACA,UAAM,CAAC,IAAI,cAAc,QAAQ,cAAc,MAAM,CAAC,CAAC;AACvD,UAAM,CAAC,IAAI,cAAc,QAAQ,UAAU,MAAM,CAAC,CAAC;AACnD,UAAM,CAAC,IAAI,cAAc,QAAQ,YAAY,MAAM,CAAC,CAAC;AAAA,EACvD;AAEA,MAAI,UAAU;AACZ,eAAW,WAAW,UAAU;AAC9B,UAAI,QAAQ,SAAS,EAAG,eAAc,QAAQ,CAAC,QAAQ,QAAQ,CAAC;AAChE,YAAM,aAAa,QAAQ,CAAC,EAAE,CAAC;AAC/B,oBAAc,QAAQ,YAAY,CAAC;AACnC,UAAI,mBAAmB;AACvB,UAAI,qBAAqB;AACzB,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,cAAM,WAAW,QAAQ,CAAC;AAC1B,2BAAmB,cAAc,QAAQ,SAAS,CAAC,GAAI,gBAAgB;AACvE,6BAAqB,cAAc,QAAQ,SAAS,CAAC,GAAI,kBAAkB;AAC3E,sBAAc,QAAQ,SAAS,CAAC,GAAI,CAAC;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAEA,OAAK,SAAS,QAAQ,OAAO,UAAU;AACrC,UAAM,OAAO,OAAO,KAAK;AACzB,UAAM,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI;AACvB,QAAI,IAAI,WAAY,MAAM,WAAW,KAAK,WAAY;AACpD;AAAA,IACF;AACA,YAAQ,uBAAuB,QAAQ,OAAO,QAAQ,KAAK;AAAA,EAC7D;AAEA,MAAI,MAAM,CAAC,IAAI,SAAS;AACtB,gBAAY,QAAQ,MAAM,CAAC,GAAG,OAAO;AACrC,UAAM,CAAC,IAAI;AACX,UAAM,CAAC,IAAI;AAAA,EACb,OAAO;AACL,WAAO,MAAM,KAAK;AAAA,EACpB;AACA,QAAM,CAAC,IAAI,cAAc,QAAQ,WAAW,MAAM,CAAC,CAAC;AAEpD,SAAO;AACT;AAEA,SAAS,YAAY,QAAsB,UAAkB,MAAc;AACzE,KAAG;AACD,WAAO,MAAM,SAAS;AAAA,EACxB,SAAS,EAAE,WAAW;AACxB;;;ACtUO,SAAS,OAAO,UAAqC;AAC1D,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,SAAS,IAAI,aAAa,QAAQ;AACxC,QAAM,UAA6B,CAAC;AACpC,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,MAAI,aAAa;AACjB,MAAI,eAAe;AACnB,MAAI,aAAa;AAEjB,KAAG;AACD,UAAM,OAAO,OAAO,QAAQ,GAAG;AAC/B,UAAM,OAAsB,CAAC;AAC7B,QAAI,SAAS;AACb,QAAI,UAAU;AACd,gBAAY;AAEZ,WAAO,OAAO,MAAM,MAAM;AACxB,UAAI;AAEJ,kBAAY,cAAc,QAAQ,SAAS;AAC3C,UAAI,YAAY,QAAS,UAAS;AAClC,gBAAU;AAEV,UAAI,WAAW,QAAQ,IAAI,GAAG;AAC5B,uBAAe,cAAc,QAAQ,YAAY;AACjD,qBAAa,cAAc,QAAQ,UAAU;AAC7C,uBAAe,cAAc,QAAQ,YAAY;AAEjD,YAAI,WAAW,QAAQ,IAAI,GAAG;AAC5B,uBAAa,cAAc,QAAQ,UAAU;AAC7C,gBAAM,CAAC,WAAW,cAAc,YAAY,cAAc,UAAU;AAAA,QACtE,OAAO;AACL,gBAAM,CAAC,WAAW,cAAc,YAAY,YAAY;AAAA,QAC1D;AAAA,MACF,OAAO;AACL,cAAM,CAAC,SAAS;AAAA,MAClB;AAEA,WAAK,KAAK,GAAG;AACb,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,OAAQ,MAAK,IAAI;AACtB,YAAQ,KAAK,IAAI;AACjB,WAAO,MAAM,OAAO;AAAA,EACtB,SAAS,OAAO,OAAO;AAEvB,SAAO;AACT;AAEA,SAAS,KAAK,MAA0B;AACtC,OAAK,KAAK,cAAc;AAC1B;AAEA,SAAS,eAAe,GAAqB,GAA6B;AACxE,SAAO,EAAE,CAAC,IAAI,EAAE,CAAC;AACnB;AAIO,SAAS,OAAO,SAA8C;AACnE,QAAM,SAAS,IAAI,aAAa;AAChC,MAAI,eAAe;AACnB,MAAI,aAAa;AACjB,MAAI,eAAe;AACnB,MAAI,aAAa;AAEjB,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,OAAO,QAAQ,CAAC;AACtB,QAAI,IAAI,EAAG,QAAO,MAAM,SAAS;AACjC,QAAI,KAAK,WAAW,EAAG;AAEvB,QAAI,YAAY;AAEhB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,UAAU,KAAK,CAAC;AACtB,UAAI,IAAI,EAAG,QAAO,MAAM,KAAK;AAE7B,kBAAY,cAAc,QAAQ,QAAQ,CAAC,GAAG,SAAS;AAEvD,UAAI,QAAQ,WAAW,EAAG;AAC1B,qBAAe,cAAc,QAAQ,QAAQ,CAAC,GAAG,YAAY;AAC7D,mBAAa,cAAc,QAAQ,QAAQ,CAAC,GAAG,UAAU;AACzD,qBAAe,cAAc,QAAQ,QAAQ,CAAC,GAAG,YAAY;AAE7D,UAAI,QAAQ,WAAW,EAAG;AAC1B,mBAAa,cAAc,QAAQ,QAAQ,CAAC,GAAG,UAAU;AAAA,IAC3D;AAAA,EACF;AAEA,SAAO,OAAO,MAAM;AACtB;", + "names": [] +} diff --git a/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js new file mode 100644 index 0000000..2d8e459 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js @@ -0,0 +1,464 @@ +(function (global, factory) { + if (typeof exports === 'object' && typeof module !== 'undefined') { + factory(module); + module.exports = def(module); + } else if (typeof define === 'function' && define.amd) { + define(['module'], function(mod) { + factory.apply(this, arguments); + mod.exports = def(mod); + }); + } else { + const mod = { exports: {} }; + factory(mod); + global = typeof globalThis !== 'undefined' ? globalThis : global || self; + global.sourcemapCodec = def(mod); + } + function def(m) { return 'default' in m.exports ? m.exports.default : m.exports; } +})(this, (function (module) { +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/sourcemap-codec.ts +var sourcemap_codec_exports = {}; +__export(sourcemap_codec_exports, { + decode: () => decode, + decodeGeneratedRanges: () => decodeGeneratedRanges, + decodeOriginalScopes: () => decodeOriginalScopes, + encode: () => encode, + encodeGeneratedRanges: () => encodeGeneratedRanges, + encodeOriginalScopes: () => encodeOriginalScopes +}); +module.exports = __toCommonJS(sourcemap_codec_exports); + +// src/vlq.ts +var comma = ",".charCodeAt(0); +var semicolon = ";".charCodeAt(0); +var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +var intToChar = new Uint8Array(64); +var charToInt = new Uint8Array(128); +for (let i = 0; i < chars.length; i++) { + const c = chars.charCodeAt(i); + intToChar[i] = c; + charToInt[c] = i; +} +function decodeInteger(reader, relative) { + let value = 0; + let shift = 0; + let integer = 0; + do { + const c = reader.next(); + integer = charToInt[c]; + value |= (integer & 31) << shift; + shift += 5; + } while (integer & 32); + const shouldNegate = value & 1; + value >>>= 1; + if (shouldNegate) { + value = -2147483648 | -value; + } + return relative + value; +} +function encodeInteger(builder, num, relative) { + let delta = num - relative; + delta = delta < 0 ? -delta << 1 | 1 : delta << 1; + do { + let clamped = delta & 31; + delta >>>= 5; + if (delta > 0) clamped |= 32; + builder.write(intToChar[clamped]); + } while (delta > 0); + return num; +} +function hasMoreVlq(reader, max) { + if (reader.pos >= max) return false; + return reader.peek() !== comma; +} + +// src/strings.ts +var bufLength = 1024 * 16; +var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? { + decode(buf) { + const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength); + return out.toString(); + } +} : { + decode(buf) { + let out = ""; + for (let i = 0; i < buf.length; i++) { + out += String.fromCharCode(buf[i]); + } + return out; + } +}; +var StringWriter = class { + constructor() { + this.pos = 0; + this.out = ""; + this.buffer = new Uint8Array(bufLength); + } + write(v) { + const { buffer } = this; + buffer[this.pos++] = v; + if (this.pos === bufLength) { + this.out += td.decode(buffer); + this.pos = 0; + } + } + flush() { + const { buffer, out, pos } = this; + return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out; + } +}; +var StringReader = class { + constructor(buffer) { + this.pos = 0; + this.buffer = buffer; + } + next() { + return this.buffer.charCodeAt(this.pos++); + } + peek() { + return this.buffer.charCodeAt(this.pos); + } + indexOf(char) { + const { buffer, pos } = this; + const idx = buffer.indexOf(char, pos); + return idx === -1 ? buffer.length : idx; + } +}; + +// src/scopes.ts +var EMPTY = []; +function decodeOriginalScopes(input) { + const { length } = input; + const reader = new StringReader(input); + const scopes = []; + const stack = []; + let line = 0; + for (; reader.pos < length; reader.pos++) { + line = decodeInteger(reader, line); + const column = decodeInteger(reader, 0); + if (!hasMoreVlq(reader, length)) { + const last = stack.pop(); + last[2] = line; + last[3] = column; + continue; + } + const kind = decodeInteger(reader, 0); + const fields = decodeInteger(reader, 0); + const hasName = fields & 1; + const scope = hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind]; + let vars = EMPTY; + if (hasMoreVlq(reader, length)) { + vars = []; + do { + const varsIndex = decodeInteger(reader, 0); + vars.push(varsIndex); + } while (hasMoreVlq(reader, length)); + } + scope.vars = vars; + scopes.push(scope); + stack.push(scope); + } + return scopes; +} +function encodeOriginalScopes(scopes) { + const writer = new StringWriter(); + for (let i = 0; i < scopes.length; ) { + i = _encodeOriginalScopes(scopes, i, writer, [0]); + } + return writer.flush(); +} +function _encodeOriginalScopes(scopes, index, writer, state) { + const scope = scopes[index]; + const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope; + if (index > 0) writer.write(comma); + state[0] = encodeInteger(writer, startLine, state[0]); + encodeInteger(writer, startColumn, 0); + encodeInteger(writer, kind, 0); + const fields = scope.length === 6 ? 1 : 0; + encodeInteger(writer, fields, 0); + if (scope.length === 6) encodeInteger(writer, scope[5], 0); + for (const v of vars) { + encodeInteger(writer, v, 0); + } + for (index++; index < scopes.length; ) { + const next = scopes[index]; + const { 0: l, 1: c } = next; + if (l > endLine || l === endLine && c >= endColumn) { + break; + } + index = _encodeOriginalScopes(scopes, index, writer, state); + } + writer.write(comma); + state[0] = encodeInteger(writer, endLine, state[0]); + encodeInteger(writer, endColumn, 0); + return index; +} +function decodeGeneratedRanges(input) { + const { length } = input; + const reader = new StringReader(input); + const ranges = []; + const stack = []; + let genLine = 0; + let definitionSourcesIndex = 0; + let definitionScopeIndex = 0; + let callsiteSourcesIndex = 0; + let callsiteLine = 0; + let callsiteColumn = 0; + let bindingLine = 0; + let bindingColumn = 0; + do { + const semi = reader.indexOf(";"); + let genColumn = 0; + for (; reader.pos < semi; reader.pos++) { + genColumn = decodeInteger(reader, genColumn); + if (!hasMoreVlq(reader, semi)) { + const last = stack.pop(); + last[2] = genLine; + last[3] = genColumn; + continue; + } + const fields = decodeInteger(reader, 0); + const hasDefinition = fields & 1; + const hasCallsite = fields & 2; + const hasScope = fields & 4; + let callsite = null; + let bindings = EMPTY; + let range; + if (hasDefinition) { + const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex); + definitionScopeIndex = decodeInteger( + reader, + definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0 + ); + definitionSourcesIndex = defSourcesIndex; + range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex]; + } else { + range = [genLine, genColumn, 0, 0]; + } + range.isScope = !!hasScope; + if (hasCallsite) { + const prevCsi = callsiteSourcesIndex; + const prevLine = callsiteLine; + callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex); + const sameSource = prevCsi === callsiteSourcesIndex; + callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0); + callsiteColumn = decodeInteger( + reader, + sameSource && prevLine === callsiteLine ? callsiteColumn : 0 + ); + callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn]; + } + range.callsite = callsite; + if (hasMoreVlq(reader, semi)) { + bindings = []; + do { + bindingLine = genLine; + bindingColumn = genColumn; + const expressionsCount = decodeInteger(reader, 0); + let expressionRanges; + if (expressionsCount < -1) { + expressionRanges = [[decodeInteger(reader, 0)]]; + for (let i = -1; i > expressionsCount; i--) { + const prevBl = bindingLine; + bindingLine = decodeInteger(reader, bindingLine); + bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0); + const expression = decodeInteger(reader, 0); + expressionRanges.push([expression, bindingLine, bindingColumn]); + } + } else { + expressionRanges = [[expressionsCount]]; + } + bindings.push(expressionRanges); + } while (hasMoreVlq(reader, semi)); + } + range.bindings = bindings; + ranges.push(range); + stack.push(range); + } + genLine++; + reader.pos = semi + 1; + } while (reader.pos < length); + return ranges; +} +function encodeGeneratedRanges(ranges) { + if (ranges.length === 0) return ""; + const writer = new StringWriter(); + for (let i = 0; i < ranges.length; ) { + i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]); + } + return writer.flush(); +} +function _encodeGeneratedRanges(ranges, index, writer, state) { + const range = ranges[index]; + const { + 0: startLine, + 1: startColumn, + 2: endLine, + 3: endColumn, + isScope, + callsite, + bindings + } = range; + if (state[0] < startLine) { + catchupLine(writer, state[0], startLine); + state[0] = startLine; + state[1] = 0; + } else if (index > 0) { + writer.write(comma); + } + state[1] = encodeInteger(writer, range[1], state[1]); + const fields = (range.length === 6 ? 1 : 0) | (callsite ? 2 : 0) | (isScope ? 4 : 0); + encodeInteger(writer, fields, 0); + if (range.length === 6) { + const { 4: sourcesIndex, 5: scopesIndex } = range; + if (sourcesIndex !== state[2]) { + state[3] = 0; + } + state[2] = encodeInteger(writer, sourcesIndex, state[2]); + state[3] = encodeInteger(writer, scopesIndex, state[3]); + } + if (callsite) { + const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite; + if (sourcesIndex !== state[4]) { + state[5] = 0; + state[6] = 0; + } else if (callLine !== state[5]) { + state[6] = 0; + } + state[4] = encodeInteger(writer, sourcesIndex, state[4]); + state[5] = encodeInteger(writer, callLine, state[5]); + state[6] = encodeInteger(writer, callColumn, state[6]); + } + if (bindings) { + for (const binding of bindings) { + if (binding.length > 1) encodeInteger(writer, -binding.length, 0); + const expression = binding[0][0]; + encodeInteger(writer, expression, 0); + let bindingStartLine = startLine; + let bindingStartColumn = startColumn; + for (let i = 1; i < binding.length; i++) { + const expRange = binding[i]; + bindingStartLine = encodeInteger(writer, expRange[1], bindingStartLine); + bindingStartColumn = encodeInteger(writer, expRange[2], bindingStartColumn); + encodeInteger(writer, expRange[0], 0); + } + } + } + for (index++; index < ranges.length; ) { + const next = ranges[index]; + const { 0: l, 1: c } = next; + if (l > endLine || l === endLine && c >= endColumn) { + break; + } + index = _encodeGeneratedRanges(ranges, index, writer, state); + } + if (state[0] < endLine) { + catchupLine(writer, state[0], endLine); + state[0] = endLine; + state[1] = 0; + } else { + writer.write(comma); + } + state[1] = encodeInteger(writer, endColumn, state[1]); + return index; +} +function catchupLine(writer, lastLine, line) { + do { + writer.write(semicolon); + } while (++lastLine < line); +} + +// src/sourcemap-codec.ts +function decode(mappings) { + const { length } = mappings; + const reader = new StringReader(mappings); + const decoded = []; + let genColumn = 0; + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + do { + const semi = reader.indexOf(";"); + const line = []; + let sorted = true; + let lastCol = 0; + genColumn = 0; + while (reader.pos < semi) { + let seg; + genColumn = decodeInteger(reader, genColumn); + if (genColumn < lastCol) sorted = false; + lastCol = genColumn; + if (hasMoreVlq(reader, semi)) { + sourcesIndex = decodeInteger(reader, sourcesIndex); + sourceLine = decodeInteger(reader, sourceLine); + sourceColumn = decodeInteger(reader, sourceColumn); + if (hasMoreVlq(reader, semi)) { + namesIndex = decodeInteger(reader, namesIndex); + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex]; + } else { + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn]; + } + } else { + seg = [genColumn]; + } + line.push(seg); + reader.pos++; + } + if (!sorted) sort(line); + decoded.push(line); + reader.pos = semi + 1; + } while (reader.pos <= length); + return decoded; +} +function sort(line) { + line.sort(sortComparator); +} +function sortComparator(a, b) { + return a[0] - b[0]; +} +function encode(decoded) { + const writer = new StringWriter(); + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + if (i > 0) writer.write(semicolon); + if (line.length === 0) continue; + let genColumn = 0; + for (let j = 0; j < line.length; j++) { + const segment = line[j]; + if (j > 0) writer.write(comma); + genColumn = encodeInteger(writer, segment[0], genColumn); + if (segment.length === 1) continue; + sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex); + sourceLine = encodeInteger(writer, segment[2], sourceLine); + sourceColumn = encodeInteger(writer, segment[3], sourceColumn); + if (segment.length === 4) continue; + namesIndex = encodeInteger(writer, segment[4], namesIndex); + } + } + return writer.flush(); +} +})); +//# sourceMappingURL=sourcemap-codec.umd.js.map diff --git a/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js.map b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js.map new file mode 100644 index 0000000..abc18d2 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js.map @@ -0,0 +1,6 @@ +{ + "version": 3, + "sources": ["../src/sourcemap-codec.ts", "../src/vlq.ts", "../src/strings.ts", "../src/scopes.ts"], + "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,IAAM,QAAQ,IAAI,WAAW,CAAC;AAC9B,IAAM,YAAY,IAAI,WAAW,CAAC;AAEzC,IAAM,QAAQ;AACd,IAAM,YAAY,IAAI,WAAW,EAAE;AACnC,IAAM,YAAY,IAAI,WAAW,GAAG;AAEpC,SAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,QAAM,IAAI,MAAM,WAAW,CAAC;AAC5B,YAAU,CAAC,IAAI;AACf,YAAU,CAAC,IAAI;AACjB;AAEO,SAAS,cAAc,QAAsB,UAA0B;AAC5E,MAAI,QAAQ;AACZ,MAAI,QAAQ;AACZ,MAAI,UAAU;AAEd,KAAG;AACD,UAAM,IAAI,OAAO,KAAK;AACtB,cAAU,UAAU,CAAC;AACrB,cAAU,UAAU,OAAO;AAC3B,aAAS;AAAA,EACX,SAAS,UAAU;AAEnB,QAAM,eAAe,QAAQ;AAC7B,aAAW;AAEX,MAAI,cAAc;AAChB,YAAQ,cAAc,CAAC;AAAA,EACzB;AAEA,SAAO,WAAW;AACpB;AAEO,SAAS,cAAc,SAAuB,KAAa,UAA0B;AAC1F,MAAI,QAAQ,MAAM;AAElB,UAAQ,QAAQ,IAAK,CAAC,SAAS,IAAK,IAAI,SAAS;AACjD,KAAG;AACD,QAAI,UAAU,QAAQ;AACtB,eAAW;AACX,QAAI,QAAQ,EAAG,YAAW;AAC1B,YAAQ,MAAM,UAAU,OAAO,CAAC;AAAA,EAClC,SAAS,QAAQ;AAEjB,SAAO;AACT;AAEO,SAAS,WAAW,QAAsB,KAAa;AAC5D,MAAI,OAAO,OAAO,IAAK,QAAO;AAC9B,SAAO,OAAO,KAAK,MAAM;AAC3B;;;ACtDA,IAAM,YAAY,OAAO;AAGzB,IAAM,KACJ,OAAO,gBAAgB,cACH,oBAAI,YAAY,IAChC,OAAO,WAAW,cAChB;AAAA,EACE,OAAO,KAAyB;AAC9B,UAAM,MAAM,OAAO,KAAK,IAAI,QAAQ,IAAI,YAAY,IAAI,UAAU;AAClE,WAAO,IAAI,SAAS;AAAA,EACtB;AACF,IACA;AAAA,EACE,OAAO,KAAyB;AAC9B,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,aAAO,OAAO,aAAa,IAAI,CAAC,CAAC;AAAA,IACnC;AACA,WAAO;AAAA,EACT;AACF;AAED,IAAM,eAAN,MAAmB;AAAA,EAAnB;AACL,eAAM;AACN,SAAQ,MAAM;AACd,SAAQ,SAAS,IAAI,WAAW,SAAS;AAAA;AAAA,EAEzC,MAAM,GAAiB;AACrB,UAAM,EAAE,OAAO,IAAI;AACnB,WAAO,KAAK,KAAK,IAAI;AACrB,QAAI,KAAK,QAAQ,WAAW;AAC1B,WAAK,OAAO,GAAG,OAAO,MAAM;AAC5B,WAAK,MAAM;AAAA,IACb;AAAA,EACF;AAAA,EAEA,QAAgB;AACd,UAAM,EAAE,QAAQ,KAAK,IAAI,IAAI;AAC7B,WAAO,MAAM,IAAI,MAAM,GAAG,OAAO,OAAO,SAAS,GAAG,GAAG,CAAC,IAAI;AAAA,EAC9D;AACF;AAEO,IAAM,eAAN,MAAmB;AAAA,EAIxB,YAAY,QAAgB;AAH5B,eAAM;AAIJ,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,OAAe;AACb,WAAO,KAAK,OAAO,WAAW,KAAK,KAAK;AAAA,EAC1C;AAAA,EAEA,OAAe;AACb,WAAO,KAAK,OAAO,WAAW,KAAK,GAAG;AAAA,EACxC;AAAA,EAEA,QAAQ,MAAsB;AAC5B,UAAM,EAAE,QAAQ,IAAI,IAAI;AACxB,UAAM,MAAM,OAAO,QAAQ,MAAM,GAAG;AACpC,WAAO,QAAQ,KAAK,OAAO,SAAS;AAAA,EACtC;AACF;;;AC7DA,IAAM,QAAe,CAAC;AA+Bf,SAAS,qBAAqB,OAAgC;AACnE,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,SAAS,IAAI,aAAa,KAAK;AACrC,QAAM,SAA0B,CAAC;AACjC,QAAM,QAAyB,CAAC;AAChC,MAAI,OAAO;AAEX,SAAO,OAAO,MAAM,QAAQ,OAAO,OAAO;AACxC,WAAO,cAAc,QAAQ,IAAI;AACjC,UAAM,SAAS,cAAc,QAAQ,CAAC;AAEtC,QAAI,CAAC,WAAW,QAAQ,MAAM,GAAG;AAC/B,YAAM,OAAO,MAAM,IAAI;AACvB,WAAK,CAAC,IAAI;AACV,WAAK,CAAC,IAAI;AACV;AAAA,IACF;AAEA,UAAM,OAAO,cAAc,QAAQ,CAAC;AACpC,UAAM,SAAS,cAAc,QAAQ,CAAC;AACtC,UAAM,UAAU,SAAS;AAEzB,UAAM,QACJ,UAAU,CAAC,MAAM,QAAQ,GAAG,GAAG,MAAM,cAAc,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,QAAQ,GAAG,GAAG,IAAI;AAG5F,QAAI,OAAc;AAClB,QAAI,WAAW,QAAQ,MAAM,GAAG;AAC9B,aAAO,CAAC;AACR,SAAG;AACD,cAAM,YAAY,cAAc,QAAQ,CAAC;AACzC,aAAK,KAAK,SAAS;AAAA,MACrB,SAAS,WAAW,QAAQ,MAAM;AAAA,IACpC;AACA,UAAM,OAAO;AAEb,WAAO,KAAK,KAAK;AACjB,UAAM,KAAK,KAAK;AAAA,EAClB;AAEA,SAAO;AACT;AAEO,SAAS,qBAAqB,QAAiC;AACpE,QAAM,SAAS,IAAI,aAAa;AAEhC,WAAS,IAAI,GAAG,IAAI,OAAO,UAAU;AACnC,QAAI,sBAAsB,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC;AAAA,EAClD;AAEA,SAAO,OAAO,MAAM;AACtB;AAEA,SAAS,sBACP,QACA,OACA,QACA,OAGQ;AACR,QAAM,QAAQ,OAAO,KAAK;AAC1B,QAAM,EAAE,GAAG,WAAW,GAAG,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,KAAK,IAAI;AAElF,MAAI,QAAQ,EAAG,QAAO,MAAM,KAAK;AAEjC,QAAM,CAAC,IAAI,cAAc,QAAQ,WAAW,MAAM,CAAC,CAAC;AACpD,gBAAc,QAAQ,aAAa,CAAC;AACpC,gBAAc,QAAQ,MAAM,CAAC;AAE7B,QAAM,SAAS,MAAM,WAAW,IAAI,IAAS;AAC7C,gBAAc,QAAQ,QAAQ,CAAC;AAC/B,MAAI,MAAM,WAAW,EAAG,eAAc,QAAQ,MAAM,CAAC,GAAG,CAAC;AAEzD,aAAW,KAAK,MAAM;AACpB,kBAAc,QAAQ,GAAG,CAAC;AAAA,EAC5B;AAEA,OAAK,SAAS,QAAQ,OAAO,UAAU;AACrC,UAAM,OAAO,OAAO,KAAK;AACzB,UAAM,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI;AACvB,QAAI,IAAI,WAAY,MAAM,WAAW,KAAK,WAAY;AACpD;AAAA,IACF;AACA,YAAQ,sBAAsB,QAAQ,OAAO,QAAQ,KAAK;AAAA,EAC5D;AAEA,SAAO,MAAM,KAAK;AAClB,QAAM,CAAC,IAAI,cAAc,QAAQ,SAAS,MAAM,CAAC,CAAC;AAClD,gBAAc,QAAQ,WAAW,CAAC;AAElC,SAAO;AACT;AAEO,SAAS,sBAAsB,OAAiC;AACrE,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,SAAS,IAAI,aAAa,KAAK;AACrC,QAAM,SAA2B,CAAC;AAClC,QAAM,QAA0B,CAAC;AAEjC,MAAI,UAAU;AACd,MAAI,yBAAyB;AAC7B,MAAI,uBAAuB;AAC3B,MAAI,uBAAuB;AAC3B,MAAI,eAAe;AACnB,MAAI,iBAAiB;AACrB,MAAI,cAAc;AAClB,MAAI,gBAAgB;AAEpB,KAAG;AACD,UAAM,OAAO,OAAO,QAAQ,GAAG;AAC/B,QAAI,YAAY;AAEhB,WAAO,OAAO,MAAM,MAAM,OAAO,OAAO;AACtC,kBAAY,cAAc,QAAQ,SAAS;AAE3C,UAAI,CAAC,WAAW,QAAQ,IAAI,GAAG;AAC7B,cAAM,OAAO,MAAM,IAAI;AACvB,aAAK,CAAC,IAAI;AACV,aAAK,CAAC,IAAI;AACV;AAAA,MACF;AAEA,YAAM,SAAS,cAAc,QAAQ,CAAC;AACtC,YAAM,gBAAgB,SAAS;AAC/B,YAAM,cAAc,SAAS;AAC7B,YAAM,WAAW,SAAS;AAE1B,UAAI,WAA4B;AAChC,UAAI,WAAsB;AAC1B,UAAI;AACJ,UAAI,eAAe;AACjB,cAAM,kBAAkB,cAAc,QAAQ,sBAAsB;AACpE,+BAAuB;AAAA,UACrB;AAAA,UACA,2BAA2B,kBAAkB,uBAAuB;AAAA,QACtE;AAEA,iCAAyB;AACzB,gBAAQ,CAAC,SAAS,WAAW,GAAG,GAAG,iBAAiB,oBAAoB;AAAA,MAC1E,OAAO;AACL,gBAAQ,CAAC,SAAS,WAAW,GAAG,CAAC;AAAA,MACnC;AAEA,YAAM,UAAU,CAAC,CAAC;AAElB,UAAI,aAAa;AACf,cAAM,UAAU;AAChB,cAAM,WAAW;AACjB,+BAAuB,cAAc,QAAQ,oBAAoB;AACjE,cAAM,aAAa,YAAY;AAC/B,uBAAe,cAAc,QAAQ,aAAa,eAAe,CAAC;AAClE,yBAAiB;AAAA,UACf;AAAA,UACA,cAAc,aAAa,eAAe,iBAAiB;AAAA,QAC7D;AAEA,mBAAW,CAAC,sBAAsB,cAAc,cAAc;AAAA,MAChE;AACA,YAAM,WAAW;AAEjB,UAAI,WAAW,QAAQ,IAAI,GAAG;AAC5B,mBAAW,CAAC;AACZ,WAAG;AACD,wBAAc;AACd,0BAAgB;AAChB,gBAAM,mBAAmB,cAAc,QAAQ,CAAC;AAChD,cAAI;AACJ,cAAI,mBAAmB,IAAI;AACzB,+BAAmB,CAAC,CAAC,cAAc,QAAQ,CAAC,CAAC,CAAC;AAC9C,qBAAS,IAAI,IAAI,IAAI,kBAAkB,KAAK;AAC1C,oBAAM,SAAS;AACf,4BAAc,cAAc,QAAQ,WAAW;AAC/C,8BAAgB,cAAc,QAAQ,gBAAgB,SAAS,gBAAgB,CAAC;AAChF,oBAAM,aAAa,cAAc,QAAQ,CAAC;AAC1C,+BAAiB,KAAK,CAAC,YAAY,aAAa,aAAa,CAAC;AAAA,YAChE;AAAA,UACF,OAAO;AACL,+BAAmB,CAAC,CAAC,gBAAgB,CAAC;AAAA,UACxC;AACA,mBAAS,KAAK,gBAAgB;AAAA,QAChC,SAAS,WAAW,QAAQ,IAAI;AAAA,MAClC;AACA,YAAM,WAAW;AAEjB,aAAO,KAAK,KAAK;AACjB,YAAM,KAAK,KAAK;AAAA,IAClB;AAEA;AACA,WAAO,MAAM,OAAO;AAAA,EACtB,SAAS,OAAO,MAAM;AAEtB,SAAO;AACT;AAEO,SAAS,sBAAsB,QAAkC;AACtE,MAAI,OAAO,WAAW,EAAG,QAAO;AAEhC,QAAM,SAAS,IAAI,aAAa;AAEhC,WAAS,IAAI,GAAG,IAAI,OAAO,UAAU;AACnC,QAAI,uBAAuB,QAAQ,GAAG,QAAQ,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;AAAA,EACrE;AAEA,SAAO,OAAO,MAAM;AACtB;AAEA,SAAS,uBACP,QACA,OACA,QACA,OASQ;AACR,QAAM,QAAQ,OAAO,KAAK;AAC1B,QAAM;AAAA,IACJ,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,MAAI,MAAM,CAAC,IAAI,WAAW;AACxB,gBAAY,QAAQ,MAAM,CAAC,GAAG,SAAS;AACvC,UAAM,CAAC,IAAI;AACX,UAAM,CAAC,IAAI;AAAA,EACb,WAAW,QAAQ,GAAG;AACpB,WAAO,MAAM,KAAK;AAAA,EACpB;AAEA,QAAM,CAAC,IAAI,cAAc,QAAQ,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;AAEnD,QAAM,UACH,MAAM,WAAW,IAAI,IAAS,MAAM,WAAW,IAAS,MAAM,UAAU,IAAS;AACpF,gBAAc,QAAQ,QAAQ,CAAC;AAE/B,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,EAAE,GAAG,cAAc,GAAG,YAAY,IAAI;AAC5C,QAAI,iBAAiB,MAAM,CAAC,GAAG;AAC7B,YAAM,CAAC,IAAI;AAAA,IACb;AACA,UAAM,CAAC,IAAI,cAAc,QAAQ,cAAc,MAAM,CAAC,CAAC;AACvD,UAAM,CAAC,IAAI,cAAc,QAAQ,aAAa,MAAM,CAAC,CAAC;AAAA,EACxD;AAEA,MAAI,UAAU;AACZ,UAAM,EAAE,GAAG,cAAc,GAAG,UAAU,GAAG,WAAW,IAAI,MAAM;AAC9D,QAAI,iBAAiB,MAAM,CAAC,GAAG;AAC7B,YAAM,CAAC,IAAI;AACX,YAAM,CAAC,IAAI;AAAA,IACb,WAAW,aAAa,MAAM,CAAC,GAAG;AAChC,YAAM,CAAC,IAAI;AAAA,IACb;AACA,UAAM,CAAC,IAAI,cAAc,QAAQ,cAAc,MAAM,CAAC,CAAC;AACvD,UAAM,CAAC,IAAI,cAAc,QAAQ,UAAU,MAAM,CAAC,CAAC;AACnD,UAAM,CAAC,IAAI,cAAc,QAAQ,YAAY,MAAM,CAAC,CAAC;AAAA,EACvD;AAEA,MAAI,UAAU;AACZ,eAAW,WAAW,UAAU;AAC9B,UAAI,QAAQ,SAAS,EAAG,eAAc,QAAQ,CAAC,QAAQ,QAAQ,CAAC;AAChE,YAAM,aAAa,QAAQ,CAAC,EAAE,CAAC;AAC/B,oBAAc,QAAQ,YAAY,CAAC;AACnC,UAAI,mBAAmB;AACvB,UAAI,qBAAqB;AACzB,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,cAAM,WAAW,QAAQ,CAAC;AAC1B,2BAAmB,cAAc,QAAQ,SAAS,CAAC,GAAI,gBAAgB;AACvE,6BAAqB,cAAc,QAAQ,SAAS,CAAC,GAAI,kBAAkB;AAC3E,sBAAc,QAAQ,SAAS,CAAC,GAAI,CAAC;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAEA,OAAK,SAAS,QAAQ,OAAO,UAAU;AACrC,UAAM,OAAO,OAAO,KAAK;AACzB,UAAM,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI;AACvB,QAAI,IAAI,WAAY,MAAM,WAAW,KAAK,WAAY;AACpD;AAAA,IACF;AACA,YAAQ,uBAAuB,QAAQ,OAAO,QAAQ,KAAK;AAAA,EAC7D;AAEA,MAAI,MAAM,CAAC,IAAI,SAAS;AACtB,gBAAY,QAAQ,MAAM,CAAC,GAAG,OAAO;AACrC,UAAM,CAAC,IAAI;AACX,UAAM,CAAC,IAAI;AAAA,EACb,OAAO;AACL,WAAO,MAAM,KAAK;AAAA,EACpB;AACA,QAAM,CAAC,IAAI,cAAc,QAAQ,WAAW,MAAM,CAAC,CAAC;AAEpD,SAAO;AACT;AAEA,SAAS,YAAY,QAAsB,UAAkB,MAAc;AACzE,KAAG;AACD,WAAO,MAAM,SAAS;AAAA,EACxB,SAAS,EAAE,WAAW;AACxB;;;AHtUO,SAAS,OAAO,UAAqC;AAC1D,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,SAAS,IAAI,aAAa,QAAQ;AACxC,QAAM,UAA6B,CAAC;AACpC,MAAI,YAAY;AAChB,MAAI,eAAe;AACnB,MAAI,aAAa;AACjB,MAAI,eAAe;AACnB,MAAI,aAAa;AAEjB,KAAG;AACD,UAAM,OAAO,OAAO,QAAQ,GAAG;AAC/B,UAAM,OAAsB,CAAC;AAC7B,QAAI,SAAS;AACb,QAAI,UAAU;AACd,gBAAY;AAEZ,WAAO,OAAO,MAAM,MAAM;AACxB,UAAI;AAEJ,kBAAY,cAAc,QAAQ,SAAS;AAC3C,UAAI,YAAY,QAAS,UAAS;AAClC,gBAAU;AAEV,UAAI,WAAW,QAAQ,IAAI,GAAG;AAC5B,uBAAe,cAAc,QAAQ,YAAY;AACjD,qBAAa,cAAc,QAAQ,UAAU;AAC7C,uBAAe,cAAc,QAAQ,YAAY;AAEjD,YAAI,WAAW,QAAQ,IAAI,GAAG;AAC5B,uBAAa,cAAc,QAAQ,UAAU;AAC7C,gBAAM,CAAC,WAAW,cAAc,YAAY,cAAc,UAAU;AAAA,QACtE,OAAO;AACL,gBAAM,CAAC,WAAW,cAAc,YAAY,YAAY;AAAA,QAC1D;AAAA,MACF,OAAO;AACL,cAAM,CAAC,SAAS;AAAA,MAClB;AAEA,WAAK,KAAK,GAAG;AACb,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,OAAQ,MAAK,IAAI;AACtB,YAAQ,KAAK,IAAI;AACjB,WAAO,MAAM,OAAO;AAAA,EACtB,SAAS,OAAO,OAAO;AAEvB,SAAO;AACT;AAEA,SAAS,KAAK,MAA0B;AACtC,OAAK,KAAK,cAAc;AAC1B;AAEA,SAAS,eAAe,GAAqB,GAA6B;AACxE,SAAO,EAAE,CAAC,IAAI,EAAE,CAAC;AACnB;AAIO,SAAS,OAAO,SAA8C;AACnE,QAAM,SAAS,IAAI,aAAa;AAChC,MAAI,eAAe;AACnB,MAAI,aAAa;AACjB,MAAI,eAAe;AACnB,MAAI,aAAa;AAEjB,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,OAAO,QAAQ,CAAC;AACtB,QAAI,IAAI,EAAG,QAAO,MAAM,SAAS;AACjC,QAAI,KAAK,WAAW,EAAG;AAEvB,QAAI,YAAY;AAEhB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,UAAU,KAAK,CAAC;AACtB,UAAI,IAAI,EAAG,QAAO,MAAM,KAAK;AAE7B,kBAAY,cAAc,QAAQ,QAAQ,CAAC,GAAG,SAAS;AAEvD,UAAI,QAAQ,WAAW,EAAG;AAC1B,qBAAe,cAAc,QAAQ,QAAQ,CAAC,GAAG,YAAY;AAC7D,mBAAa,cAAc,QAAQ,QAAQ,CAAC,GAAG,UAAU;AACzD,qBAAe,cAAc,QAAQ,QAAQ,CAAC,GAAG,YAAY;AAE7D,UAAI,QAAQ,WAAW,EAAG;AAC1B,mBAAa,cAAc,QAAQ,QAAQ,CAAC,GAAG,UAAU;AAAA,IAC3D;AAAA,EACF;AAEA,SAAO,OAAO,MAAM;AACtB;", + "names": [] +} diff --git a/node_modules/@jridgewell/sourcemap-codec/package.json b/node_modules/@jridgewell/sourcemap-codec/package.json new file mode 100644 index 0000000..da55137 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/package.json @@ -0,0 +1,63 @@ +{ + "name": "@jridgewell/sourcemap-codec", + "version": "1.5.5", + "description": "Encode/decode sourcemap mappings", + "keywords": [ + "sourcemap", + "vlq" + ], + "main": "dist/sourcemap-codec.umd.js", + "module": "dist/sourcemap-codec.mjs", + "types": "types/sourcemap-codec.d.cts", + "files": [ + "dist", + "src", + "types" + ], + "exports": { + ".": [ + { + "import": { + "types": "./types/sourcemap-codec.d.mts", + "default": "./dist/sourcemap-codec.mjs" + }, + "default": { + "types": "./types/sourcemap-codec.d.cts", + "default": "./dist/sourcemap-codec.umd.js" + } + }, + "./dist/sourcemap-codec.umd.js" + ], + "./package.json": "./package.json" + }, + "scripts": { + "benchmark": "run-s build:code benchmark:*", + "benchmark:install": "cd benchmark && npm install", + "benchmark:only": "node --expose-gc benchmark/index.js", + "build": "run-s -n build:code build:types", + "build:code": "node ../../esbuild.mjs sourcemap-codec.ts", + "build:types": "run-s build:types:force build:types:emit build:types:mts", + "build:types:force": "rimraf tsconfig.build.tsbuildinfo", + "build:types:emit": "tsc --project tsconfig.build.json", + "build:types:mts": "node ../../mts-types.mjs", + "clean": "run-s -n clean:code clean:types", + "clean:code": "tsc --build --clean tsconfig.build.json", + "clean:types": "rimraf dist types", + "test": "run-s -n test:types test:only test:format", + "test:format": "prettier --check '{src,test}/**/*.ts'", + "test:only": "mocha", + "test:types": "eslint '{src,test}/**/*.ts'", + "lint": "run-s -n lint:types lint:format", + "lint:format": "npm run test:format -- --write", + "lint:types": "npm run test:types -- --fix", + "prepublishOnly": "npm run-s -n build test" + }, + "homepage": "https://github.com/jridgewell/sourcemaps/tree/main/packages/sourcemap-codec", + "repository": { + "type": "git", + "url": "git+https://github.com/jridgewell/sourcemaps.git", + "directory": "packages/sourcemap-codec" + }, + "author": "Justin Ridgewell ", + "license": "MIT" +} diff --git a/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts b/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts new file mode 100644 index 0000000..d194c2f --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts @@ -0,0 +1,345 @@ +import { StringReader, StringWriter } from './strings'; +import { comma, decodeInteger, encodeInteger, hasMoreVlq, semicolon } from './vlq'; + +const EMPTY: any[] = []; + +type Line = number; +type Column = number; +type Kind = number; +type Name = number; +type Var = number; +type SourcesIndex = number; +type ScopesIndex = number; + +type Mix = (A & O) | (B & O); + +export type OriginalScope = Mix< + [Line, Column, Line, Column, Kind], + [Line, Column, Line, Column, Kind, Name], + { vars: Var[] } +>; + +export type GeneratedRange = Mix< + [Line, Column, Line, Column], + [Line, Column, Line, Column, SourcesIndex, ScopesIndex], + { + callsite: CallSite | null; + bindings: Binding[]; + isScope: boolean; + } +>; +export type CallSite = [SourcesIndex, Line, Column]; +type Binding = BindingExpressionRange[]; +export type BindingExpressionRange = [Name] | [Name, Line, Column]; + +export function decodeOriginalScopes(input: string): OriginalScope[] { + const { length } = input; + const reader = new StringReader(input); + const scopes: OriginalScope[] = []; + const stack: OriginalScope[] = []; + let line = 0; + + for (; reader.pos < length; reader.pos++) { + line = decodeInteger(reader, line); + const column = decodeInteger(reader, 0); + + if (!hasMoreVlq(reader, length)) { + const last = stack.pop()!; + last[2] = line; + last[3] = column; + continue; + } + + const kind = decodeInteger(reader, 0); + const fields = decodeInteger(reader, 0); + const hasName = fields & 0b0001; + + const scope: OriginalScope = ( + hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind] + ) as OriginalScope; + + let vars: Var[] = EMPTY; + if (hasMoreVlq(reader, length)) { + vars = []; + do { + const varsIndex = decodeInteger(reader, 0); + vars.push(varsIndex); + } while (hasMoreVlq(reader, length)); + } + scope.vars = vars; + + scopes.push(scope); + stack.push(scope); + } + + return scopes; +} + +export function encodeOriginalScopes(scopes: OriginalScope[]): string { + const writer = new StringWriter(); + + for (let i = 0; i < scopes.length; ) { + i = _encodeOriginalScopes(scopes, i, writer, [0]); + } + + return writer.flush(); +} + +function _encodeOriginalScopes( + scopes: OriginalScope[], + index: number, + writer: StringWriter, + state: [ + number, // GenColumn + ], +): number { + const scope = scopes[index]; + const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope; + + if (index > 0) writer.write(comma); + + state[0] = encodeInteger(writer, startLine, state[0]); + encodeInteger(writer, startColumn, 0); + encodeInteger(writer, kind, 0); + + const fields = scope.length === 6 ? 0b0001 : 0; + encodeInteger(writer, fields, 0); + if (scope.length === 6) encodeInteger(writer, scope[5], 0); + + for (const v of vars) { + encodeInteger(writer, v, 0); + } + + for (index++; index < scopes.length; ) { + const next = scopes[index]; + const { 0: l, 1: c } = next; + if (l > endLine || (l === endLine && c >= endColumn)) { + break; + } + index = _encodeOriginalScopes(scopes, index, writer, state); + } + + writer.write(comma); + state[0] = encodeInteger(writer, endLine, state[0]); + encodeInteger(writer, endColumn, 0); + + return index; +} + +export function decodeGeneratedRanges(input: string): GeneratedRange[] { + const { length } = input; + const reader = new StringReader(input); + const ranges: GeneratedRange[] = []; + const stack: GeneratedRange[] = []; + + let genLine = 0; + let definitionSourcesIndex = 0; + let definitionScopeIndex = 0; + let callsiteSourcesIndex = 0; + let callsiteLine = 0; + let callsiteColumn = 0; + let bindingLine = 0; + let bindingColumn = 0; + + do { + const semi = reader.indexOf(';'); + let genColumn = 0; + + for (; reader.pos < semi; reader.pos++) { + genColumn = decodeInteger(reader, genColumn); + + if (!hasMoreVlq(reader, semi)) { + const last = stack.pop()!; + last[2] = genLine; + last[3] = genColumn; + continue; + } + + const fields = decodeInteger(reader, 0); + const hasDefinition = fields & 0b0001; + const hasCallsite = fields & 0b0010; + const hasScope = fields & 0b0100; + + let callsite: CallSite | null = null; + let bindings: Binding[] = EMPTY; + let range: GeneratedRange; + if (hasDefinition) { + const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex); + definitionScopeIndex = decodeInteger( + reader, + definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0, + ); + + definitionSourcesIndex = defSourcesIndex; + range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex] as GeneratedRange; + } else { + range = [genLine, genColumn, 0, 0] as GeneratedRange; + } + + range.isScope = !!hasScope; + + if (hasCallsite) { + const prevCsi = callsiteSourcesIndex; + const prevLine = callsiteLine; + callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex); + const sameSource = prevCsi === callsiteSourcesIndex; + callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0); + callsiteColumn = decodeInteger( + reader, + sameSource && prevLine === callsiteLine ? callsiteColumn : 0, + ); + + callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn]; + } + range.callsite = callsite; + + if (hasMoreVlq(reader, semi)) { + bindings = []; + do { + bindingLine = genLine; + bindingColumn = genColumn; + const expressionsCount = decodeInteger(reader, 0); + let expressionRanges: BindingExpressionRange[]; + if (expressionsCount < -1) { + expressionRanges = [[decodeInteger(reader, 0)]]; + for (let i = -1; i > expressionsCount; i--) { + const prevBl = bindingLine; + bindingLine = decodeInteger(reader, bindingLine); + bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0); + const expression = decodeInteger(reader, 0); + expressionRanges.push([expression, bindingLine, bindingColumn]); + } + } else { + expressionRanges = [[expressionsCount]]; + } + bindings.push(expressionRanges); + } while (hasMoreVlq(reader, semi)); + } + range.bindings = bindings; + + ranges.push(range); + stack.push(range); + } + + genLine++; + reader.pos = semi + 1; + } while (reader.pos < length); + + return ranges; +} + +export function encodeGeneratedRanges(ranges: GeneratedRange[]): string { + if (ranges.length === 0) return ''; + + const writer = new StringWriter(); + + for (let i = 0; i < ranges.length; ) { + i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]); + } + + return writer.flush(); +} + +function _encodeGeneratedRanges( + ranges: GeneratedRange[], + index: number, + writer: StringWriter, + state: [ + number, // GenLine + number, // GenColumn + number, // DefSourcesIndex + number, // DefScopesIndex + number, // CallSourcesIndex + number, // CallLine + number, // CallColumn + ], +): number { + const range = ranges[index]; + const { + 0: startLine, + 1: startColumn, + 2: endLine, + 3: endColumn, + isScope, + callsite, + bindings, + } = range; + + if (state[0] < startLine) { + catchupLine(writer, state[0], startLine); + state[0] = startLine; + state[1] = 0; + } else if (index > 0) { + writer.write(comma); + } + + state[1] = encodeInteger(writer, range[1], state[1]); + + const fields = + (range.length === 6 ? 0b0001 : 0) | (callsite ? 0b0010 : 0) | (isScope ? 0b0100 : 0); + encodeInteger(writer, fields, 0); + + if (range.length === 6) { + const { 4: sourcesIndex, 5: scopesIndex } = range; + if (sourcesIndex !== state[2]) { + state[3] = 0; + } + state[2] = encodeInteger(writer, sourcesIndex, state[2]); + state[3] = encodeInteger(writer, scopesIndex, state[3]); + } + + if (callsite) { + const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite!; + if (sourcesIndex !== state[4]) { + state[5] = 0; + state[6] = 0; + } else if (callLine !== state[5]) { + state[6] = 0; + } + state[4] = encodeInteger(writer, sourcesIndex, state[4]); + state[5] = encodeInteger(writer, callLine, state[5]); + state[6] = encodeInteger(writer, callColumn, state[6]); + } + + if (bindings) { + for (const binding of bindings) { + if (binding.length > 1) encodeInteger(writer, -binding.length, 0); + const expression = binding[0][0]; + encodeInteger(writer, expression, 0); + let bindingStartLine = startLine; + let bindingStartColumn = startColumn; + for (let i = 1; i < binding.length; i++) { + const expRange = binding[i]; + bindingStartLine = encodeInteger(writer, expRange[1]!, bindingStartLine); + bindingStartColumn = encodeInteger(writer, expRange[2]!, bindingStartColumn); + encodeInteger(writer, expRange[0]!, 0); + } + } + } + + for (index++; index < ranges.length; ) { + const next = ranges[index]; + const { 0: l, 1: c } = next; + if (l > endLine || (l === endLine && c >= endColumn)) { + break; + } + index = _encodeGeneratedRanges(ranges, index, writer, state); + } + + if (state[0] < endLine) { + catchupLine(writer, state[0], endLine); + state[0] = endLine; + state[1] = 0; + } else { + writer.write(comma); + } + state[1] = encodeInteger(writer, endColumn, state[1]); + + return index; +} + +function catchupLine(writer: StringWriter, lastLine: number, line: number) { + do { + writer.write(semicolon); + } while (++lastLine < line); +} diff --git a/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts b/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts new file mode 100644 index 0000000..a81f894 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts @@ -0,0 +1,111 @@ +import { comma, decodeInteger, encodeInteger, hasMoreVlq, semicolon } from './vlq'; +import { StringWriter, StringReader } from './strings'; + +export { + decodeOriginalScopes, + encodeOriginalScopes, + decodeGeneratedRanges, + encodeGeneratedRanges, +} from './scopes'; +export type { OriginalScope, GeneratedRange, CallSite, BindingExpressionRange } from './scopes'; + +export type SourceMapSegment = + | [number] + | [number, number, number, number] + | [number, number, number, number, number]; +export type SourceMapLine = SourceMapSegment[]; +export type SourceMapMappings = SourceMapLine[]; + +export function decode(mappings: string): SourceMapMappings { + const { length } = mappings; + const reader = new StringReader(mappings); + const decoded: SourceMapMappings = []; + let genColumn = 0; + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + + do { + const semi = reader.indexOf(';'); + const line: SourceMapLine = []; + let sorted = true; + let lastCol = 0; + genColumn = 0; + + while (reader.pos < semi) { + let seg: SourceMapSegment; + + genColumn = decodeInteger(reader, genColumn); + if (genColumn < lastCol) sorted = false; + lastCol = genColumn; + + if (hasMoreVlq(reader, semi)) { + sourcesIndex = decodeInteger(reader, sourcesIndex); + sourceLine = decodeInteger(reader, sourceLine); + sourceColumn = decodeInteger(reader, sourceColumn); + + if (hasMoreVlq(reader, semi)) { + namesIndex = decodeInteger(reader, namesIndex); + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex]; + } else { + seg = [genColumn, sourcesIndex, sourceLine, sourceColumn]; + } + } else { + seg = [genColumn]; + } + + line.push(seg); + reader.pos++; + } + + if (!sorted) sort(line); + decoded.push(line); + reader.pos = semi + 1; + } while (reader.pos <= length); + + return decoded; +} + +function sort(line: SourceMapSegment[]) { + line.sort(sortComparator); +} + +function sortComparator(a: SourceMapSegment, b: SourceMapSegment): number { + return a[0] - b[0]; +} + +export function encode(decoded: SourceMapMappings): string; +export function encode(decoded: Readonly): string; +export function encode(decoded: Readonly): string { + const writer = new StringWriter(); + let sourcesIndex = 0; + let sourceLine = 0; + let sourceColumn = 0; + let namesIndex = 0; + + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + if (i > 0) writer.write(semicolon); + if (line.length === 0) continue; + + let genColumn = 0; + + for (let j = 0; j < line.length; j++) { + const segment = line[j]; + if (j > 0) writer.write(comma); + + genColumn = encodeInteger(writer, segment[0], genColumn); + + if (segment.length === 1) continue; + sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex); + sourceLine = encodeInteger(writer, segment[2], sourceLine); + sourceColumn = encodeInteger(writer, segment[3], sourceColumn); + + if (segment.length === 4) continue; + namesIndex = encodeInteger(writer, segment[4], namesIndex); + } + } + + return writer.flush(); +} diff --git a/node_modules/@jridgewell/sourcemap-codec/src/strings.ts b/node_modules/@jridgewell/sourcemap-codec/src/strings.ts new file mode 100644 index 0000000..d161965 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/src/strings.ts @@ -0,0 +1,65 @@ +const bufLength = 1024 * 16; + +// Provide a fallback for older environments. +const td = + typeof TextDecoder !== 'undefined' + ? /* #__PURE__ */ new TextDecoder() + : typeof Buffer !== 'undefined' + ? { + decode(buf: Uint8Array): string { + const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength); + return out.toString(); + }, + } + : { + decode(buf: Uint8Array): string { + let out = ''; + for (let i = 0; i < buf.length; i++) { + out += String.fromCharCode(buf[i]); + } + return out; + }, + }; + +export class StringWriter { + pos = 0; + private out = ''; + private buffer = new Uint8Array(bufLength); + + write(v: number): void { + const { buffer } = this; + buffer[this.pos++] = v; + if (this.pos === bufLength) { + this.out += td.decode(buffer); + this.pos = 0; + } + } + + flush(): string { + const { buffer, out, pos } = this; + return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out; + } +} + +export class StringReader { + pos = 0; + declare private buffer: string; + + constructor(buffer: string) { + this.buffer = buffer; + } + + next(): number { + return this.buffer.charCodeAt(this.pos++); + } + + peek(): number { + return this.buffer.charCodeAt(this.pos); + } + + indexOf(char: string): number { + const { buffer, pos } = this; + const idx = buffer.indexOf(char, pos); + return idx === -1 ? buffer.length : idx; + } +} diff --git a/node_modules/@jridgewell/sourcemap-codec/src/vlq.ts b/node_modules/@jridgewell/sourcemap-codec/src/vlq.ts new file mode 100644 index 0000000..a42c681 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/src/vlq.ts @@ -0,0 +1,55 @@ +import type { StringReader, StringWriter } from './strings'; + +export const comma = ','.charCodeAt(0); +export const semicolon = ';'.charCodeAt(0); + +const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +const intToChar = new Uint8Array(64); // 64 possible chars. +const charToInt = new Uint8Array(128); // z is 122 in ASCII + +for (let i = 0; i < chars.length; i++) { + const c = chars.charCodeAt(i); + intToChar[i] = c; + charToInt[c] = i; +} + +export function decodeInteger(reader: StringReader, relative: number): number { + let value = 0; + let shift = 0; + let integer = 0; + + do { + const c = reader.next(); + integer = charToInt[c]; + value |= (integer & 31) << shift; + shift += 5; + } while (integer & 32); + + const shouldNegate = value & 1; + value >>>= 1; + + if (shouldNegate) { + value = -0x80000000 | -value; + } + + return relative + value; +} + +export function encodeInteger(builder: StringWriter, num: number, relative: number): number { + let delta = num - relative; + + delta = delta < 0 ? (-delta << 1) | 1 : delta << 1; + do { + let clamped = delta & 0b011111; + delta >>>= 5; + if (delta > 0) clamped |= 0b100000; + builder.write(intToChar[clamped]); + } while (delta > 0); + + return num; +} + +export function hasMoreVlq(reader: StringReader, max: number) { + if (reader.pos >= max) return false; + return reader.peek() !== comma; +} diff --git a/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts new file mode 100644 index 0000000..c583c75 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts @@ -0,0 +1,50 @@ +type Line = number; +type Column = number; +type Kind = number; +type Name = number; +type Var = number; +type SourcesIndex = number; +type ScopesIndex = number; +type Mix = (A & O) | (B & O); +export type OriginalScope = Mix<[ + Line, + Column, + Line, + Column, + Kind +], [ + Line, + Column, + Line, + Column, + Kind, + Name +], { + vars: Var[]; +}>; +export type GeneratedRange = Mix<[ + Line, + Column, + Line, + Column +], [ + Line, + Column, + Line, + Column, + SourcesIndex, + ScopesIndex +], { + callsite: CallSite | null; + bindings: Binding[]; + isScope: boolean; +}>; +export type CallSite = [SourcesIndex, Line, Column]; +type Binding = BindingExpressionRange[]; +export type BindingExpressionRange = [Name] | [Name, Line, Column]; +export declare function decodeOriginalScopes(input: string): OriginalScope[]; +export declare function encodeOriginalScopes(scopes: OriginalScope[]): string; +export declare function decodeGeneratedRanges(input: string): GeneratedRange[]; +export declare function encodeGeneratedRanges(ranges: GeneratedRange[]): string; +export {}; +//# sourceMappingURL=scopes.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts.map b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts.map new file mode 100644 index 0000000..630e647 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAKA,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,MAAM,GAAG,MAAM,CAAC;AACrB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,GAAG,GAAG,MAAM,CAAC;AAClB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,WAAW,GAAG,MAAM,CAAC;AAE1B,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG,GAAG,CAC7B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;CAAC,EAClC;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,IAAI;CAAC,EACxC;IAAE,IAAI,EAAE,GAAG,EAAE,CAAA;CAAE,CAChB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,GAAG,CAC9B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;CAAC,EAC5B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,YAAY;IAAE,WAAW;CAAC,EACvD;IACE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB,CACF,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACpD,KAAK,OAAO,GAAG,sBAAsB,EAAE,CAAC;AACxC,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAEnE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE,CAyCnE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAQpE;AA2CD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAoGrE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,CAUtE"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts new file mode 100644 index 0000000..c583c75 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts @@ -0,0 +1,50 @@ +type Line = number; +type Column = number; +type Kind = number; +type Name = number; +type Var = number; +type SourcesIndex = number; +type ScopesIndex = number; +type Mix = (A & O) | (B & O); +export type OriginalScope = Mix<[ + Line, + Column, + Line, + Column, + Kind +], [ + Line, + Column, + Line, + Column, + Kind, + Name +], { + vars: Var[]; +}>; +export type GeneratedRange = Mix<[ + Line, + Column, + Line, + Column +], [ + Line, + Column, + Line, + Column, + SourcesIndex, + ScopesIndex +], { + callsite: CallSite | null; + bindings: Binding[]; + isScope: boolean; +}>; +export type CallSite = [SourcesIndex, Line, Column]; +type Binding = BindingExpressionRange[]; +export type BindingExpressionRange = [Name] | [Name, Line, Column]; +export declare function decodeOriginalScopes(input: string): OriginalScope[]; +export declare function encodeOriginalScopes(scopes: OriginalScope[]): string; +export declare function decodeGeneratedRanges(input: string): GeneratedRange[]; +export declare function encodeGeneratedRanges(ranges: GeneratedRange[]): string; +export {}; +//# sourceMappingURL=scopes.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts.map b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts.map new file mode 100644 index 0000000..630e647 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAKA,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,MAAM,GAAG,MAAM,CAAC;AACrB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,GAAG,GAAG,MAAM,CAAC;AAClB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,WAAW,GAAG,MAAM,CAAC;AAE1B,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG,GAAG,CAC7B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;CAAC,EAClC;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,IAAI;CAAC,EACxC;IAAE,IAAI,EAAE,GAAG,EAAE,CAAA;CAAE,CAChB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,GAAG,CAC9B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;CAAC,EAC5B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,YAAY;IAAE,WAAW;CAAC,EACvD;IACE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB,CACF,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACpD,KAAK,OAAO,GAAG,sBAAsB,EAAE,CAAC;AACxC,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAEnE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE,CAyCnE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAQpE;AA2CD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAoGrE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,CAUtE"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts new file mode 100644 index 0000000..5f35e22 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts @@ -0,0 +1,9 @@ +export { decodeOriginalScopes, encodeOriginalScopes, decodeGeneratedRanges, encodeGeneratedRanges, } from './scopes.cts'; +export type { OriginalScope, GeneratedRange, CallSite, BindingExpressionRange } from './scopes.cts'; +export type SourceMapSegment = [number] | [number, number, number, number] | [number, number, number, number, number]; +export type SourceMapLine = SourceMapSegment[]; +export type SourceMapMappings = SourceMapLine[]; +export declare function decode(mappings: string): SourceMapMappings; +export declare function encode(decoded: SourceMapMappings): string; +export declare function encode(decoded: Readonly): string; +//# sourceMappingURL=sourcemap-codec.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts.map b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts.map new file mode 100644 index 0000000..7123d52 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"sourcemap-codec.d.ts","sourceRoot":"","sources":["../src/sourcemap-codec.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEhG,MAAM,MAAM,gBAAgB,GACxB,CAAC,MAAM,CAAC,GACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAChC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC7C,MAAM,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;AAC/C,MAAM,MAAM,iBAAiB,GAAG,aAAa,EAAE,CAAC;AAEhD,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAiD1D;AAUD,wBAAgB,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAAC;AAC3D,wBAAgB,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts new file mode 100644 index 0000000..199fb9f --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts @@ -0,0 +1,9 @@ +export { decodeOriginalScopes, encodeOriginalScopes, decodeGeneratedRanges, encodeGeneratedRanges, } from './scopes.mts'; +export type { OriginalScope, GeneratedRange, CallSite, BindingExpressionRange } from './scopes.mts'; +export type SourceMapSegment = [number] | [number, number, number, number] | [number, number, number, number, number]; +export type SourceMapLine = SourceMapSegment[]; +export type SourceMapMappings = SourceMapLine[]; +export declare function decode(mappings: string): SourceMapMappings; +export declare function encode(decoded: SourceMapMappings): string; +export declare function encode(decoded: Readonly): string; +//# sourceMappingURL=sourcemap-codec.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts.map b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts.map new file mode 100644 index 0000000..7123d52 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"sourcemap-codec.d.ts","sourceRoot":"","sources":["../src/sourcemap-codec.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEhG,MAAM,MAAM,gBAAgB,GACxB,CAAC,MAAM,CAAC,GACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAChC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC7C,MAAM,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;AAC/C,MAAM,MAAM,iBAAiB,GAAG,aAAa,EAAE,CAAC;AAEhD,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAiD1D;AAUD,wBAAgB,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAAC;AAC3D,wBAAgB,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts new file mode 100644 index 0000000..62faceb --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts @@ -0,0 +1,16 @@ +export declare class StringWriter { + pos: number; + private out; + private buffer; + write(v: number): void; + flush(): string; +} +export declare class StringReader { + pos: number; + private buffer; + constructor(buffer: string); + next(): number; + peek(): number; + indexOf(char: string): number; +} +//# sourceMappingURL=strings.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts.map b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts.map new file mode 100644 index 0000000..d3602da --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"AAuBA,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAA6B;IAE3C,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAStB,KAAK,IAAI,MAAM;CAIhB;AAED,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,QAAgB,MAAM,CAAS;gBAEnB,MAAM,EAAE,MAAM;IAI1B,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAId,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAK9B"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts new file mode 100644 index 0000000..62faceb --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts @@ -0,0 +1,16 @@ +export declare class StringWriter { + pos: number; + private out; + private buffer; + write(v: number): void; + flush(): string; +} +export declare class StringReader { + pos: number; + private buffer; + constructor(buffer: string); + next(): number; + peek(): number; + indexOf(char: string): number; +} +//# sourceMappingURL=strings.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts.map b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts.map new file mode 100644 index 0000000..d3602da --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/strings.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"AAuBA,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAA6B;IAE3C,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAStB,KAAK,IAAI,MAAM;CAIhB;AAED,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,QAAgB,MAAM,CAAS;gBAEnB,MAAM,EAAE,MAAM;IAI1B,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAId,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAK9B"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts new file mode 100644 index 0000000..dbd6602 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts @@ -0,0 +1,7 @@ +import type { StringReader, StringWriter } from './strings.cts'; +export declare const comma: number; +export declare const semicolon: number; +export declare function decodeInteger(reader: StringReader, relative: number): number; +export declare function encodeInteger(builder: StringWriter, num: number, relative: number): number; +export declare function hasMoreVlq(reader: StringReader, max: number): boolean; +//# sourceMappingURL=vlq.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts.map b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts.map new file mode 100644 index 0000000..6fdc356 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"vlq.d.ts","sourceRoot":"","sources":["../src/vlq.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE5D,eAAO,MAAM,KAAK,QAAoB,CAAC;AACvC,eAAO,MAAM,SAAS,QAAoB,CAAC;AAY3C,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAoB5E;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAY1F;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,WAG3D"} \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts new file mode 100644 index 0000000..2c739bc --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts @@ -0,0 +1,7 @@ +import type { StringReader, StringWriter } from './strings.mts'; +export declare const comma: number; +export declare const semicolon: number; +export declare function decodeInteger(reader: StringReader, relative: number): number; +export declare function encodeInteger(builder: StringWriter, num: number, relative: number): number; +export declare function hasMoreVlq(reader: StringReader, max: number): boolean; +//# sourceMappingURL=vlq.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts.map b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts.map new file mode 100644 index 0000000..6fdc356 --- /dev/null +++ b/node_modules/@jridgewell/sourcemap-codec/types/vlq.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"vlq.d.ts","sourceRoot":"","sources":["../src/vlq.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE5D,eAAO,MAAM,KAAK,QAAoB,CAAC;AACvC,eAAO,MAAM,SAAS,QAAoB,CAAC;AAY3C,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAoB5E;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAY1F;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,WAG3D"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/LICENSE b/node_modules/@jridgewell/trace-mapping/LICENSE new file mode 100644 index 0000000..1f6ce94 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/LICENSE @@ -0,0 +1,19 @@ +Copyright 2024 Justin Ridgewell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/@jridgewell/trace-mapping/README.md b/node_modules/@jridgewell/trace-mapping/README.md new file mode 100644 index 0000000..9fc0ed0 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/README.md @@ -0,0 +1,348 @@ +# @jridgewell/trace-mapping + +> Trace the original position through a source map + +`trace-mapping` allows you to take the line and column of an output file and trace it to the +original location in the source file through a source map. + +You may already be familiar with the [`source-map`][source-map] package's `SourceMapConsumer`. This +provides the same `originalPositionFor` and `generatedPositionFor` API, without requiring WASM. + +## Installation + +```sh +npm install @jridgewell/trace-mapping +``` + +## Usage + +```typescript +import { + TraceMap, + originalPositionFor, + generatedPositionFor, + sourceContentFor, + isIgnored, +} from '@jridgewell/trace-mapping'; + +const tracer = new TraceMap({ + version: 3, + sources: ['input.js'], + sourcesContent: ['content of input.js'], + names: ['foo'], + mappings: 'KAyCIA', + ignoreList: [], +}); + +// Lines start at line 1, columns at column 0. +const traced = originalPositionFor(tracer, { line: 1, column: 5 }); +assert.deepEqual(traced, { + source: 'input.js', + line: 42, + column: 4, + name: 'foo', +}); + +const content = sourceContentFor(tracer, traced.source); +assert.strictEqual(content, 'content for input.js'); + +const generated = generatedPositionFor(tracer, { + source: 'input.js', + line: 42, + column: 4, +}); +assert.deepEqual(generated, { + line: 1, + column: 5, +}); + +const ignored = isIgnored(tracer, 'input.js'); +assert.equal(ignored, false); +``` + +We also provide a lower level API to get the actual segment that matches our line and column. Unlike +`originalPositionFor`, `traceSegment` uses a 0-base for `line`: + +```typescript +import { traceSegment } from '@jridgewell/trace-mapping'; + +// line is 0-base. +const traced = traceSegment(tracer, /* line */ 0, /* column */ 5); + +// Segments are [outputColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex] +// Again, line is 0-base and so is sourceLine +assert.deepEqual(traced, [5, 0, 41, 4, 0]); +``` + +### SectionedSourceMaps + +The sourcemap spec defines a special `sections` field that's designed to handle concatenation of +output code with associated sourcemaps. This type of sourcemap is rarely used (no major build tool +produces it), but if you are hand coding a concatenation you may need it. We provide an `AnyMap` +helper that can receive either a regular sourcemap or a `SectionedSourceMap` and returns a +`TraceMap` instance: + +```typescript +import { AnyMap } from '@jridgewell/trace-mapping'; +const fooOutput = 'foo'; +const barOutput = 'bar'; +const output = [fooOutput, barOutput].join('\n'); + +const sectioned = new AnyMap({ + version: 3, + sections: [ + { + // 0-base line and column + offset: { line: 0, column: 0 }, + // fooOutput's sourcemap + map: { + version: 3, + sources: ['foo.js'], + names: ['foo'], + mappings: 'AAAAA', + }, + }, + { + // barOutput's sourcemap will not affect the first line, only the second + offset: { line: 1, column: 0 }, + map: { + version: 3, + sources: ['bar.js'], + names: ['bar'], + mappings: 'AAAAA', + }, + }, + ], +}); + +const traced = originalPositionFor(sectioned, { + line: 2, + column: 0, +}); + +assert.deepEqual(traced, { + source: 'bar.js', + line: 1, + column: 0, + name: 'bar', +}); +``` + +## Benchmarks + +``` +node v20.10.0 + +amp.js.map - 45120 segments + +Memory Usage: +trace-mapping decoded 414164 bytes +trace-mapping encoded 6274352 bytes +source-map-js 10968904 bytes +source-map-0.6.1 17587160 bytes +source-map-0.8.0 8812155 bytes +Chrome dev tools 8672912 bytes +Smallest memory usage is trace-mapping decoded + +Init speed: +trace-mapping: decoded JSON input x 205 ops/sec ±0.19% (88 runs sampled) +trace-mapping: encoded JSON input x 405 ops/sec ±1.47% (88 runs sampled) +trace-mapping: decoded Object input x 4,645 ops/sec ±0.15% (98 runs sampled) +trace-mapping: encoded Object input x 458 ops/sec ±1.63% (91 runs sampled) +source-map-js: encoded Object input x 75.48 ops/sec ±1.64% (67 runs sampled) +source-map-0.6.1: encoded Object input x 39.37 ops/sec ±1.44% (53 runs sampled) +Chrome dev tools: encoded Object input x 150 ops/sec ±1.76% (79 runs sampled) +Fastest is trace-mapping: decoded Object input + +Trace speed (random): +trace-mapping: decoded originalPositionFor x 44,946 ops/sec ±0.16% (99 runs sampled) +trace-mapping: encoded originalPositionFor x 37,995 ops/sec ±1.81% (89 runs sampled) +source-map-js: encoded originalPositionFor x 9,230 ops/sec ±1.36% (93 runs sampled) +source-map-0.6.1: encoded originalPositionFor x 8,057 ops/sec ±0.84% (96 runs sampled) +source-map-0.8.0: encoded originalPositionFor x 28,198 ops/sec ±1.12% (91 runs sampled) +Chrome dev tools: encoded originalPositionFor x 46,276 ops/sec ±1.35% (95 runs sampled) +Fastest is Chrome dev tools: encoded originalPositionFor + +Trace speed (ascending): +trace-mapping: decoded originalPositionFor x 204,406 ops/sec ±0.19% (97 runs sampled) +trace-mapping: encoded originalPositionFor x 196,695 ops/sec ±0.24% (99 runs sampled) +source-map-js: encoded originalPositionFor x 11,948 ops/sec ±0.94% (99 runs sampled) +source-map-0.6.1: encoded originalPositionFor x 10,730 ops/sec ±0.36% (100 runs sampled) +source-map-0.8.0: encoded originalPositionFor x 51,427 ops/sec ±0.21% (98 runs sampled) +Chrome dev tools: encoded originalPositionFor x 162,615 ops/sec ±0.18% (98 runs sampled) +Fastest is trace-mapping: decoded originalPositionFor + + +*** + + +babel.min.js.map - 347793 segments + +Memory Usage: +trace-mapping decoded 18504 bytes +trace-mapping encoded 35428008 bytes +source-map-js 51676808 bytes +source-map-0.6.1 63367136 bytes +source-map-0.8.0 43158400 bytes +Chrome dev tools 50721552 bytes +Smallest memory usage is trace-mapping decoded + +Init speed: +trace-mapping: decoded JSON input x 17.82 ops/sec ±6.35% (35 runs sampled) +trace-mapping: encoded JSON input x 31.57 ops/sec ±7.50% (43 runs sampled) +trace-mapping: decoded Object input x 867 ops/sec ±0.74% (94 runs sampled) +trace-mapping: encoded Object input x 33.83 ops/sec ±7.66% (46 runs sampled) +source-map-js: encoded Object input x 6.58 ops/sec ±3.31% (20 runs sampled) +source-map-0.6.1: encoded Object input x 4.23 ops/sec ±3.43% (15 runs sampled) +Chrome dev tools: encoded Object input x 22.14 ops/sec ±3.79% (41 runs sampled) +Fastest is trace-mapping: decoded Object input + +Trace speed (random): +trace-mapping: decoded originalPositionFor x 78,234 ops/sec ±1.48% (29 runs sampled) +trace-mapping: encoded originalPositionFor x 60,761 ops/sec ±1.35% (21 runs sampled) +source-map-js: encoded originalPositionFor x 51,448 ops/sec ±2.17% (89 runs sampled) +source-map-0.6.1: encoded originalPositionFor x 47,221 ops/sec ±1.99% (15 runs sampled) +source-map-0.8.0: encoded originalPositionFor x 84,002 ops/sec ±1.45% (27 runs sampled) +Chrome dev tools: encoded originalPositionFor x 106,457 ops/sec ±1.38% (37 runs sampled) +Fastest is Chrome dev tools: encoded originalPositionFor + +Trace speed (ascending): +trace-mapping: decoded originalPositionFor x 930,943 ops/sec ±0.25% (99 runs sampled) +trace-mapping: encoded originalPositionFor x 843,545 ops/sec ±0.34% (97 runs sampled) +source-map-js: encoded originalPositionFor x 114,510 ops/sec ±1.37% (36 runs sampled) +source-map-0.6.1: encoded originalPositionFor x 87,412 ops/sec ±0.72% (92 runs sampled) +source-map-0.8.0: encoded originalPositionFor x 197,709 ops/sec ±0.89% (59 runs sampled) +Chrome dev tools: encoded originalPositionFor x 688,983 ops/sec ±0.33% (98 runs sampled) +Fastest is trace-mapping: decoded originalPositionFor + + +*** + + +preact.js.map - 1992 segments + +Memory Usage: +trace-mapping decoded 33136 bytes +trace-mapping encoded 254240 bytes +source-map-js 837488 bytes +source-map-0.6.1 961928 bytes +source-map-0.8.0 54384 bytes +Chrome dev tools 709680 bytes +Smallest memory usage is trace-mapping decoded + +Init speed: +trace-mapping: decoded JSON input x 3,709 ops/sec ±0.13% (99 runs sampled) +trace-mapping: encoded JSON input x 6,447 ops/sec ±0.22% (101 runs sampled) +trace-mapping: decoded Object input x 83,062 ops/sec ±0.23% (100 runs sampled) +trace-mapping: encoded Object input x 14,980 ops/sec ±0.28% (100 runs sampled) +source-map-js: encoded Object input x 2,544 ops/sec ±0.16% (99 runs sampled) +source-map-0.6.1: encoded Object input x 1,221 ops/sec ±0.37% (97 runs sampled) +Chrome dev tools: encoded Object input x 4,241 ops/sec ±0.39% (93 runs sampled) +Fastest is trace-mapping: decoded Object input + +Trace speed (random): +trace-mapping: decoded originalPositionFor x 91,028 ops/sec ±0.14% (94 runs sampled) +trace-mapping: encoded originalPositionFor x 84,348 ops/sec ±0.26% (98 runs sampled) +source-map-js: encoded originalPositionFor x 26,998 ops/sec ±0.23% (98 runs sampled) +source-map-0.6.1: encoded originalPositionFor x 18,049 ops/sec ±0.26% (100 runs sampled) +source-map-0.8.0: encoded originalPositionFor x 41,916 ops/sec ±0.28% (98 runs sampled) +Chrome dev tools: encoded originalPositionFor x 88,616 ops/sec ±0.14% (98 runs sampled) +Fastest is trace-mapping: decoded originalPositionFor + +Trace speed (ascending): +trace-mapping: decoded originalPositionFor x 319,960 ops/sec ±0.16% (100 runs sampled) +trace-mapping: encoded originalPositionFor x 302,153 ops/sec ±0.18% (100 runs sampled) +source-map-js: encoded originalPositionFor x 35,574 ops/sec ±0.19% (100 runs sampled) +source-map-0.6.1: encoded originalPositionFor x 19,943 ops/sec ±0.12% (101 runs sampled) +source-map-0.8.0: encoded originalPositionFor x 54,648 ops/sec ±0.20% (99 runs sampled) +Chrome dev tools: encoded originalPositionFor x 278,319 ops/sec ±0.17% (102 runs sampled) +Fastest is trace-mapping: decoded originalPositionFor + + +*** + + +react.js.map - 5726 segments + +Memory Usage: +trace-mapping decoded 10872 bytes +trace-mapping encoded 681512 bytes +source-map-js 2563944 bytes +source-map-0.6.1 2150864 bytes +source-map-0.8.0 88680 bytes +Chrome dev tools 1149576 bytes +Smallest memory usage is trace-mapping decoded + +Init speed: +trace-mapping: decoded JSON input x 1,887 ops/sec ±0.28% (99 runs sampled) +trace-mapping: encoded JSON input x 4,749 ops/sec ±0.48% (97 runs sampled) +trace-mapping: decoded Object input x 74,236 ops/sec ±0.11% (99 runs sampled) +trace-mapping: encoded Object input x 5,752 ops/sec ±0.38% (100 runs sampled) +source-map-js: encoded Object input x 806 ops/sec ±0.19% (97 runs sampled) +source-map-0.6.1: encoded Object input x 418 ops/sec ±0.33% (94 runs sampled) +Chrome dev tools: encoded Object input x 1,524 ops/sec ±0.57% (92 runs sampled) +Fastest is trace-mapping: decoded Object input + +Trace speed (random): +trace-mapping: decoded originalPositionFor x 620,201 ops/sec ±0.33% (96 runs sampled) +trace-mapping: encoded originalPositionFor x 579,548 ops/sec ±0.35% (97 runs sampled) +source-map-js: encoded originalPositionFor x 230,983 ops/sec ±0.62% (54 runs sampled) +source-map-0.6.1: encoded originalPositionFor x 158,145 ops/sec ±0.80% (46 runs sampled) +source-map-0.8.0: encoded originalPositionFor x 343,801 ops/sec ±0.55% (96 runs sampled) +Chrome dev tools: encoded originalPositionFor x 659,649 ops/sec ±0.49% (98 runs sampled) +Fastest is Chrome dev tools: encoded originalPositionFor + +Trace speed (ascending): +trace-mapping: decoded originalPositionFor x 2,368,079 ops/sec ±0.32% (98 runs sampled) +trace-mapping: encoded originalPositionFor x 2,134,039 ops/sec ±2.72% (87 runs sampled) +source-map-js: encoded originalPositionFor x 290,120 ops/sec ±2.49% (82 runs sampled) +source-map-0.6.1: encoded originalPositionFor x 187,613 ops/sec ±0.86% (49 runs sampled) +source-map-0.8.0: encoded originalPositionFor x 479,569 ops/sec ±0.65% (96 runs sampled) +Chrome dev tools: encoded originalPositionFor x 2,048,414 ops/sec ±0.24% (98 runs sampled) +Fastest is trace-mapping: decoded originalPositionFor + + +*** + + +vscode.map - 2141001 segments + +Memory Usage: +trace-mapping decoded 5206584 bytes +trace-mapping encoded 208370336 bytes +source-map-js 278493008 bytes +source-map-0.6.1 391564048 bytes +source-map-0.8.0 257508787 bytes +Chrome dev tools 291053000 bytes +Smallest memory usage is trace-mapping decoded + +Init speed: +trace-mapping: decoded JSON input x 1.63 ops/sec ±33.88% (9 runs sampled) +trace-mapping: encoded JSON input x 3.29 ops/sec ±36.13% (13 runs sampled) +trace-mapping: decoded Object input x 103 ops/sec ±0.93% (77 runs sampled) +trace-mapping: encoded Object input x 5.42 ops/sec ±28.54% (19 runs sampled) +source-map-js: encoded Object input x 1.07 ops/sec ±13.84% (7 runs sampled) +source-map-0.6.1: encoded Object input x 0.60 ops/sec ±2.43% (6 runs sampled) +Chrome dev tools: encoded Object input x 2.61 ops/sec ±22.00% (11 runs sampled) +Fastest is trace-mapping: decoded Object input + +Trace speed (random): +trace-mapping: decoded originalPositionFor x 257,019 ops/sec ±0.97% (93 runs sampled) +trace-mapping: encoded originalPositionFor x 179,163 ops/sec ±0.83% (92 runs sampled) +source-map-js: encoded originalPositionFor x 73,337 ops/sec ±1.35% (87 runs sampled) +source-map-0.6.1: encoded originalPositionFor x 38,797 ops/sec ±1.66% (88 runs sampled) +source-map-0.8.0: encoded originalPositionFor x 107,758 ops/sec ±1.94% (45 runs sampled) +Chrome dev tools: encoded originalPositionFor x 188,550 ops/sec ±1.85% (79 runs sampled) +Fastest is trace-mapping: decoded originalPositionFor + +Trace speed (ascending): +trace-mapping: decoded originalPositionFor x 447,621 ops/sec ±3.64% (94 runs sampled) +trace-mapping: encoded originalPositionFor x 323,698 ops/sec ±5.20% (88 runs sampled) +source-map-js: encoded originalPositionFor x 78,387 ops/sec ±1.69% (89 runs sampled) +source-map-0.6.1: encoded originalPositionFor x 41,016 ops/sec ±3.01% (25 runs sampled) +source-map-0.8.0: encoded originalPositionFor x 124,204 ops/sec ±0.90% (92 runs sampled) +Chrome dev tools: encoded originalPositionFor x 230,087 ops/sec ±2.61% (93 runs sampled) +Fastest is trace-mapping: decoded originalPositionFor +``` + +[source-map]: https://www.npmjs.com/package/source-map diff --git a/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs b/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs new file mode 100644 index 0000000..73a95c7 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs @@ -0,0 +1,493 @@ +// src/trace-mapping.ts +import { encode, decode } from "@jridgewell/sourcemap-codec"; + +// src/resolve.ts +import resolveUri from "@jridgewell/resolve-uri"; + +// src/strip-filename.ts +function stripFilename(path) { + if (!path) return ""; + const index = path.lastIndexOf("/"); + return path.slice(0, index + 1); +} + +// src/resolve.ts +function resolver(mapUrl, sourceRoot) { + const from = stripFilename(mapUrl); + const prefix = sourceRoot ? sourceRoot + "/" : ""; + return (source) => resolveUri(prefix + (source || ""), from); +} + +// src/sourcemap-segment.ts +var COLUMN = 0; +var SOURCES_INDEX = 1; +var SOURCE_LINE = 2; +var SOURCE_COLUMN = 3; +var NAMES_INDEX = 4; +var REV_GENERATED_LINE = 1; +var REV_GENERATED_COLUMN = 2; + +// src/sort.ts +function maybeSort(mappings, owned) { + const unsortedIndex = nextUnsortedSegmentLine(mappings, 0); + if (unsortedIndex === mappings.length) return mappings; + if (!owned) mappings = mappings.slice(); + for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) { + mappings[i] = sortSegments(mappings[i], owned); + } + return mappings; +} +function nextUnsortedSegmentLine(mappings, start) { + for (let i = start; i < mappings.length; i++) { + if (!isSorted(mappings[i])) return i; + } + return mappings.length; +} +function isSorted(line) { + for (let j = 1; j < line.length; j++) { + if (line[j][COLUMN] < line[j - 1][COLUMN]) { + return false; + } + } + return true; +} +function sortSegments(line, owned) { + if (!owned) line = line.slice(); + return line.sort(sortComparator); +} +function sortComparator(a, b) { + return a[COLUMN] - b[COLUMN]; +} + +// src/by-source.ts +function buildBySources(decoded, memos) { + const sources = memos.map(() => []); + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + for (let j = 0; j < line.length; j++) { + const seg = line[j]; + if (seg.length === 1) continue; + const sourceIndex2 = seg[SOURCES_INDEX]; + const sourceLine = seg[SOURCE_LINE]; + const sourceColumn = seg[SOURCE_COLUMN]; + const source = sources[sourceIndex2]; + const segs = source[sourceLine] || (source[sourceLine] = []); + segs.push([sourceColumn, i, seg[COLUMN]]); + } + } + for (let i = 0; i < sources.length; i++) { + const source = sources[i]; + for (let j = 0; j < source.length; j++) { + const line = source[j]; + if (line) line.sort(sortComparator); + } + } + return sources; +} + +// src/binary-search.ts +var found = false; +function binarySearch(haystack, needle, low, high) { + while (low <= high) { + const mid = low + (high - low >> 1); + const cmp = haystack[mid][COLUMN] - needle; + if (cmp === 0) { + found = true; + return mid; + } + if (cmp < 0) { + low = mid + 1; + } else { + high = mid - 1; + } + } + found = false; + return low - 1; +} +function upperBound(haystack, needle, index) { + for (let i = index + 1; i < haystack.length; index = i++) { + if (haystack[i][COLUMN] !== needle) break; + } + return index; +} +function lowerBound(haystack, needle, index) { + for (let i = index - 1; i >= 0; index = i--) { + if (haystack[i][COLUMN] !== needle) break; + } + return index; +} +function memoizedState() { + return { + lastKey: -1, + lastNeedle: -1, + lastIndex: -1 + }; +} +function memoizedBinarySearch(haystack, needle, state, key) { + const { lastKey, lastNeedle, lastIndex } = state; + let low = 0; + let high = haystack.length - 1; + if (key === lastKey) { + if (needle === lastNeedle) { + found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle; + return lastIndex; + } + if (needle >= lastNeedle) { + low = lastIndex === -1 ? 0 : lastIndex; + } else { + high = lastIndex; + } + } + state.lastKey = key; + state.lastNeedle = needle; + return state.lastIndex = binarySearch(haystack, needle, low, high); +} + +// src/types.ts +function parse(map) { + return typeof map === "string" ? JSON.parse(map) : map; +} + +// src/flatten-map.ts +var FlattenMap = function(map, mapUrl) { + const parsed = parse(map); + if (!("sections" in parsed)) { + return new TraceMap(parsed, mapUrl); + } + const mappings = []; + const sources = []; + const sourcesContent = []; + const names = []; + const ignoreList = []; + recurse( + parsed, + mapUrl, + mappings, + sources, + sourcesContent, + names, + ignoreList, + 0, + 0, + Infinity, + Infinity + ); + const joined = { + version: 3, + file: parsed.file, + names, + sources, + sourcesContent, + mappings, + ignoreList + }; + return presortedDecodedMap(joined); +}; +function recurse(input, mapUrl, mappings, sources, sourcesContent, names, ignoreList, lineOffset, columnOffset, stopLine, stopColumn) { + const { sections } = input; + for (let i = 0; i < sections.length; i++) { + const { map, offset } = sections[i]; + let sl = stopLine; + let sc = stopColumn; + if (i + 1 < sections.length) { + const nextOffset = sections[i + 1].offset; + sl = Math.min(stopLine, lineOffset + nextOffset.line); + if (sl === stopLine) { + sc = Math.min(stopColumn, columnOffset + nextOffset.column); + } else if (sl < stopLine) { + sc = columnOffset + nextOffset.column; + } + } + addSection( + map, + mapUrl, + mappings, + sources, + sourcesContent, + names, + ignoreList, + lineOffset + offset.line, + columnOffset + offset.column, + sl, + sc + ); + } +} +function addSection(input, mapUrl, mappings, sources, sourcesContent, names, ignoreList, lineOffset, columnOffset, stopLine, stopColumn) { + const parsed = parse(input); + if ("sections" in parsed) return recurse(...arguments); + const map = new TraceMap(parsed, mapUrl); + const sourcesOffset = sources.length; + const namesOffset = names.length; + const decoded = decodedMappings(map); + const { resolvedSources, sourcesContent: contents, ignoreList: ignores } = map; + append(sources, resolvedSources); + append(names, map.names); + if (contents) append(sourcesContent, contents); + else for (let i = 0; i < resolvedSources.length; i++) sourcesContent.push(null); + if (ignores) for (let i = 0; i < ignores.length; i++) ignoreList.push(ignores[i] + sourcesOffset); + for (let i = 0; i < decoded.length; i++) { + const lineI = lineOffset + i; + if (lineI > stopLine) return; + const out = getLine(mappings, lineI); + const cOffset = i === 0 ? columnOffset : 0; + const line = decoded[i]; + for (let j = 0; j < line.length; j++) { + const seg = line[j]; + const column = cOffset + seg[COLUMN]; + if (lineI === stopLine && column >= stopColumn) return; + if (seg.length === 1) { + out.push([column]); + continue; + } + const sourcesIndex = sourcesOffset + seg[SOURCES_INDEX]; + const sourceLine = seg[SOURCE_LINE]; + const sourceColumn = seg[SOURCE_COLUMN]; + out.push( + seg.length === 4 ? [column, sourcesIndex, sourceLine, sourceColumn] : [column, sourcesIndex, sourceLine, sourceColumn, namesOffset + seg[NAMES_INDEX]] + ); + } + } +} +function append(arr, other) { + for (let i = 0; i < other.length; i++) arr.push(other[i]); +} +function getLine(arr, index) { + for (let i = arr.length; i <= index; i++) arr[i] = []; + return arr[index]; +} + +// src/trace-mapping.ts +var LINE_GTR_ZERO = "`line` must be greater than 0 (lines start at line 1)"; +var COL_GTR_EQ_ZERO = "`column` must be greater than or equal to 0 (columns start at column 0)"; +var LEAST_UPPER_BOUND = -1; +var GREATEST_LOWER_BOUND = 1; +var TraceMap = class { + constructor(map, mapUrl) { + const isString = typeof map === "string"; + if (!isString && map._decodedMemo) return map; + const parsed = parse(map); + const { version, file, names, sourceRoot, sources, sourcesContent } = parsed; + this.version = version; + this.file = file; + this.names = names || []; + this.sourceRoot = sourceRoot; + this.sources = sources; + this.sourcesContent = sourcesContent; + this.ignoreList = parsed.ignoreList || parsed.x_google_ignoreList || void 0; + const resolve = resolver(mapUrl, sourceRoot); + this.resolvedSources = sources.map(resolve); + const { mappings } = parsed; + if (typeof mappings === "string") { + this._encoded = mappings; + this._decoded = void 0; + } else if (Array.isArray(mappings)) { + this._encoded = void 0; + this._decoded = maybeSort(mappings, isString); + } else if (parsed.sections) { + throw new Error(`TraceMap passed sectioned source map, please use FlattenMap export instead`); + } else { + throw new Error(`invalid source map: ${JSON.stringify(parsed)}`); + } + this._decodedMemo = memoizedState(); + this._bySources = void 0; + this._bySourceMemos = void 0; + } +}; +function cast(map) { + return map; +} +function encodedMappings(map) { + var _a, _b; + return (_b = (_a = cast(map))._encoded) != null ? _b : _a._encoded = encode(cast(map)._decoded); +} +function decodedMappings(map) { + var _a; + return (_a = cast(map))._decoded || (_a._decoded = decode(cast(map)._encoded)); +} +function traceSegment(map, line, column) { + const decoded = decodedMappings(map); + if (line >= decoded.length) return null; + const segments = decoded[line]; + const index = traceSegmentInternal( + segments, + cast(map)._decodedMemo, + line, + column, + GREATEST_LOWER_BOUND + ); + return index === -1 ? null : segments[index]; +} +function originalPositionFor(map, needle) { + let { line, column, bias } = needle; + line--; + if (line < 0) throw new Error(LINE_GTR_ZERO); + if (column < 0) throw new Error(COL_GTR_EQ_ZERO); + const decoded = decodedMappings(map); + if (line >= decoded.length) return OMapping(null, null, null, null); + const segments = decoded[line]; + const index = traceSegmentInternal( + segments, + cast(map)._decodedMemo, + line, + column, + bias || GREATEST_LOWER_BOUND + ); + if (index === -1) return OMapping(null, null, null, null); + const segment = segments[index]; + if (segment.length === 1) return OMapping(null, null, null, null); + const { names, resolvedSources } = map; + return OMapping( + resolvedSources[segment[SOURCES_INDEX]], + segment[SOURCE_LINE] + 1, + segment[SOURCE_COLUMN], + segment.length === 5 ? names[segment[NAMES_INDEX]] : null + ); +} +function generatedPositionFor(map, needle) { + const { source, line, column, bias } = needle; + return generatedPosition(map, source, line, column, bias || GREATEST_LOWER_BOUND, false); +} +function allGeneratedPositionsFor(map, needle) { + const { source, line, column, bias } = needle; + return generatedPosition(map, source, line, column, bias || LEAST_UPPER_BOUND, true); +} +function eachMapping(map, cb) { + const decoded = decodedMappings(map); + const { names, resolvedSources } = map; + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + for (let j = 0; j < line.length; j++) { + const seg = line[j]; + const generatedLine = i + 1; + const generatedColumn = seg[0]; + let source = null; + let originalLine = null; + let originalColumn = null; + let name = null; + if (seg.length !== 1) { + source = resolvedSources[seg[1]]; + originalLine = seg[2] + 1; + originalColumn = seg[3]; + } + if (seg.length === 5) name = names[seg[4]]; + cb({ + generatedLine, + generatedColumn, + source, + originalLine, + originalColumn, + name + }); + } + } +} +function sourceIndex(map, source) { + const { sources, resolvedSources } = map; + let index = sources.indexOf(source); + if (index === -1) index = resolvedSources.indexOf(source); + return index; +} +function sourceContentFor(map, source) { + const { sourcesContent } = map; + if (sourcesContent == null) return null; + const index = sourceIndex(map, source); + return index === -1 ? null : sourcesContent[index]; +} +function isIgnored(map, source) { + const { ignoreList } = map; + if (ignoreList == null) return false; + const index = sourceIndex(map, source); + return index === -1 ? false : ignoreList.includes(index); +} +function presortedDecodedMap(map, mapUrl) { + const tracer = new TraceMap(clone(map, []), mapUrl); + cast(tracer)._decoded = map.mappings; + return tracer; +} +function decodedMap(map) { + return clone(map, decodedMappings(map)); +} +function encodedMap(map) { + return clone(map, encodedMappings(map)); +} +function clone(map, mappings) { + return { + version: map.version, + file: map.file, + names: map.names, + sourceRoot: map.sourceRoot, + sources: map.sources, + sourcesContent: map.sourcesContent, + mappings, + ignoreList: map.ignoreList || map.x_google_ignoreList + }; +} +function OMapping(source, line, column, name) { + return { source, line, column, name }; +} +function GMapping(line, column) { + return { line, column }; +} +function traceSegmentInternal(segments, memo, line, column, bias) { + let index = memoizedBinarySearch(segments, column, memo, line); + if (found) { + index = (bias === LEAST_UPPER_BOUND ? upperBound : lowerBound)(segments, column, index); + } else if (bias === LEAST_UPPER_BOUND) index++; + if (index === -1 || index === segments.length) return -1; + return index; +} +function sliceGeneratedPositions(segments, memo, line, column, bias) { + let min = traceSegmentInternal(segments, memo, line, column, GREATEST_LOWER_BOUND); + if (!found && bias === LEAST_UPPER_BOUND) min++; + if (min === -1 || min === segments.length) return []; + const matchedColumn = found ? column : segments[min][COLUMN]; + if (!found) min = lowerBound(segments, matchedColumn, min); + const max = upperBound(segments, matchedColumn, min); + const result = []; + for (; min <= max; min++) { + const segment = segments[min]; + result.push(GMapping(segment[REV_GENERATED_LINE] + 1, segment[REV_GENERATED_COLUMN])); + } + return result; +} +function generatedPosition(map, source, line, column, bias, all) { + var _a, _b; + line--; + if (line < 0) throw new Error(LINE_GTR_ZERO); + if (column < 0) throw new Error(COL_GTR_EQ_ZERO); + const { sources, resolvedSources } = map; + let sourceIndex2 = sources.indexOf(source); + if (sourceIndex2 === -1) sourceIndex2 = resolvedSources.indexOf(source); + if (sourceIndex2 === -1) return all ? [] : GMapping(null, null); + const bySourceMemos = (_a = cast(map))._bySourceMemos || (_a._bySourceMemos = sources.map(memoizedState)); + const generated = (_b = cast(map))._bySources || (_b._bySources = buildBySources(decodedMappings(map), bySourceMemos)); + const segments = generated[sourceIndex2][line]; + if (segments == null) return all ? [] : GMapping(null, null); + const memo = bySourceMemos[sourceIndex2]; + if (all) return sliceGeneratedPositions(segments, memo, line, column, bias); + const index = traceSegmentInternal(segments, memo, line, column, bias); + if (index === -1) return GMapping(null, null); + const segment = segments[index]; + return GMapping(segment[REV_GENERATED_LINE] + 1, segment[REV_GENERATED_COLUMN]); +} +export { + FlattenMap as AnyMap, + FlattenMap, + GREATEST_LOWER_BOUND, + LEAST_UPPER_BOUND, + TraceMap, + allGeneratedPositionsFor, + decodedMap, + decodedMappings, + eachMapping, + encodedMap, + encodedMappings, + generatedPositionFor, + isIgnored, + originalPositionFor, + presortedDecodedMap, + sourceContentFor, + traceSegment +}; +//# sourceMappingURL=trace-mapping.mjs.map diff --git a/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs.map b/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs.map new file mode 100644 index 0000000..a789581 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.mjs.map @@ -0,0 +1,6 @@ +{ + "version": 3, + "sources": ["../src/trace-mapping.ts", "../src/resolve.ts", "../src/strip-filename.ts", "../src/sourcemap-segment.ts", "../src/sort.ts", "../src/by-source.ts", "../src/binary-search.ts", "../src/types.ts", "../src/flatten-map.ts"], + "mappings": ";AAAA,SAAS,QAAQ,cAAc;;;ACA/B,OAAO,gBAAgB;;;ACGR,SAAR,cAA+B,MAAyC;AAC7E,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,QAAQ,KAAK,YAAY,GAAG;AAClC,SAAO,KAAK,MAAM,GAAG,QAAQ,CAAC;AAChC;;;ADHe,SAAR,SACL,QACA,YACS;AACT,QAAM,OAAO,cAAc,MAAM;AAIjC,QAAM,SAAS,aAAa,aAAa,MAAM;AAE/C,SAAO,CAAC,WAAW,WAAW,UAAU,UAAU,KAAK,IAAI;AAC7D;;;AEAO,IAAM,SAAS;AACf,IAAM,gBAAgB;AACtB,IAAM,cAAc;AACpB,IAAM,gBAAgB;AACtB,IAAM,cAAc;AAEpB,IAAM,qBAAqB;AAC3B,IAAM,uBAAuB;;;AClBrB,SAAR,UACL,UACA,OACsB;AACtB,QAAM,gBAAgB,wBAAwB,UAAU,CAAC;AACzD,MAAI,kBAAkB,SAAS,OAAQ,QAAO;AAI9C,MAAI,CAAC,MAAO,YAAW,SAAS,MAAM;AAEtC,WAAS,IAAI,eAAe,IAAI,SAAS,QAAQ,IAAI,wBAAwB,UAAU,IAAI,CAAC,GAAG;AAC7F,aAAS,CAAC,IAAI,aAAa,SAAS,CAAC,GAAG,KAAK;AAAA,EAC/C;AACA,SAAO;AACT;AAEA,SAAS,wBAAwB,UAAgC,OAAuB;AACtF,WAAS,IAAI,OAAO,IAAI,SAAS,QAAQ,KAAK;AAC5C,QAAI,CAAC,SAAS,SAAS,CAAC,CAAC,EAAG,QAAO;AAAA,EACrC;AACA,SAAO,SAAS;AAClB;AAEA,SAAS,SAAS,MAAmC;AACnD,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,KAAK,CAAC,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC,EAAE,MAAM,GAAG;AACzC,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,aAAa,MAA0B,OAAoC;AAClF,MAAI,CAAC,MAAO,QAAO,KAAK,MAAM;AAC9B,SAAO,KAAK,KAAK,cAAc;AACjC;AAEO,SAAS,eAA4D,GAAM,GAAc;AAC9F,SAAO,EAAE,MAAM,IAAI,EAAE,MAAM;AAC7B;;;ACnCe,SAAR,eACL,SACA,OACU;AACV,QAAM,UAAoB,MAAM,IAAI,MAAM,CAAC,CAAC;AAE5C,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,OAAO,QAAQ,CAAC;AACtB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,MAAM,KAAK,CAAC;AAClB,UAAI,IAAI,WAAW,EAAG;AAEtB,YAAMA,eAAc,IAAI,aAAa;AACrC,YAAM,aAAa,IAAI,WAAW;AAClC,YAAM,eAAe,IAAI,aAAa;AAEtC,YAAM,SAAS,QAAQA,YAAW;AAClC,YAAM,OAAQ,4CAAuB,CAAC;AACtC,WAAK,KAAK,CAAC,cAAc,GAAG,IAAI,MAAM,CAAC,CAAC;AAAA,IAC1C;AAAA,EACF;AAEA,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,SAAS,QAAQ,CAAC;AACxB,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,YAAM,OAAO,OAAO,CAAC;AACrB,UAAI,KAAM,MAAK,KAAK,cAAc;AAAA,IACpC;AAAA,EACF;AAEA,SAAO;AACT;;;AC/BO,IAAI,QAAQ;AAkBZ,SAAS,aACd,UACA,QACA,KACA,MACQ;AACR,SAAO,OAAO,MAAM;AAClB,UAAM,MAAM,OAAQ,OAAO,OAAQ;AACnC,UAAM,MAAM,SAAS,GAAG,EAAE,MAAM,IAAI;AAEpC,QAAI,QAAQ,GAAG;AACb,cAAQ;AACR,aAAO;AAAA,IACT;AAEA,QAAI,MAAM,GAAG;AACX,YAAM,MAAM;AAAA,IACd,OAAO;AACL,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AAEA,UAAQ;AACR,SAAO,MAAM;AACf;AAEO,SAAS,WACd,UACA,QACA,OACQ;AACR,WAAS,IAAI,QAAQ,GAAG,IAAI,SAAS,QAAQ,QAAQ,KAAK;AACxD,QAAI,SAAS,CAAC,EAAE,MAAM,MAAM,OAAQ;AAAA,EACtC;AACA,SAAO;AACT;AAEO,SAAS,WACd,UACA,QACA,OACQ;AACR,WAAS,IAAI,QAAQ,GAAG,KAAK,GAAG,QAAQ,KAAK;AAC3C,QAAI,SAAS,CAAC,EAAE,MAAM,MAAM,OAAQ;AAAA,EACtC;AACA,SAAO;AACT;AAEO,SAAS,gBAA2B;AACzC,SAAO;AAAA,IACL,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,WAAW;AAAA,EACb;AACF;AAMO,SAAS,qBACd,UACA,QACA,OACA,KACQ;AACR,QAAM,EAAE,SAAS,YAAY,UAAU,IAAI;AAE3C,MAAI,MAAM;AACV,MAAI,OAAO,SAAS,SAAS;AAC7B,MAAI,QAAQ,SAAS;AACnB,QAAI,WAAW,YAAY;AACzB,cAAQ,cAAc,MAAM,SAAS,SAAS,EAAE,MAAM,MAAM;AAC5D,aAAO;AAAA,IACT;AAEA,QAAI,UAAU,YAAY;AAExB,YAAM,cAAc,KAAK,IAAI;AAAA,IAC/B,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,UAAU;AAChB,QAAM,aAAa;AAEnB,SAAQ,MAAM,YAAY,aAAa,UAAU,QAAQ,KAAK,IAAI;AACpE;;;ACHO,SAAS,MAAS,KAA4B;AACnD,SAAO,OAAO,QAAQ,WAAW,KAAK,MAAM,GAAG,IAAK;AACtD;;;ACvFO,IAAM,aAAyB,SAAU,KAAK,QAAQ;AAC3D,QAAM,SAAS,MAAM,GAA8B;AAEnD,MAAI,EAAE,cAAc,SAAS;AAC3B,WAAO,IAAI,SAAS,QAA2D,MAAM;AAAA,EACvF;AAEA,QAAM,WAAiC,CAAC;AACxC,QAAM,UAAoB,CAAC;AAC3B,QAAM,iBAAoC,CAAC;AAC3C,QAAM,QAAkB,CAAC;AACzB,QAAM,aAAuB,CAAC;AAE9B;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,SAA2B;AAAA,IAC/B,SAAS;AAAA,IACT,MAAM,OAAO;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,oBAAoB,MAAM;AACnC;AAEA,SAAS,QACP,OACA,QACA,UACA,SACA,gBACA,OACA,YACA,YACA,cACA,UACA,YACA;AACA,QAAM,EAAE,SAAS,IAAI;AACrB,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAM,EAAE,KAAK,OAAO,IAAI,SAAS,CAAC;AAElC,QAAI,KAAK;AACT,QAAI,KAAK;AACT,QAAI,IAAI,IAAI,SAAS,QAAQ;AAC3B,YAAM,aAAa,SAAS,IAAI,CAAC,EAAE;AACnC,WAAK,KAAK,IAAI,UAAU,aAAa,WAAW,IAAI;AAEpD,UAAI,OAAO,UAAU;AACnB,aAAK,KAAK,IAAI,YAAY,eAAe,WAAW,MAAM;AAAA,MAC5D,WAAW,KAAK,UAAU;AACxB,aAAK,eAAe,WAAW;AAAA,MACjC;AAAA,IACF;AAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa,OAAO;AAAA,MACpB,eAAe,OAAO;AAAA,MACtB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,WACP,OACA,QACA,UACA,SACA,gBACA,OACA,YACA,YACA,cACA,UACA,YACA;AACA,QAAM,SAAS,MAAM,KAAK;AAC1B,MAAI,cAAc,OAAQ,QAAO,QAAQ,GAAI,SAAmD;AAEhG,QAAM,MAAM,IAAI,SAAS,QAAQ,MAAM;AACvC,QAAM,gBAAgB,QAAQ;AAC9B,QAAM,cAAc,MAAM;AAC1B,QAAM,UAAU,gBAAgB,GAAG;AACnC,QAAM,EAAE,iBAAiB,gBAAgB,UAAU,YAAY,QAAQ,IAAI;AAE3E,SAAO,SAAS,eAAe;AAC/B,SAAO,OAAO,IAAI,KAAK;AAEvB,MAAI,SAAU,QAAO,gBAAgB,QAAQ;AAAA,MACxC,UAAS,IAAI,GAAG,IAAI,gBAAgB,QAAQ,IAAK,gBAAe,KAAK,IAAI;AAE9E,MAAI,QAAS,UAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAAK,YAAW,KAAK,QAAQ,CAAC,IAAI,aAAa;AAEhG,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,QAAQ,aAAa;AAM3B,QAAI,QAAQ,SAAU;AAItB,UAAM,MAAM,QAAQ,UAAU,KAAK;AAGnC,UAAM,UAAU,MAAM,IAAI,eAAe;AAEzC,UAAM,OAAO,QAAQ,CAAC;AACtB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,MAAM,KAAK,CAAC;AAClB,YAAM,SAAS,UAAU,IAAI,MAAM;AAInC,UAAI,UAAU,YAAY,UAAU,WAAY;AAEhD,UAAI,IAAI,WAAW,GAAG;AACpB,YAAI,KAAK,CAAC,MAAM,CAAC;AACjB;AAAA,MACF;AAEA,YAAM,eAAe,gBAAgB,IAAI,aAAa;AACtD,YAAM,aAAa,IAAI,WAAW;AAClC,YAAM,eAAe,IAAI,aAAa;AACtC,UAAI;AAAA,QACF,IAAI,WAAW,IACX,CAAC,QAAQ,cAAc,YAAY,YAAY,IAC/C,CAAC,QAAQ,cAAc,YAAY,cAAc,cAAc,IAAI,WAAW,CAAC;AAAA,MACrF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,OAAU,KAAU,OAAY;AACvC,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,IAAK,KAAI,KAAK,MAAM,CAAC,CAAC;AAC1D;AAEA,SAAS,QAAW,KAAY,OAAoB;AAClD,WAAS,IAAI,IAAI,QAAQ,KAAK,OAAO,IAAK,KAAI,CAAC,IAAI,CAAC;AACpD,SAAO,IAAI,KAAK;AAClB;;;ARhHA,IAAM,gBAAgB;AACtB,IAAM,kBAAkB;AAEjB,IAAM,oBAAoB;AAC1B,IAAM,uBAAuB;AAI7B,IAAM,WAAN,MAAoC;AAAA,EAkBzC,YAAY,KAAyB,QAAwB;AAC3D,UAAM,WAAW,OAAO,QAAQ;AAChC,QAAI,CAAC,YAAa,IAAyC,aAAc,QAAO;AAEhF,UAAM,SAAS,MAAM,GAAwC;AAE7D,UAAM,EAAE,SAAS,MAAM,OAAO,YAAY,SAAS,eAAe,IAAI;AACtE,SAAK,UAAU;AACf,SAAK,OAAO;AACZ,SAAK,QAAQ,SAAS,CAAC;AACvB,SAAK,aAAa;AAClB,SAAK,UAAU;AACf,SAAK,iBAAiB;AACtB,SAAK,aAAa,OAAO,cAAe,OAAkB,uBAAuB;AAEjF,UAAM,UAAU,SAAS,QAAQ,UAAU;AAC3C,SAAK,kBAAkB,QAAQ,IAAI,OAAO;AAE1C,UAAM,EAAE,SAAS,IAAI;AACrB,QAAI,OAAO,aAAa,UAAU;AAChC,WAAK,WAAW;AAChB,WAAK,WAAW;AAAA,IAClB,WAAW,MAAM,QAAQ,QAAQ,GAAG;AAClC,WAAK,WAAW;AAChB,WAAK,WAAW,UAAU,UAAU,QAAQ;AAAA,IAC9C,WAAY,OAAyC,UAAU;AAC7D,YAAM,IAAI,MAAM,4EAA4E;AAAA,IAC9F,OAAO;AACL,YAAM,IAAI,MAAM,uBAAuB,KAAK,UAAU,MAAM,CAAC,EAAE;AAAA,IACjE;AAEA,SAAK,eAAe,cAAc;AAClC,SAAK,aAAa;AAClB,SAAK,iBAAiB;AAAA,EACxB;AACF;AAMA,SAAS,KAAK,KAAyB;AACrC,SAAO;AACT;AAKO,SAAS,gBAAgB,KAA6C;AAzJ7E;AA0JE,UAAQ,gBAAK,GAAG,GAAE,aAAV,eAAU,WAAa,OAAO,KAAK,GAAG,EAAE,QAAS;AAC3D;AAKO,SAAS,gBAAgB,KAAuD;AAhKvF;AAiKE,UAAQ,UAAK,GAAG,GAAE,aAAV,GAAU,WAAa,OAAO,KAAK,GAAG,EAAE,QAAS;AAC3D;AAMO,SAAS,aACd,KACA,MACA,QACmC;AACnC,QAAM,UAAU,gBAAgB,GAAG;AAInC,MAAI,QAAQ,QAAQ,OAAQ,QAAO;AAEnC,QAAM,WAAW,QAAQ,IAAI;AAC7B,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,KAAK,GAAG,EAAE;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,UAAU,KAAK,OAAO,SAAS,KAAK;AAC7C;AAOO,SAAS,oBACd,KACA,QAC0C;AAC1C,MAAI,EAAE,MAAM,QAAQ,KAAK,IAAI;AAC7B;AACA,MAAI,OAAO,EAAG,OAAM,IAAI,MAAM,aAAa;AAC3C,MAAI,SAAS,EAAG,OAAM,IAAI,MAAM,eAAe;AAE/C,QAAM,UAAU,gBAAgB,GAAG;AAInC,MAAI,QAAQ,QAAQ,OAAQ,QAAO,SAAS,MAAM,MAAM,MAAM,IAAI;AAElE,QAAM,WAAW,QAAQ,IAAI;AAC7B,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,KAAK,GAAG,EAAE;AAAA,IACV;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV;AAEA,MAAI,UAAU,GAAI,QAAO,SAAS,MAAM,MAAM,MAAM,IAAI;AAExD,QAAM,UAAU,SAAS,KAAK;AAC9B,MAAI,QAAQ,WAAW,EAAG,QAAO,SAAS,MAAM,MAAM,MAAM,IAAI;AAEhE,QAAM,EAAE,OAAO,gBAAgB,IAAI;AACnC,SAAO;AAAA,IACL,gBAAgB,QAAQ,aAAa,CAAC;AAAA,IACtC,QAAQ,WAAW,IAAI;AAAA,IACvB,QAAQ,aAAa;AAAA,IACrB,QAAQ,WAAW,IAAI,MAAM,QAAQ,WAAW,CAAC,IAAI;AAAA,EACvD;AACF;AAKO,SAAS,qBACd,KACA,QAC4C;AAC5C,QAAM,EAAE,QAAQ,MAAM,QAAQ,KAAK,IAAI;AACvC,SAAO,kBAAkB,KAAK,QAAQ,MAAM,QAAQ,QAAQ,sBAAsB,KAAK;AACzF;AAKO,SAAS,yBAAyB,KAAe,QAA0C;AAChG,QAAM,EAAE,QAAQ,MAAM,QAAQ,KAAK,IAAI;AAEvC,SAAO,kBAAkB,KAAK,QAAQ,MAAM,QAAQ,QAAQ,mBAAmB,IAAI;AACrF;AAKO,SAAS,YAAY,KAAe,IAA0C;AACnF,QAAM,UAAU,gBAAgB,GAAG;AACnC,QAAM,EAAE,OAAO,gBAAgB,IAAI;AAEnC,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,OAAO,QAAQ,CAAC;AACtB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,MAAM,KAAK,CAAC;AAElB,YAAM,gBAAgB,IAAI;AAC1B,YAAM,kBAAkB,IAAI,CAAC;AAC7B,UAAI,SAAS;AACb,UAAI,eAAe;AACnB,UAAI,iBAAiB;AACrB,UAAI,OAAO;AACX,UAAI,IAAI,WAAW,GAAG;AACpB,iBAAS,gBAAgB,IAAI,CAAC,CAAC;AAC/B,uBAAe,IAAI,CAAC,IAAI;AACxB,yBAAiB,IAAI,CAAC;AAAA,MACxB;AACA,UAAI,IAAI,WAAW,EAAG,QAAO,MAAM,IAAI,CAAC,CAAC;AAEzC,SAAG;AAAA,QACD;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAgB;AAAA,IAClB;AAAA,EACF;AACF;AAEA,SAAS,YAAY,KAAe,QAAwB;AAC1D,QAAM,EAAE,SAAS,gBAAgB,IAAI;AACrC,MAAI,QAAQ,QAAQ,QAAQ,MAAM;AAClC,MAAI,UAAU,GAAI,SAAQ,gBAAgB,QAAQ,MAAM;AACxD,SAAO;AACT;AAKO,SAAS,iBAAiB,KAAe,QAA+B;AAC7E,QAAM,EAAE,eAAe,IAAI;AAC3B,MAAI,kBAAkB,KAAM,QAAO;AACnC,QAAM,QAAQ,YAAY,KAAK,MAAM;AACrC,SAAO,UAAU,KAAK,OAAO,eAAe,KAAK;AACnD;AAKO,SAAS,UAAU,KAAe,QAAyB;AAChE,QAAM,EAAE,WAAW,IAAI;AACvB,MAAI,cAAc,KAAM,QAAO;AAC/B,QAAM,QAAQ,YAAY,KAAK,MAAM;AACrC,SAAO,UAAU,KAAK,QAAQ,WAAW,SAAS,KAAK;AACzD;AAMO,SAAS,oBAAoB,KAAuB,QAA2B;AACpF,QAAM,SAAS,IAAI,SAAS,MAAM,KAAK,CAAC,CAAC,GAAG,MAAM;AAClD,OAAK,MAAM,EAAE,WAAW,IAAI;AAC5B,SAAO;AACT;AAMO,SAAS,WACd,KACkF;AAClF,SAAO,MAAM,KAAK,gBAAgB,GAAG,CAAC;AACxC;AAMO,SAAS,WAAW,KAAiC;AAC1D,SAAO,MAAM,KAAK,gBAAgB,GAAG,CAAC;AACxC;AAEA,SAAS,MACP,KACA,UACwD;AACxD,SAAO;AAAA,IACL,SAAS,IAAI;AAAA,IACb,MAAM,IAAI;AAAA,IACV,OAAO,IAAI;AAAA,IACX,YAAY,IAAI;AAAA,IAChB,SAAS,IAAI;AAAA,IACb,gBAAgB,IAAI;AAAA,IACpB;AAAA,IACA,YAAY,IAAI,cAAe,IAAe;AAAA,EAChD;AACF;AASA,SAAS,SACP,QACA,MACA,QACA,MAC0C;AAC1C,SAAO,EAAE,QAAQ,MAAM,QAAQ,KAAK;AACtC;AAIA,SAAS,SACP,MACA,QAC4C;AAC5C,SAAO,EAAE,MAAM,OAAO;AACxB;AAgBA,SAAS,qBACP,UACA,MACA,MACA,QACA,MACQ;AACR,MAAI,QAAQ,qBAAqB,UAAU,QAAQ,MAAM,IAAI;AAC7D,MAAI,OAAS;AACX,aAAS,SAAS,oBAAoB,aAAa,YAAY,UAAU,QAAQ,KAAK;AAAA,EACxF,WAAW,SAAS,kBAAmB;AAEvC,MAAI,UAAU,MAAM,UAAU,SAAS,OAAQ,QAAO;AACtD,SAAO;AACT;AAEA,SAAS,wBACP,UACA,MACA,MACA,QACA,MACoB;AACpB,MAAI,MAAM,qBAAqB,UAAU,MAAM,MAAM,QAAQ,oBAAoB;AAQjF,MAAI,CAAC,SAAW,SAAS,kBAAmB;AAE5C,MAAI,QAAQ,MAAM,QAAQ,SAAS,OAAQ,QAAO,CAAC;AAKnD,QAAM,gBAAgB,QAAU,SAAS,SAAS,GAAG,EAAE,MAAM;AAG7D,MAAI,CAAC,MAAS,OAAM,WAAW,UAAU,eAAe,GAAG;AAC3D,QAAM,MAAM,WAAW,UAAU,eAAe,GAAG;AAEnD,QAAM,SAAS,CAAC;AAChB,SAAO,OAAO,KAAK,OAAO;AACxB,UAAM,UAAU,SAAS,GAAG;AAC5B,WAAO,KAAK,SAAS,QAAQ,kBAAkB,IAAI,GAAG,QAAQ,oBAAoB,CAAC,CAAC;AAAA,EACtF;AACA,SAAO;AACT;AAkBA,SAAS,kBACP,KACA,QACA,MACA,QACA,MACA,KACiE;AA5dnE;AA6dE;AACA,MAAI,OAAO,EAAG,OAAM,IAAI,MAAM,aAAa;AAC3C,MAAI,SAAS,EAAG,OAAM,IAAI,MAAM,eAAe;AAE/C,QAAM,EAAE,SAAS,gBAAgB,IAAI;AACrC,MAAIC,eAAc,QAAQ,QAAQ,MAAM;AACxC,MAAIA,iBAAgB,GAAI,CAAAA,eAAc,gBAAgB,QAAQ,MAAM;AACpE,MAAIA,iBAAgB,GAAI,QAAO,MAAM,CAAC,IAAI,SAAS,MAAM,IAAI;AAE7D,QAAM,iBAAiB,UAAK,GAAG,GAAE,mBAAV,GAAU,iBAAmB,QAAQ,IAAI,aAAa;AAC7E,QAAM,aAAa,UAAK,GAAG,GAAE,eAAV,GAAU,aAAe,eAAe,gBAAgB,GAAG,GAAG,aAAa;AAE9F,QAAM,WAAW,UAAUA,YAAW,EAAE,IAAI;AAC5C,MAAI,YAAY,KAAM,QAAO,MAAM,CAAC,IAAI,SAAS,MAAM,IAAI;AAE3D,QAAM,OAAO,cAAcA,YAAW;AAEtC,MAAI,IAAK,QAAO,wBAAwB,UAAU,MAAM,MAAM,QAAQ,IAAI;AAE1E,QAAM,QAAQ,qBAAqB,UAAU,MAAM,MAAM,QAAQ,IAAI;AACrE,MAAI,UAAU,GAAI,QAAO,SAAS,MAAM,IAAI;AAE5C,QAAM,UAAU,SAAS,KAAK;AAC9B,SAAO,SAAS,QAAQ,kBAAkB,IAAI,GAAG,QAAQ,oBAAoB,CAAC;AAChF;", + "names": ["sourceIndex", "sourceIndex"] +} diff --git a/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js b/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js new file mode 100644 index 0000000..0387ae3 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js @@ -0,0 +1,559 @@ +(function (global, factory) { + if (typeof exports === 'object' && typeof module !== 'undefined') { + factory(module, require('@jridgewell/resolve-uri'), require('@jridgewell/sourcemap-codec')); + module.exports = def(module); + } else if (typeof define === 'function' && define.amd) { + define(['module', '@jridgewell/resolve-uri', '@jridgewell/sourcemap-codec'], function(mod) { + factory.apply(this, arguments); + mod.exports = def(mod); + }); + } else { + const mod = { exports: {} }; + factory(mod, global.resolveURI, global.sourcemapCodec); + global = typeof globalThis !== 'undefined' ? globalThis : global || self; + global.traceMapping = def(mod); + } + function def(m) { return 'default' in m.exports ? m.exports.default : m.exports; } +})(this, (function (module, require_resolveURI, require_sourcemapCodec) { +"use strict"; +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// umd:@jridgewell/sourcemap-codec +var require_sourcemap_codec = __commonJS({ + "umd:@jridgewell/sourcemap-codec"(exports, module2) { + module2.exports = require_sourcemapCodec; + } +}); + +// umd:@jridgewell/resolve-uri +var require_resolve_uri = __commonJS({ + "umd:@jridgewell/resolve-uri"(exports, module2) { + module2.exports = require_resolveURI; + } +}); + +// src/trace-mapping.ts +var trace_mapping_exports = {}; +__export(trace_mapping_exports, { + AnyMap: () => FlattenMap, + FlattenMap: () => FlattenMap, + GREATEST_LOWER_BOUND: () => GREATEST_LOWER_BOUND, + LEAST_UPPER_BOUND: () => LEAST_UPPER_BOUND, + TraceMap: () => TraceMap, + allGeneratedPositionsFor: () => allGeneratedPositionsFor, + decodedMap: () => decodedMap, + decodedMappings: () => decodedMappings, + eachMapping: () => eachMapping, + encodedMap: () => encodedMap, + encodedMappings: () => encodedMappings, + generatedPositionFor: () => generatedPositionFor, + isIgnored: () => isIgnored, + originalPositionFor: () => originalPositionFor, + presortedDecodedMap: () => presortedDecodedMap, + sourceContentFor: () => sourceContentFor, + traceSegment: () => traceSegment +}); +module.exports = __toCommonJS(trace_mapping_exports); +var import_sourcemap_codec = __toESM(require_sourcemap_codec()); + +// src/resolve.ts +var import_resolve_uri = __toESM(require_resolve_uri()); + +// src/strip-filename.ts +function stripFilename(path) { + if (!path) return ""; + const index = path.lastIndexOf("/"); + return path.slice(0, index + 1); +} + +// src/resolve.ts +function resolver(mapUrl, sourceRoot) { + const from = stripFilename(mapUrl); + const prefix = sourceRoot ? sourceRoot + "/" : ""; + return (source) => (0, import_resolve_uri.default)(prefix + (source || ""), from); +} + +// src/sourcemap-segment.ts +var COLUMN = 0; +var SOURCES_INDEX = 1; +var SOURCE_LINE = 2; +var SOURCE_COLUMN = 3; +var NAMES_INDEX = 4; +var REV_GENERATED_LINE = 1; +var REV_GENERATED_COLUMN = 2; + +// src/sort.ts +function maybeSort(mappings, owned) { + const unsortedIndex = nextUnsortedSegmentLine(mappings, 0); + if (unsortedIndex === mappings.length) return mappings; + if (!owned) mappings = mappings.slice(); + for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) { + mappings[i] = sortSegments(mappings[i], owned); + } + return mappings; +} +function nextUnsortedSegmentLine(mappings, start) { + for (let i = start; i < mappings.length; i++) { + if (!isSorted(mappings[i])) return i; + } + return mappings.length; +} +function isSorted(line) { + for (let j = 1; j < line.length; j++) { + if (line[j][COLUMN] < line[j - 1][COLUMN]) { + return false; + } + } + return true; +} +function sortSegments(line, owned) { + if (!owned) line = line.slice(); + return line.sort(sortComparator); +} +function sortComparator(a, b) { + return a[COLUMN] - b[COLUMN]; +} + +// src/by-source.ts +function buildBySources(decoded, memos) { + const sources = memos.map(() => []); + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + for (let j = 0; j < line.length; j++) { + const seg = line[j]; + if (seg.length === 1) continue; + const sourceIndex2 = seg[SOURCES_INDEX]; + const sourceLine = seg[SOURCE_LINE]; + const sourceColumn = seg[SOURCE_COLUMN]; + const source = sources[sourceIndex2]; + const segs = source[sourceLine] || (source[sourceLine] = []); + segs.push([sourceColumn, i, seg[COLUMN]]); + } + } + for (let i = 0; i < sources.length; i++) { + const source = sources[i]; + for (let j = 0; j < source.length; j++) { + const line = source[j]; + if (line) line.sort(sortComparator); + } + } + return sources; +} + +// src/binary-search.ts +var found = false; +function binarySearch(haystack, needle, low, high) { + while (low <= high) { + const mid = low + (high - low >> 1); + const cmp = haystack[mid][COLUMN] - needle; + if (cmp === 0) { + found = true; + return mid; + } + if (cmp < 0) { + low = mid + 1; + } else { + high = mid - 1; + } + } + found = false; + return low - 1; +} +function upperBound(haystack, needle, index) { + for (let i = index + 1; i < haystack.length; index = i++) { + if (haystack[i][COLUMN] !== needle) break; + } + return index; +} +function lowerBound(haystack, needle, index) { + for (let i = index - 1; i >= 0; index = i--) { + if (haystack[i][COLUMN] !== needle) break; + } + return index; +} +function memoizedState() { + return { + lastKey: -1, + lastNeedle: -1, + lastIndex: -1 + }; +} +function memoizedBinarySearch(haystack, needle, state, key) { + const { lastKey, lastNeedle, lastIndex } = state; + let low = 0; + let high = haystack.length - 1; + if (key === lastKey) { + if (needle === lastNeedle) { + found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle; + return lastIndex; + } + if (needle >= lastNeedle) { + low = lastIndex === -1 ? 0 : lastIndex; + } else { + high = lastIndex; + } + } + state.lastKey = key; + state.lastNeedle = needle; + return state.lastIndex = binarySearch(haystack, needle, low, high); +} + +// src/types.ts +function parse(map) { + return typeof map === "string" ? JSON.parse(map) : map; +} + +// src/flatten-map.ts +var FlattenMap = function(map, mapUrl) { + const parsed = parse(map); + if (!("sections" in parsed)) { + return new TraceMap(parsed, mapUrl); + } + const mappings = []; + const sources = []; + const sourcesContent = []; + const names = []; + const ignoreList = []; + recurse( + parsed, + mapUrl, + mappings, + sources, + sourcesContent, + names, + ignoreList, + 0, + 0, + Infinity, + Infinity + ); + const joined = { + version: 3, + file: parsed.file, + names, + sources, + sourcesContent, + mappings, + ignoreList + }; + return presortedDecodedMap(joined); +}; +function recurse(input, mapUrl, mappings, sources, sourcesContent, names, ignoreList, lineOffset, columnOffset, stopLine, stopColumn) { + const { sections } = input; + for (let i = 0; i < sections.length; i++) { + const { map, offset } = sections[i]; + let sl = stopLine; + let sc = stopColumn; + if (i + 1 < sections.length) { + const nextOffset = sections[i + 1].offset; + sl = Math.min(stopLine, lineOffset + nextOffset.line); + if (sl === stopLine) { + sc = Math.min(stopColumn, columnOffset + nextOffset.column); + } else if (sl < stopLine) { + sc = columnOffset + nextOffset.column; + } + } + addSection( + map, + mapUrl, + mappings, + sources, + sourcesContent, + names, + ignoreList, + lineOffset + offset.line, + columnOffset + offset.column, + sl, + sc + ); + } +} +function addSection(input, mapUrl, mappings, sources, sourcesContent, names, ignoreList, lineOffset, columnOffset, stopLine, stopColumn) { + const parsed = parse(input); + if ("sections" in parsed) return recurse(...arguments); + const map = new TraceMap(parsed, mapUrl); + const sourcesOffset = sources.length; + const namesOffset = names.length; + const decoded = decodedMappings(map); + const { resolvedSources, sourcesContent: contents, ignoreList: ignores } = map; + append(sources, resolvedSources); + append(names, map.names); + if (contents) append(sourcesContent, contents); + else for (let i = 0; i < resolvedSources.length; i++) sourcesContent.push(null); + if (ignores) for (let i = 0; i < ignores.length; i++) ignoreList.push(ignores[i] + sourcesOffset); + for (let i = 0; i < decoded.length; i++) { + const lineI = lineOffset + i; + if (lineI > stopLine) return; + const out = getLine(mappings, lineI); + const cOffset = i === 0 ? columnOffset : 0; + const line = decoded[i]; + for (let j = 0; j < line.length; j++) { + const seg = line[j]; + const column = cOffset + seg[COLUMN]; + if (lineI === stopLine && column >= stopColumn) return; + if (seg.length === 1) { + out.push([column]); + continue; + } + const sourcesIndex = sourcesOffset + seg[SOURCES_INDEX]; + const sourceLine = seg[SOURCE_LINE]; + const sourceColumn = seg[SOURCE_COLUMN]; + out.push( + seg.length === 4 ? [column, sourcesIndex, sourceLine, sourceColumn] : [column, sourcesIndex, sourceLine, sourceColumn, namesOffset + seg[NAMES_INDEX]] + ); + } + } +} +function append(arr, other) { + for (let i = 0; i < other.length; i++) arr.push(other[i]); +} +function getLine(arr, index) { + for (let i = arr.length; i <= index; i++) arr[i] = []; + return arr[index]; +} + +// src/trace-mapping.ts +var LINE_GTR_ZERO = "`line` must be greater than 0 (lines start at line 1)"; +var COL_GTR_EQ_ZERO = "`column` must be greater than or equal to 0 (columns start at column 0)"; +var LEAST_UPPER_BOUND = -1; +var GREATEST_LOWER_BOUND = 1; +var TraceMap = class { + constructor(map, mapUrl) { + const isString = typeof map === "string"; + if (!isString && map._decodedMemo) return map; + const parsed = parse(map); + const { version, file, names, sourceRoot, sources, sourcesContent } = parsed; + this.version = version; + this.file = file; + this.names = names || []; + this.sourceRoot = sourceRoot; + this.sources = sources; + this.sourcesContent = sourcesContent; + this.ignoreList = parsed.ignoreList || parsed.x_google_ignoreList || void 0; + const resolve = resolver(mapUrl, sourceRoot); + this.resolvedSources = sources.map(resolve); + const { mappings } = parsed; + if (typeof mappings === "string") { + this._encoded = mappings; + this._decoded = void 0; + } else if (Array.isArray(mappings)) { + this._encoded = void 0; + this._decoded = maybeSort(mappings, isString); + } else if (parsed.sections) { + throw new Error(`TraceMap passed sectioned source map, please use FlattenMap export instead`); + } else { + throw new Error(`invalid source map: ${JSON.stringify(parsed)}`); + } + this._decodedMemo = memoizedState(); + this._bySources = void 0; + this._bySourceMemos = void 0; + } +}; +function cast(map) { + return map; +} +function encodedMappings(map) { + var _a, _b; + return (_b = (_a = cast(map))._encoded) != null ? _b : _a._encoded = (0, import_sourcemap_codec.encode)(cast(map)._decoded); +} +function decodedMappings(map) { + var _a; + return (_a = cast(map))._decoded || (_a._decoded = (0, import_sourcemap_codec.decode)(cast(map)._encoded)); +} +function traceSegment(map, line, column) { + const decoded = decodedMappings(map); + if (line >= decoded.length) return null; + const segments = decoded[line]; + const index = traceSegmentInternal( + segments, + cast(map)._decodedMemo, + line, + column, + GREATEST_LOWER_BOUND + ); + return index === -1 ? null : segments[index]; +} +function originalPositionFor(map, needle) { + let { line, column, bias } = needle; + line--; + if (line < 0) throw new Error(LINE_GTR_ZERO); + if (column < 0) throw new Error(COL_GTR_EQ_ZERO); + const decoded = decodedMappings(map); + if (line >= decoded.length) return OMapping(null, null, null, null); + const segments = decoded[line]; + const index = traceSegmentInternal( + segments, + cast(map)._decodedMemo, + line, + column, + bias || GREATEST_LOWER_BOUND + ); + if (index === -1) return OMapping(null, null, null, null); + const segment = segments[index]; + if (segment.length === 1) return OMapping(null, null, null, null); + const { names, resolvedSources } = map; + return OMapping( + resolvedSources[segment[SOURCES_INDEX]], + segment[SOURCE_LINE] + 1, + segment[SOURCE_COLUMN], + segment.length === 5 ? names[segment[NAMES_INDEX]] : null + ); +} +function generatedPositionFor(map, needle) { + const { source, line, column, bias } = needle; + return generatedPosition(map, source, line, column, bias || GREATEST_LOWER_BOUND, false); +} +function allGeneratedPositionsFor(map, needle) { + const { source, line, column, bias } = needle; + return generatedPosition(map, source, line, column, bias || LEAST_UPPER_BOUND, true); +} +function eachMapping(map, cb) { + const decoded = decodedMappings(map); + const { names, resolvedSources } = map; + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + for (let j = 0; j < line.length; j++) { + const seg = line[j]; + const generatedLine = i + 1; + const generatedColumn = seg[0]; + let source = null; + let originalLine = null; + let originalColumn = null; + let name = null; + if (seg.length !== 1) { + source = resolvedSources[seg[1]]; + originalLine = seg[2] + 1; + originalColumn = seg[3]; + } + if (seg.length === 5) name = names[seg[4]]; + cb({ + generatedLine, + generatedColumn, + source, + originalLine, + originalColumn, + name + }); + } + } +} +function sourceIndex(map, source) { + const { sources, resolvedSources } = map; + let index = sources.indexOf(source); + if (index === -1) index = resolvedSources.indexOf(source); + return index; +} +function sourceContentFor(map, source) { + const { sourcesContent } = map; + if (sourcesContent == null) return null; + const index = sourceIndex(map, source); + return index === -1 ? null : sourcesContent[index]; +} +function isIgnored(map, source) { + const { ignoreList } = map; + if (ignoreList == null) return false; + const index = sourceIndex(map, source); + return index === -1 ? false : ignoreList.includes(index); +} +function presortedDecodedMap(map, mapUrl) { + const tracer = new TraceMap(clone(map, []), mapUrl); + cast(tracer)._decoded = map.mappings; + return tracer; +} +function decodedMap(map) { + return clone(map, decodedMappings(map)); +} +function encodedMap(map) { + return clone(map, encodedMappings(map)); +} +function clone(map, mappings) { + return { + version: map.version, + file: map.file, + names: map.names, + sourceRoot: map.sourceRoot, + sources: map.sources, + sourcesContent: map.sourcesContent, + mappings, + ignoreList: map.ignoreList || map.x_google_ignoreList + }; +} +function OMapping(source, line, column, name) { + return { source, line, column, name }; +} +function GMapping(line, column) { + return { line, column }; +} +function traceSegmentInternal(segments, memo, line, column, bias) { + let index = memoizedBinarySearch(segments, column, memo, line); + if (found) { + index = (bias === LEAST_UPPER_BOUND ? upperBound : lowerBound)(segments, column, index); + } else if (bias === LEAST_UPPER_BOUND) index++; + if (index === -1 || index === segments.length) return -1; + return index; +} +function sliceGeneratedPositions(segments, memo, line, column, bias) { + let min = traceSegmentInternal(segments, memo, line, column, GREATEST_LOWER_BOUND); + if (!found && bias === LEAST_UPPER_BOUND) min++; + if (min === -1 || min === segments.length) return []; + const matchedColumn = found ? column : segments[min][COLUMN]; + if (!found) min = lowerBound(segments, matchedColumn, min); + const max = upperBound(segments, matchedColumn, min); + const result = []; + for (; min <= max; min++) { + const segment = segments[min]; + result.push(GMapping(segment[REV_GENERATED_LINE] + 1, segment[REV_GENERATED_COLUMN])); + } + return result; +} +function generatedPosition(map, source, line, column, bias, all) { + var _a, _b; + line--; + if (line < 0) throw new Error(LINE_GTR_ZERO); + if (column < 0) throw new Error(COL_GTR_EQ_ZERO); + const { sources, resolvedSources } = map; + let sourceIndex2 = sources.indexOf(source); + if (sourceIndex2 === -1) sourceIndex2 = resolvedSources.indexOf(source); + if (sourceIndex2 === -1) return all ? [] : GMapping(null, null); + const bySourceMemos = (_a = cast(map))._bySourceMemos || (_a._bySourceMemos = sources.map(memoizedState)); + const generated = (_b = cast(map))._bySources || (_b._bySources = buildBySources(decodedMappings(map), bySourceMemos)); + const segments = generated[sourceIndex2][line]; + if (segments == null) return all ? [] : GMapping(null, null); + const memo = bySourceMemos[sourceIndex2]; + if (all) return sliceGeneratedPositions(segments, memo, line, column, bias); + const index = traceSegmentInternal(segments, memo, line, column, bias); + if (index === -1) return GMapping(null, null); + const segment = segments[index]; + return GMapping(segment[REV_GENERATED_LINE] + 1, segment[REV_GENERATED_COLUMN]); +} +})); +//# sourceMappingURL=trace-mapping.umd.js.map diff --git a/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js.map b/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js.map new file mode 100644 index 0000000..68b0c77 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js.map @@ -0,0 +1,6 @@ +{ + "version": 3, + "sources": ["umd:@jridgewell/sourcemap-codec", "umd:@jridgewell/resolve-uri", "../src/trace-mapping.ts", "../src/resolve.ts", "../src/strip-filename.ts", "../src/sourcemap-segment.ts", "../src/sort.ts", "../src/by-source.ts", "../src/binary-search.ts", "../src/types.ts", "../src/flatten-map.ts"], + "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,6CAAAA,SAAA;AAAA,IAAAA,QAAO,UAAU;AAAA;AAAA;;;ACAjB;AAAA,yCAAAC,SAAA;AAAA,IAAAA,QAAO,UAAU;AAAA;AAAA;;;ACAjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,6BAA+B;;;ACA/B,yBAAuB;;;ACGR,SAAR,cAA+B,MAAyC;AAC7E,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,QAAQ,KAAK,YAAY,GAAG;AAClC,SAAO,KAAK,MAAM,GAAG,QAAQ,CAAC;AAChC;;;ADHe,SAAR,SACL,QACA,YACS;AACT,QAAM,OAAO,cAAc,MAAM;AAIjC,QAAM,SAAS,aAAa,aAAa,MAAM;AAE/C,SAAO,CAAC,eAAW,mBAAAC,SAAW,UAAU,UAAU,KAAK,IAAI;AAC7D;;;AEAO,IAAM,SAAS;AACf,IAAM,gBAAgB;AACtB,IAAM,cAAc;AACpB,IAAM,gBAAgB;AACtB,IAAM,cAAc;AAEpB,IAAM,qBAAqB;AAC3B,IAAM,uBAAuB;;;AClBrB,SAAR,UACL,UACA,OACsB;AACtB,QAAM,gBAAgB,wBAAwB,UAAU,CAAC;AACzD,MAAI,kBAAkB,SAAS,OAAQ,QAAO;AAI9C,MAAI,CAAC,MAAO,YAAW,SAAS,MAAM;AAEtC,WAAS,IAAI,eAAe,IAAI,SAAS,QAAQ,IAAI,wBAAwB,UAAU,IAAI,CAAC,GAAG;AAC7F,aAAS,CAAC,IAAI,aAAa,SAAS,CAAC,GAAG,KAAK;AAAA,EAC/C;AACA,SAAO;AACT;AAEA,SAAS,wBAAwB,UAAgC,OAAuB;AACtF,WAAS,IAAI,OAAO,IAAI,SAAS,QAAQ,KAAK;AAC5C,QAAI,CAAC,SAAS,SAAS,CAAC,CAAC,EAAG,QAAO;AAAA,EACrC;AACA,SAAO,SAAS;AAClB;AAEA,SAAS,SAAS,MAAmC;AACnD,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,KAAK,CAAC,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC,EAAE,MAAM,GAAG;AACzC,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,aAAa,MAA0B,OAAoC;AAClF,MAAI,CAAC,MAAO,QAAO,KAAK,MAAM;AAC9B,SAAO,KAAK,KAAK,cAAc;AACjC;AAEO,SAAS,eAA4D,GAAM,GAAc;AAC9F,SAAO,EAAE,MAAM,IAAI,EAAE,MAAM;AAC7B;;;ACnCe,SAAR,eACL,SACA,OACU;AACV,QAAM,UAAoB,MAAM,IAAI,MAAM,CAAC,CAAC;AAE5C,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,OAAO,QAAQ,CAAC;AACtB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,MAAM,KAAK,CAAC;AAClB,UAAI,IAAI,WAAW,EAAG;AAEtB,YAAMC,eAAc,IAAI,aAAa;AACrC,YAAM,aAAa,IAAI,WAAW;AAClC,YAAM,eAAe,IAAI,aAAa;AAEtC,YAAM,SAAS,QAAQA,YAAW;AAClC,YAAM,OAAQ,4CAAuB,CAAC;AACtC,WAAK,KAAK,CAAC,cAAc,GAAG,IAAI,MAAM,CAAC,CAAC;AAAA,IAC1C;AAAA,EACF;AAEA,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,SAAS,QAAQ,CAAC;AACxB,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,YAAM,OAAO,OAAO,CAAC;AACrB,UAAI,KAAM,MAAK,KAAK,cAAc;AAAA,IACpC;AAAA,EACF;AAEA,SAAO;AACT;;;AC/BO,IAAI,QAAQ;AAkBZ,SAAS,aACd,UACA,QACA,KACA,MACQ;AACR,SAAO,OAAO,MAAM;AAClB,UAAM,MAAM,OAAQ,OAAO,OAAQ;AACnC,UAAM,MAAM,SAAS,GAAG,EAAE,MAAM,IAAI;AAEpC,QAAI,QAAQ,GAAG;AACb,cAAQ;AACR,aAAO;AAAA,IACT;AAEA,QAAI,MAAM,GAAG;AACX,YAAM,MAAM;AAAA,IACd,OAAO;AACL,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AAEA,UAAQ;AACR,SAAO,MAAM;AACf;AAEO,SAAS,WACd,UACA,QACA,OACQ;AACR,WAAS,IAAI,QAAQ,GAAG,IAAI,SAAS,QAAQ,QAAQ,KAAK;AACxD,QAAI,SAAS,CAAC,EAAE,MAAM,MAAM,OAAQ;AAAA,EACtC;AACA,SAAO;AACT;AAEO,SAAS,WACd,UACA,QACA,OACQ;AACR,WAAS,IAAI,QAAQ,GAAG,KAAK,GAAG,QAAQ,KAAK;AAC3C,QAAI,SAAS,CAAC,EAAE,MAAM,MAAM,OAAQ;AAAA,EACtC;AACA,SAAO;AACT;AAEO,SAAS,gBAA2B;AACzC,SAAO;AAAA,IACL,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,WAAW;AAAA,EACb;AACF;AAMO,SAAS,qBACd,UACA,QACA,OACA,KACQ;AACR,QAAM,EAAE,SAAS,YAAY,UAAU,IAAI;AAE3C,MAAI,MAAM;AACV,MAAI,OAAO,SAAS,SAAS;AAC7B,MAAI,QAAQ,SAAS;AACnB,QAAI,WAAW,YAAY;AACzB,cAAQ,cAAc,MAAM,SAAS,SAAS,EAAE,MAAM,MAAM;AAC5D,aAAO;AAAA,IACT;AAEA,QAAI,UAAU,YAAY;AAExB,YAAM,cAAc,KAAK,IAAI;AAAA,IAC/B,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,UAAU;AAChB,QAAM,aAAa;AAEnB,SAAQ,MAAM,YAAY,aAAa,UAAU,QAAQ,KAAK,IAAI;AACpE;;;ACHO,SAAS,MAAS,KAA4B;AACnD,SAAO,OAAO,QAAQ,WAAW,KAAK,MAAM,GAAG,IAAK;AACtD;;;ACvFO,IAAM,aAAyB,SAAU,KAAK,QAAQ;AAC3D,QAAM,SAAS,MAAM,GAA8B;AAEnD,MAAI,EAAE,cAAc,SAAS;AAC3B,WAAO,IAAI,SAAS,QAA2D,MAAM;AAAA,EACvF;AAEA,QAAM,WAAiC,CAAC;AACxC,QAAM,UAAoB,CAAC;AAC3B,QAAM,iBAAoC,CAAC;AAC3C,QAAM,QAAkB,CAAC;AACzB,QAAM,aAAuB,CAAC;AAE9B;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,SAA2B;AAAA,IAC/B,SAAS;AAAA,IACT,MAAM,OAAO;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,oBAAoB,MAAM;AACnC;AAEA,SAAS,QACP,OACA,QACA,UACA,SACA,gBACA,OACA,YACA,YACA,cACA,UACA,YACA;AACA,QAAM,EAAE,SAAS,IAAI;AACrB,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAM,EAAE,KAAK,OAAO,IAAI,SAAS,CAAC;AAElC,QAAI,KAAK;AACT,QAAI,KAAK;AACT,QAAI,IAAI,IAAI,SAAS,QAAQ;AAC3B,YAAM,aAAa,SAAS,IAAI,CAAC,EAAE;AACnC,WAAK,KAAK,IAAI,UAAU,aAAa,WAAW,IAAI;AAEpD,UAAI,OAAO,UAAU;AACnB,aAAK,KAAK,IAAI,YAAY,eAAe,WAAW,MAAM;AAAA,MAC5D,WAAW,KAAK,UAAU;AACxB,aAAK,eAAe,WAAW;AAAA,MACjC;AAAA,IACF;AAEA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa,OAAO;AAAA,MACpB,eAAe,OAAO;AAAA,MACtB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,WACP,OACA,QACA,UACA,SACA,gBACA,OACA,YACA,YACA,cACA,UACA,YACA;AACA,QAAM,SAAS,MAAM,KAAK;AAC1B,MAAI,cAAc,OAAQ,QAAO,QAAQ,GAAI,SAAmD;AAEhG,QAAM,MAAM,IAAI,SAAS,QAAQ,MAAM;AACvC,QAAM,gBAAgB,QAAQ;AAC9B,QAAM,cAAc,MAAM;AAC1B,QAAM,UAAU,gBAAgB,GAAG;AACnC,QAAM,EAAE,iBAAiB,gBAAgB,UAAU,YAAY,QAAQ,IAAI;AAE3E,SAAO,SAAS,eAAe;AAC/B,SAAO,OAAO,IAAI,KAAK;AAEvB,MAAI,SAAU,QAAO,gBAAgB,QAAQ;AAAA,MACxC,UAAS,IAAI,GAAG,IAAI,gBAAgB,QAAQ,IAAK,gBAAe,KAAK,IAAI;AAE9E,MAAI,QAAS,UAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAAK,YAAW,KAAK,QAAQ,CAAC,IAAI,aAAa;AAEhG,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,QAAQ,aAAa;AAM3B,QAAI,QAAQ,SAAU;AAItB,UAAM,MAAM,QAAQ,UAAU,KAAK;AAGnC,UAAM,UAAU,MAAM,IAAI,eAAe;AAEzC,UAAM,OAAO,QAAQ,CAAC;AACtB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,MAAM,KAAK,CAAC;AAClB,YAAM,SAAS,UAAU,IAAI,MAAM;AAInC,UAAI,UAAU,YAAY,UAAU,WAAY;AAEhD,UAAI,IAAI,WAAW,GAAG;AACpB,YAAI,KAAK,CAAC,MAAM,CAAC;AACjB;AAAA,MACF;AAEA,YAAM,eAAe,gBAAgB,IAAI,aAAa;AACtD,YAAM,aAAa,IAAI,WAAW;AAClC,YAAM,eAAe,IAAI,aAAa;AACtC,UAAI;AAAA,QACF,IAAI,WAAW,IACX,CAAC,QAAQ,cAAc,YAAY,YAAY,IAC/C,CAAC,QAAQ,cAAc,YAAY,cAAc,cAAc,IAAI,WAAW,CAAC;AAAA,MACrF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,OAAU,KAAU,OAAY;AACvC,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,IAAK,KAAI,KAAK,MAAM,CAAC,CAAC;AAC1D;AAEA,SAAS,QAAW,KAAY,OAAoB;AAClD,WAAS,IAAI,IAAI,QAAQ,KAAK,OAAO,IAAK,KAAI,CAAC,IAAI,CAAC;AACpD,SAAO,IAAI,KAAK;AAClB;;;ARhHA,IAAM,gBAAgB;AACtB,IAAM,kBAAkB;AAEjB,IAAM,oBAAoB;AAC1B,IAAM,uBAAuB;AAI7B,IAAM,WAAN,MAAoC;AAAA,EAkBzC,YAAY,KAAyB,QAAwB;AAC3D,UAAM,WAAW,OAAO,QAAQ;AAChC,QAAI,CAAC,YAAa,IAAyC,aAAc,QAAO;AAEhF,UAAM,SAAS,MAAM,GAAwC;AAE7D,UAAM,EAAE,SAAS,MAAM,OAAO,YAAY,SAAS,eAAe,IAAI;AACtE,SAAK,UAAU;AACf,SAAK,OAAO;AACZ,SAAK,QAAQ,SAAS,CAAC;AACvB,SAAK,aAAa;AAClB,SAAK,UAAU;AACf,SAAK,iBAAiB;AACtB,SAAK,aAAa,OAAO,cAAe,OAAkB,uBAAuB;AAEjF,UAAM,UAAU,SAAS,QAAQ,UAAU;AAC3C,SAAK,kBAAkB,QAAQ,IAAI,OAAO;AAE1C,UAAM,EAAE,SAAS,IAAI;AACrB,QAAI,OAAO,aAAa,UAAU;AAChC,WAAK,WAAW;AAChB,WAAK,WAAW;AAAA,IAClB,WAAW,MAAM,QAAQ,QAAQ,GAAG;AAClC,WAAK,WAAW;AAChB,WAAK,WAAW,UAAU,UAAU,QAAQ;AAAA,IAC9C,WAAY,OAAyC,UAAU;AAC7D,YAAM,IAAI,MAAM,4EAA4E;AAAA,IAC9F,OAAO;AACL,YAAM,IAAI,MAAM,uBAAuB,KAAK,UAAU,MAAM,CAAC,EAAE;AAAA,IACjE;AAEA,SAAK,eAAe,cAAc;AAClC,SAAK,aAAa;AAClB,SAAK,iBAAiB;AAAA,EACxB;AACF;AAMA,SAAS,KAAK,KAAyB;AACrC,SAAO;AACT;AAKO,SAAS,gBAAgB,KAA6C;AAzJ7E;AA0JE,UAAQ,gBAAK,GAAG,GAAE,aAAV,eAAU,eAAa,+BAAO,KAAK,GAAG,EAAE,QAAS;AAC3D;AAKO,SAAS,gBAAgB,KAAuD;AAhKvF;AAiKE,UAAQ,UAAK,GAAG,GAAE,aAAV,GAAU,eAAa,+BAAO,KAAK,GAAG,EAAE,QAAS;AAC3D;AAMO,SAAS,aACd,KACA,MACA,QACmC;AACnC,QAAM,UAAU,gBAAgB,GAAG;AAInC,MAAI,QAAQ,QAAQ,OAAQ,QAAO;AAEnC,QAAM,WAAW,QAAQ,IAAI;AAC7B,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,KAAK,GAAG,EAAE;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,UAAU,KAAK,OAAO,SAAS,KAAK;AAC7C;AAOO,SAAS,oBACd,KACA,QAC0C;AAC1C,MAAI,EAAE,MAAM,QAAQ,KAAK,IAAI;AAC7B;AACA,MAAI,OAAO,EAAG,OAAM,IAAI,MAAM,aAAa;AAC3C,MAAI,SAAS,EAAG,OAAM,IAAI,MAAM,eAAe;AAE/C,QAAM,UAAU,gBAAgB,GAAG;AAInC,MAAI,QAAQ,QAAQ,OAAQ,QAAO,SAAS,MAAM,MAAM,MAAM,IAAI;AAElE,QAAM,WAAW,QAAQ,IAAI;AAC7B,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,KAAK,GAAG,EAAE;AAAA,IACV;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV;AAEA,MAAI,UAAU,GAAI,QAAO,SAAS,MAAM,MAAM,MAAM,IAAI;AAExD,QAAM,UAAU,SAAS,KAAK;AAC9B,MAAI,QAAQ,WAAW,EAAG,QAAO,SAAS,MAAM,MAAM,MAAM,IAAI;AAEhE,QAAM,EAAE,OAAO,gBAAgB,IAAI;AACnC,SAAO;AAAA,IACL,gBAAgB,QAAQ,aAAa,CAAC;AAAA,IACtC,QAAQ,WAAW,IAAI;AAAA,IACvB,QAAQ,aAAa;AAAA,IACrB,QAAQ,WAAW,IAAI,MAAM,QAAQ,WAAW,CAAC,IAAI;AAAA,EACvD;AACF;AAKO,SAAS,qBACd,KACA,QAC4C;AAC5C,QAAM,EAAE,QAAQ,MAAM,QAAQ,KAAK,IAAI;AACvC,SAAO,kBAAkB,KAAK,QAAQ,MAAM,QAAQ,QAAQ,sBAAsB,KAAK;AACzF;AAKO,SAAS,yBAAyB,KAAe,QAA0C;AAChG,QAAM,EAAE,QAAQ,MAAM,QAAQ,KAAK,IAAI;AAEvC,SAAO,kBAAkB,KAAK,QAAQ,MAAM,QAAQ,QAAQ,mBAAmB,IAAI;AACrF;AAKO,SAAS,YAAY,KAAe,IAA0C;AACnF,QAAM,UAAU,gBAAgB,GAAG;AACnC,QAAM,EAAE,OAAO,gBAAgB,IAAI;AAEnC,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,OAAO,QAAQ,CAAC;AACtB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,MAAM,KAAK,CAAC;AAElB,YAAM,gBAAgB,IAAI;AAC1B,YAAM,kBAAkB,IAAI,CAAC;AAC7B,UAAI,SAAS;AACb,UAAI,eAAe;AACnB,UAAI,iBAAiB;AACrB,UAAI,OAAO;AACX,UAAI,IAAI,WAAW,GAAG;AACpB,iBAAS,gBAAgB,IAAI,CAAC,CAAC;AAC/B,uBAAe,IAAI,CAAC,IAAI;AACxB,yBAAiB,IAAI,CAAC;AAAA,MACxB;AACA,UAAI,IAAI,WAAW,EAAG,QAAO,MAAM,IAAI,CAAC,CAAC;AAEzC,SAAG;AAAA,QACD;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAgB;AAAA,IAClB;AAAA,EACF;AACF;AAEA,SAAS,YAAY,KAAe,QAAwB;AAC1D,QAAM,EAAE,SAAS,gBAAgB,IAAI;AACrC,MAAI,QAAQ,QAAQ,QAAQ,MAAM;AAClC,MAAI,UAAU,GAAI,SAAQ,gBAAgB,QAAQ,MAAM;AACxD,SAAO;AACT;AAKO,SAAS,iBAAiB,KAAe,QAA+B;AAC7E,QAAM,EAAE,eAAe,IAAI;AAC3B,MAAI,kBAAkB,KAAM,QAAO;AACnC,QAAM,QAAQ,YAAY,KAAK,MAAM;AACrC,SAAO,UAAU,KAAK,OAAO,eAAe,KAAK;AACnD;AAKO,SAAS,UAAU,KAAe,QAAyB;AAChE,QAAM,EAAE,WAAW,IAAI;AACvB,MAAI,cAAc,KAAM,QAAO;AAC/B,QAAM,QAAQ,YAAY,KAAK,MAAM;AACrC,SAAO,UAAU,KAAK,QAAQ,WAAW,SAAS,KAAK;AACzD;AAMO,SAAS,oBAAoB,KAAuB,QAA2B;AACpF,QAAM,SAAS,IAAI,SAAS,MAAM,KAAK,CAAC,CAAC,GAAG,MAAM;AAClD,OAAK,MAAM,EAAE,WAAW,IAAI;AAC5B,SAAO;AACT;AAMO,SAAS,WACd,KACkF;AAClF,SAAO,MAAM,KAAK,gBAAgB,GAAG,CAAC;AACxC;AAMO,SAAS,WAAW,KAAiC;AAC1D,SAAO,MAAM,KAAK,gBAAgB,GAAG,CAAC;AACxC;AAEA,SAAS,MACP,KACA,UACwD;AACxD,SAAO;AAAA,IACL,SAAS,IAAI;AAAA,IACb,MAAM,IAAI;AAAA,IACV,OAAO,IAAI;AAAA,IACX,YAAY,IAAI;AAAA,IAChB,SAAS,IAAI;AAAA,IACb,gBAAgB,IAAI;AAAA,IACpB;AAAA,IACA,YAAY,IAAI,cAAe,IAAe;AAAA,EAChD;AACF;AASA,SAAS,SACP,QACA,MACA,QACA,MAC0C;AAC1C,SAAO,EAAE,QAAQ,MAAM,QAAQ,KAAK;AACtC;AAIA,SAAS,SACP,MACA,QAC4C;AAC5C,SAAO,EAAE,MAAM,OAAO;AACxB;AAgBA,SAAS,qBACP,UACA,MACA,MACA,QACA,MACQ;AACR,MAAI,QAAQ,qBAAqB,UAAU,QAAQ,MAAM,IAAI;AAC7D,MAAI,OAAS;AACX,aAAS,SAAS,oBAAoB,aAAa,YAAY,UAAU,QAAQ,KAAK;AAAA,EACxF,WAAW,SAAS,kBAAmB;AAEvC,MAAI,UAAU,MAAM,UAAU,SAAS,OAAQ,QAAO;AACtD,SAAO;AACT;AAEA,SAAS,wBACP,UACA,MACA,MACA,QACA,MACoB;AACpB,MAAI,MAAM,qBAAqB,UAAU,MAAM,MAAM,QAAQ,oBAAoB;AAQjF,MAAI,CAAC,SAAW,SAAS,kBAAmB;AAE5C,MAAI,QAAQ,MAAM,QAAQ,SAAS,OAAQ,QAAO,CAAC;AAKnD,QAAM,gBAAgB,QAAU,SAAS,SAAS,GAAG,EAAE,MAAM;AAG7D,MAAI,CAAC,MAAS,OAAM,WAAW,UAAU,eAAe,GAAG;AAC3D,QAAM,MAAM,WAAW,UAAU,eAAe,GAAG;AAEnD,QAAM,SAAS,CAAC;AAChB,SAAO,OAAO,KAAK,OAAO;AACxB,UAAM,UAAU,SAAS,GAAG;AAC5B,WAAO,KAAK,SAAS,QAAQ,kBAAkB,IAAI,GAAG,QAAQ,oBAAoB,CAAC,CAAC;AAAA,EACtF;AACA,SAAO;AACT;AAkBA,SAAS,kBACP,KACA,QACA,MACA,QACA,MACA,KACiE;AA5dnE;AA6dE;AACA,MAAI,OAAO,EAAG,OAAM,IAAI,MAAM,aAAa;AAC3C,MAAI,SAAS,EAAG,OAAM,IAAI,MAAM,eAAe;AAE/C,QAAM,EAAE,SAAS,gBAAgB,IAAI;AACrC,MAAIC,eAAc,QAAQ,QAAQ,MAAM;AACxC,MAAIA,iBAAgB,GAAI,CAAAA,eAAc,gBAAgB,QAAQ,MAAM;AACpE,MAAIA,iBAAgB,GAAI,QAAO,MAAM,CAAC,IAAI,SAAS,MAAM,IAAI;AAE7D,QAAM,iBAAiB,UAAK,GAAG,GAAE,mBAAV,GAAU,iBAAmB,QAAQ,IAAI,aAAa;AAC7E,QAAM,aAAa,UAAK,GAAG,GAAE,eAAV,GAAU,aAAe,eAAe,gBAAgB,GAAG,GAAG,aAAa;AAE9F,QAAM,WAAW,UAAUA,YAAW,EAAE,IAAI;AAC5C,MAAI,YAAY,KAAM,QAAO,MAAM,CAAC,IAAI,SAAS,MAAM,IAAI;AAE3D,QAAM,OAAO,cAAcA,YAAW;AAEtC,MAAI,IAAK,QAAO,wBAAwB,UAAU,MAAM,MAAM,QAAQ,IAAI;AAE1E,QAAM,QAAQ,qBAAqB,UAAU,MAAM,MAAM,QAAQ,IAAI;AACrE,MAAI,UAAU,GAAI,QAAO,SAAS,MAAM,IAAI;AAE5C,QAAM,UAAU,SAAS,KAAK;AAC9B,SAAO,SAAS,QAAQ,kBAAkB,IAAI,GAAG,QAAQ,oBAAoB,CAAC;AAChF;", + "names": ["module", "module", "resolveUri", "sourceIndex", "sourceIndex"] +} diff --git a/node_modules/@jridgewell/trace-mapping/package.json b/node_modules/@jridgewell/trace-mapping/package.json new file mode 100644 index 0000000..9d3a1c0 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/package.json @@ -0,0 +1,67 @@ +{ + "name": "@jridgewell/trace-mapping", + "version": "0.3.31", + "description": "Trace the original position through a source map", + "keywords": [ + "source", + "map" + ], + "main": "dist/trace-mapping.umd.js", + "module": "dist/trace-mapping.mjs", + "types": "types/trace-mapping.d.cts", + "files": [ + "dist", + "src", + "types" + ], + "exports": { + ".": [ + { + "import": { + "types": "./types/trace-mapping.d.mts", + "default": "./dist/trace-mapping.mjs" + }, + "default": { + "types": "./types/trace-mapping.d.cts", + "default": "./dist/trace-mapping.umd.js" + } + }, + "./dist/trace-mapping.umd.js" + ], + "./package.json": "./package.json" + }, + "scripts": { + "benchmark": "run-s build:code benchmark:*", + "benchmark:install": "cd benchmark && npm install", + "benchmark:only": "node --expose-gc benchmark/index.mjs", + "build": "run-s -n build:code build:types", + "build:code": "node ../../esbuild.mjs trace-mapping.ts", + "build:types": "run-s build:types:force build:types:emit build:types:mts", + "build:types:force": "rimraf tsconfig.build.tsbuildinfo", + "build:types:emit": "tsc --project tsconfig.build.json", + "build:types:mts": "node ../../mts-types.mjs", + "clean": "run-s -n clean:code clean:types", + "clean:code": "tsc --build --clean tsconfig.build.json", + "clean:types": "rimraf dist types", + "test": "run-s -n test:types test:only test:format", + "test:format": "prettier --check '{src,test}/**/*.ts'", + "test:only": "mocha", + "test:types": "eslint '{src,test}/**/*.ts'", + "lint": "run-s -n lint:types lint:format", + "lint:format": "npm run test:format -- --write", + "lint:types": "npm run test:types -- --fix", + "prepublishOnly": "npm run-s -n build test" + }, + "homepage": "https://github.com/jridgewell/sourcemaps/tree/main/packages/trace-mapping", + "repository": { + "type": "git", + "url": "git+https://github.com/jridgewell/sourcemaps.git", + "directory": "packages/trace-mapping" + }, + "author": "Justin Ridgewell ", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } +} diff --git a/node_modules/@jridgewell/trace-mapping/src/binary-search.ts b/node_modules/@jridgewell/trace-mapping/src/binary-search.ts new file mode 100644 index 0000000..c1144ad --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/src/binary-search.ts @@ -0,0 +1,115 @@ +import type { SourceMapSegment, ReverseSegment } from './sourcemap-segment'; +import { COLUMN } from './sourcemap-segment'; + +export type MemoState = { + lastKey: number; + lastNeedle: number; + lastIndex: number; +}; + +export let found = false; + +/** + * A binary search implementation that returns the index if a match is found. + * If no match is found, then the left-index (the index associated with the item that comes just + * before the desired index) is returned. To maintain proper sort order, a splice would happen at + * the next index: + * + * ```js + * const array = [1, 3]; + * const needle = 2; + * const index = binarySearch(array, needle, (item, needle) => item - needle); + * + * assert.equal(index, 0); + * array.splice(index + 1, 0, needle); + * assert.deepEqual(array, [1, 2, 3]); + * ``` + */ +export function binarySearch( + haystack: SourceMapSegment[] | ReverseSegment[], + needle: number, + low: number, + high: number, +): number { + while (low <= high) { + const mid = low + ((high - low) >> 1); + const cmp = haystack[mid][COLUMN] - needle; + + if (cmp === 0) { + found = true; + return mid; + } + + if (cmp < 0) { + low = mid + 1; + } else { + high = mid - 1; + } + } + + found = false; + return low - 1; +} + +export function upperBound( + haystack: SourceMapSegment[] | ReverseSegment[], + needle: number, + index: number, +): number { + for (let i = index + 1; i < haystack.length; index = i++) { + if (haystack[i][COLUMN] !== needle) break; + } + return index; +} + +export function lowerBound( + haystack: SourceMapSegment[] | ReverseSegment[], + needle: number, + index: number, +): number { + for (let i = index - 1; i >= 0; index = i--) { + if (haystack[i][COLUMN] !== needle) break; + } + return index; +} + +export function memoizedState(): MemoState { + return { + lastKey: -1, + lastNeedle: -1, + lastIndex: -1, + }; +} + +/** + * This overly complicated beast is just to record the last tested line/column and the resulting + * index, allowing us to skip a few tests if mappings are monotonically increasing. + */ +export function memoizedBinarySearch( + haystack: SourceMapSegment[] | ReverseSegment[], + needle: number, + state: MemoState, + key: number, +): number { + const { lastKey, lastNeedle, lastIndex } = state; + + let low = 0; + let high = haystack.length - 1; + if (key === lastKey) { + if (needle === lastNeedle) { + found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle; + return lastIndex; + } + + if (needle >= lastNeedle) { + // lastIndex may be -1 if the previous needle was not found. + low = lastIndex === -1 ? 0 : lastIndex; + } else { + high = lastIndex; + } + } + state.lastKey = key; + state.lastNeedle = needle; + + return (state.lastIndex = binarySearch(haystack, needle, low, high)); +} diff --git a/node_modules/@jridgewell/trace-mapping/src/by-source.ts b/node_modules/@jridgewell/trace-mapping/src/by-source.ts new file mode 100644 index 0000000..1da6af0 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/src/by-source.ts @@ -0,0 +1,41 @@ +import { COLUMN, SOURCES_INDEX, SOURCE_LINE, SOURCE_COLUMN } from './sourcemap-segment'; +import { sortComparator } from './sort'; + +import type { ReverseSegment, SourceMapSegment } from './sourcemap-segment'; + +export type Source = ReverseSegment[][]; + +// Rebuilds the original source files, with mappings that are ordered by source line/column instead +// of generated line/column. +export default function buildBySources( + decoded: readonly SourceMapSegment[][], + memos: unknown[], +): Source[] { + const sources: Source[] = memos.map(() => []); + + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + for (let j = 0; j < line.length; j++) { + const seg = line[j]; + if (seg.length === 1) continue; + + const sourceIndex = seg[SOURCES_INDEX]; + const sourceLine = seg[SOURCE_LINE]; + const sourceColumn = seg[SOURCE_COLUMN]; + + const source = sources[sourceIndex]; + const segs = (source[sourceLine] ||= []); + segs.push([sourceColumn, i, seg[COLUMN]]); + } + } + + for (let i = 0; i < sources.length; i++) { + const source = sources[i]; + for (let j = 0; j < source.length; j++) { + const line = source[j]; + if (line) line.sort(sortComparator); + } + } + + return sources; +} diff --git a/node_modules/@jridgewell/trace-mapping/src/flatten-map.ts b/node_modules/@jridgewell/trace-mapping/src/flatten-map.ts new file mode 100644 index 0000000..61ac40c --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/src/flatten-map.ts @@ -0,0 +1,192 @@ +import { TraceMap, presortedDecodedMap, decodedMappings } from './trace-mapping'; +import { + COLUMN, + SOURCES_INDEX, + SOURCE_LINE, + SOURCE_COLUMN, + NAMES_INDEX, +} from './sourcemap-segment'; +import { parse } from './types'; + +import type { + DecodedSourceMap, + DecodedSourceMapXInput, + EncodedSourceMapXInput, + SectionedSourceMapXInput, + SectionedSourceMapInput, + SectionXInput, + Ro, +} from './types'; +import type { SourceMapSegment } from './sourcemap-segment'; + +type FlattenMap = { + new (map: Ro, mapUrl?: string | null): TraceMap; + (map: Ro, mapUrl?: string | null): TraceMap; +}; + +export const FlattenMap: FlattenMap = function (map, mapUrl) { + const parsed = parse(map as SectionedSourceMapInput); + + if (!('sections' in parsed)) { + return new TraceMap(parsed as DecodedSourceMapXInput | EncodedSourceMapXInput, mapUrl); + } + + const mappings: SourceMapSegment[][] = []; + const sources: string[] = []; + const sourcesContent: (string | null)[] = []; + const names: string[] = []; + const ignoreList: number[] = []; + + recurse( + parsed, + mapUrl, + mappings, + sources, + sourcesContent, + names, + ignoreList, + 0, + 0, + Infinity, + Infinity, + ); + + const joined: DecodedSourceMap = { + version: 3, + file: parsed.file, + names, + sources, + sourcesContent, + mappings, + ignoreList, + }; + + return presortedDecodedMap(joined); +} as FlattenMap; + +function recurse( + input: SectionedSourceMapXInput, + mapUrl: string | null | undefined, + mappings: SourceMapSegment[][], + sources: string[], + sourcesContent: (string | null)[], + names: string[], + ignoreList: number[], + lineOffset: number, + columnOffset: number, + stopLine: number, + stopColumn: number, +) { + const { sections } = input; + for (let i = 0; i < sections.length; i++) { + const { map, offset } = sections[i]; + + let sl = stopLine; + let sc = stopColumn; + if (i + 1 < sections.length) { + const nextOffset = sections[i + 1].offset; + sl = Math.min(stopLine, lineOffset + nextOffset.line); + + if (sl === stopLine) { + sc = Math.min(stopColumn, columnOffset + nextOffset.column); + } else if (sl < stopLine) { + sc = columnOffset + nextOffset.column; + } + } + + addSection( + map, + mapUrl, + mappings, + sources, + sourcesContent, + names, + ignoreList, + lineOffset + offset.line, + columnOffset + offset.column, + sl, + sc, + ); + } +} + +function addSection( + input: SectionXInput['map'], + mapUrl: string | null | undefined, + mappings: SourceMapSegment[][], + sources: string[], + sourcesContent: (string | null)[], + names: string[], + ignoreList: number[], + lineOffset: number, + columnOffset: number, + stopLine: number, + stopColumn: number, +) { + const parsed = parse(input); + if ('sections' in parsed) return recurse(...(arguments as unknown as Parameters)); + + const map = new TraceMap(parsed, mapUrl); + const sourcesOffset = sources.length; + const namesOffset = names.length; + const decoded = decodedMappings(map); + const { resolvedSources, sourcesContent: contents, ignoreList: ignores } = map; + + append(sources, resolvedSources); + append(names, map.names); + + if (contents) append(sourcesContent, contents); + else for (let i = 0; i < resolvedSources.length; i++) sourcesContent.push(null); + + if (ignores) for (let i = 0; i < ignores.length; i++) ignoreList.push(ignores[i] + sourcesOffset); + + for (let i = 0; i < decoded.length; i++) { + const lineI = lineOffset + i; + + // We can only add so many lines before we step into the range that the next section's map + // controls. When we get to the last line, then we'll start checking the segments to see if + // they've crossed into the column range. But it may not have any columns that overstep, so we + // still need to check that we don't overstep lines, too. + if (lineI > stopLine) return; + + // The out line may already exist in mappings (if we're continuing the line started by a + // previous section). Or, we may have jumped ahead several lines to start this section. + const out = getLine(mappings, lineI); + // On the 0th loop, the section's column offset shifts us forward. On all other lines (since the + // map can be multiple lines), it doesn't. + const cOffset = i === 0 ? columnOffset : 0; + + const line = decoded[i]; + for (let j = 0; j < line.length; j++) { + const seg = line[j]; + const column = cOffset + seg[COLUMN]; + + // If this segment steps into the column range that the next section's map controls, we need + // to stop early. + if (lineI === stopLine && column >= stopColumn) return; + + if (seg.length === 1) { + out.push([column]); + continue; + } + + const sourcesIndex = sourcesOffset + seg[SOURCES_INDEX]; + const sourceLine = seg[SOURCE_LINE]; + const sourceColumn = seg[SOURCE_COLUMN]; + out.push( + seg.length === 4 + ? [column, sourcesIndex, sourceLine, sourceColumn] + : [column, sourcesIndex, sourceLine, sourceColumn, namesOffset + seg[NAMES_INDEX]], + ); + } + } +} + +function append(arr: T[], other: T[]) { + for (let i = 0; i < other.length; i++) arr.push(other[i]); +} + +function getLine(arr: T[][], index: number): T[] { + for (let i = arr.length; i <= index; i++) arr[i] = []; + return arr[index]; +} diff --git a/node_modules/@jridgewell/trace-mapping/src/resolve.ts b/node_modules/@jridgewell/trace-mapping/src/resolve.ts new file mode 100644 index 0000000..30bfa3b --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/src/resolve.ts @@ -0,0 +1,16 @@ +import resolveUri from '@jridgewell/resolve-uri'; +import stripFilename from './strip-filename'; + +type Resolve = (source: string | null) => string; +export default function resolver( + mapUrl: string | null | undefined, + sourceRoot: string | undefined, +): Resolve { + const from = stripFilename(mapUrl); + // The sourceRoot is always treated as a directory, if it's not empty. + // https://github.com/mozilla/source-map/blob/8cb3ee57/lib/util.js#L327 + // https://github.com/chromium/chromium/blob/da4adbb3/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js#L400-L401 + const prefix = sourceRoot ? sourceRoot + '/' : ''; + + return (source) => resolveUri(prefix + (source || ''), from); +} diff --git a/node_modules/@jridgewell/trace-mapping/src/sort.ts b/node_modules/@jridgewell/trace-mapping/src/sort.ts new file mode 100644 index 0000000..5d016cb --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/src/sort.ts @@ -0,0 +1,45 @@ +import { COLUMN } from './sourcemap-segment'; + +import type { ReverseSegment, SourceMapSegment } from './sourcemap-segment'; + +export default function maybeSort( + mappings: SourceMapSegment[][], + owned: boolean, +): SourceMapSegment[][] { + const unsortedIndex = nextUnsortedSegmentLine(mappings, 0); + if (unsortedIndex === mappings.length) return mappings; + + // If we own the array (meaning we parsed it from JSON), then we're free to directly mutate it. If + // not, we do not want to modify the consumer's input array. + if (!owned) mappings = mappings.slice(); + + for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) { + mappings[i] = sortSegments(mappings[i], owned); + } + return mappings; +} + +function nextUnsortedSegmentLine(mappings: SourceMapSegment[][], start: number): number { + for (let i = start; i < mappings.length; i++) { + if (!isSorted(mappings[i])) return i; + } + return mappings.length; +} + +function isSorted(line: SourceMapSegment[]): boolean { + for (let j = 1; j < line.length; j++) { + if (line[j][COLUMN] < line[j - 1][COLUMN]) { + return false; + } + } + return true; +} + +function sortSegments(line: SourceMapSegment[], owned: boolean): SourceMapSegment[] { + if (!owned) line = line.slice(); + return line.sort(sortComparator); +} + +export function sortComparator(a: T, b: T): number { + return a[COLUMN] - b[COLUMN]; +} diff --git a/node_modules/@jridgewell/trace-mapping/src/sourcemap-segment.ts b/node_modules/@jridgewell/trace-mapping/src/sourcemap-segment.ts new file mode 100644 index 0000000..94f1b6a --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/src/sourcemap-segment.ts @@ -0,0 +1,23 @@ +type GeneratedColumn = number; +type SourcesIndex = number; +type SourceLine = number; +type SourceColumn = number; +type NamesIndex = number; + +type GeneratedLine = number; + +export type SourceMapSegment = + | [GeneratedColumn] + | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn] + | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex]; + +export type ReverseSegment = [SourceColumn, GeneratedLine, GeneratedColumn]; + +export const COLUMN = 0; +export const SOURCES_INDEX = 1; +export const SOURCE_LINE = 2; +export const SOURCE_COLUMN = 3; +export const NAMES_INDEX = 4; + +export const REV_GENERATED_LINE = 1; +export const REV_GENERATED_COLUMN = 2; diff --git a/node_modules/@jridgewell/trace-mapping/src/strip-filename.ts b/node_modules/@jridgewell/trace-mapping/src/strip-filename.ts new file mode 100644 index 0000000..2c88980 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/src/strip-filename.ts @@ -0,0 +1,8 @@ +/** + * Removes everything after the last "/", but leaves the slash. + */ +export default function stripFilename(path: string | undefined | null): string { + if (!path) return ''; + const index = path.lastIndexOf('/'); + return path.slice(0, index + 1); +} diff --git a/node_modules/@jridgewell/trace-mapping/src/trace-mapping.ts b/node_modules/@jridgewell/trace-mapping/src/trace-mapping.ts new file mode 100644 index 0000000..0b793d5 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/src/trace-mapping.ts @@ -0,0 +1,502 @@ +import { encode, decode } from '@jridgewell/sourcemap-codec'; + +import resolver from './resolve'; +import maybeSort from './sort'; +import buildBySources from './by-source'; +import { + memoizedState, + memoizedBinarySearch, + upperBound, + lowerBound, + found as bsFound, +} from './binary-search'; +import { + COLUMN, + SOURCES_INDEX, + SOURCE_LINE, + SOURCE_COLUMN, + NAMES_INDEX, + REV_GENERATED_LINE, + REV_GENERATED_COLUMN, +} from './sourcemap-segment'; +import { parse } from './types'; + +import type { SourceMapSegment, ReverseSegment } from './sourcemap-segment'; +import type { + SourceMapV3, + DecodedSourceMap, + EncodedSourceMap, + InvalidOriginalMapping, + OriginalMapping, + InvalidGeneratedMapping, + GeneratedMapping, + SourceMapInput, + Needle, + SourceNeedle, + SourceMap, + EachMapping, + Bias, + XInput, + SectionedSourceMap, + Ro, +} from './types'; +import type { Source } from './by-source'; +import type { MemoState } from './binary-search'; + +export type { SourceMapSegment } from './sourcemap-segment'; +export type { + SourceMap, + DecodedSourceMap, + EncodedSourceMap, + Section, + SectionedSourceMap, + SourceMapV3, + Bias, + EachMapping, + GeneratedMapping, + InvalidGeneratedMapping, + InvalidOriginalMapping, + Needle, + OriginalMapping, + OriginalMapping as Mapping, + SectionedSourceMapInput, + SourceMapInput, + SourceNeedle, + XInput, + EncodedSourceMapXInput, + DecodedSourceMapXInput, + SectionedSourceMapXInput, + SectionXInput, +} from './types'; + +interface PublicMap { + _encoded: TraceMap['_encoded']; + _decoded: TraceMap['_decoded']; + _decodedMemo: TraceMap['_decodedMemo']; + _bySources: TraceMap['_bySources']; + _bySourceMemos: TraceMap['_bySourceMemos']; +} + +const LINE_GTR_ZERO = '`line` must be greater than 0 (lines start at line 1)'; +const COL_GTR_EQ_ZERO = '`column` must be greater than or equal to 0 (columns start at column 0)'; + +export const LEAST_UPPER_BOUND = -1; +export const GREATEST_LOWER_BOUND = 1; + +export { FlattenMap, FlattenMap as AnyMap } from './flatten-map'; + +export class TraceMap implements SourceMap { + declare version: SourceMapV3['version']; + declare file: SourceMapV3['file']; + declare names: SourceMapV3['names']; + declare sourceRoot: SourceMapV3['sourceRoot']; + declare sources: SourceMapV3['sources']; + declare sourcesContent: SourceMapV3['sourcesContent']; + declare ignoreList: SourceMapV3['ignoreList']; + + declare resolvedSources: string[]; + declare private _encoded: string | undefined; + + declare private _decoded: SourceMapSegment[][] | undefined; + declare private _decodedMemo: MemoState; + + declare private _bySources: Source[] | undefined; + declare private _bySourceMemos: MemoState[] | undefined; + + constructor(map: Ro, mapUrl?: string | null) { + const isString = typeof map === 'string'; + if (!isString && (map as unknown as { _decodedMemo: any })._decodedMemo) return map as TraceMap; + + const parsed = parse(map as Exclude); + + const { version, file, names, sourceRoot, sources, sourcesContent } = parsed; + this.version = version; + this.file = file; + this.names = names || []; + this.sourceRoot = sourceRoot; + this.sources = sources; + this.sourcesContent = sourcesContent; + this.ignoreList = parsed.ignoreList || (parsed as XInput).x_google_ignoreList || undefined; + + const resolve = resolver(mapUrl, sourceRoot); + this.resolvedSources = sources.map(resolve); + + const { mappings } = parsed; + if (typeof mappings === 'string') { + this._encoded = mappings; + this._decoded = undefined; + } else if (Array.isArray(mappings)) { + this._encoded = undefined; + this._decoded = maybeSort(mappings, isString); + } else if ((parsed as unknown as SectionedSourceMap).sections) { + throw new Error(`TraceMap passed sectioned source map, please use FlattenMap export instead`); + } else { + throw new Error(`invalid source map: ${JSON.stringify(parsed)}`); + } + + this._decodedMemo = memoizedState(); + this._bySources = undefined; + this._bySourceMemos = undefined; + } +} + +/** + * Typescript doesn't allow friend access to private fields, so this just casts the map into a type + * with public access modifiers. + */ +function cast(map: unknown): PublicMap { + return map as any; +} + +/** + * Returns the encoded (VLQ string) form of the SourceMap's mappings field. + */ +export function encodedMappings(map: TraceMap): EncodedSourceMap['mappings'] { + return (cast(map)._encoded ??= encode(cast(map)._decoded!)); +} + +/** + * Returns the decoded (array of lines of segments) form of the SourceMap's mappings field. + */ +export function decodedMappings(map: TraceMap): Readonly { + return (cast(map)._decoded ||= decode(cast(map)._encoded!)); +} + +/** + * A low-level API to find the segment associated with a generated line/column (think, from a + * stack trace). Line and column here are 0-based, unlike `originalPositionFor`. + */ +export function traceSegment( + map: TraceMap, + line: number, + column: number, +): Readonly | null { + const decoded = decodedMappings(map); + + // It's common for parent source maps to have pointers to lines that have no + // mapping (like a "//# sourceMappingURL=") at the end of the child file. + if (line >= decoded.length) return null; + + const segments = decoded[line]; + const index = traceSegmentInternal( + segments, + cast(map)._decodedMemo, + line, + column, + GREATEST_LOWER_BOUND, + ); + + return index === -1 ? null : segments[index]; +} + +/** + * A higher-level API to find the source/line/column associated with a generated line/column + * (think, from a stack trace). Line is 1-based, but column is 0-based, due to legacy behavior in + * `source-map` library. + */ +export function originalPositionFor( + map: TraceMap, + needle: Needle, +): OriginalMapping | InvalidOriginalMapping { + let { line, column, bias } = needle; + line--; + if (line < 0) throw new Error(LINE_GTR_ZERO); + if (column < 0) throw new Error(COL_GTR_EQ_ZERO); + + const decoded = decodedMappings(map); + + // It's common for parent source maps to have pointers to lines that have no + // mapping (like a "//# sourceMappingURL=") at the end of the child file. + if (line >= decoded.length) return OMapping(null, null, null, null); + + const segments = decoded[line]; + const index = traceSegmentInternal( + segments, + cast(map)._decodedMemo, + line, + column, + bias || GREATEST_LOWER_BOUND, + ); + + if (index === -1) return OMapping(null, null, null, null); + + const segment = segments[index]; + if (segment.length === 1) return OMapping(null, null, null, null); + + const { names, resolvedSources } = map; + return OMapping( + resolvedSources[segment[SOURCES_INDEX]], + segment[SOURCE_LINE] + 1, + segment[SOURCE_COLUMN], + segment.length === 5 ? names[segment[NAMES_INDEX]] : null, + ); +} + +/** + * Finds the generated line/column position of the provided source/line/column source position. + */ +export function generatedPositionFor( + map: TraceMap, + needle: SourceNeedle, +): GeneratedMapping | InvalidGeneratedMapping { + const { source, line, column, bias } = needle; + return generatedPosition(map, source, line, column, bias || GREATEST_LOWER_BOUND, false); +} + +/** + * Finds all generated line/column positions of the provided source/line/column source position. + */ +export function allGeneratedPositionsFor(map: TraceMap, needle: SourceNeedle): GeneratedMapping[] { + const { source, line, column, bias } = needle; + // SourceMapConsumer uses LEAST_UPPER_BOUND for some reason, so we follow suit. + return generatedPosition(map, source, line, column, bias || LEAST_UPPER_BOUND, true); +} + +/** + * Iterates each mapping in generated position order. + */ +export function eachMapping(map: TraceMap, cb: (mapping: EachMapping) => void): void { + const decoded = decodedMappings(map); + const { names, resolvedSources } = map; + + for (let i = 0; i < decoded.length; i++) { + const line = decoded[i]; + for (let j = 0; j < line.length; j++) { + const seg = line[j]; + + const generatedLine = i + 1; + const generatedColumn = seg[0]; + let source = null; + let originalLine = null; + let originalColumn = null; + let name = null; + if (seg.length !== 1) { + source = resolvedSources[seg[1]]; + originalLine = seg[2] + 1; + originalColumn = seg[3]; + } + if (seg.length === 5) name = names[seg[4]]; + + cb({ + generatedLine, + generatedColumn, + source, + originalLine, + originalColumn, + name, + } as EachMapping); + } + } +} + +function sourceIndex(map: TraceMap, source: string): number { + const { sources, resolvedSources } = map; + let index = sources.indexOf(source); + if (index === -1) index = resolvedSources.indexOf(source); + return index; +} + +/** + * Retrieves the source content for a particular source, if its found. Returns null if not. + */ +export function sourceContentFor(map: TraceMap, source: string): string | null { + const { sourcesContent } = map; + if (sourcesContent == null) return null; + const index = sourceIndex(map, source); + return index === -1 ? null : sourcesContent[index]; +} + +/** + * Determines if the source is marked to ignore by the source map. + */ +export function isIgnored(map: TraceMap, source: string): boolean { + const { ignoreList } = map; + if (ignoreList == null) return false; + const index = sourceIndex(map, source); + return index === -1 ? false : ignoreList.includes(index); +} + +/** + * A helper that skips sorting of the input map's mappings array, which can be expensive for larger + * maps. + */ +export function presortedDecodedMap(map: DecodedSourceMap, mapUrl?: string): TraceMap { + const tracer = new TraceMap(clone(map, []), mapUrl); + cast(tracer)._decoded = map.mappings; + return tracer; +} + +/** + * Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects + * a sourcemap, or to JSON.stringify. + */ +export function decodedMap( + map: TraceMap, +): Omit & { mappings: readonly SourceMapSegment[][] } { + return clone(map, decodedMappings(map)); +} + +/** + * Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects + * a sourcemap, or to JSON.stringify. + */ +export function encodedMap(map: TraceMap): EncodedSourceMap { + return clone(map, encodedMappings(map)); +} + +function clone( + map: TraceMap | DecodedSourceMap, + mappings: T, +): T extends string ? EncodedSourceMap : DecodedSourceMap { + return { + version: map.version, + file: map.file, + names: map.names, + sourceRoot: map.sourceRoot, + sources: map.sources, + sourcesContent: map.sourcesContent, + mappings, + ignoreList: map.ignoreList || (map as XInput).x_google_ignoreList, + } as any; +} + +function OMapping(source: null, line: null, column: null, name: null): InvalidOriginalMapping; +function OMapping( + source: string, + line: number, + column: number, + name: string | null, +): OriginalMapping; +function OMapping( + source: string | null, + line: number | null, + column: number | null, + name: string | null, +): OriginalMapping | InvalidOriginalMapping { + return { source, line, column, name } as any; +} + +function GMapping(line: null, column: null): InvalidGeneratedMapping; +function GMapping(line: number, column: number): GeneratedMapping; +function GMapping( + line: number | null, + column: number | null, +): GeneratedMapping | InvalidGeneratedMapping { + return { line, column } as any; +} + +function traceSegmentInternal( + segments: SourceMapSegment[], + memo: MemoState, + line: number, + column: number, + bias: Bias, +): number; +function traceSegmentInternal( + segments: ReverseSegment[], + memo: MemoState, + line: number, + column: number, + bias: Bias, +): number; +function traceSegmentInternal( + segments: SourceMapSegment[] | ReverseSegment[], + memo: MemoState, + line: number, + column: number, + bias: Bias, +): number { + let index = memoizedBinarySearch(segments, column, memo, line); + if (bsFound) { + index = (bias === LEAST_UPPER_BOUND ? upperBound : lowerBound)(segments, column, index); + } else if (bias === LEAST_UPPER_BOUND) index++; + + if (index === -1 || index === segments.length) return -1; + return index; +} + +function sliceGeneratedPositions( + segments: ReverseSegment[], + memo: MemoState, + line: number, + column: number, + bias: Bias, +): GeneratedMapping[] { + let min = traceSegmentInternal(segments, memo, line, column, GREATEST_LOWER_BOUND); + + // We ignored the bias when tracing the segment so that we're guarnateed to find the first (in + // insertion order) segment that matched. Even if we did respect the bias when tracing, we would + // still need to call `lowerBound()` to find the first segment, which is slower than just looking + // for the GREATEST_LOWER_BOUND to begin with. The only difference that matters for us is when the + // binary search didn't match, in which case GREATEST_LOWER_BOUND just needs to increment to + // match LEAST_UPPER_BOUND. + if (!bsFound && bias === LEAST_UPPER_BOUND) min++; + + if (min === -1 || min === segments.length) return []; + + // We may have found the segment that started at an earlier column. If this is the case, then we + // need to slice all generated segments that match _that_ column, because all such segments span + // to our desired column. + const matchedColumn = bsFound ? column : segments[min][COLUMN]; + + // The binary search is not guaranteed to find the lower bound when a match wasn't found. + if (!bsFound) min = lowerBound(segments, matchedColumn, min); + const max = upperBound(segments, matchedColumn, min); + + const result = []; + for (; min <= max; min++) { + const segment = segments[min]; + result.push(GMapping(segment[REV_GENERATED_LINE] + 1, segment[REV_GENERATED_COLUMN])); + } + return result; +} + +function generatedPosition( + map: TraceMap, + source: string, + line: number, + column: number, + bias: Bias, + all: false, +): GeneratedMapping | InvalidGeneratedMapping; +function generatedPosition( + map: TraceMap, + source: string, + line: number, + column: number, + bias: Bias, + all: true, +): GeneratedMapping[]; +function generatedPosition( + map: TraceMap, + source: string, + line: number, + column: number, + bias: Bias, + all: boolean, +): GeneratedMapping | InvalidGeneratedMapping | GeneratedMapping[] { + line--; + if (line < 0) throw new Error(LINE_GTR_ZERO); + if (column < 0) throw new Error(COL_GTR_EQ_ZERO); + + const { sources, resolvedSources } = map; + let sourceIndex = sources.indexOf(source); + if (sourceIndex === -1) sourceIndex = resolvedSources.indexOf(source); + if (sourceIndex === -1) return all ? [] : GMapping(null, null); + + const bySourceMemos = (cast(map)._bySourceMemos ||= sources.map(memoizedState)); + const generated = (cast(map)._bySources ||= buildBySources(decodedMappings(map), bySourceMemos)); + + const segments = generated[sourceIndex][line]; + if (segments == null) return all ? [] : GMapping(null, null); + + const memo = bySourceMemos[sourceIndex]; + + if (all) return sliceGeneratedPositions(segments, memo, line, column, bias); + + const index = traceSegmentInternal(segments, memo, line, column, bias); + if (index === -1) return GMapping(null, null); + + const segment = segments[index]; + return GMapping(segment[REV_GENERATED_LINE] + 1, segment[REV_GENERATED_COLUMN]); +} diff --git a/node_modules/@jridgewell/trace-mapping/src/types.ts b/node_modules/@jridgewell/trace-mapping/src/types.ts new file mode 100644 index 0000000..730a61f --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/src/types.ts @@ -0,0 +1,114 @@ +import type { SourceMapSegment } from './sourcemap-segment'; +import type { GREATEST_LOWER_BOUND, LEAST_UPPER_BOUND, TraceMap } from './trace-mapping'; + +export interface SourceMapV3 { + file?: string | null; + names: string[]; + sourceRoot?: string; + sources: (string | null)[]; + sourcesContent?: (string | null)[]; + version: 3; + ignoreList?: number[]; +} + +export interface EncodedSourceMap extends SourceMapV3 { + mappings: string; +} + +export interface DecodedSourceMap extends SourceMapV3 { + mappings: SourceMapSegment[][]; +} + +export interface Section { + offset: { line: number; column: number }; + map: EncodedSourceMap | DecodedSourceMap | SectionedSourceMap; +} + +export interface SectionedSourceMap { + file?: string | null; + sections: Section[]; + version: 3; +} + +export type OriginalMapping = { + source: string | null; + line: number; + column: number; + name: string | null; +}; + +export type InvalidOriginalMapping = { + source: null; + line: null; + column: null; + name: null; +}; + +export type GeneratedMapping = { + line: number; + column: number; +}; +export type InvalidGeneratedMapping = { + line: null; + column: null; +}; + +export type Bias = typeof GREATEST_LOWER_BOUND | typeof LEAST_UPPER_BOUND; + +export type XInput = { x_google_ignoreList?: SourceMapV3['ignoreList'] }; +export type EncodedSourceMapXInput = EncodedSourceMap & XInput; +export type DecodedSourceMapXInput = DecodedSourceMap & XInput; +export type SectionedSourceMapXInput = Omit & { + sections: SectionXInput[]; +}; +export type SectionXInput = Omit & { + map: SectionedSourceMapInput; +}; + +export type SourceMapInput = string | EncodedSourceMapXInput | DecodedSourceMapXInput | TraceMap; +export type SectionedSourceMapInput = SourceMapInput | SectionedSourceMapXInput; + +export type Needle = { line: number; column: number; bias?: Bias }; +export type SourceNeedle = { source: string; line: number; column: number; bias?: Bias }; + +export type EachMapping = + | { + generatedLine: number; + generatedColumn: number; + source: null; + originalLine: null; + originalColumn: null; + name: null; + } + | { + generatedLine: number; + generatedColumn: number; + source: string | null; + originalLine: number; + originalColumn: number; + name: string | null; + }; + +export abstract class SourceMap { + declare version: SourceMapV3['version']; + declare file: SourceMapV3['file']; + declare names: SourceMapV3['names']; + declare sourceRoot: SourceMapV3['sourceRoot']; + declare sources: SourceMapV3['sources']; + declare sourcesContent: SourceMapV3['sourcesContent']; + declare resolvedSources: SourceMapV3['sources']; + declare ignoreList: SourceMapV3['ignoreList']; +} + +export type Ro = + T extends Array + ? V[] | Readonly | RoArray | Readonly> + : T extends object + ? T | Readonly | RoObject | Readonly> + : T; +type RoArray = Ro[]; +type RoObject = { [K in keyof T]: T[K] | Ro }; + +export function parse(map: T): Exclude { + return typeof map === 'string' ? JSON.parse(map) : (map as Exclude); +} diff --git a/node_modules/@jridgewell/trace-mapping/types/binary-search.d.cts b/node_modules/@jridgewell/trace-mapping/types/binary-search.d.cts new file mode 100644 index 0000000..b7bb85c --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/binary-search.d.cts @@ -0,0 +1,33 @@ +import type { SourceMapSegment, ReverseSegment } from './sourcemap-segment.cts'; +export type MemoState = { + lastKey: number; + lastNeedle: number; + lastIndex: number; +}; +export declare let found: boolean; +/** + * A binary search implementation that returns the index if a match is found. + * If no match is found, then the left-index (the index associated with the item that comes just + * before the desired index) is returned. To maintain proper sort order, a splice would happen at + * the next index: + * + * ```js + * const array = [1, 3]; + * const needle = 2; + * const index = binarySearch(array, needle, (item, needle) => item - needle); + * + * assert.equal(index, 0); + * array.splice(index + 1, 0, needle); + * assert.deepEqual(array, [1, 2, 3]); + * ``` + */ +export declare function binarySearch(haystack: SourceMapSegment[] | ReverseSegment[], needle: number, low: number, high: number): number; +export declare function upperBound(haystack: SourceMapSegment[] | ReverseSegment[], needle: number, index: number): number; +export declare function lowerBound(haystack: SourceMapSegment[] | ReverseSegment[], needle: number, index: number): number; +export declare function memoizedState(): MemoState; +/** + * This overly complicated beast is just to record the last tested line/column and the resulting + * index, allowing us to skip a few tests if mappings are monotonically increasing. + */ +export declare function memoizedBinarySearch(haystack: SourceMapSegment[] | ReverseSegment[], needle: number, state: MemoState, key: number): number; +//# sourceMappingURL=binary-search.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/binary-search.d.cts.map b/node_modules/@jridgewell/trace-mapping/types/binary-search.d.cts.map new file mode 100644 index 0000000..648e84c --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/binary-search.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"binary-search.d.ts","sourceRoot":"","sources":["../src/binary-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG5E,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,IAAI,KAAK,SAAQ,CAAC;AAEzB;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,gBAAgB,EAAE,GAAG,cAAc,EAAE,EAC/C,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GACX,MAAM,CAmBR;AAED,wBAAgB,UAAU,CACxB,QAAQ,EAAE,gBAAgB,EAAE,GAAG,cAAc,EAAE,EAC/C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,MAAM,CAKR;AAED,wBAAgB,UAAU,CACxB,QAAQ,EAAE,gBAAgB,EAAE,GAAG,cAAc,EAAE,EAC/C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,MAAM,CAKR;AAED,wBAAgB,aAAa,IAAI,SAAS,CAMzC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,cAAc,EAAE,EAC/C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE,MAAM,GACV,MAAM,CAsBR"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/binary-search.d.mts b/node_modules/@jridgewell/trace-mapping/types/binary-search.d.mts new file mode 100644 index 0000000..19e1e6b --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/binary-search.d.mts @@ -0,0 +1,33 @@ +import type { SourceMapSegment, ReverseSegment } from './sourcemap-segment.mts'; +export type MemoState = { + lastKey: number; + lastNeedle: number; + lastIndex: number; +}; +export declare let found: boolean; +/** + * A binary search implementation that returns the index if a match is found. + * If no match is found, then the left-index (the index associated with the item that comes just + * before the desired index) is returned. To maintain proper sort order, a splice would happen at + * the next index: + * + * ```js + * const array = [1, 3]; + * const needle = 2; + * const index = binarySearch(array, needle, (item, needle) => item - needle); + * + * assert.equal(index, 0); + * array.splice(index + 1, 0, needle); + * assert.deepEqual(array, [1, 2, 3]); + * ``` + */ +export declare function binarySearch(haystack: SourceMapSegment[] | ReverseSegment[], needle: number, low: number, high: number): number; +export declare function upperBound(haystack: SourceMapSegment[] | ReverseSegment[], needle: number, index: number): number; +export declare function lowerBound(haystack: SourceMapSegment[] | ReverseSegment[], needle: number, index: number): number; +export declare function memoizedState(): MemoState; +/** + * This overly complicated beast is just to record the last tested line/column and the resulting + * index, allowing us to skip a few tests if mappings are monotonically increasing. + */ +export declare function memoizedBinarySearch(haystack: SourceMapSegment[] | ReverseSegment[], needle: number, state: MemoState, key: number): number; +//# sourceMappingURL=binary-search.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/binary-search.d.mts.map b/node_modules/@jridgewell/trace-mapping/types/binary-search.d.mts.map new file mode 100644 index 0000000..648e84c --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/binary-search.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"binary-search.d.ts","sourceRoot":"","sources":["../src/binary-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG5E,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,IAAI,KAAK,SAAQ,CAAC;AAEzB;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,gBAAgB,EAAE,GAAG,cAAc,EAAE,EAC/C,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GACX,MAAM,CAmBR;AAED,wBAAgB,UAAU,CACxB,QAAQ,EAAE,gBAAgB,EAAE,GAAG,cAAc,EAAE,EAC/C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,MAAM,CAKR;AAED,wBAAgB,UAAU,CACxB,QAAQ,EAAE,gBAAgB,EAAE,GAAG,cAAc,EAAE,EAC/C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,MAAM,CAKR;AAED,wBAAgB,aAAa,IAAI,SAAS,CAMzC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,cAAc,EAAE,EAC/C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE,MAAM,GACV,MAAM,CAsBR"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/by-source.d.cts b/node_modules/@jridgewell/trace-mapping/types/by-source.d.cts new file mode 100644 index 0000000..da49693 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/by-source.d.cts @@ -0,0 +1,4 @@ +import type { ReverseSegment, SourceMapSegment } from './sourcemap-segment.cts'; +export type Source = ReverseSegment[][]; +export = function buildBySources(decoded: readonly SourceMapSegment[][], memos: unknown[]): Source[]; +//# sourceMappingURL=by-source.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/by-source.d.cts.map b/node_modules/@jridgewell/trace-mapping/types/by-source.d.cts.map new file mode 100644 index 0000000..32d2a7a --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/by-source.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"by-source.d.ts","sourceRoot":"","sources":["../src/by-source.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5E,MAAM,MAAM,MAAM,GAAG,cAAc,EAAE,EAAE,CAAC;AAIxC,MAAM,CAAC,OAAO,UAAU,cAAc,CACpC,OAAO,EAAE,SAAS,gBAAgB,EAAE,EAAE,EACtC,KAAK,EAAE,OAAO,EAAE,GACf,MAAM,EAAE,CA4BV"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/by-source.d.mts b/node_modules/@jridgewell/trace-mapping/types/by-source.d.mts new file mode 100644 index 0000000..f361049 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/by-source.d.mts @@ -0,0 +1,4 @@ +import type { ReverseSegment, SourceMapSegment } from './sourcemap-segment.mts'; +export type Source = ReverseSegment[][]; +export default function buildBySources(decoded: readonly SourceMapSegment[][], memos: unknown[]): Source[]; +//# sourceMappingURL=by-source.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/by-source.d.mts.map b/node_modules/@jridgewell/trace-mapping/types/by-source.d.mts.map new file mode 100644 index 0000000..32d2a7a --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/by-source.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"by-source.d.ts","sourceRoot":"","sources":["../src/by-source.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5E,MAAM,MAAM,MAAM,GAAG,cAAc,EAAE,EAAE,CAAC;AAIxC,MAAM,CAAC,OAAO,UAAU,cAAc,CACpC,OAAO,EAAE,SAAS,gBAAgB,EAAE,EAAE,EACtC,KAAK,EAAE,OAAO,EAAE,GACf,MAAM,EAAE,CA4BV"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.cts b/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.cts new file mode 100644 index 0000000..433d849 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.cts @@ -0,0 +1,9 @@ +import { TraceMap } from './trace-mapping.cts'; +import type { SectionedSourceMapInput, Ro } from './types.cts'; +type FlattenMap = { + new (map: Ro, mapUrl?: string | null): TraceMap; + (map: Ro, mapUrl?: string | null): TraceMap; +}; +export declare const FlattenMap: FlattenMap; +export {}; +//# sourceMappingURL=flatten-map.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.cts.map b/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.cts.map new file mode 100644 index 0000000..994b208 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"flatten-map.d.ts","sourceRoot":"","sources":["../src/flatten-map.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAwC,MAAM,iBAAiB,CAAC;AAUjF,OAAO,KAAK,EAKV,uBAAuB,EAEvB,EAAE,EACH,MAAM,SAAS,CAAC;AAGjB,KAAK,UAAU,GAAG;IAChB,KAAK,GAAG,EAAE,EAAE,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC;IACzE,CAAC,GAAG,EAAE,EAAE,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC;CACtE,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,UAsCV,CAAC"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.mts b/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.mts new file mode 100644 index 0000000..444a1be --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.mts @@ -0,0 +1,9 @@ +import { TraceMap } from './trace-mapping.mts'; +import type { SectionedSourceMapInput, Ro } from './types.mts'; +type FlattenMap = { + new (map: Ro, mapUrl?: string | null): TraceMap; + (map: Ro, mapUrl?: string | null): TraceMap; +}; +export declare const FlattenMap: FlattenMap; +export {}; +//# sourceMappingURL=flatten-map.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.mts.map b/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.mts.map new file mode 100644 index 0000000..994b208 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/flatten-map.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"flatten-map.d.ts","sourceRoot":"","sources":["../src/flatten-map.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAwC,MAAM,iBAAiB,CAAC;AAUjF,OAAO,KAAK,EAKV,uBAAuB,EAEvB,EAAE,EACH,MAAM,SAAS,CAAC;AAGjB,KAAK,UAAU,GAAG;IAChB,KAAK,GAAG,EAAE,EAAE,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC;IACzE,CAAC,GAAG,EAAE,EAAE,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC;CACtE,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,UAsCV,CAAC"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/resolve.d.cts b/node_modules/@jridgewell/trace-mapping/types/resolve.d.cts new file mode 100644 index 0000000..62aeedb --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/resolve.d.cts @@ -0,0 +1,4 @@ +type Resolve = (source: string | null) => string; +export = function resolver(mapUrl: string | null | undefined, sourceRoot: string | undefined): Resolve; +export {}; +//# sourceMappingURL=resolve.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/resolve.d.cts.map b/node_modules/@jridgewell/trace-mapping/types/resolve.d.cts.map new file mode 100644 index 0000000..9f155ac --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/resolve.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAGA,KAAK,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,MAAM,CAAC;AACjD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAC9B,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACjC,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,OAAO,CAQT"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/resolve.d.mts b/node_modules/@jridgewell/trace-mapping/types/resolve.d.mts new file mode 100644 index 0000000..e2798a1 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/resolve.d.mts @@ -0,0 +1,4 @@ +type Resolve = (source: string | null) => string; +export default function resolver(mapUrl: string | null | undefined, sourceRoot: string | undefined): Resolve; +export {}; +//# sourceMappingURL=resolve.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/resolve.d.mts.map b/node_modules/@jridgewell/trace-mapping/types/resolve.d.mts.map new file mode 100644 index 0000000..9f155ac --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/resolve.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AAGA,KAAK,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,MAAM,CAAC;AACjD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAC9B,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACjC,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,OAAO,CAQT"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/sort.d.cts b/node_modules/@jridgewell/trace-mapping/types/sort.d.cts new file mode 100644 index 0000000..aa14c12 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/sort.d.cts @@ -0,0 +1,4 @@ +import type { ReverseSegment, SourceMapSegment } from './sourcemap-segment.cts'; +export = function maybeSort(mappings: SourceMapSegment[][], owned: boolean): SourceMapSegment[][]; +export declare function sortComparator(a: T, b: T): number; +//# sourceMappingURL=sort.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/sort.d.cts.map b/node_modules/@jridgewell/trace-mapping/types/sort.d.cts.map new file mode 100644 index 0000000..48b8e67 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/sort.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"sort.d.ts","sourceRoot":"","sources":["../src/sort.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5E,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,QAAQ,EAAE,gBAAgB,EAAE,EAAE,EAC9B,KAAK,EAAE,OAAO,GACb,gBAAgB,EAAE,EAAE,CAYtB;AAuBD,wBAAgB,cAAc,CAAC,CAAC,SAAS,gBAAgB,GAAG,cAAc,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,MAAM,CAE9F"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/sort.d.mts b/node_modules/@jridgewell/trace-mapping/types/sort.d.mts new file mode 100644 index 0000000..c5b94e6 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/sort.d.mts @@ -0,0 +1,4 @@ +import type { ReverseSegment, SourceMapSegment } from './sourcemap-segment.mts'; +export default function maybeSort(mappings: SourceMapSegment[][], owned: boolean): SourceMapSegment[][]; +export declare function sortComparator(a: T, b: T): number; +//# sourceMappingURL=sort.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/sort.d.mts.map b/node_modules/@jridgewell/trace-mapping/types/sort.d.mts.map new file mode 100644 index 0000000..48b8e67 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/sort.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"sort.d.ts","sourceRoot":"","sources":["../src/sort.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5E,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,QAAQ,EAAE,gBAAgB,EAAE,EAAE,EAC9B,KAAK,EAAE,OAAO,GACb,gBAAgB,EAAE,EAAE,CAYtB;AAuBD,wBAAgB,cAAc,CAAC,CAAC,SAAS,gBAAgB,GAAG,cAAc,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,MAAM,CAE9F"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.cts b/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.cts new file mode 100644 index 0000000..8d3cabc --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.cts @@ -0,0 +1,17 @@ +type GeneratedColumn = number; +type SourcesIndex = number; +type SourceLine = number; +type SourceColumn = number; +type NamesIndex = number; +type GeneratedLine = number; +export type SourceMapSegment = [GeneratedColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex]; +export type ReverseSegment = [SourceColumn, GeneratedLine, GeneratedColumn]; +export declare const COLUMN = 0; +export declare const SOURCES_INDEX = 1; +export declare const SOURCE_LINE = 2; +export declare const SOURCE_COLUMN = 3; +export declare const NAMES_INDEX = 4; +export declare const REV_GENERATED_LINE = 1; +export declare const REV_GENERATED_COLUMN = 2; +export {}; +//# sourceMappingURL=sourcemap-segment.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.cts.map b/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.cts.map new file mode 100644 index 0000000..0c94a46 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"sourcemap-segment.d.ts","sourceRoot":"","sources":["../src/sourcemap-segment.ts"],"names":[],"mappings":"AAAA,KAAK,eAAe,GAAG,MAAM,CAAC;AAC9B,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,UAAU,GAAG,MAAM,CAAC;AACzB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,UAAU,GAAG,MAAM,CAAC;AAEzB,KAAK,aAAa,GAAG,MAAM,CAAC;AAE5B,MAAM,MAAM,gBAAgB,GACxB,CAAC,eAAe,CAAC,GACjB,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,GACzD,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;AAE1E,MAAM,MAAM,cAAc,GAAG,CAAC,YAAY,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC;AAE5E,eAAO,MAAM,MAAM,IAAI,CAAC;AACxB,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,WAAW,IAAI,CAAC;AAE7B,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,oBAAoB,IAAI,CAAC"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.mts b/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.mts new file mode 100644 index 0000000..8d3cabc --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.mts @@ -0,0 +1,17 @@ +type GeneratedColumn = number; +type SourcesIndex = number; +type SourceLine = number; +type SourceColumn = number; +type NamesIndex = number; +type GeneratedLine = number; +export type SourceMapSegment = [GeneratedColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn] | [GeneratedColumn, SourcesIndex, SourceLine, SourceColumn, NamesIndex]; +export type ReverseSegment = [SourceColumn, GeneratedLine, GeneratedColumn]; +export declare const COLUMN = 0; +export declare const SOURCES_INDEX = 1; +export declare const SOURCE_LINE = 2; +export declare const SOURCE_COLUMN = 3; +export declare const NAMES_INDEX = 4; +export declare const REV_GENERATED_LINE = 1; +export declare const REV_GENERATED_COLUMN = 2; +export {}; +//# sourceMappingURL=sourcemap-segment.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.mts.map b/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.mts.map new file mode 100644 index 0000000..0c94a46 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/sourcemap-segment.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"sourcemap-segment.d.ts","sourceRoot":"","sources":["../src/sourcemap-segment.ts"],"names":[],"mappings":"AAAA,KAAK,eAAe,GAAG,MAAM,CAAC;AAC9B,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,UAAU,GAAG,MAAM,CAAC;AACzB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,UAAU,GAAG,MAAM,CAAC;AAEzB,KAAK,aAAa,GAAG,MAAM,CAAC;AAE5B,MAAM,MAAM,gBAAgB,GACxB,CAAC,eAAe,CAAC,GACjB,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,CAAC,GACzD,CAAC,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;AAE1E,MAAM,MAAM,cAAc,GAAG,CAAC,YAAY,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC;AAE5E,eAAO,MAAM,MAAM,IAAI,CAAC;AACxB,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,WAAW,IAAI,CAAC;AAE7B,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,oBAAoB,IAAI,CAAC"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.cts b/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.cts new file mode 100644 index 0000000..8b3c0e9 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.cts @@ -0,0 +1,5 @@ +/** + * Removes everything after the last "/", but leaves the slash. + */ +export = function stripFilename(path: string | undefined | null): string; +//# sourceMappingURL=strip-filename.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.cts.map b/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.cts.map new file mode 100644 index 0000000..17a25da --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"strip-filename.d.ts","sourceRoot":"","sources":["../src/strip-filename.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAI7E"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.mts b/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.mts new file mode 100644 index 0000000..cbbaee0 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.mts @@ -0,0 +1,5 @@ +/** + * Removes everything after the last "/", but leaves the slash. + */ +export default function stripFilename(path: string | undefined | null): string; +//# sourceMappingURL=strip-filename.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.mts.map b/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.mts.map new file mode 100644 index 0000000..17a25da --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/strip-filename.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"strip-filename.d.ts","sourceRoot":"","sources":["../src/strip-filename.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAI7E"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.cts b/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.cts new file mode 100644 index 0000000..a40f305 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.cts @@ -0,0 +1,80 @@ +import type { SourceMapSegment } from './sourcemap-segment.cts'; +import type { SourceMapV3, DecodedSourceMap, EncodedSourceMap, InvalidOriginalMapping, OriginalMapping, InvalidGeneratedMapping, GeneratedMapping, SourceMapInput, Needle, SourceNeedle, SourceMap, EachMapping, Ro } from './types.cts'; +export type { SourceMapSegment } from './sourcemap-segment.cts'; +export type { SourceMap, DecodedSourceMap, EncodedSourceMap, Section, SectionedSourceMap, SourceMapV3, Bias, EachMapping, GeneratedMapping, InvalidGeneratedMapping, InvalidOriginalMapping, Needle, OriginalMapping, OriginalMapping as Mapping, SectionedSourceMapInput, SourceMapInput, SourceNeedle, XInput, EncodedSourceMapXInput, DecodedSourceMapXInput, SectionedSourceMapXInput, SectionXInput, } from './types.cts'; +export declare const LEAST_UPPER_BOUND = -1; +export declare const GREATEST_LOWER_BOUND = 1; +export { FlattenMap, FlattenMap as AnyMap } from './flatten-map.cts'; +export declare class TraceMap implements SourceMap { + version: SourceMapV3['version']; + file: SourceMapV3['file']; + names: SourceMapV3['names']; + sourceRoot: SourceMapV3['sourceRoot']; + sources: SourceMapV3['sources']; + sourcesContent: SourceMapV3['sourcesContent']; + ignoreList: SourceMapV3['ignoreList']; + resolvedSources: string[]; + private _encoded; + private _decoded; + private _decodedMemo; + private _bySources; + private _bySourceMemos; + constructor(map: Ro, mapUrl?: string | null); +} +/** + * Returns the encoded (VLQ string) form of the SourceMap's mappings field. + */ +export declare function encodedMappings(map: TraceMap): EncodedSourceMap['mappings']; +/** + * Returns the decoded (array of lines of segments) form of the SourceMap's mappings field. + */ +export declare function decodedMappings(map: TraceMap): Readonly; +/** + * A low-level API to find the segment associated with a generated line/column (think, from a + * stack trace). Line and column here are 0-based, unlike `originalPositionFor`. + */ +export declare function traceSegment(map: TraceMap, line: number, column: number): Readonly | null; +/** + * A higher-level API to find the source/line/column associated with a generated line/column + * (think, from a stack trace). Line is 1-based, but column is 0-based, due to legacy behavior in + * `source-map` library. + */ +export declare function originalPositionFor(map: TraceMap, needle: Needle): OriginalMapping | InvalidOriginalMapping; +/** + * Finds the generated line/column position of the provided source/line/column source position. + */ +export declare function generatedPositionFor(map: TraceMap, needle: SourceNeedle): GeneratedMapping | InvalidGeneratedMapping; +/** + * Finds all generated line/column positions of the provided source/line/column source position. + */ +export declare function allGeneratedPositionsFor(map: TraceMap, needle: SourceNeedle): GeneratedMapping[]; +/** + * Iterates each mapping in generated position order. + */ +export declare function eachMapping(map: TraceMap, cb: (mapping: EachMapping) => void): void; +/** + * Retrieves the source content for a particular source, if its found. Returns null if not. + */ +export declare function sourceContentFor(map: TraceMap, source: string): string | null; +/** + * Determines if the source is marked to ignore by the source map. + */ +export declare function isIgnored(map: TraceMap, source: string): boolean; +/** + * A helper that skips sorting of the input map's mappings array, which can be expensive for larger + * maps. + */ +export declare function presortedDecodedMap(map: DecodedSourceMap, mapUrl?: string): TraceMap; +/** + * Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects + * a sourcemap, or to JSON.stringify. + */ +export declare function decodedMap(map: TraceMap): Omit & { + mappings: readonly SourceMapSegment[][]; +}; +/** + * Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects + * a sourcemap, or to JSON.stringify. + */ +export declare function encodedMap(map: TraceMap): EncodedSourceMap; +//# sourceMappingURL=trace-mapping.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.cts.map b/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.cts.map new file mode 100644 index 0000000..b5a874c --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"trace-mapping.d.ts","sourceRoot":"","sources":["../src/trace-mapping.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,gBAAgB,EAAkB,MAAM,qBAAqB,CAAC;AAC5E,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,uBAAuB,EACvB,gBAAgB,EAChB,cAAc,EACd,MAAM,EACN,YAAY,EACZ,SAAS,EACT,WAAW,EAIX,EAAE,EACH,MAAM,SAAS,CAAC;AAIjB,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,OAAO,EACP,kBAAkB,EAClB,WAAW,EACX,IAAI,EACJ,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,sBAAsB,EACtB,MAAM,EACN,eAAe,EACf,eAAe,IAAI,OAAO,EAC1B,uBAAuB,EACvB,cAAc,EACd,YAAY,EACZ,MAAM,EACN,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,aAAa,GACd,MAAM,SAAS,CAAC;AAajB,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,OAAO,EAAE,UAAU,EAAE,UAAU,IAAI,MAAM,EAAE,MAAM,eAAe,CAAC;AAEjE,qBAAa,QAAS,YAAW,SAAS;IAChC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAChC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1B,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC5B,UAAU,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;IACtC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAChC,cAAc,EAAE,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAC9C,UAAU,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;IAEtC,eAAe,EAAE,MAAM,EAAE,CAAC;IAClC,QAAgB,QAAQ,CAAqB;IAE7C,QAAgB,QAAQ,CAAmC;IAC3D,QAAgB,YAAY,CAAY;IAExC,QAAgB,UAAU,CAAuB;IACjD,QAAgB,cAAc,CAA0B;gBAE5C,GAAG,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;CAmC5D;AAUD;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAE3E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,GAAG,QAAQ,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAErF;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,QAAQ,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAiBnC;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,MAAM,GACb,eAAe,GAAG,sBAAsB,CAiC1C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,YAAY,GACnB,gBAAgB,GAAG,uBAAuB,CAG5C;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,GAAG,gBAAgB,EAAE,CAIhG;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI,CAgCnF;AASD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK7E;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAKhE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAIpF;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,QAAQ,GACZ,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,GAAG;IAAE,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EAAE,CAAA;CAAE,CAElF;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,QAAQ,GAAG,gBAAgB,CAE1D"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.mts b/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.mts new file mode 100644 index 0000000..bc2ff0f --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.mts @@ -0,0 +1,80 @@ +import type { SourceMapSegment } from './sourcemap-segment.mts'; +import type { SourceMapV3, DecodedSourceMap, EncodedSourceMap, InvalidOriginalMapping, OriginalMapping, InvalidGeneratedMapping, GeneratedMapping, SourceMapInput, Needle, SourceNeedle, SourceMap, EachMapping, Ro } from './types.mts'; +export type { SourceMapSegment } from './sourcemap-segment.mts'; +export type { SourceMap, DecodedSourceMap, EncodedSourceMap, Section, SectionedSourceMap, SourceMapV3, Bias, EachMapping, GeneratedMapping, InvalidGeneratedMapping, InvalidOriginalMapping, Needle, OriginalMapping, OriginalMapping as Mapping, SectionedSourceMapInput, SourceMapInput, SourceNeedle, XInput, EncodedSourceMapXInput, DecodedSourceMapXInput, SectionedSourceMapXInput, SectionXInput, } from './types.mts'; +export declare const LEAST_UPPER_BOUND = -1; +export declare const GREATEST_LOWER_BOUND = 1; +export { FlattenMap, FlattenMap as AnyMap } from './flatten-map.mts'; +export declare class TraceMap implements SourceMap { + version: SourceMapV3['version']; + file: SourceMapV3['file']; + names: SourceMapV3['names']; + sourceRoot: SourceMapV3['sourceRoot']; + sources: SourceMapV3['sources']; + sourcesContent: SourceMapV3['sourcesContent']; + ignoreList: SourceMapV3['ignoreList']; + resolvedSources: string[]; + private _encoded; + private _decoded; + private _decodedMemo; + private _bySources; + private _bySourceMemos; + constructor(map: Ro, mapUrl?: string | null); +} +/** + * Returns the encoded (VLQ string) form of the SourceMap's mappings field. + */ +export declare function encodedMappings(map: TraceMap): EncodedSourceMap['mappings']; +/** + * Returns the decoded (array of lines of segments) form of the SourceMap's mappings field. + */ +export declare function decodedMappings(map: TraceMap): Readonly; +/** + * A low-level API to find the segment associated with a generated line/column (think, from a + * stack trace). Line and column here are 0-based, unlike `originalPositionFor`. + */ +export declare function traceSegment(map: TraceMap, line: number, column: number): Readonly | null; +/** + * A higher-level API to find the source/line/column associated with a generated line/column + * (think, from a stack trace). Line is 1-based, but column is 0-based, due to legacy behavior in + * `source-map` library. + */ +export declare function originalPositionFor(map: TraceMap, needle: Needle): OriginalMapping | InvalidOriginalMapping; +/** + * Finds the generated line/column position of the provided source/line/column source position. + */ +export declare function generatedPositionFor(map: TraceMap, needle: SourceNeedle): GeneratedMapping | InvalidGeneratedMapping; +/** + * Finds all generated line/column positions of the provided source/line/column source position. + */ +export declare function allGeneratedPositionsFor(map: TraceMap, needle: SourceNeedle): GeneratedMapping[]; +/** + * Iterates each mapping in generated position order. + */ +export declare function eachMapping(map: TraceMap, cb: (mapping: EachMapping) => void): void; +/** + * Retrieves the source content for a particular source, if its found. Returns null if not. + */ +export declare function sourceContentFor(map: TraceMap, source: string): string | null; +/** + * Determines if the source is marked to ignore by the source map. + */ +export declare function isIgnored(map: TraceMap, source: string): boolean; +/** + * A helper that skips sorting of the input map's mappings array, which can be expensive for larger + * maps. + */ +export declare function presortedDecodedMap(map: DecodedSourceMap, mapUrl?: string): TraceMap; +/** + * Returns a sourcemap object (with decoded mappings) suitable for passing to a library that expects + * a sourcemap, or to JSON.stringify. + */ +export declare function decodedMap(map: TraceMap): Omit & { + mappings: readonly SourceMapSegment[][]; +}; +/** + * Returns a sourcemap object (with encoded mappings) suitable for passing to a library that expects + * a sourcemap, or to JSON.stringify. + */ +export declare function encodedMap(map: TraceMap): EncodedSourceMap; +//# sourceMappingURL=trace-mapping.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.mts.map b/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.mts.map new file mode 100644 index 0000000..b5a874c --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/trace-mapping.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"trace-mapping.d.ts","sourceRoot":"","sources":["../src/trace-mapping.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,gBAAgB,EAAkB,MAAM,qBAAqB,CAAC;AAC5E,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,uBAAuB,EACvB,gBAAgB,EAChB,cAAc,EACd,MAAM,EACN,YAAY,EACZ,SAAS,EACT,WAAW,EAIX,EAAE,EACH,MAAM,SAAS,CAAC;AAIjB,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,OAAO,EACP,kBAAkB,EAClB,WAAW,EACX,IAAI,EACJ,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,sBAAsB,EACtB,MAAM,EACN,eAAe,EACf,eAAe,IAAI,OAAO,EAC1B,uBAAuB,EACvB,cAAc,EACd,YAAY,EACZ,MAAM,EACN,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,aAAa,GACd,MAAM,SAAS,CAAC;AAajB,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,OAAO,EAAE,UAAU,EAAE,UAAU,IAAI,MAAM,EAAE,MAAM,eAAe,CAAC;AAEjE,qBAAa,QAAS,YAAW,SAAS;IAChC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAChC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1B,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC5B,UAAU,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;IACtC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAChC,cAAc,EAAE,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAC9C,UAAU,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;IAEtC,eAAe,EAAE,MAAM,EAAE,CAAC;IAClC,QAAgB,QAAQ,CAAqB;IAE7C,QAAgB,QAAQ,CAAmC;IAC3D,QAAgB,YAAY,CAAY;IAExC,QAAgB,UAAU,CAAuB;IACjD,QAAgB,cAAc,CAA0B;gBAE5C,GAAG,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;CAmC5D;AAUD;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAE3E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,GAAG,QAAQ,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAErF;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,QAAQ,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAiBnC;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,MAAM,GACb,eAAe,GAAG,sBAAsB,CAiC1C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,YAAY,GACnB,gBAAgB,GAAG,uBAAuB,CAG5C;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,GAAG,gBAAgB,EAAE,CAIhG;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI,CAgCnF;AASD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK7E;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAKhE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAIpF;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,QAAQ,GACZ,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,GAAG;IAAE,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EAAE,CAAA;CAAE,CAElF;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,QAAQ,GAAG,gBAAgB,CAE1D"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/types.d.cts b/node_modules/@jridgewell/trace-mapping/types/types.d.cts new file mode 100644 index 0000000..729c2c3 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/types.d.cts @@ -0,0 +1,107 @@ +import type { SourceMapSegment } from './sourcemap-segment.cts'; +import type { GREATEST_LOWER_BOUND, LEAST_UPPER_BOUND, TraceMap } from './trace-mapping.cts'; +export interface SourceMapV3 { + file?: string | null; + names: string[]; + sourceRoot?: string; + sources: (string | null)[]; + sourcesContent?: (string | null)[]; + version: 3; + ignoreList?: number[]; +} +export interface EncodedSourceMap extends SourceMapV3 { + mappings: string; +} +export interface DecodedSourceMap extends SourceMapV3 { + mappings: SourceMapSegment[][]; +} +export interface Section { + offset: { + line: number; + column: number; + }; + map: EncodedSourceMap | DecodedSourceMap | SectionedSourceMap; +} +export interface SectionedSourceMap { + file?: string | null; + sections: Section[]; + version: 3; +} +export type OriginalMapping = { + source: string | null; + line: number; + column: number; + name: string | null; +}; +export type InvalidOriginalMapping = { + source: null; + line: null; + column: null; + name: null; +}; +export type GeneratedMapping = { + line: number; + column: number; +}; +export type InvalidGeneratedMapping = { + line: null; + column: null; +}; +export type Bias = typeof GREATEST_LOWER_BOUND | typeof LEAST_UPPER_BOUND; +export type XInput = { + x_google_ignoreList?: SourceMapV3['ignoreList']; +}; +export type EncodedSourceMapXInput = EncodedSourceMap & XInput; +export type DecodedSourceMapXInput = DecodedSourceMap & XInput; +export type SectionedSourceMapXInput = Omit & { + sections: SectionXInput[]; +}; +export type SectionXInput = Omit & { + map: SectionedSourceMapInput; +}; +export type SourceMapInput = string | EncodedSourceMapXInput | DecodedSourceMapXInput | TraceMap; +export type SectionedSourceMapInput = SourceMapInput | SectionedSourceMapXInput; +export type Needle = { + line: number; + column: number; + bias?: Bias; +}; +export type SourceNeedle = { + source: string; + line: number; + column: number; + bias?: Bias; +}; +export type EachMapping = { + generatedLine: number; + generatedColumn: number; + source: null; + originalLine: null; + originalColumn: null; + name: null; +} | { + generatedLine: number; + generatedColumn: number; + source: string | null; + originalLine: number; + originalColumn: number; + name: string | null; +}; +export declare abstract class SourceMap { + version: SourceMapV3['version']; + file: SourceMapV3['file']; + names: SourceMapV3['names']; + sourceRoot: SourceMapV3['sourceRoot']; + sources: SourceMapV3['sources']; + sourcesContent: SourceMapV3['sourcesContent']; + resolvedSources: SourceMapV3['sources']; + ignoreList: SourceMapV3['ignoreList']; +} +export type Ro = T extends Array ? V[] | Readonly | RoArray | Readonly> : T extends object ? T | Readonly | RoObject | Readonly> : T; +type RoArray = Ro[]; +type RoObject = { + [K in keyof T]: T[K] | Ro; +}; +export declare function parse(map: T): Exclude; +export {}; +//# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/types.d.cts.map b/node_modules/@jridgewell/trace-mapping/types/types.d.cts.map new file mode 100644 index 0000000..9224783 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/types.d.cts.map @@ -0,0 +1 @@ +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEzF,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAC3B,cAAc,CAAC,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IACnC,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,gBAAgB,EAAE,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,GAAG,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,kBAAkB,CAAC;CAC/D;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,CAAC,CAAC;CACZ;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,IAAI,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,IAAI,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AACF,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,IAAI,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG,OAAO,oBAAoB,GAAG,OAAO,iBAAiB,CAAC;AAE1E,MAAM,MAAM,MAAM,GAAG;IAAE,mBAAmB,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,CAAA;CAAE,CAAC;AACzE,MAAM,MAAM,sBAAsB,GAAG,gBAAgB,GAAG,MAAM,CAAC;AAC/D,MAAM,MAAM,sBAAsB,GAAG,gBAAgB,GAAG,MAAM,CAAC;AAC/D,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC,GAAG;IAC5E,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B,CAAC;AACF,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG;IACjD,GAAG,EAAE,uBAAuB,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,sBAAsB,GAAG,sBAAsB,GAAG,QAAQ,CAAC;AACjG,MAAM,MAAM,uBAAuB,GAAG,cAAc,GAAG,wBAAwB,CAAC;AAEhF,MAAM,MAAM,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AACnE,MAAM,MAAM,YAAY,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAEzF,MAAM,MAAM,WAAW,GACnB;IACE,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,IAAI,CAAC;IACb,YAAY,EAAE,IAAI,CAAC;IACnB,cAAc,EAAE,IAAI,CAAC;IACrB,IAAI,EAAE,IAAI,CAAC;CACZ,GACD;IACE,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAAC;AAEN,8BAAsB,SAAS;IACrB,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAChC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1B,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC5B,UAAU,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;IACtC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAChC,cAAc,EAAE,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAC9C,eAAe,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACxC,UAAU,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;CAC/C;AAED,MAAM,MAAM,EAAE,CAAC,CAAC,IACd,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,GACpB,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GACvD,CAAC,SAAS,MAAM,GACd,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GACrD,CAAC,CAAC;AACV,KAAK,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC1B,KAAK,QAAQ,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC;AAEvD,wBAAgB,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,CAEnD"} \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/types.d.mts b/node_modules/@jridgewell/trace-mapping/types/types.d.mts new file mode 100644 index 0000000..a26d186 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/types.d.mts @@ -0,0 +1,107 @@ +import type { SourceMapSegment } from './sourcemap-segment.mts'; +import type { GREATEST_LOWER_BOUND, LEAST_UPPER_BOUND, TraceMap } from './trace-mapping.mts'; +export interface SourceMapV3 { + file?: string | null; + names: string[]; + sourceRoot?: string; + sources: (string | null)[]; + sourcesContent?: (string | null)[]; + version: 3; + ignoreList?: number[]; +} +export interface EncodedSourceMap extends SourceMapV3 { + mappings: string; +} +export interface DecodedSourceMap extends SourceMapV3 { + mappings: SourceMapSegment[][]; +} +export interface Section { + offset: { + line: number; + column: number; + }; + map: EncodedSourceMap | DecodedSourceMap | SectionedSourceMap; +} +export interface SectionedSourceMap { + file?: string | null; + sections: Section[]; + version: 3; +} +export type OriginalMapping = { + source: string | null; + line: number; + column: number; + name: string | null; +}; +export type InvalidOriginalMapping = { + source: null; + line: null; + column: null; + name: null; +}; +export type GeneratedMapping = { + line: number; + column: number; +}; +export type InvalidGeneratedMapping = { + line: null; + column: null; +}; +export type Bias = typeof GREATEST_LOWER_BOUND | typeof LEAST_UPPER_BOUND; +export type XInput = { + x_google_ignoreList?: SourceMapV3['ignoreList']; +}; +export type EncodedSourceMapXInput = EncodedSourceMap & XInput; +export type DecodedSourceMapXInput = DecodedSourceMap & XInput; +export type SectionedSourceMapXInput = Omit & { + sections: SectionXInput[]; +}; +export type SectionXInput = Omit & { + map: SectionedSourceMapInput; +}; +export type SourceMapInput = string | EncodedSourceMapXInput | DecodedSourceMapXInput | TraceMap; +export type SectionedSourceMapInput = SourceMapInput | SectionedSourceMapXInput; +export type Needle = { + line: number; + column: number; + bias?: Bias; +}; +export type SourceNeedle = { + source: string; + line: number; + column: number; + bias?: Bias; +}; +export type EachMapping = { + generatedLine: number; + generatedColumn: number; + source: null; + originalLine: null; + originalColumn: null; + name: null; +} | { + generatedLine: number; + generatedColumn: number; + source: string | null; + originalLine: number; + originalColumn: number; + name: string | null; +}; +export declare abstract class SourceMap { + version: SourceMapV3['version']; + file: SourceMapV3['file']; + names: SourceMapV3['names']; + sourceRoot: SourceMapV3['sourceRoot']; + sources: SourceMapV3['sources']; + sourcesContent: SourceMapV3['sourcesContent']; + resolvedSources: SourceMapV3['sources']; + ignoreList: SourceMapV3['ignoreList']; +} +export type Ro = T extends Array ? V[] | Readonly | RoArray | Readonly> : T extends object ? T | Readonly | RoObject | Readonly> : T; +type RoArray = Ro[]; +type RoObject = { + [K in keyof T]: T[K] | Ro; +}; +export declare function parse(map: T): Exclude; +export {}; +//# sourceMappingURL=types.d.ts.map \ No newline at end of file diff --git a/node_modules/@jridgewell/trace-mapping/types/types.d.mts.map b/node_modules/@jridgewell/trace-mapping/types/types.d.mts.map new file mode 100644 index 0000000..9224783 --- /dev/null +++ b/node_modules/@jridgewell/trace-mapping/types/types.d.mts.map @@ -0,0 +1 @@ +{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEzF,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IAC3B,cAAc,CAAC,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IACnC,OAAO,EAAE,CAAC,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,gBAAgB,EAAE,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,GAAG,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,kBAAkB,CAAC;CAC/D;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,CAAC,CAAC;CACZ;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,IAAI,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,IAAI,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AACF,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,IAAI,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG,OAAO,oBAAoB,GAAG,OAAO,iBAAiB,CAAC;AAE1E,MAAM,MAAM,MAAM,GAAG;IAAE,mBAAmB,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,CAAA;CAAE,CAAC;AACzE,MAAM,MAAM,sBAAsB,GAAG,gBAAgB,GAAG,MAAM,CAAC;AAC/D,MAAM,MAAM,sBAAsB,GAAG,gBAAgB,GAAG,MAAM,CAAC;AAC/D,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC,GAAG;IAC5E,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B,CAAC;AACF,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG;IACjD,GAAG,EAAE,uBAAuB,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,sBAAsB,GAAG,sBAAsB,GAAG,QAAQ,CAAC;AACjG,MAAM,MAAM,uBAAuB,GAAG,cAAc,GAAG,wBAAwB,CAAC;AAEhF,MAAM,MAAM,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AACnE,MAAM,MAAM,YAAY,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAEzF,MAAM,MAAM,WAAW,GACnB;IACE,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,IAAI,CAAC;IACb,YAAY,EAAE,IAAI,CAAC;IACnB,cAAc,EAAE,IAAI,CAAC;IACrB,IAAI,EAAE,IAAI,CAAC;CACZ,GACD;IACE,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAAC;AAEN,8BAAsB,SAAS;IACrB,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAChC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1B,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAC5B,UAAU,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;IACtC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAChC,cAAc,EAAE,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAC9C,eAAe,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACxC,UAAU,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;CAC/C;AAED,MAAM,MAAM,EAAE,CAAC,CAAC,IACd,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,GACpB,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GACvD,CAAC,SAAS,MAAM,GACd,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GACrD,CAAC,CAAC;AACV,KAAK,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC1B,KAAK,QAAQ,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC;AAEvD,wBAAgB,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,CAEnD"} \ No newline at end of file diff --git a/node_modules/acorn/CHANGELOG.md b/node_modules/acorn/CHANGELOG.md new file mode 100644 index 0000000..c86068c --- /dev/null +++ b/node_modules/acorn/CHANGELOG.md @@ -0,0 +1,954 @@ +## 8.15.0 (2025-06-08) + +### New features + +Support `using` and `await using` syntax. + +The `AnyNode` type is now defined in such a way that plugins can extend it. + +### Bug fixes + +Fix an issue where the `bigint` property of literal nodes for non-decimal bigints had the wrong format. + +The `acorn` CLI tool no longer crashes when emitting a tree that contains a bigint. + +## 8.14.1 (2025-03-05) + +### Bug fixes + +Fix an issue where `await` expressions in class field initializers were inappropriately allowed. + +Properly allow await inside an async arrow function inside a class field initializer. + +Mention the source file name in syntax error messages when given. + +Properly add an empty `attributes` property to every form of `ExportNamedDeclaration`. + +## 8.14.0 (2024-10-27) + +### New features + +Support ES2025 import attributes. + +Support ES2025 RegExp modifiers. + +### Bug fixes + +Support some missing Unicode properties. + +## 8.13.0 (2024-10-16) + +### New features + +Upgrade to Unicode 16.0. + +## 8.12.1 (2024-07-03) + +### Bug fixes + +Fix a regression that caused Acorn to no longer run on Node versions <8.10. + +## 8.12.0 (2024-06-14) + +### New features + +Support ES2025 duplicate capture group names in regular expressions. + +### Bug fixes + +Include `VariableDeclarator` in the `AnyNode` type so that walker objects can refer to it without getting a type error. + +Properly raise a parse error for invalid `for`/`of` statements using `async` as binding name. + +Properly recognize \"use strict\" when preceded by a string with an escaped newline. + +Mark the `Parser` constructor as protected, not private, so plugins can extend it without type errors. + +Fix a bug where some invalid `delete` expressions were let through when the operand was parenthesized and `preserveParens` was enabled. + +Properly normalize line endings in raw strings of invalid template tokens. + +Properly track line numbers for escaped newlines in strings. + +Fix a bug that broke line number accounting after a template literal with invalid escape sequences. + +## 8.11.3 (2023-12-29) + +### Bug fixes + +Add `Function` and `Class` to the `AggregateType` type, so that they can be used in walkers without raising a type error. + +Make sure `onToken` get an `import` keyword token when parsing `import.meta`. + +Fix a bug where `.loc.start` could be undefined for `new.target` `meta` nodes. + +## 8.11.2 (2023-10-27) + +### Bug fixes + +Fix a bug that caused regular expressions after colon tokens to not be properly tokenized in some circumstances. + +## 8.11.1 (2023-10-26) + +### Bug fixes + +Fix a regression where `onToken` would receive 'name' tokens for 'new' keyword tokens. + +## 8.11.0 (2023-10-26) + +### Bug fixes + +Fix an issue where tokenizing (without parsing) an object literal with a property named `class` or `function` could, in some circumstance, put the tokenizer into an invalid state. + +Fix an issue where a slash after a call to a propery named the same as some keywords would be tokenized as a regular expression. + +### New features + +Upgrade to Unicode 15.1. + +Use a set of new, much more precise, TypeScript types. + +## 8.10.0 (2023-07-05) + +### New features + +Add a `checkPrivateFields` option that disables strict checking of private property use. + +## 8.9.0 (2023-06-16) + +### Bug fixes + +Forbid dynamic import after `new`, even when part of a member expression. + +### New features + +Add Unicode properties for ES2023. + +Add support for the `v` flag to regular expressions. + +## 8.8.2 (2023-01-23) + +### Bug fixes + +Fix a bug that caused `allowHashBang` to be set to false when not provided, even with `ecmaVersion >= 14`. + +Fix an exception when passing no option object to `parse` or `new Parser`. + +Fix incorrect parse error on `if (0) let\n[astral identifier char]`. + +## 8.8.1 (2022-10-24) + +### Bug fixes + +Make type for `Comment` compatible with estree types. + +## 8.8.0 (2022-07-21) + +### Bug fixes + +Allow parentheses around spread args in destructuring object assignment. + +Fix an issue where the tree contained `directive` properties in when parsing with a language version that doesn't support them. + +### New features + +Support hashbang comments by default in ECMAScript 2023 and later. + +## 8.7.1 (2021-04-26) + +### Bug fixes + +Stop handling `"use strict"` directives in ECMAScript versions before 5. + +Fix an issue where duplicate quoted export names in `export *` syntax were incorrectly checked. + +Add missing type for `tokTypes`. + +## 8.7.0 (2021-12-27) + +### New features + +Support quoted export names. + +Upgrade to Unicode 14. + +Add support for Unicode 13 properties in regular expressions. + +### Bug fixes + +Use a loop to find line breaks, because the existing regexp search would overrun the end of the searched range and waste a lot of time in minified code. + +## 8.6.0 (2021-11-18) + +### Bug fixes + +Fix a bug where an object literal with multiple `__proto__` properties would incorrectly be accepted if a later property value held an assigment. + +### New features + +Support class private fields with the `in` operator. + +## 8.5.0 (2021-09-06) + +### Bug fixes + +Improve context-dependent tokenization in a number of corner cases. + +Fix location tracking after a 0x2028 or 0x2029 character in a string literal (which before did not increase the line number). + +Fix an issue where arrow function bodies in for loop context would inappropriately consume `in` operators. + +Fix wrong end locations stored on SequenceExpression nodes. + +Implement restriction that `for`/`of` loop LHS can't start with `let`. + +### New features + +Add support for ES2022 class static blocks. + +Allow multiple input files to be passed to the CLI tool. + +## 8.4.1 (2021-06-24) + +### Bug fixes + +Fix a bug where `allowAwaitOutsideFunction` would allow `await` in class field initializers, and setting `ecmaVersion` to 13 or higher would allow top-level await in non-module sources. + +## 8.4.0 (2021-06-11) + +### New features + +A new option, `allowSuperOutsideMethod`, can be used to suppress the error when `super` is used in the wrong context. + +## 8.3.0 (2021-05-31) + +### New features + +Default `allowAwaitOutsideFunction` to true for ECMAScript 2022 an higher. + +Add support for the `d` ([indices](https://github.com/tc39/proposal-regexp-match-indices)) regexp flag. + +## 8.2.4 (2021-05-04) + +### Bug fixes + +Fix spec conformity in corner case 'for await (async of ...)'. + +## 8.2.3 (2021-05-04) + +### Bug fixes + +Fix an issue where the library couldn't parse 'for (async of ...)'. + +Fix a bug in UTF-16 decoding that would read characters incorrectly in some circumstances. + +## 8.2.2 (2021-04-29) + +### Bug fixes + +Fix a bug where a class field initialized to an async arrow function wouldn't allow await inside it. Same issue existed for generator arrow functions with yield. + +## 8.2.1 (2021-04-24) + +### Bug fixes + +Fix a regression introduced in 8.2.0 where static or async class methods with keyword names fail to parse. + +## 8.2.0 (2021-04-24) + +### New features + +Add support for ES2022 class fields and private methods. + +## 8.1.1 (2021-04-12) + +### Various + +Stop shipping source maps in the NPM package. + +## 8.1.0 (2021-03-09) + +### Bug fixes + +Fix a spurious error in nested destructuring arrays. + +### New features + +Expose `allowAwaitOutsideFunction` in CLI interface. + +Make `allowImportExportAnywhere` also apply to `import.meta`. + +## 8.0.5 (2021-01-25) + +### Bug fixes + +Adjust package.json to work with Node 12.16.0 and 13.0-13.6. + +## 8.0.4 (2020-10-05) + +### Bug fixes + +Make `await x ** y` an error, following the spec. + +Fix potentially exponential regular expression. + +## 8.0.3 (2020-10-02) + +### Bug fixes + +Fix a wasteful loop during `Parser` creation when setting `ecmaVersion` to `"latest"`. + +## 8.0.2 (2020-09-30) + +### Bug fixes + +Make the TypeScript types reflect the current allowed values for `ecmaVersion`. + +Fix another regexp/division tokenizer issue. + +## 8.0.1 (2020-08-12) + +### Bug fixes + +Provide the correct value in the `version` export. + +## 8.0.0 (2020-08-12) + +### Bug fixes + +Disallow expressions like `(a = b) = c`. + +Make non-octal escape sequences a syntax error in strict mode. + +### New features + +The package can now be loaded directly as an ECMAScript module in node 13+. + +Update to the set of Unicode properties from ES2021. + +### Breaking changes + +The `ecmaVersion` option is now required. For the moment, omitting it will still work with a warning, but that will change in a future release. + +Some changes to method signatures that may be used by plugins. + +## 7.4.0 (2020-08-03) + +### New features + +Add support for logical assignment operators. + +Add support for numeric separators. + +## 7.3.1 (2020-06-11) + +### Bug fixes + +Make the string in the `version` export match the actual library version. + +## 7.3.0 (2020-06-11) + +### Bug fixes + +Fix a bug that caused parsing of object patterns with a property named `set` that had a default value to fail. + +### New features + +Add support for optional chaining (`?.`). + +## 7.2.0 (2020-05-09) + +### Bug fixes + +Fix precedence issue in parsing of async arrow functions. + +### New features + +Add support for nullish coalescing. + +Add support for `import.meta`. + +Support `export * as ...` syntax. + +Upgrade to Unicode 13. + +## 6.4.1 (2020-03-09) + +### Bug fixes + +More carefully check for valid UTF16 surrogate pairs in regexp validator. + +## 7.1.1 (2020-03-01) + +### Bug fixes + +Treat `\8` and `\9` as invalid escapes in template strings. + +Allow unicode escapes in property names that are keywords. + +Don't error on an exponential operator expression as argument to `await`. + +More carefully check for valid UTF16 surrogate pairs in regexp validator. + +## 7.1.0 (2019-09-24) + +### Bug fixes + +Disallow trailing object literal commas when ecmaVersion is less than 5. + +### New features + +Add a static `acorn` property to the `Parser` class that contains the entire module interface, to allow plugins to access the instance of the library that they are acting on. + +## 7.0.0 (2019-08-13) + +### Breaking changes + +Changes the node format for dynamic imports to use the `ImportExpression` node type, as defined in [ESTree](https://github.com/estree/estree/blob/master/es2020.md#importexpression). + +Makes 10 (ES2019) the default value for the `ecmaVersion` option. + +## 6.3.0 (2019-08-12) + +### New features + +`sourceType: "module"` can now be used even when `ecmaVersion` is less than 6, to parse module-style code that otherwise conforms to an older standard. + +## 6.2.1 (2019-07-21) + +### Bug fixes + +Fix bug causing Acorn to treat some characters as identifier characters that shouldn't be treated as such. + +Fix issue where setting the `allowReserved` option to `"never"` allowed reserved words in some circumstances. + +## 6.2.0 (2019-07-04) + +### Bug fixes + +Improve valid assignment checking in `for`/`in` and `for`/`of` loops. + +Disallow binding `let` in patterns. + +### New features + +Support bigint syntax with `ecmaVersion` >= 11. + +Support dynamic `import` syntax with `ecmaVersion` >= 11. + +Upgrade to Unicode version 12. + +## 6.1.1 (2019-02-27) + +### Bug fixes + +Fix bug that caused parsing default exports of with names to fail. + +## 6.1.0 (2019-02-08) + +### Bug fixes + +Fix scope checking when redefining a `var` as a lexical binding. + +### New features + +Split up `parseSubscripts` to use an internal `parseSubscript` method to make it easier to extend with plugins. + +## 6.0.7 (2019-02-04) + +### Bug fixes + +Check that exported bindings are defined. + +Don't treat `\u180e` as a whitespace character. + +Check for duplicate parameter names in methods. + +Don't allow shorthand properties when they are generators or async methods. + +Forbid binding `await` in async arrow function's parameter list. + +## 6.0.6 (2019-01-30) + +### Bug fixes + +The content of class declarations and expressions is now always parsed in strict mode. + +Don't allow `let` or `const` to bind the variable name `let`. + +Treat class declarations as lexical. + +Don't allow a generator function declaration as the sole body of an `if` or `else`. + +Ignore `"use strict"` when after an empty statement. + +Allow string line continuations with special line terminator characters. + +Treat `for` bodies as part of the `for` scope when checking for conflicting bindings. + +Fix bug with parsing `yield` in a `for` loop initializer. + +Implement special cases around scope checking for functions. + +## 6.0.5 (2019-01-02) + +### Bug fixes + +Fix TypeScript type for `Parser.extend` and add `allowAwaitOutsideFunction` to options type. + +Don't treat `let` as a keyword when the next token is `{` on the next line. + +Fix bug that broke checking for parentheses around an object pattern in a destructuring assignment when `preserveParens` was on. + +## 6.0.4 (2018-11-05) + +### Bug fixes + +Further improvements to tokenizing regular expressions in corner cases. + +## 6.0.3 (2018-11-04) + +### Bug fixes + +Fix bug in tokenizing an expression-less return followed by a function followed by a regular expression. + +Remove stray symlink in the package tarball. + +## 6.0.2 (2018-09-26) + +### Bug fixes + +Fix bug where default expressions could fail to parse inside an object destructuring assignment expression. + +## 6.0.1 (2018-09-14) + +### Bug fixes + +Fix wrong value in `version` export. + +## 6.0.0 (2018-09-14) + +### Bug fixes + +Better handle variable-redefinition checks for catch bindings and functions directly under if statements. + +Forbid `new.target` in top-level arrow functions. + +Fix issue with parsing a regexp after `yield` in some contexts. + +### New features + +The package now comes with TypeScript definitions. + +### Breaking changes + +The default value of the `ecmaVersion` option is now 9 (2018). + +Plugins work differently, and will have to be rewritten to work with this version. + +The loose parser and walker have been moved into separate packages (`acorn-loose` and `acorn-walk`). + +## 5.7.3 (2018-09-10) + +### Bug fixes + +Fix failure to tokenize regexps after expressions like `x.of`. + +Better error message for unterminated template literals. + +## 5.7.2 (2018-08-24) + +### Bug fixes + +Properly handle `allowAwaitOutsideFunction` in for statements. + +Treat function declarations at the top level of modules like let bindings. + +Don't allow async function declarations as the only statement under a label. + +## 5.7.0 (2018-06-15) + +### New features + +Upgraded to Unicode 11. + +## 5.6.0 (2018-05-31) + +### New features + +Allow U+2028 and U+2029 in string when ECMAVersion >= 10. + +Allow binding-less catch statements when ECMAVersion >= 10. + +Add `allowAwaitOutsideFunction` option for parsing top-level `await`. + +## 5.5.3 (2018-03-08) + +### Bug fixes + +A _second_ republish of the code in 5.5.1, this time with yarn, to hopefully get valid timestamps. + +## 5.5.2 (2018-03-08) + +### Bug fixes + +A republish of the code in 5.5.1 in an attempt to solve an issue with the file timestamps in the npm package being 0. + +## 5.5.1 (2018-03-06) + +### Bug fixes + +Fix misleading error message for octal escapes in template strings. + +## 5.5.0 (2018-02-27) + +### New features + +The identifier character categorization is now based on Unicode version 10. + +Acorn will now validate the content of regular expressions, including new ES9 features. + +## 5.4.0 (2018-02-01) + +### Bug fixes + +Disallow duplicate or escaped flags on regular expressions. + +Disallow octal escapes in strings in strict mode. + +### New features + +Add support for async iteration. + +Add support for object spread and rest. + +## 5.3.0 (2017-12-28) + +### Bug fixes + +Fix parsing of floating point literals with leading zeroes in loose mode. + +Allow duplicate property names in object patterns. + +Don't allow static class methods named `prototype`. + +Disallow async functions directly under `if` or `else`. + +Parse right-hand-side of `for`/`of` as an assignment expression. + +Stricter parsing of `for`/`in`. + +Don't allow unicode escapes in contextual keywords. + +### New features + +Parsing class members was factored into smaller methods to allow plugins to hook into it. + +## 5.2.1 (2017-10-30) + +### Bug fixes + +Fix a token context corruption bug. + +## 5.2.0 (2017-10-30) + +### Bug fixes + +Fix token context tracking for `class` and `function` in property-name position. + +Make sure `%*` isn't parsed as a valid operator. + +Allow shorthand properties `get` and `set` to be followed by default values. + +Disallow `super` when not in callee or object position. + +### New features + +Support [`directive` property](https://github.com/estree/estree/compare/b3de58c9997504d6fba04b72f76e6dd1619ee4eb...1da8e603237144f44710360f8feb7a9977e905e0) on directive expression statements. + +## 5.1.2 (2017-09-04) + +### Bug fixes + +Disable parsing of legacy HTML-style comments in modules. + +Fix parsing of async methods whose names are keywords. + +## 5.1.1 (2017-07-06) + +### Bug fixes + +Fix problem with disambiguating regexp and division after a class. + +## 5.1.0 (2017-07-05) + +### Bug fixes + +Fix tokenizing of regexps in an object-desctructuring `for`/`of` loop and after `yield`. + +Parse zero-prefixed numbers with non-octal digits as decimal. + +Allow object/array patterns in rest parameters. + +Don't error when `yield` is used as a property name. + +Allow `async` as a shorthand object property. + +### New features + +Implement the [template literal revision proposal](https://github.com/tc39/proposal-template-literal-revision) for ES9. + +## 5.0.3 (2017-04-01) + +### Bug fixes + +Fix spurious duplicate variable definition errors for named functions. + +## 5.0.2 (2017-03-30) + +### Bug fixes + +A binary operator after a parenthesized arrow expression is no longer incorrectly treated as an error. + +## 5.0.0 (2017-03-28) + +### Bug fixes + +Raise an error for duplicated lexical bindings. + +Fix spurious error when an assignement expression occurred after a spread expression. + +Accept regular expressions after `of` (in `for`/`of`), `yield` (in a generator), and braced arrow functions. + +Allow labels in front or `var` declarations, even in strict mode. + +### Breaking changes + +Parse declarations following `export default` as declaration nodes, not expressions. This means that class and function declarations nodes can now have `null` as their `id`. + +## 4.0.11 (2017-02-07) + +### Bug fixes + +Allow all forms of member expressions to be parenthesized as lvalue. + +## 4.0.10 (2017-02-07) + +### Bug fixes + +Don't expect semicolons after default-exported functions or classes, even when they are expressions. + +Check for use of `'use strict'` directives in non-simple parameter functions, even when already in strict mode. + +## 4.0.9 (2017-02-06) + +### Bug fixes + +Fix incorrect error raised for parenthesized simple assignment targets, so that `(x) = 1` parses again. + +## 4.0.8 (2017-02-03) + +### Bug fixes + +Solve spurious parenthesized pattern errors by temporarily erring on the side of accepting programs that our delayed errors don't handle correctly yet. + +## 4.0.7 (2017-02-02) + +### Bug fixes + +Accept invalidly rejected code like `(x).y = 2` again. + +Don't raise an error when a function _inside_ strict code has a non-simple parameter list. + +## 4.0.6 (2017-02-02) + +### Bug fixes + +Fix exponential behavior (manifesting itself as a complete hang for even relatively small source files) introduced by the new 'use strict' check. + +## 4.0.5 (2017-02-02) + +### Bug fixes + +Disallow parenthesized pattern expressions. + +Allow keywords as export names. + +Don't allow the `async` keyword to be parenthesized. + +Properly raise an error when a keyword contains a character escape. + +Allow `"use strict"` to appear after other string literal expressions. + +Disallow labeled declarations. + +## 4.0.4 (2016-12-19) + +### Bug fixes + +Fix crash when `export` was followed by a keyword that can't be +exported. + +## 4.0.3 (2016-08-16) + +### Bug fixes + +Allow regular function declarations inside single-statement `if` branches in loose mode. Forbid them entirely in strict mode. + +Properly parse properties named `async` in ES2017 mode. + +Fix bug where reserved words were broken in ES2017 mode. + +## 4.0.2 (2016-08-11) + +### Bug fixes + +Don't ignore period or 'e' characters after octal numbers. + +Fix broken parsing for call expressions in default parameter values of arrow functions. + +## 4.0.1 (2016-08-08) + +### Bug fixes + +Fix false positives in duplicated export name errors. + +## 4.0.0 (2016-08-07) + +### Breaking changes + +The default `ecmaVersion` option value is now 7. + +A number of internal method signatures changed, so plugins might need to be updated. + +### Bug fixes + +The parser now raises errors on duplicated export names. + +`arguments` and `eval` can now be used in shorthand properties. + +Duplicate parameter names in non-simple argument lists now always produce an error. + +### New features + +The `ecmaVersion` option now also accepts year-style version numbers +(2015, etc). + +Support for `async`/`await` syntax when `ecmaVersion` is >= 8. + +Support for trailing commas in call expressions when `ecmaVersion` is >= 8. + +## 3.3.0 (2016-07-25) + +### Bug fixes + +Fix bug in tokenizing of regexp operator after a function declaration. + +Fix parser crash when parsing an array pattern with a hole. + +### New features + +Implement check against complex argument lists in functions that enable strict mode in ES7. + +## 3.2.0 (2016-06-07) + +### Bug fixes + +Improve handling of lack of unicode regexp support in host +environment. + +Properly reject shorthand properties whose name is a keyword. + +### New features + +Visitors created with `visit.make` now have their base as _prototype_, rather than copying properties into a fresh object. + +## 3.1.0 (2016-04-18) + +### Bug fixes + +Properly tokenize the division operator directly after a function expression. + +Allow trailing comma in destructuring arrays. + +## 3.0.4 (2016-02-25) + +### Fixes + +Allow update expressions as left-hand-side of the ES7 exponential operator. + +## 3.0.2 (2016-02-10) + +### Fixes + +Fix bug that accidentally made `undefined` a reserved word when parsing ES7. + +## 3.0.0 (2016-02-10) + +### Breaking changes + +The default value of the `ecmaVersion` option is now 6 (used to be 5). + +Support for comprehension syntax (which was dropped from the draft spec) has been removed. + +### Fixes + +`let` and `yield` are now “contextual keywords”, meaning you can mostly use them as identifiers in ES5 non-strict code. + +A parenthesized class or function expression after `export default` is now parsed correctly. + +### New features + +When `ecmaVersion` is set to 7, Acorn will parse the exponentiation operator (`**`). + +The identifier character ranges are now based on Unicode 8.0.0. + +Plugins can now override the `raiseRecoverable` method to override the way non-critical errors are handled. + +## 2.7.0 (2016-01-04) + +### Fixes + +Stop allowing rest parameters in setters. + +Disallow `y` rexexp flag in ES5. + +Disallow `\00` and `\000` escapes in strict mode. + +Raise an error when an import name is a reserved word. + +## 2.6.2 (2015-11-10) + +### Fixes + +Don't crash when no options object is passed. + +## 2.6.0 (2015-11-09) + +### Fixes + +Add `await` as a reserved word in module sources. + +Disallow `yield` in a parameter default value for a generator. + +Forbid using a comma after a rest pattern in an array destructuring. + +### New features + +Support parsing stdin in command-line tool. + +## 2.5.0 (2015-10-27) + +### Fixes + +Fix tokenizer support in the command-line tool. + +Stop allowing `new.target` outside of functions. + +Remove legacy `guard` and `guardedHandler` properties from try nodes. + +Stop allowing multiple `__proto__` properties on an object literal in strict mode. + +Don't allow rest parameters to be non-identifier patterns. + +Check for duplicate paramter names in arrow functions. diff --git a/node_modules/acorn/LICENSE b/node_modules/acorn/LICENSE new file mode 100644 index 0000000..9d71cc6 --- /dev/null +++ b/node_modules/acorn/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (C) 2012-2022 by various contributors (see AUTHORS) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/acorn/README.md b/node_modules/acorn/README.md new file mode 100644 index 0000000..f7ff966 --- /dev/null +++ b/node_modules/acorn/README.md @@ -0,0 +1,282 @@ +# Acorn + +A tiny, fast JavaScript parser written in JavaScript. + +## Community + +Acorn is open source software released under an +[MIT license](https://github.com/acornjs/acorn/blob/master/acorn/LICENSE). + +You are welcome to +[report bugs](https://github.com/acornjs/acorn/issues) or create pull +requests on [github](https://github.com/acornjs/acorn). + +## Installation + +The easiest way to install acorn is from [`npm`](https://www.npmjs.com/): + +```sh +npm install acorn +``` + +Alternately, you can download the source and build acorn yourself: + +```sh +git clone https://github.com/acornjs/acorn.git +cd acorn +npm install +``` + +## Interface + +**parse**`(input, options)` is the main interface to the library. The +`input` parameter is a string, `options` must be an object setting +some of the options listed below. The return value will be an abstract +syntax tree object as specified by the [ESTree +spec](https://github.com/estree/estree). + +```javascript +let acorn = require("acorn"); +console.log(acorn.parse("1 + 1", {ecmaVersion: 2020})); +``` + +When encountering a syntax error, the parser will raise a +`SyntaxError` object with a meaningful message. The error object will +have a `pos` property that indicates the string offset at which the +error occurred, and a `loc` object that contains a `{line, column}` +object referring to that same position. + +Options are provided by in a second argument, which should be an +object containing any of these fields (only `ecmaVersion` is +required): + +- **ecmaVersion**: Indicates the ECMAScript version to parse. Can be a + number, either in year (`2022`) or plain version number (`6`) form, + or `"latest"` (the latest the library supports). This influences + support for strict mode, the set of reserved words, and support for + new syntax features. + + **NOTE**: Only 'stage 4' (finalized) ECMAScript features are being + implemented by Acorn. Other proposed new features must be + implemented through plugins. + +- **sourceType**: Indicate the mode the code should be parsed in. Can be + either `"script"` or `"module"`. This influences global strict mode + and parsing of `import` and `export` declarations. + + **NOTE**: If set to `"module"`, then static `import` / `export` syntax + will be valid, even if `ecmaVersion` is less than 6. + +- **onInsertedSemicolon**: If given a callback, that callback will be + called whenever a missing semicolon is inserted by the parser. The + callback will be given the character offset of the point where the + semicolon is inserted as argument, and if `locations` is on, also a + `{line, column}` object representing this position. + +- **onTrailingComma**: Like `onInsertedSemicolon`, but for trailing + commas. + +- **allowReserved**: If `false`, using a reserved word will generate + an error. Defaults to `true` for `ecmaVersion` 3, `false` for higher + versions. When given the value `"never"`, reserved words and + keywords can also not be used as property names (as in Internet + Explorer's old parser). + +- **allowReturnOutsideFunction**: By default, a return statement at + the top level raises an error. Set this to `true` to accept such + code. + +- **allowImportExportEverywhere**: By default, `import` and `export` + declarations can only appear at a program's top level. Setting this + option to `true` allows them anywhere where a statement is allowed, + and also allows `import.meta` expressions to appear in scripts + (when `sourceType` is not `"module"`). + +- **allowAwaitOutsideFunction**: If `false`, `await` expressions can + only appear inside `async` functions. Defaults to `true` in modules + for `ecmaVersion` 2022 and later, `false` for lower versions. + Setting this option to `true` allows to have top-level `await` + expressions. They are still not allowed in non-`async` functions, + though. + +- **allowSuperOutsideMethod**: By default, `super` outside a method + raises an error. Set this to `true` to accept such code. + +- **allowHashBang**: When this is enabled, if the code starts with the + characters `#!` (as in a shellscript), the first line will be + treated as a comment. Defaults to true when `ecmaVersion` >= 2023. + +- **checkPrivateFields**: By default, the parser will verify that + private properties are only used in places where they are valid and + have been declared. Set this to false to turn such checks off. + +- **locations**: When `true`, each node has a `loc` object attached + with `start` and `end` subobjects, each of which contains the + one-based line and zero-based column numbers in `{line, column}` + form. Default is `false`. + +- **onToken**: If a function is passed for this option, each found + token will be passed in same format as tokens returned from + `tokenizer().getToken()`. + + If array is passed, each found token is pushed to it. + + Note that you are not allowed to call the parser from the + callback—that will corrupt its internal state. + +- **onComment**: If a function is passed for this option, whenever a + comment is encountered the function will be called with the + following parameters: + + - `block`: `true` if the comment is a block comment, false if it + is a line comment. + - `text`: The content of the comment. + - `start`: Character offset of the start of the comment. + - `end`: Character offset of the end of the comment. + + When the `locations` options is on, the `{line, column}` locations + of the comment’s start and end are passed as two additional + parameters. + + If array is passed for this option, each found comment is pushed + to it as object in Esprima format: + + ```javascript + { + "type": "Line" | "Block", + "value": "comment text", + "start": Number, + "end": Number, + // If `locations` option is on: + "loc": { + "start": {line: Number, column: Number} + "end": {line: Number, column: Number} + }, + // If `ranges` option is on: + "range": [Number, Number] + } + ``` + + Note that you are not allowed to call the parser from the + callback—that will corrupt its internal state. + +- **ranges**: Nodes have their start and end characters offsets + recorded in `start` and `end` properties (directly on the node, + rather than the `loc` object, which holds line/column data. To also + add a + [semi-standardized](https://bugzilla.mozilla.org/show_bug.cgi?id=745678) + `range` property holding a `[start, end]` array with the same + numbers, set the `ranges` option to `true`. + +- **program**: It is possible to parse multiple files into a single + AST by passing the tree produced by parsing the first file as the + `program` option in subsequent parses. This will add the toplevel + forms of the parsed file to the "Program" (top) node of an existing + parse tree. + +- **sourceFile**: When the `locations` option is `true`, you can pass + this option to add a `source` attribute in every node’s `loc` + object. Note that the contents of this option are not examined or + processed in any way; you are free to use whatever format you + choose. + +- **directSourceFile**: Like `sourceFile`, but a `sourceFile` property + will be added (regardless of the `location` option) directly to the + nodes, rather than the `loc` object. + +- **preserveParens**: If this option is `true`, parenthesized expressions + are represented by (non-standard) `ParenthesizedExpression` nodes + that have a single `expression` property containing the expression + inside parentheses. + +**parseExpressionAt**`(input, offset, options)` will parse a single +expression in a string, and return its AST. It will not complain if +there is more of the string left after the expression. + +**tokenizer**`(input, options)` returns an object with a `getToken` +method that can be called repeatedly to get the next token, a `{start, +end, type, value}` object (with added `loc` property when the +`locations` option is enabled and `range` property when the `ranges` +option is enabled). When the token's type is `tokTypes.eof`, you +should stop calling the method, since it will keep returning that same +token forever. + +Note that tokenizing JavaScript without parsing it is, in modern +versions of the language, not really possible due to the way syntax is +overloaded in ways that can only be disambiguated by the parse +context. This package applies a bunch of heuristics to try and do a +reasonable job, but you are advised to use `parse` with the `onToken` +option instead of this. + +In ES6 environment, returned result can be used as any other +protocol-compliant iterable: + +```javascript +for (let token of acorn.tokenizer(str)) { + // iterate over the tokens +} + +// transform code to array of tokens: +var tokens = [...acorn.tokenizer(str)]; +``` + +**tokTypes** holds an object mapping names to the token type objects +that end up in the `type` properties of tokens. + +**getLineInfo**`(input, offset)` can be used to get a `{line, +column}` object for a given program string and offset. + +### The `Parser` class + +Instances of the **`Parser`** class contain all the state and logic +that drives a parse. It has static methods `parse`, +`parseExpressionAt`, and `tokenizer` that match the top-level +functions by the same name. + +When extending the parser with plugins, you need to call these methods +on the extended version of the class. To extend a parser with plugins, +you can use its static `extend` method. + +```javascript +var acorn = require("acorn"); +var jsx = require("acorn-jsx"); +var JSXParser = acorn.Parser.extend(jsx()); +JSXParser.parse("foo()", {ecmaVersion: 2020}); +``` + +The `extend` method takes any number of plugin values, and returns a +new `Parser` class that includes the extra parser logic provided by +the plugins. + +## Command line interface + +The `bin/acorn` utility can be used to parse a file from the command +line. It accepts as arguments its input file and the following +options: + +- `--ecma3|--ecma5|--ecma6|--ecma7|--ecma8|--ecma9|--ecma10`: Sets the ECMAScript version + to parse. Default is version 9. + +- `--module`: Sets the parsing mode to `"module"`. Is set to `"script"` otherwise. + +- `--locations`: Attaches a "loc" object to each node with "start" and + "end" subobjects, each of which contains the one-based line and + zero-based column numbers in `{line, column}` form. + +- `--allow-hash-bang`: If the code starts with the characters #! (as + in a shellscript), the first line will be treated as a comment. + +- `--allow-await-outside-function`: Allows top-level `await` expressions. + See the `allowAwaitOutsideFunction` option for more information. + +- `--compact`: No whitespace is used in the AST output. + +- `--silent`: Do not output the AST, just return the exit status. + +- `--help`: Print the usage information and quit. + +The utility spits out the syntax tree as JSON data. + +## Existing plugins + + - [`acorn-jsx`](https://github.com/RReverser/acorn-jsx): Parse [Facebook JSX syntax extensions](https://github.com/facebook/jsx) diff --git a/node_modules/acorn/bin/acorn b/node_modules/acorn/bin/acorn new file mode 100755 index 0000000..3ef3c12 --- /dev/null +++ b/node_modules/acorn/bin/acorn @@ -0,0 +1,4 @@ +#!/usr/bin/env node +"use strict" + +require("../dist/bin.js") diff --git a/node_modules/acorn/dist/acorn.d.mts b/node_modules/acorn/dist/acorn.d.mts new file mode 100644 index 0000000..f2ec524 --- /dev/null +++ b/node_modules/acorn/dist/acorn.d.mts @@ -0,0 +1,883 @@ +export interface Node { + start: number + end: number + type: string + range?: [number, number] + loc?: SourceLocation | null +} + +export interface SourceLocation { + source?: string | null + start: Position + end: Position +} + +export interface Position { + /** 1-based */ + line: number + /** 0-based */ + column: number +} + +export interface Identifier extends Node { + type: "Identifier" + name: string +} + +export interface Literal extends Node { + type: "Literal" + value?: string | boolean | null | number | RegExp | bigint + raw?: string + regex?: { + pattern: string + flags: string + } + bigint?: string +} + +export interface Program extends Node { + type: "Program" + body: Array + sourceType: "script" | "module" +} + +export interface Function extends Node { + id?: Identifier | null + params: Array + body: BlockStatement | Expression + generator: boolean + expression: boolean + async: boolean +} + +export interface ExpressionStatement extends Node { + type: "ExpressionStatement" + expression: Expression | Literal + directive?: string +} + +export interface BlockStatement extends Node { + type: "BlockStatement" + body: Array +} + +export interface EmptyStatement extends Node { + type: "EmptyStatement" +} + +export interface DebuggerStatement extends Node { + type: "DebuggerStatement" +} + +export interface WithStatement extends Node { + type: "WithStatement" + object: Expression + body: Statement +} + +export interface ReturnStatement extends Node { + type: "ReturnStatement" + argument?: Expression | null +} + +export interface LabeledStatement extends Node { + type: "LabeledStatement" + label: Identifier + body: Statement +} + +export interface BreakStatement extends Node { + type: "BreakStatement" + label?: Identifier | null +} + +export interface ContinueStatement extends Node { + type: "ContinueStatement" + label?: Identifier | null +} + +export interface IfStatement extends Node { + type: "IfStatement" + test: Expression + consequent: Statement + alternate?: Statement | null +} + +export interface SwitchStatement extends Node { + type: "SwitchStatement" + discriminant: Expression + cases: Array +} + +export interface SwitchCase extends Node { + type: "SwitchCase" + test?: Expression | null + consequent: Array +} + +export interface ThrowStatement extends Node { + type: "ThrowStatement" + argument: Expression +} + +export interface TryStatement extends Node { + type: "TryStatement" + block: BlockStatement + handler?: CatchClause | null + finalizer?: BlockStatement | null +} + +export interface CatchClause extends Node { + type: "CatchClause" + param?: Pattern | null + body: BlockStatement +} + +export interface WhileStatement extends Node { + type: "WhileStatement" + test: Expression + body: Statement +} + +export interface DoWhileStatement extends Node { + type: "DoWhileStatement" + body: Statement + test: Expression +} + +export interface ForStatement extends Node { + type: "ForStatement" + init?: VariableDeclaration | Expression | null + test?: Expression | null + update?: Expression | null + body: Statement +} + +export interface ForInStatement extends Node { + type: "ForInStatement" + left: VariableDeclaration | Pattern + right: Expression + body: Statement +} + +export interface FunctionDeclaration extends Function { + type: "FunctionDeclaration" + id: Identifier + body: BlockStatement +} + +export interface VariableDeclaration extends Node { + type: "VariableDeclaration" + declarations: Array + kind: "var" | "let" | "const" | "using" | "await using" +} + +export interface VariableDeclarator extends Node { + type: "VariableDeclarator" + id: Pattern + init?: Expression | null +} + +export interface ThisExpression extends Node { + type: "ThisExpression" +} + +export interface ArrayExpression extends Node { + type: "ArrayExpression" + elements: Array +} + +export interface ObjectExpression extends Node { + type: "ObjectExpression" + properties: Array +} + +export interface Property extends Node { + type: "Property" + key: Expression + value: Expression + kind: "init" | "get" | "set" + method: boolean + shorthand: boolean + computed: boolean +} + +export interface FunctionExpression extends Function { + type: "FunctionExpression" + body: BlockStatement +} + +export interface UnaryExpression extends Node { + type: "UnaryExpression" + operator: UnaryOperator + prefix: boolean + argument: Expression +} + +export type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete" + +export interface UpdateExpression extends Node { + type: "UpdateExpression" + operator: UpdateOperator + argument: Expression + prefix: boolean +} + +export type UpdateOperator = "++" | "--" + +export interface BinaryExpression extends Node { + type: "BinaryExpression" + operator: BinaryOperator + left: Expression | PrivateIdentifier + right: Expression +} + +export type BinaryOperator = "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "|" | "^" | "&" | "in" | "instanceof" | "**" + +export interface AssignmentExpression extends Node { + type: "AssignmentExpression" + operator: AssignmentOperator + left: Pattern + right: Expression +} + +export type AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | ">>>=" | "|=" | "^=" | "&=" | "**=" | "||=" | "&&=" | "??=" + +export interface LogicalExpression extends Node { + type: "LogicalExpression" + operator: LogicalOperator + left: Expression + right: Expression +} + +export type LogicalOperator = "||" | "&&" | "??" + +export interface MemberExpression extends Node { + type: "MemberExpression" + object: Expression | Super + property: Expression | PrivateIdentifier + computed: boolean + optional: boolean +} + +export interface ConditionalExpression extends Node { + type: "ConditionalExpression" + test: Expression + alternate: Expression + consequent: Expression +} + +export interface CallExpression extends Node { + type: "CallExpression" + callee: Expression | Super + arguments: Array + optional: boolean +} + +export interface NewExpression extends Node { + type: "NewExpression" + callee: Expression + arguments: Array +} + +export interface SequenceExpression extends Node { + type: "SequenceExpression" + expressions: Array +} + +export interface ForOfStatement extends Node { + type: "ForOfStatement" + left: VariableDeclaration | Pattern + right: Expression + body: Statement + await: boolean +} + +export interface Super extends Node { + type: "Super" +} + +export interface SpreadElement extends Node { + type: "SpreadElement" + argument: Expression +} + +export interface ArrowFunctionExpression extends Function { + type: "ArrowFunctionExpression" +} + +export interface YieldExpression extends Node { + type: "YieldExpression" + argument?: Expression | null + delegate: boolean +} + +export interface TemplateLiteral extends Node { + type: "TemplateLiteral" + quasis: Array + expressions: Array +} + +export interface TaggedTemplateExpression extends Node { + type: "TaggedTemplateExpression" + tag: Expression + quasi: TemplateLiteral +} + +export interface TemplateElement extends Node { + type: "TemplateElement" + tail: boolean + value: { + cooked?: string | null + raw: string + } +} + +export interface AssignmentProperty extends Node { + type: "Property" + key: Expression + value: Pattern + kind: "init" + method: false + shorthand: boolean + computed: boolean +} + +export interface ObjectPattern extends Node { + type: "ObjectPattern" + properties: Array +} + +export interface ArrayPattern extends Node { + type: "ArrayPattern" + elements: Array +} + +export interface RestElement extends Node { + type: "RestElement" + argument: Pattern +} + +export interface AssignmentPattern extends Node { + type: "AssignmentPattern" + left: Pattern + right: Expression +} + +export interface Class extends Node { + id?: Identifier | null + superClass?: Expression | null + body: ClassBody +} + +export interface ClassBody extends Node { + type: "ClassBody" + body: Array +} + +export interface MethodDefinition extends Node { + type: "MethodDefinition" + key: Expression | PrivateIdentifier + value: FunctionExpression + kind: "constructor" | "method" | "get" | "set" + computed: boolean + static: boolean +} + +export interface ClassDeclaration extends Class { + type: "ClassDeclaration" + id: Identifier +} + +export interface ClassExpression extends Class { + type: "ClassExpression" +} + +export interface MetaProperty extends Node { + type: "MetaProperty" + meta: Identifier + property: Identifier +} + +export interface ImportDeclaration extends Node { + type: "ImportDeclaration" + specifiers: Array + source: Literal + attributes: Array +} + +export interface ImportSpecifier extends Node { + type: "ImportSpecifier" + imported: Identifier | Literal + local: Identifier +} + +export interface ImportDefaultSpecifier extends Node { + type: "ImportDefaultSpecifier" + local: Identifier +} + +export interface ImportNamespaceSpecifier extends Node { + type: "ImportNamespaceSpecifier" + local: Identifier +} + +export interface ImportAttribute extends Node { + type: "ImportAttribute" + key: Identifier | Literal + value: Literal +} + +export interface ExportNamedDeclaration extends Node { + type: "ExportNamedDeclaration" + declaration?: Declaration | null + specifiers: Array + source?: Literal | null + attributes: Array +} + +export interface ExportSpecifier extends Node { + type: "ExportSpecifier" + exported: Identifier | Literal + local: Identifier | Literal +} + +export interface AnonymousFunctionDeclaration extends Function { + type: "FunctionDeclaration" + id: null + body: BlockStatement +} + +export interface AnonymousClassDeclaration extends Class { + type: "ClassDeclaration" + id: null +} + +export interface ExportDefaultDeclaration extends Node { + type: "ExportDefaultDeclaration" + declaration: AnonymousFunctionDeclaration | FunctionDeclaration | AnonymousClassDeclaration | ClassDeclaration | Expression +} + +export interface ExportAllDeclaration extends Node { + type: "ExportAllDeclaration" + source: Literal + exported?: Identifier | Literal | null + attributes: Array +} + +export interface AwaitExpression extends Node { + type: "AwaitExpression" + argument: Expression +} + +export interface ChainExpression extends Node { + type: "ChainExpression" + expression: MemberExpression | CallExpression +} + +export interface ImportExpression extends Node { + type: "ImportExpression" + source: Expression + options: Expression | null +} + +export interface ParenthesizedExpression extends Node { + type: "ParenthesizedExpression" + expression: Expression +} + +export interface PropertyDefinition extends Node { + type: "PropertyDefinition" + key: Expression | PrivateIdentifier + value?: Expression | null + computed: boolean + static: boolean +} + +export interface PrivateIdentifier extends Node { + type: "PrivateIdentifier" + name: string +} + +export interface StaticBlock extends Node { + type: "StaticBlock" + body: Array +} + +export type Statement = +| ExpressionStatement +| BlockStatement +| EmptyStatement +| DebuggerStatement +| WithStatement +| ReturnStatement +| LabeledStatement +| BreakStatement +| ContinueStatement +| IfStatement +| SwitchStatement +| ThrowStatement +| TryStatement +| WhileStatement +| DoWhileStatement +| ForStatement +| ForInStatement +| ForOfStatement +| Declaration + +export type Declaration = +| FunctionDeclaration +| VariableDeclaration +| ClassDeclaration + +export type Expression = +| Identifier +| Literal +| ThisExpression +| ArrayExpression +| ObjectExpression +| FunctionExpression +| UnaryExpression +| UpdateExpression +| BinaryExpression +| AssignmentExpression +| LogicalExpression +| MemberExpression +| ConditionalExpression +| CallExpression +| NewExpression +| SequenceExpression +| ArrowFunctionExpression +| YieldExpression +| TemplateLiteral +| TaggedTemplateExpression +| ClassExpression +| MetaProperty +| AwaitExpression +| ChainExpression +| ImportExpression +| ParenthesizedExpression + +export type Pattern = +| Identifier +| MemberExpression +| ObjectPattern +| ArrayPattern +| RestElement +| AssignmentPattern + +export type ModuleDeclaration = +| ImportDeclaration +| ExportNamedDeclaration +| ExportDefaultDeclaration +| ExportAllDeclaration + +/** + * This interface is only used for defining {@link AnyNode}. + * It exists so that it can be extended by plugins: + * + * @example + * ```typescript + * declare module 'acorn' { + * interface NodeTypes { + * pluginName: FirstNode | SecondNode | ThirdNode | ... | LastNode + * } + * } + * ``` + */ +interface NodeTypes { + core: Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportAttribute | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator +} + +export type AnyNode = NodeTypes[keyof NodeTypes] + +export function parse(input: string, options: Options): Program + +export function parseExpressionAt(input: string, pos: number, options: Options): Expression + +export function tokenizer(input: string, options: Options): { + getToken(): Token + [Symbol.iterator](): Iterator +} + +export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | "latest" + +export interface Options { + /** + * `ecmaVersion` indicates the ECMAScript version to parse. Can be a + * number, either in year (`2022`) or plain version number (`6`) form, + * or `"latest"` (the latest the library supports). This influences + * support for strict mode, the set of reserved words, and support for + * new syntax features. + */ + ecmaVersion: ecmaVersion + + /** + * `sourceType` indicates the mode the code should be parsed in. + * Can be either `"script"` or `"module"`. This influences global + * strict mode and parsing of `import` and `export` declarations. + */ + sourceType?: "script" | "module" + + /** + * a callback that will be called when a semicolon is automatically inserted. + * @param lastTokEnd the position of the comma as an offset + * @param lastTokEndLoc location if {@link locations} is enabled + */ + onInsertedSemicolon?: (lastTokEnd: number, lastTokEndLoc?: Position) => void + + /** + * similar to `onInsertedSemicolon`, but for trailing commas + * @param lastTokEnd the position of the comma as an offset + * @param lastTokEndLoc location if `locations` is enabled + */ + onTrailingComma?: (lastTokEnd: number, lastTokEndLoc?: Position) => void + + /** + * By default, reserved words are only enforced if ecmaVersion >= 5. + * Set `allowReserved` to a boolean value to explicitly turn this on + * an off. When this option has the value "never", reserved words + * and keywords can also not be used as property names. + */ + allowReserved?: boolean | "never" + + /** + * When enabled, a return at the top level is not considered an error. + */ + allowReturnOutsideFunction?: boolean + + /** + * When enabled, import/export statements are not constrained to + * appearing at the top of the program, and an import.meta expression + * in a script isn't considered an error. + */ + allowImportExportEverywhere?: boolean + + /** + * By default, `await` identifiers are allowed to appear at the top-level scope only if {@link ecmaVersion} >= 2022. + * When enabled, await identifiers are allowed to appear at the top-level scope, + * but they are still not allowed in non-async functions. + */ + allowAwaitOutsideFunction?: boolean + + /** + * When enabled, super identifiers are not constrained to + * appearing in methods and do not raise an error when they appear elsewhere. + */ + allowSuperOutsideMethod?: boolean + + /** + * When enabled, hashbang directive in the beginning of file is + * allowed and treated as a line comment. Enabled by default when + * {@link ecmaVersion} >= 2023. + */ + allowHashBang?: boolean + + /** + * By default, the parser will verify that private properties are + * only used in places where they are valid and have been declared. + * Set this to false to turn such checks off. + */ + checkPrivateFields?: boolean + + /** + * When `locations` is on, `loc` properties holding objects with + * `start` and `end` properties as {@link Position} objects will be attached to the + * nodes. + */ + locations?: boolean + + /** + * a callback that will cause Acorn to call that export function with object in the same + * format as tokens returned from `tokenizer().getToken()`. Note + * that you are not allowed to call the parser from the + * callback—that will corrupt its internal state. + */ + onToken?: ((token: Token) => void) | Token[] + + + /** + * This takes a export function or an array. + * + * When a export function is passed, Acorn will call that export function with `(block, text, start, + * end)` parameters whenever a comment is skipped. `block` is a + * boolean indicating whether this is a block (`/* *\/`) comment, + * `text` is the content of the comment, and `start` and `end` are + * character offsets that denote the start and end of the comment. + * When the {@link locations} option is on, two more parameters are + * passed, the full locations of {@link Position} export type of the start and + * end of the comments. + * + * When a array is passed, each found comment of {@link Comment} export type is pushed to the array. + * + * Note that you are not allowed to call the + * parser from the callback—that will corrupt its internal state. + */ + onComment?: (( + isBlock: boolean, text: string, start: number, end: number, startLoc?: Position, + endLoc?: Position + ) => void) | Comment[] + + /** + * Nodes have their start and end characters offsets recorded in + * `start` and `end` properties (directly on the node, rather than + * the `loc` object, which holds line/column data. To also add a + * [semi-standardized][range] `range` property holding a `[start, + * end]` array with the same numbers, set the `ranges` option to + * `true`. + */ + ranges?: boolean + + /** + * It is possible to parse multiple files into a single AST by + * passing the tree produced by parsing the first file as + * `program` option in subsequent parses. This will add the + * toplevel forms of the parsed file to the `Program` (top) node + * of an existing parse tree. + */ + program?: Node + + /** + * When {@link locations} is on, you can pass this to record the source + * file in every node's `loc` object. + */ + sourceFile?: string + + /** + * This value, if given, is stored in every node, whether {@link locations} is on or off. + */ + directSourceFile?: string + + /** + * When enabled, parenthesized expressions are represented by + * (non-standard) ParenthesizedExpression nodes + */ + preserveParens?: boolean +} + +export class Parser { + options: Options + input: string + + protected constructor(options: Options, input: string, startPos?: number) + parse(): Program + + static parse(input: string, options: Options): Program + static parseExpressionAt(input: string, pos: number, options: Options): Expression + static tokenizer(input: string, options: Options): { + getToken(): Token + [Symbol.iterator](): Iterator + } + static extend(...plugins: ((BaseParser: typeof Parser) => typeof Parser)[]): typeof Parser +} + +export const defaultOptions: Options + +export function getLineInfo(input: string, offset: number): Position + +export class TokenType { + label: string + keyword: string | undefined +} + +export const tokTypes: { + num: TokenType + regexp: TokenType + string: TokenType + name: TokenType + privateId: TokenType + eof: TokenType + + bracketL: TokenType + bracketR: TokenType + braceL: TokenType + braceR: TokenType + parenL: TokenType + parenR: TokenType + comma: TokenType + semi: TokenType + colon: TokenType + dot: TokenType + question: TokenType + questionDot: TokenType + arrow: TokenType + template: TokenType + invalidTemplate: TokenType + ellipsis: TokenType + backQuote: TokenType + dollarBraceL: TokenType + + eq: TokenType + assign: TokenType + incDec: TokenType + prefix: TokenType + logicalOR: TokenType + logicalAND: TokenType + bitwiseOR: TokenType + bitwiseXOR: TokenType + bitwiseAND: TokenType + equality: TokenType + relational: TokenType + bitShift: TokenType + plusMin: TokenType + modulo: TokenType + star: TokenType + slash: TokenType + starstar: TokenType + coalesce: TokenType + + _break: TokenType + _case: TokenType + _catch: TokenType + _continue: TokenType + _debugger: TokenType + _default: TokenType + _do: TokenType + _else: TokenType + _finally: TokenType + _for: TokenType + _function: TokenType + _if: TokenType + _return: TokenType + _switch: TokenType + _throw: TokenType + _try: TokenType + _var: TokenType + _const: TokenType + _while: TokenType + _with: TokenType + _new: TokenType + _this: TokenType + _super: TokenType + _class: TokenType + _extends: TokenType + _export: TokenType + _import: TokenType + _null: TokenType + _true: TokenType + _false: TokenType + _in: TokenType + _instanceof: TokenType + _typeof: TokenType + _void: TokenType + _delete: TokenType +} + +export interface Comment { + type: "Line" | "Block" + value: string + start: number + end: number + loc?: SourceLocation + range?: [number, number] +} + +export class Token { + type: TokenType + start: number + end: number + loc?: SourceLocation + range?: [number, number] +} + +export const version: string diff --git a/node_modules/acorn/dist/acorn.d.ts b/node_modules/acorn/dist/acorn.d.ts new file mode 100644 index 0000000..f2ec524 --- /dev/null +++ b/node_modules/acorn/dist/acorn.d.ts @@ -0,0 +1,883 @@ +export interface Node { + start: number + end: number + type: string + range?: [number, number] + loc?: SourceLocation | null +} + +export interface SourceLocation { + source?: string | null + start: Position + end: Position +} + +export interface Position { + /** 1-based */ + line: number + /** 0-based */ + column: number +} + +export interface Identifier extends Node { + type: "Identifier" + name: string +} + +export interface Literal extends Node { + type: "Literal" + value?: string | boolean | null | number | RegExp | bigint + raw?: string + regex?: { + pattern: string + flags: string + } + bigint?: string +} + +export interface Program extends Node { + type: "Program" + body: Array + sourceType: "script" | "module" +} + +export interface Function extends Node { + id?: Identifier | null + params: Array + body: BlockStatement | Expression + generator: boolean + expression: boolean + async: boolean +} + +export interface ExpressionStatement extends Node { + type: "ExpressionStatement" + expression: Expression | Literal + directive?: string +} + +export interface BlockStatement extends Node { + type: "BlockStatement" + body: Array +} + +export interface EmptyStatement extends Node { + type: "EmptyStatement" +} + +export interface DebuggerStatement extends Node { + type: "DebuggerStatement" +} + +export interface WithStatement extends Node { + type: "WithStatement" + object: Expression + body: Statement +} + +export interface ReturnStatement extends Node { + type: "ReturnStatement" + argument?: Expression | null +} + +export interface LabeledStatement extends Node { + type: "LabeledStatement" + label: Identifier + body: Statement +} + +export interface BreakStatement extends Node { + type: "BreakStatement" + label?: Identifier | null +} + +export interface ContinueStatement extends Node { + type: "ContinueStatement" + label?: Identifier | null +} + +export interface IfStatement extends Node { + type: "IfStatement" + test: Expression + consequent: Statement + alternate?: Statement | null +} + +export interface SwitchStatement extends Node { + type: "SwitchStatement" + discriminant: Expression + cases: Array +} + +export interface SwitchCase extends Node { + type: "SwitchCase" + test?: Expression | null + consequent: Array +} + +export interface ThrowStatement extends Node { + type: "ThrowStatement" + argument: Expression +} + +export interface TryStatement extends Node { + type: "TryStatement" + block: BlockStatement + handler?: CatchClause | null + finalizer?: BlockStatement | null +} + +export interface CatchClause extends Node { + type: "CatchClause" + param?: Pattern | null + body: BlockStatement +} + +export interface WhileStatement extends Node { + type: "WhileStatement" + test: Expression + body: Statement +} + +export interface DoWhileStatement extends Node { + type: "DoWhileStatement" + body: Statement + test: Expression +} + +export interface ForStatement extends Node { + type: "ForStatement" + init?: VariableDeclaration | Expression | null + test?: Expression | null + update?: Expression | null + body: Statement +} + +export interface ForInStatement extends Node { + type: "ForInStatement" + left: VariableDeclaration | Pattern + right: Expression + body: Statement +} + +export interface FunctionDeclaration extends Function { + type: "FunctionDeclaration" + id: Identifier + body: BlockStatement +} + +export interface VariableDeclaration extends Node { + type: "VariableDeclaration" + declarations: Array + kind: "var" | "let" | "const" | "using" | "await using" +} + +export interface VariableDeclarator extends Node { + type: "VariableDeclarator" + id: Pattern + init?: Expression | null +} + +export interface ThisExpression extends Node { + type: "ThisExpression" +} + +export interface ArrayExpression extends Node { + type: "ArrayExpression" + elements: Array +} + +export interface ObjectExpression extends Node { + type: "ObjectExpression" + properties: Array +} + +export interface Property extends Node { + type: "Property" + key: Expression + value: Expression + kind: "init" | "get" | "set" + method: boolean + shorthand: boolean + computed: boolean +} + +export interface FunctionExpression extends Function { + type: "FunctionExpression" + body: BlockStatement +} + +export interface UnaryExpression extends Node { + type: "UnaryExpression" + operator: UnaryOperator + prefix: boolean + argument: Expression +} + +export type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete" + +export interface UpdateExpression extends Node { + type: "UpdateExpression" + operator: UpdateOperator + argument: Expression + prefix: boolean +} + +export type UpdateOperator = "++" | "--" + +export interface BinaryExpression extends Node { + type: "BinaryExpression" + operator: BinaryOperator + left: Expression | PrivateIdentifier + right: Expression +} + +export type BinaryOperator = "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "|" | "^" | "&" | "in" | "instanceof" | "**" + +export interface AssignmentExpression extends Node { + type: "AssignmentExpression" + operator: AssignmentOperator + left: Pattern + right: Expression +} + +export type AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | ">>>=" | "|=" | "^=" | "&=" | "**=" | "||=" | "&&=" | "??=" + +export interface LogicalExpression extends Node { + type: "LogicalExpression" + operator: LogicalOperator + left: Expression + right: Expression +} + +export type LogicalOperator = "||" | "&&" | "??" + +export interface MemberExpression extends Node { + type: "MemberExpression" + object: Expression | Super + property: Expression | PrivateIdentifier + computed: boolean + optional: boolean +} + +export interface ConditionalExpression extends Node { + type: "ConditionalExpression" + test: Expression + alternate: Expression + consequent: Expression +} + +export interface CallExpression extends Node { + type: "CallExpression" + callee: Expression | Super + arguments: Array + optional: boolean +} + +export interface NewExpression extends Node { + type: "NewExpression" + callee: Expression + arguments: Array +} + +export interface SequenceExpression extends Node { + type: "SequenceExpression" + expressions: Array +} + +export interface ForOfStatement extends Node { + type: "ForOfStatement" + left: VariableDeclaration | Pattern + right: Expression + body: Statement + await: boolean +} + +export interface Super extends Node { + type: "Super" +} + +export interface SpreadElement extends Node { + type: "SpreadElement" + argument: Expression +} + +export interface ArrowFunctionExpression extends Function { + type: "ArrowFunctionExpression" +} + +export interface YieldExpression extends Node { + type: "YieldExpression" + argument?: Expression | null + delegate: boolean +} + +export interface TemplateLiteral extends Node { + type: "TemplateLiteral" + quasis: Array + expressions: Array +} + +export interface TaggedTemplateExpression extends Node { + type: "TaggedTemplateExpression" + tag: Expression + quasi: TemplateLiteral +} + +export interface TemplateElement extends Node { + type: "TemplateElement" + tail: boolean + value: { + cooked?: string | null + raw: string + } +} + +export interface AssignmentProperty extends Node { + type: "Property" + key: Expression + value: Pattern + kind: "init" + method: false + shorthand: boolean + computed: boolean +} + +export interface ObjectPattern extends Node { + type: "ObjectPattern" + properties: Array +} + +export interface ArrayPattern extends Node { + type: "ArrayPattern" + elements: Array +} + +export interface RestElement extends Node { + type: "RestElement" + argument: Pattern +} + +export interface AssignmentPattern extends Node { + type: "AssignmentPattern" + left: Pattern + right: Expression +} + +export interface Class extends Node { + id?: Identifier | null + superClass?: Expression | null + body: ClassBody +} + +export interface ClassBody extends Node { + type: "ClassBody" + body: Array +} + +export interface MethodDefinition extends Node { + type: "MethodDefinition" + key: Expression | PrivateIdentifier + value: FunctionExpression + kind: "constructor" | "method" | "get" | "set" + computed: boolean + static: boolean +} + +export interface ClassDeclaration extends Class { + type: "ClassDeclaration" + id: Identifier +} + +export interface ClassExpression extends Class { + type: "ClassExpression" +} + +export interface MetaProperty extends Node { + type: "MetaProperty" + meta: Identifier + property: Identifier +} + +export interface ImportDeclaration extends Node { + type: "ImportDeclaration" + specifiers: Array + source: Literal + attributes: Array +} + +export interface ImportSpecifier extends Node { + type: "ImportSpecifier" + imported: Identifier | Literal + local: Identifier +} + +export interface ImportDefaultSpecifier extends Node { + type: "ImportDefaultSpecifier" + local: Identifier +} + +export interface ImportNamespaceSpecifier extends Node { + type: "ImportNamespaceSpecifier" + local: Identifier +} + +export interface ImportAttribute extends Node { + type: "ImportAttribute" + key: Identifier | Literal + value: Literal +} + +export interface ExportNamedDeclaration extends Node { + type: "ExportNamedDeclaration" + declaration?: Declaration | null + specifiers: Array + source?: Literal | null + attributes: Array +} + +export interface ExportSpecifier extends Node { + type: "ExportSpecifier" + exported: Identifier | Literal + local: Identifier | Literal +} + +export interface AnonymousFunctionDeclaration extends Function { + type: "FunctionDeclaration" + id: null + body: BlockStatement +} + +export interface AnonymousClassDeclaration extends Class { + type: "ClassDeclaration" + id: null +} + +export interface ExportDefaultDeclaration extends Node { + type: "ExportDefaultDeclaration" + declaration: AnonymousFunctionDeclaration | FunctionDeclaration | AnonymousClassDeclaration | ClassDeclaration | Expression +} + +export interface ExportAllDeclaration extends Node { + type: "ExportAllDeclaration" + source: Literal + exported?: Identifier | Literal | null + attributes: Array +} + +export interface AwaitExpression extends Node { + type: "AwaitExpression" + argument: Expression +} + +export interface ChainExpression extends Node { + type: "ChainExpression" + expression: MemberExpression | CallExpression +} + +export interface ImportExpression extends Node { + type: "ImportExpression" + source: Expression + options: Expression | null +} + +export interface ParenthesizedExpression extends Node { + type: "ParenthesizedExpression" + expression: Expression +} + +export interface PropertyDefinition extends Node { + type: "PropertyDefinition" + key: Expression | PrivateIdentifier + value?: Expression | null + computed: boolean + static: boolean +} + +export interface PrivateIdentifier extends Node { + type: "PrivateIdentifier" + name: string +} + +export interface StaticBlock extends Node { + type: "StaticBlock" + body: Array +} + +export type Statement = +| ExpressionStatement +| BlockStatement +| EmptyStatement +| DebuggerStatement +| WithStatement +| ReturnStatement +| LabeledStatement +| BreakStatement +| ContinueStatement +| IfStatement +| SwitchStatement +| ThrowStatement +| TryStatement +| WhileStatement +| DoWhileStatement +| ForStatement +| ForInStatement +| ForOfStatement +| Declaration + +export type Declaration = +| FunctionDeclaration +| VariableDeclaration +| ClassDeclaration + +export type Expression = +| Identifier +| Literal +| ThisExpression +| ArrayExpression +| ObjectExpression +| FunctionExpression +| UnaryExpression +| UpdateExpression +| BinaryExpression +| AssignmentExpression +| LogicalExpression +| MemberExpression +| ConditionalExpression +| CallExpression +| NewExpression +| SequenceExpression +| ArrowFunctionExpression +| YieldExpression +| TemplateLiteral +| TaggedTemplateExpression +| ClassExpression +| MetaProperty +| AwaitExpression +| ChainExpression +| ImportExpression +| ParenthesizedExpression + +export type Pattern = +| Identifier +| MemberExpression +| ObjectPattern +| ArrayPattern +| RestElement +| AssignmentPattern + +export type ModuleDeclaration = +| ImportDeclaration +| ExportNamedDeclaration +| ExportDefaultDeclaration +| ExportAllDeclaration + +/** + * This interface is only used for defining {@link AnyNode}. + * It exists so that it can be extended by plugins: + * + * @example + * ```typescript + * declare module 'acorn' { + * interface NodeTypes { + * pluginName: FirstNode | SecondNode | ThirdNode | ... | LastNode + * } + * } + * ``` + */ +interface NodeTypes { + core: Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportAttribute | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator +} + +export type AnyNode = NodeTypes[keyof NodeTypes] + +export function parse(input: string, options: Options): Program + +export function parseExpressionAt(input: string, pos: number, options: Options): Expression + +export function tokenizer(input: string, options: Options): { + getToken(): Token + [Symbol.iterator](): Iterator +} + +export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | "latest" + +export interface Options { + /** + * `ecmaVersion` indicates the ECMAScript version to parse. Can be a + * number, either in year (`2022`) or plain version number (`6`) form, + * or `"latest"` (the latest the library supports). This influences + * support for strict mode, the set of reserved words, and support for + * new syntax features. + */ + ecmaVersion: ecmaVersion + + /** + * `sourceType` indicates the mode the code should be parsed in. + * Can be either `"script"` or `"module"`. This influences global + * strict mode and parsing of `import` and `export` declarations. + */ + sourceType?: "script" | "module" + + /** + * a callback that will be called when a semicolon is automatically inserted. + * @param lastTokEnd the position of the comma as an offset + * @param lastTokEndLoc location if {@link locations} is enabled + */ + onInsertedSemicolon?: (lastTokEnd: number, lastTokEndLoc?: Position) => void + + /** + * similar to `onInsertedSemicolon`, but for trailing commas + * @param lastTokEnd the position of the comma as an offset + * @param lastTokEndLoc location if `locations` is enabled + */ + onTrailingComma?: (lastTokEnd: number, lastTokEndLoc?: Position) => void + + /** + * By default, reserved words are only enforced if ecmaVersion >= 5. + * Set `allowReserved` to a boolean value to explicitly turn this on + * an off. When this option has the value "never", reserved words + * and keywords can also not be used as property names. + */ + allowReserved?: boolean | "never" + + /** + * When enabled, a return at the top level is not considered an error. + */ + allowReturnOutsideFunction?: boolean + + /** + * When enabled, import/export statements are not constrained to + * appearing at the top of the program, and an import.meta expression + * in a script isn't considered an error. + */ + allowImportExportEverywhere?: boolean + + /** + * By default, `await` identifiers are allowed to appear at the top-level scope only if {@link ecmaVersion} >= 2022. + * When enabled, await identifiers are allowed to appear at the top-level scope, + * but they are still not allowed in non-async functions. + */ + allowAwaitOutsideFunction?: boolean + + /** + * When enabled, super identifiers are not constrained to + * appearing in methods and do not raise an error when they appear elsewhere. + */ + allowSuperOutsideMethod?: boolean + + /** + * When enabled, hashbang directive in the beginning of file is + * allowed and treated as a line comment. Enabled by default when + * {@link ecmaVersion} >= 2023. + */ + allowHashBang?: boolean + + /** + * By default, the parser will verify that private properties are + * only used in places where they are valid and have been declared. + * Set this to false to turn such checks off. + */ + checkPrivateFields?: boolean + + /** + * When `locations` is on, `loc` properties holding objects with + * `start` and `end` properties as {@link Position} objects will be attached to the + * nodes. + */ + locations?: boolean + + /** + * a callback that will cause Acorn to call that export function with object in the same + * format as tokens returned from `tokenizer().getToken()`. Note + * that you are not allowed to call the parser from the + * callback—that will corrupt its internal state. + */ + onToken?: ((token: Token) => void) | Token[] + + + /** + * This takes a export function or an array. + * + * When a export function is passed, Acorn will call that export function with `(block, text, start, + * end)` parameters whenever a comment is skipped. `block` is a + * boolean indicating whether this is a block (`/* *\/`) comment, + * `text` is the content of the comment, and `start` and `end` are + * character offsets that denote the start and end of the comment. + * When the {@link locations} option is on, two more parameters are + * passed, the full locations of {@link Position} export type of the start and + * end of the comments. + * + * When a array is passed, each found comment of {@link Comment} export type is pushed to the array. + * + * Note that you are not allowed to call the + * parser from the callback—that will corrupt its internal state. + */ + onComment?: (( + isBlock: boolean, text: string, start: number, end: number, startLoc?: Position, + endLoc?: Position + ) => void) | Comment[] + + /** + * Nodes have their start and end characters offsets recorded in + * `start` and `end` properties (directly on the node, rather than + * the `loc` object, which holds line/column data. To also add a + * [semi-standardized][range] `range` property holding a `[start, + * end]` array with the same numbers, set the `ranges` option to + * `true`. + */ + ranges?: boolean + + /** + * It is possible to parse multiple files into a single AST by + * passing the tree produced by parsing the first file as + * `program` option in subsequent parses. This will add the + * toplevel forms of the parsed file to the `Program` (top) node + * of an existing parse tree. + */ + program?: Node + + /** + * When {@link locations} is on, you can pass this to record the source + * file in every node's `loc` object. + */ + sourceFile?: string + + /** + * This value, if given, is stored in every node, whether {@link locations} is on or off. + */ + directSourceFile?: string + + /** + * When enabled, parenthesized expressions are represented by + * (non-standard) ParenthesizedExpression nodes + */ + preserveParens?: boolean +} + +export class Parser { + options: Options + input: string + + protected constructor(options: Options, input: string, startPos?: number) + parse(): Program + + static parse(input: string, options: Options): Program + static parseExpressionAt(input: string, pos: number, options: Options): Expression + static tokenizer(input: string, options: Options): { + getToken(): Token + [Symbol.iterator](): Iterator + } + static extend(...plugins: ((BaseParser: typeof Parser) => typeof Parser)[]): typeof Parser +} + +export const defaultOptions: Options + +export function getLineInfo(input: string, offset: number): Position + +export class TokenType { + label: string + keyword: string | undefined +} + +export const tokTypes: { + num: TokenType + regexp: TokenType + string: TokenType + name: TokenType + privateId: TokenType + eof: TokenType + + bracketL: TokenType + bracketR: TokenType + braceL: TokenType + braceR: TokenType + parenL: TokenType + parenR: TokenType + comma: TokenType + semi: TokenType + colon: TokenType + dot: TokenType + question: TokenType + questionDot: TokenType + arrow: TokenType + template: TokenType + invalidTemplate: TokenType + ellipsis: TokenType + backQuote: TokenType + dollarBraceL: TokenType + + eq: TokenType + assign: TokenType + incDec: TokenType + prefix: TokenType + logicalOR: TokenType + logicalAND: TokenType + bitwiseOR: TokenType + bitwiseXOR: TokenType + bitwiseAND: TokenType + equality: TokenType + relational: TokenType + bitShift: TokenType + plusMin: TokenType + modulo: TokenType + star: TokenType + slash: TokenType + starstar: TokenType + coalesce: TokenType + + _break: TokenType + _case: TokenType + _catch: TokenType + _continue: TokenType + _debugger: TokenType + _default: TokenType + _do: TokenType + _else: TokenType + _finally: TokenType + _for: TokenType + _function: TokenType + _if: TokenType + _return: TokenType + _switch: TokenType + _throw: TokenType + _try: TokenType + _var: TokenType + _const: TokenType + _while: TokenType + _with: TokenType + _new: TokenType + _this: TokenType + _super: TokenType + _class: TokenType + _extends: TokenType + _export: TokenType + _import: TokenType + _null: TokenType + _true: TokenType + _false: TokenType + _in: TokenType + _instanceof: TokenType + _typeof: TokenType + _void: TokenType + _delete: TokenType +} + +export interface Comment { + type: "Line" | "Block" + value: string + start: number + end: number + loc?: SourceLocation + range?: [number, number] +} + +export class Token { + type: TokenType + start: number + end: number + loc?: SourceLocation + range?: [number, number] +} + +export const version: string diff --git a/node_modules/acorn/dist/acorn.js b/node_modules/acorn/dist/acorn.js new file mode 100644 index 0000000..cb5628b --- /dev/null +++ b/node_modules/acorn/dist/acorn.js @@ -0,0 +1,6262 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.acorn = {})); +})(this, (function (exports) { 'use strict'; + + // This file was generated. Do not modify manually! + var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 7, 9, 32, 4, 318, 1, 80, 3, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 68, 8, 2, 0, 3, 0, 2, 3, 2, 4, 2, 0, 15, 1, 83, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 7, 19, 58, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 343, 9, 54, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 10, 5350, 0, 7, 14, 11465, 27, 2343, 9, 87, 9, 39, 4, 60, 6, 26, 9, 535, 9, 470, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4178, 9, 519, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 245, 1, 2, 9, 726, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; + + // This file was generated. Do not modify manually! + var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 4, 51, 13, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 39, 27, 10, 22, 251, 41, 7, 1, 17, 2, 60, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 31, 9, 2, 0, 3, 0, 2, 37, 2, 0, 26, 0, 2, 0, 45, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 200, 32, 32, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 26, 3994, 6, 582, 6842, 29, 1763, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 433, 44, 212, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 42, 9, 8936, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 229, 29, 3, 0, 496, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4153, 7, 221, 3, 5761, 15, 7472, 16, 621, 2467, 541, 1507, 4938, 6, 4191]; + + // This file was generated. Do not modify manually! + var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0897-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\u30fb\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f\uff65"; + + // This file was generated. Do not modify manually! + var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c8a\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7cd\ua7d0\ua7d1\ua7d3\ua7d5-\ua7dc\ua7f2-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; + + // These are a run-length and offset encoded representation of the + // >0xffff code points that are a valid part of identifiers. The + // offset starts at 0x10000, and each pair of numbers represents an + // offset to the next range, and then a size of the range. + + // Reserved word lists for various dialects of the language + + var reservedWords = { + 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", + 5: "class enum extends super const export import", + 6: "enum", + strict: "implements interface let package private protected public static yield", + strictBind: "eval arguments" + }; + + // And the keywords + + var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"; + + var keywords$1 = { + 5: ecma5AndLessKeywords, + "5module": ecma5AndLessKeywords + " export import", + 6: ecma5AndLessKeywords + " const class extends export import super" + }; + + var keywordRelationalOperator = /^in(stanceof)?$/; + + // ## Character categories + + var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); + var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); + + // This has a complexity linear to the value of the code. The + // assumption is that looking up astral identifier characters is + // rare. + function isInAstralSet(code, set) { + var pos = 0x10000; + for (var i = 0; i < set.length; i += 2) { + pos += set[i]; + if (pos > code) { return false } + pos += set[i + 1]; + if (pos >= code) { return true } + } + return false + } + + // Test whether a given character code starts an identifier. + + function isIdentifierStart(code, astral) { + if (code < 65) { return code === 36 } + if (code < 91) { return true } + if (code < 97) { return code === 95 } + if (code < 123) { return true } + if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) } + if (astral === false) { return false } + return isInAstralSet(code, astralIdentifierStartCodes) + } + + // Test whether a given character is part of an identifier. + + function isIdentifierChar(code, astral) { + if (code < 48) { return code === 36 } + if (code < 58) { return true } + if (code < 65) { return false } + if (code < 91) { return true } + if (code < 97) { return code === 95 } + if (code < 123) { return true } + if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) } + if (astral === false) { return false } + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) + } + + // ## Token types + + // The assignment of fine-grained, information-carrying type objects + // allows the tokenizer to store the information it has about a + // token in a way that is very cheap for the parser to look up. + + // All token type variables start with an underscore, to make them + // easy to recognize. + + // The `beforeExpr` property is used to disambiguate between regular + // expressions and divisions. It is set on all token types that can + // be followed by an expression (thus, a slash after them would be a + // regular expression). + // + // The `startsExpr` property is used to check if the token ends a + // `yield` expression. It is set on all token types that either can + // directly start an expression (like a quotation mark) or can + // continue an expression (like the body of a string). + // + // `isLoop` marks a keyword as starting a loop, which is important + // to know when parsing a label, in order to allow or disallow + // continue jumps to that label. + + var TokenType = function TokenType(label, conf) { + if ( conf === void 0 ) conf = {}; + + this.label = label; + this.keyword = conf.keyword; + this.beforeExpr = !!conf.beforeExpr; + this.startsExpr = !!conf.startsExpr; + this.isLoop = !!conf.isLoop; + this.isAssign = !!conf.isAssign; + this.prefix = !!conf.prefix; + this.postfix = !!conf.postfix; + this.binop = conf.binop || null; + this.updateContext = null; + }; + + function binop(name, prec) { + return new TokenType(name, {beforeExpr: true, binop: prec}) + } + var beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true}; + + // Map keyword names to token types. + + var keywords = {}; + + // Succinct definitions of keyword token types + function kw(name, options) { + if ( options === void 0 ) options = {}; + + options.keyword = name; + return keywords[name] = new TokenType(name, options) + } + + var types$1 = { + num: new TokenType("num", startsExpr), + regexp: new TokenType("regexp", startsExpr), + string: new TokenType("string", startsExpr), + name: new TokenType("name", startsExpr), + privateId: new TokenType("privateId", startsExpr), + eof: new TokenType("eof"), + + // Punctuation token types. + bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), + bracketR: new TokenType("]"), + braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), + braceR: new TokenType("}"), + parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), + parenR: new TokenType(")"), + comma: new TokenType(",", beforeExpr), + semi: new TokenType(";", beforeExpr), + colon: new TokenType(":", beforeExpr), + dot: new TokenType("."), + question: new TokenType("?", beforeExpr), + questionDot: new TokenType("?."), + arrow: new TokenType("=>", beforeExpr), + template: new TokenType("template"), + invalidTemplate: new TokenType("invalidTemplate"), + ellipsis: new TokenType("...", beforeExpr), + backQuote: new TokenType("`", startsExpr), + dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), + + // Operators. These carry several kinds of properties to help the + // parser use them properly (the presence of these properties is + // what categorizes them as operators). + // + // `binop`, when present, specifies that this operator is a binary + // operator, and will refer to its precedence. + // + // `prefix` and `postfix` mark the operator as a prefix or postfix + // unary operator. + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. + + eq: new TokenType("=", {beforeExpr: true, isAssign: true}), + assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), + incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), + prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}), + logicalOR: binop("||", 1), + logicalAND: binop("&&", 2), + bitwiseOR: binop("|", 3), + bitwiseXOR: binop("^", 4), + bitwiseAND: binop("&", 5), + equality: binop("==/!=/===/!==", 6), + relational: binop("/<=/>=", 7), + bitShift: binop("<>/>>>", 8), + plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), + modulo: binop("%", 10), + star: binop("*", 10), + slash: binop("/", 10), + starstar: new TokenType("**", {beforeExpr: true}), + coalesce: binop("??", 1), + + // Keyword token types. + _break: kw("break"), + _case: kw("case", beforeExpr), + _catch: kw("catch"), + _continue: kw("continue"), + _debugger: kw("debugger"), + _default: kw("default", beforeExpr), + _do: kw("do", {isLoop: true, beforeExpr: true}), + _else: kw("else", beforeExpr), + _finally: kw("finally"), + _for: kw("for", {isLoop: true}), + _function: kw("function", startsExpr), + _if: kw("if"), + _return: kw("return", beforeExpr), + _switch: kw("switch"), + _throw: kw("throw", beforeExpr), + _try: kw("try"), + _var: kw("var"), + _const: kw("const"), + _while: kw("while", {isLoop: true}), + _with: kw("with"), + _new: kw("new", {beforeExpr: true, startsExpr: true}), + _this: kw("this", startsExpr), + _super: kw("super", startsExpr), + _class: kw("class", startsExpr), + _extends: kw("extends", beforeExpr), + _export: kw("export"), + _import: kw("import", startsExpr), + _null: kw("null", startsExpr), + _true: kw("true", startsExpr), + _false: kw("false", startsExpr), + _in: kw("in", {beforeExpr: true, binop: 7}), + _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), + _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), + _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), + _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) + }; + + // Matches a whole line break (where CRLF is considered a single + // line break). Used to count lines. + + var lineBreak = /\r\n?|\n|\u2028|\u2029/; + var lineBreakG = new RegExp(lineBreak.source, "g"); + + function isNewLine(code) { + return code === 10 || code === 13 || code === 0x2028 || code === 0x2029 + } + + function nextLineBreak(code, from, end) { + if ( end === void 0 ) end = code.length; + + for (var i = from; i < end; i++) { + var next = code.charCodeAt(i); + if (isNewLine(next)) + { return i < end - 1 && next === 13 && code.charCodeAt(i + 1) === 10 ? i + 2 : i + 1 } + } + return -1 + } + + var nonASCIIwhitespace = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/; + + var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; + + var ref = Object.prototype; + var hasOwnProperty = ref.hasOwnProperty; + var toString = ref.toString; + + var hasOwn = Object.hasOwn || (function (obj, propName) { return ( + hasOwnProperty.call(obj, propName) + ); }); + + var isArray = Array.isArray || (function (obj) { return ( + toString.call(obj) === "[object Array]" + ); }); + + var regexpCache = Object.create(null); + + function wordsRegexp(words) { + return regexpCache[words] || (regexpCache[words] = new RegExp("^(?:" + words.replace(/ /g, "|") + ")$")) + } + + function codePointToString(code) { + // UTF-16 Decoding + if (code <= 0xFFFF) { return String.fromCharCode(code) } + code -= 0x10000; + return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00) + } + + var loneSurrogate = /(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/; + + // These are used when `options.locations` is on, for the + // `startLoc` and `endLoc` properties. + + var Position = function Position(line, col) { + this.line = line; + this.column = col; + }; + + Position.prototype.offset = function offset (n) { + return new Position(this.line, this.column + n) + }; + + var SourceLocation = function SourceLocation(p, start, end) { + this.start = start; + this.end = end; + if (p.sourceFile !== null) { this.source = p.sourceFile; } + }; + + // The `getLineInfo` function is mostly useful when the + // `locations` option is off (for performance reasons) and you + // want to find the line/column position for a given character + // offset. `input` should be the code string that the offset refers + // into. + + function getLineInfo(input, offset) { + for (var line = 1, cur = 0;;) { + var nextBreak = nextLineBreak(input, cur, offset); + if (nextBreak < 0) { return new Position(line, offset - cur) } + ++line; + cur = nextBreak; + } + } + + // A second argument must be given to configure the parser process. + // These options are recognized (only `ecmaVersion` is required): + + var defaultOptions = { + // `ecmaVersion` indicates the ECMAScript version to parse. Must be + // either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10 + // (2019), 11 (2020), 12 (2021), 13 (2022), 14 (2023), or `"latest"` + // (the latest version the library supports). This influences + // support for strict mode, the set of reserved words, and support + // for new syntax features. + ecmaVersion: null, + // `sourceType` indicates the mode the code should be parsed in. + // Can be either `"script"` or `"module"`. This influences global + // strict mode and parsing of `import` and `export` declarations. + sourceType: "script", + // `onInsertedSemicolon` can be a callback that will be called when + // a semicolon is automatically inserted. It will be passed the + // position of the inserted semicolon as an offset, and if + // `locations` is enabled, it is given the location as a `{line, + // column}` object as second argument. + onInsertedSemicolon: null, + // `onTrailingComma` is similar to `onInsertedSemicolon`, but for + // trailing commas. + onTrailingComma: null, + // By default, reserved words are only enforced if ecmaVersion >= 5. + // Set `allowReserved` to a boolean value to explicitly turn this on + // an off. When this option has the value "never", reserved words + // and keywords can also not be used as property names. + allowReserved: null, + // When enabled, a return at the top level is not considered an + // error. + allowReturnOutsideFunction: false, + // When enabled, import/export statements are not constrained to + // appearing at the top of the program, and an import.meta expression + // in a script isn't considered an error. + allowImportExportEverywhere: false, + // By default, await identifiers are allowed to appear at the top-level scope only if ecmaVersion >= 2022. + // When enabled, await identifiers are allowed to appear at the top-level scope, + // but they are still not allowed in non-async functions. + allowAwaitOutsideFunction: null, + // When enabled, super identifiers are not constrained to + // appearing in methods and do not raise an error when they appear elsewhere. + allowSuperOutsideMethod: null, + // When enabled, hashbang directive in the beginning of file is + // allowed and treated as a line comment. Enabled by default when + // `ecmaVersion` >= 2023. + allowHashBang: false, + // By default, the parser will verify that private properties are + // only used in places where they are valid and have been declared. + // Set this to false to turn such checks off. + checkPrivateFields: true, + // When `locations` is on, `loc` properties holding objects with + // `start` and `end` properties in `{line, column}` form (with + // line being 1-based and column 0-based) will be attached to the + // nodes. + locations: false, + // A function can be passed as `onToken` option, which will + // cause Acorn to call that function with object in the same + // format as tokens returned from `tokenizer().getToken()`. Note + // that you are not allowed to call the parser from the + // callback—that will corrupt its internal state. + onToken: null, + // A function can be passed as `onComment` option, which will + // cause Acorn to call that function with `(block, text, start, + // end)` parameters whenever a comment is skipped. `block` is a + // boolean indicating whether this is a block (`/* */`) comment, + // `text` is the content of the comment, and `start` and `end` are + // character offsets that denote the start and end of the comment. + // When the `locations` option is on, two more parameters are + // passed, the full `{line, column}` locations of the start and + // end of the comments. Note that you are not allowed to call the + // parser from the callback—that will corrupt its internal state. + // When this option has an array as value, objects representing the + // comments are pushed to it. + onComment: null, + // Nodes have their start and end characters offsets recorded in + // `start` and `end` properties (directly on the node, rather than + // the `loc` object, which holds line/column data. To also add a + // [semi-standardized][range] `range` property holding a `[start, + // end]` array with the same numbers, set the `ranges` option to + // `true`. + // + // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + ranges: false, + // It is possible to parse multiple files into a single AST by + // passing the tree produced by parsing the first file as + // `program` option in subsequent parses. This will add the + // toplevel forms of the parsed file to the `Program` (top) node + // of an existing parse tree. + program: null, + // When `locations` is on, you can pass this to record the source + // file in every node's `loc` object. + sourceFile: null, + // This value, if given, is stored in every node, whether + // `locations` is on or off. + directSourceFile: null, + // When enabled, parenthesized expressions are represented by + // (non-standard) ParenthesizedExpression nodes + preserveParens: false + }; + + // Interpret and default an options object + + var warnedAboutEcmaVersion = false; + + function getOptions(opts) { + var options = {}; + + for (var opt in defaultOptions) + { options[opt] = opts && hasOwn(opts, opt) ? opts[opt] : defaultOptions[opt]; } + + if (options.ecmaVersion === "latest") { + options.ecmaVersion = 1e8; + } else if (options.ecmaVersion == null) { + if (!warnedAboutEcmaVersion && typeof console === "object" && console.warn) { + warnedAboutEcmaVersion = true; + console.warn("Since Acorn 8.0.0, options.ecmaVersion is required.\nDefaulting to 2020, but this will stop working in the future."); + } + options.ecmaVersion = 11; + } else if (options.ecmaVersion >= 2015) { + options.ecmaVersion -= 2009; + } + + if (options.allowReserved == null) + { options.allowReserved = options.ecmaVersion < 5; } + + if (!opts || opts.allowHashBang == null) + { options.allowHashBang = options.ecmaVersion >= 14; } + + if (isArray(options.onToken)) { + var tokens = options.onToken; + options.onToken = function (token) { return tokens.push(token); }; + } + if (isArray(options.onComment)) + { options.onComment = pushComment(options, options.onComment); } + + return options + } + + function pushComment(options, array) { + return function(block, text, start, end, startLoc, endLoc) { + var comment = { + type: block ? "Block" : "Line", + value: text, + start: start, + end: end + }; + if (options.locations) + { comment.loc = new SourceLocation(this, startLoc, endLoc); } + if (options.ranges) + { comment.range = [start, end]; } + array.push(comment); + } + } + + // Each scope gets a bitset that may contain these flags + var + SCOPE_TOP = 1, + SCOPE_FUNCTION = 2, + SCOPE_ASYNC = 4, + SCOPE_GENERATOR = 8, + SCOPE_ARROW = 16, + SCOPE_SIMPLE_CATCH = 32, + SCOPE_SUPER = 64, + SCOPE_DIRECT_SUPER = 128, + SCOPE_CLASS_STATIC_BLOCK = 256, + SCOPE_CLASS_FIELD_INIT = 512, + SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK; + + function functionFlags(async, generator) { + return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0) + } + + // Used in checkLVal* and declareName to determine the type of a binding + var + BIND_NONE = 0, // Not a binding + BIND_VAR = 1, // Var-style binding + BIND_LEXICAL = 2, // Let- or const-style binding + BIND_FUNCTION = 3, // Function declaration + BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding + BIND_OUTSIDE = 5; // Special case for function names as bound inside the function + + var Parser = function Parser(options, input, startPos) { + this.options = options = getOptions(options); + this.sourceFile = options.sourceFile; + this.keywords = wordsRegexp(keywords$1[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]); + var reserved = ""; + if (options.allowReserved !== true) { + reserved = reservedWords[options.ecmaVersion >= 6 ? 6 : options.ecmaVersion === 5 ? 5 : 3]; + if (options.sourceType === "module") { reserved += " await"; } + } + this.reservedWords = wordsRegexp(reserved); + var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict; + this.reservedWordsStrict = wordsRegexp(reservedStrict); + this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind); + this.input = String(input); + + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + this.containsEsc = false; + + // Set up token state + + // The current position of the tokenizer in the input. + if (startPos) { + this.pos = startPos; + this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1; + this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length; + } else { + this.pos = this.lineStart = 0; + this.curLine = 1; + } + + // Properties of the current token: + // Its type + this.type = types$1.eof; + // For tokens that include more information than their type, the value + this.value = null; + // Its start and end offset + this.start = this.end = this.pos; + // And, if locations are used, the {line, column} object + // corresponding to those offsets + this.startLoc = this.endLoc = this.curPosition(); + + // Position information for the previous token + this.lastTokEndLoc = this.lastTokStartLoc = null; + this.lastTokStart = this.lastTokEnd = this.pos; + + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + this.context = this.initialContext(); + this.exprAllowed = true; + + // Figure out if it's a module code. + this.inModule = options.sourceType === "module"; + this.strict = this.inModule || this.strictDirective(this.pos); + + // Used to signify the start of a potential arrow function + this.potentialArrowAt = -1; + this.potentialArrowInForAwait = false; + + // Positions to delayed-check that yield/await does not exist in default parameters. + this.yieldPos = this.awaitPos = this.awaitIdentPos = 0; + // Labels in scope. + this.labels = []; + // Thus-far undefined exports. + this.undefinedExports = Object.create(null); + + // If enabled, skip leading hashbang line. + if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") + { this.skipLineComment(2); } + + // Scope tracking for duplicate variable names (see scope.js) + this.scopeStack = []; + this.enterScope(SCOPE_TOP); + + // For RegExp validation + this.regexpState = null; + + // The stack of private names. + // Each element has two properties: 'declared' and 'used'. + // When it exited from the outermost class definition, all used private names must be declared. + this.privateNameStack = []; + }; + + var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },canAwait: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },allowNewDotTarget: { configurable: true },inClassStaticBlock: { configurable: true } }; + + Parser.prototype.parse = function parse () { + var node = this.options.program || this.startNode(); + this.nextToken(); + return this.parseTopLevel(node) + }; + + prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 }; + + prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 }; + + prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 }; + + prototypeAccessors.canAwait.get = function () { + for (var i = this.scopeStack.length - 1; i >= 0; i--) { + var ref = this.scopeStack[i]; + var flags = ref.flags; + if (flags & (SCOPE_CLASS_STATIC_BLOCK | SCOPE_CLASS_FIELD_INIT)) { return false } + if (flags & SCOPE_FUNCTION) { return (flags & SCOPE_ASYNC) > 0 } + } + return (this.inModule && this.options.ecmaVersion >= 13) || this.options.allowAwaitOutsideFunction + }; + + prototypeAccessors.allowSuper.get = function () { + var ref = this.currentThisScope(); + var flags = ref.flags; + return (flags & SCOPE_SUPER) > 0 || this.options.allowSuperOutsideMethod + }; + + prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 }; + + prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) }; + + prototypeAccessors.allowNewDotTarget.get = function () { + for (var i = this.scopeStack.length - 1; i >= 0; i--) { + var ref = this.scopeStack[i]; + var flags = ref.flags; + if (flags & (SCOPE_CLASS_STATIC_BLOCK | SCOPE_CLASS_FIELD_INIT) || + ((flags & SCOPE_FUNCTION) && !(flags & SCOPE_ARROW))) { return true } + } + return false + }; + + prototypeAccessors.inClassStaticBlock.get = function () { + return (this.currentVarScope().flags & SCOPE_CLASS_STATIC_BLOCK) > 0 + }; + + Parser.extend = function extend () { + var plugins = [], len = arguments.length; + while ( len-- ) plugins[ len ] = arguments[ len ]; + + var cls = this; + for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); } + return cls + }; + + Parser.parse = function parse (input, options) { + return new this(options, input).parse() + }; + + Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) { + var parser = new this(options, input, pos); + parser.nextToken(); + return parser.parseExpression() + }; + + Parser.tokenizer = function tokenizer (input, options) { + return new this(options, input) + }; + + Object.defineProperties( Parser.prototype, prototypeAccessors ); + + var pp$9 = Parser.prototype; + + // ## Parser utilities + + var literal = /^(?:'((?:\\[^]|[^'\\])*?)'|"((?:\\[^]|[^"\\])*?)")/; + pp$9.strictDirective = function(start) { + if (this.options.ecmaVersion < 5) { return false } + for (;;) { + // Try to find string literal. + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this.input)[0].length; + var match = literal.exec(this.input.slice(start)); + if (!match) { return false } + if ((match[1] || match[2]) === "use strict") { + skipWhiteSpace.lastIndex = start + match[0].length; + var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length; + var next = this.input.charAt(end); + return next === ";" || next === "}" || + (lineBreak.test(spaceAfter[0]) && + !(/[(`.[+\-/*%<>=,?^&]/.test(next) || next === "!" && this.input.charAt(end + 1) === "=")) + } + start += match[0].length; + + // Skip semicolon, if any. + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this.input)[0].length; + if (this.input[start] === ";") + { start++; } + } + }; + + // Predicate that tests whether the next token is of the given + // type, and if yes, consumes it as a side effect. + + pp$9.eat = function(type) { + if (this.type === type) { + this.next(); + return true + } else { + return false + } + }; + + // Tests whether parsed token is a contextual keyword. + + pp$9.isContextual = function(name) { + return this.type === types$1.name && this.value === name && !this.containsEsc + }; + + // Consumes contextual keyword if possible. + + pp$9.eatContextual = function(name) { + if (!this.isContextual(name)) { return false } + this.next(); + return true + }; + + // Asserts that following token is given contextual keyword. + + pp$9.expectContextual = function(name) { + if (!this.eatContextual(name)) { this.unexpected(); } + }; + + // Test whether a semicolon can be inserted at the current position. + + pp$9.canInsertSemicolon = function() { + return this.type === types$1.eof || + this.type === types$1.braceR || + lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + }; + + pp$9.insertSemicolon = function() { + if (this.canInsertSemicolon()) { + if (this.options.onInsertedSemicolon) + { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); } + return true + } + }; + + // Consume a semicolon, or, failing that, see if we are allowed to + // pretend that there is a semicolon at this position. + + pp$9.semicolon = function() { + if (!this.eat(types$1.semi) && !this.insertSemicolon()) { this.unexpected(); } + }; + + pp$9.afterTrailingComma = function(tokType, notNext) { + if (this.type === tokType) { + if (this.options.onTrailingComma) + { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); } + if (!notNext) + { this.next(); } + return true + } + }; + + // Expect a token of a given type. If found, consume it, otherwise, + // raise an unexpected token error. + + pp$9.expect = function(type) { + this.eat(type) || this.unexpected(); + }; + + // Raise an unexpected token error. + + pp$9.unexpected = function(pos) { + this.raise(pos != null ? pos : this.start, "Unexpected token"); + }; + + var DestructuringErrors = function DestructuringErrors() { + this.shorthandAssign = + this.trailingComma = + this.parenthesizedAssign = + this.parenthesizedBind = + this.doubleProto = + -1; + }; + + pp$9.checkPatternErrors = function(refDestructuringErrors, isAssign) { + if (!refDestructuringErrors) { return } + if (refDestructuringErrors.trailingComma > -1) + { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); } + var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind; + if (parens > -1) { this.raiseRecoverable(parens, isAssign ? "Assigning to rvalue" : "Parenthesized pattern"); } + }; + + pp$9.checkExpressionErrors = function(refDestructuringErrors, andThrow) { + if (!refDestructuringErrors) { return false } + var shorthandAssign = refDestructuringErrors.shorthandAssign; + var doubleProto = refDestructuringErrors.doubleProto; + if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 } + if (shorthandAssign >= 0) + { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); } + if (doubleProto >= 0) + { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); } + }; + + pp$9.checkYieldAwaitInDefaultParams = function() { + if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) + { this.raise(this.yieldPos, "Yield expression cannot be a default value"); } + if (this.awaitPos) + { this.raise(this.awaitPos, "Await expression cannot be a default value"); } + }; + + pp$9.isSimpleAssignTarget = function(expr) { + if (expr.type === "ParenthesizedExpression") + { return this.isSimpleAssignTarget(expr.expression) } + return expr.type === "Identifier" || expr.type === "MemberExpression" + }; + + var pp$8 = Parser.prototype; + + // ### Statement parsing + + // Parse a program. Initializes the parser, reads any number of + // statements, and wraps them in a Program node. Optionally takes a + // `program` argument. If present, the statements will be appended + // to its body instead of creating a new node. + + pp$8.parseTopLevel = function(node) { + var exports = Object.create(null); + if (!node.body) { node.body = []; } + while (this.type !== types$1.eof) { + var stmt = this.parseStatement(null, true, exports); + node.body.push(stmt); + } + if (this.inModule) + { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1) + { + var name = list[i]; + + this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined")); + } } + this.adaptDirectivePrologue(node.body); + this.next(); + node.sourceType = this.options.sourceType; + return this.finishNode(node, "Program") + }; + + var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"}; + + pp$8.isLet = function(context) { + if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false } + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); + // For ambiguous cases, determine if a LexicalDeclaration (or only a + // Statement) is allowed here. If context is not empty then only a Statement + // is allowed. However, `let [` is an explicit negative lookahead for + // ExpressionStatement, so special-case it first. + if (nextCh === 91 || nextCh === 92) { return true } // '[', '\' + if (context) { return false } + + if (nextCh === 123 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } // '{', astral + if (isIdentifierStart(nextCh, true)) { + var pos = next + 1; + while (isIdentifierChar(nextCh = this.input.charCodeAt(pos), true)) { ++pos; } + if (nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } + var ident = this.input.slice(next, pos); + if (!keywordRelationalOperator.test(ident)) { return true } + } + return false + }; + + // check 'async [no LineTerminator here] function' + // - 'async /*foo*/ function' is OK. + // - 'async /*\n*/ function' is invalid. + pp$8.isAsyncFunction = function() { + if (this.options.ecmaVersion < 8 || !this.isContextual("async")) + { return false } + + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, after; + return !lineBreak.test(this.input.slice(this.pos, next)) && + this.input.slice(next, next + 8) === "function" && + (next + 8 === this.input.length || + !(isIdentifierChar(after = this.input.charCodeAt(next + 8)) || after > 0xd7ff && after < 0xdc00)) + }; + + pp$8.isUsingKeyword = function(isAwaitUsing, isFor) { + if (this.options.ecmaVersion < 17 || !this.isContextual(isAwaitUsing ? "await" : "using")) + { return false } + + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length; + + if (lineBreak.test(this.input.slice(this.pos, next))) { return false } + + if (isAwaitUsing) { + var awaitEndPos = next + 5 /* await */, after; + if (this.input.slice(next, awaitEndPos) !== "using" || + awaitEndPos === this.input.length || + isIdentifierChar(after = this.input.charCodeAt(awaitEndPos)) || + (after > 0xd7ff && after < 0xdc00) + ) { return false } + + skipWhiteSpace.lastIndex = awaitEndPos; + var skipAfterUsing = skipWhiteSpace.exec(this.input); + if (skipAfterUsing && lineBreak.test(this.input.slice(awaitEndPos, awaitEndPos + skipAfterUsing[0].length))) { return false } + } + + if (isFor) { + var ofEndPos = next + 2 /* of */, after$1; + if (this.input.slice(next, ofEndPos) === "of") { + if (ofEndPos === this.input.length || + (!isIdentifierChar(after$1 = this.input.charCodeAt(ofEndPos)) && !(after$1 > 0xd7ff && after$1 < 0xdc00))) { return false } + } + } + + var ch = this.input.charCodeAt(next); + return isIdentifierStart(ch, true) || ch === 92 // '\' + }; + + pp$8.isAwaitUsing = function(isFor) { + return this.isUsingKeyword(true, isFor) + }; + + pp$8.isUsing = function(isFor) { + return this.isUsingKeyword(false, isFor) + }; + + // Parse a single statement. + // + // If expecting a statement and finding a slash operator, parse a + // regular expression literal. This is to handle cases like + // `if (foo) /blah/.exec(foo)`, where looking at the previous token + // does not help. + + pp$8.parseStatement = function(context, topLevel, exports) { + var starttype = this.type, node = this.startNode(), kind; + + if (this.isLet(context)) { + starttype = types$1._var; + kind = "let"; + } + + // Most types of statements are recognized by the keyword they + // start with. Many are trivial to parse, some require a bit of + // complexity. + + switch (starttype) { + case types$1._break: case types$1._continue: return this.parseBreakContinueStatement(node, starttype.keyword) + case types$1._debugger: return this.parseDebuggerStatement(node) + case types$1._do: return this.parseDoStatement(node) + case types$1._for: return this.parseForStatement(node) + case types$1._function: + // Function as sole body of either an if statement or a labeled statement + // works, but not when it is part of a labeled statement that is the sole + // body of an if statement. + if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); } + return this.parseFunctionStatement(node, false, !context) + case types$1._class: + if (context) { this.unexpected(); } + return this.parseClass(node, true) + case types$1._if: return this.parseIfStatement(node) + case types$1._return: return this.parseReturnStatement(node) + case types$1._switch: return this.parseSwitchStatement(node) + case types$1._throw: return this.parseThrowStatement(node) + case types$1._try: return this.parseTryStatement(node) + case types$1._const: case types$1._var: + kind = kind || this.value; + if (context && kind !== "var") { this.unexpected(); } + return this.parseVarStatement(node, kind) + case types$1._while: return this.parseWhileStatement(node) + case types$1._with: return this.parseWithStatement(node) + case types$1.braceL: return this.parseBlock(true, node) + case types$1.semi: return this.parseEmptyStatement(node) + case types$1._export: + case types$1._import: + if (this.options.ecmaVersion > 10 && starttype === types$1._import) { + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); + if (nextCh === 40 || nextCh === 46) // '(' or '.' + { return this.parseExpressionStatement(node, this.parseExpression()) } + } + + if (!this.options.allowImportExportEverywhere) { + if (!topLevel) + { this.raise(this.start, "'import' and 'export' may only appear at the top level"); } + if (!this.inModule) + { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); } + } + return starttype === types$1._import ? this.parseImport(node) : this.parseExport(node, exports) + + // If the statement does not start with a statement keyword or a + // brace, it's an ExpressionStatement or LabeledStatement. We + // simply start parsing an expression, and afterwards, if the + // next token is a colon and the expression was a simple + // Identifier node, we switch to interpreting it as a label. + default: + if (this.isAsyncFunction()) { + if (context) { this.unexpected(); } + this.next(); + return this.parseFunctionStatement(node, true, !context) + } + + var usingKind = this.isAwaitUsing(false) ? "await using" : this.isUsing(false) ? "using" : null; + if (usingKind) { + if (topLevel && this.options.sourceType === "script") { + this.raise(this.start, "Using declaration cannot appear in the top level when source type is `script`"); + } + if (usingKind === "await using") { + if (!this.canAwait) { + this.raise(this.start, "Await using cannot appear outside of async function"); + } + this.next(); + } + this.next(); + this.parseVar(node, false, usingKind); + this.semicolon(); + return this.finishNode(node, "VariableDeclaration") + } + + var maybeName = this.value, expr = this.parseExpression(); + if (starttype === types$1.name && expr.type === "Identifier" && this.eat(types$1.colon)) + { return this.parseLabeledStatement(node, maybeName, expr, context) } + else { return this.parseExpressionStatement(node, expr) } + } + }; + + pp$8.parseBreakContinueStatement = function(node, keyword) { + var isBreak = keyword === "break"; + this.next(); + if (this.eat(types$1.semi) || this.insertSemicolon()) { node.label = null; } + else if (this.type !== types$1.name) { this.unexpected(); } + else { + node.label = this.parseIdent(); + this.semicolon(); + } + + // Verify that there is an actual destination to break or + // continue to. + var i = 0; + for (; i < this.labels.length; ++i) { + var lab = this.labels[i]; + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) { break } + if (node.label && isBreak) { break } + } + } + if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); } + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") + }; + + pp$8.parseDebuggerStatement = function(node) { + this.next(); + this.semicolon(); + return this.finishNode(node, "DebuggerStatement") + }; + + pp$8.parseDoStatement = function(node) { + this.next(); + this.labels.push(loopLabel); + node.body = this.parseStatement("do"); + this.labels.pop(); + this.expect(types$1._while); + node.test = this.parseParenExpression(); + if (this.options.ecmaVersion >= 6) + { this.eat(types$1.semi); } + else + { this.semicolon(); } + return this.finishNode(node, "DoWhileStatement") + }; + + // Disambiguating between a `for` and a `for`/`in` or `for`/`of` + // loop is non-trivial. Basically, we have to parse the init `var` + // statement or expression, disallowing the `in` operator (see + // the second parameter to `parseExpression`), and then check + // whether the next token is `in` or `of`. When there is no init + // part (semicolon immediately after the opening parenthesis), it + // is a regular `for` loop. + + pp$8.parseForStatement = function(node) { + this.next(); + var awaitAt = (this.options.ecmaVersion >= 9 && this.canAwait && this.eatContextual("await")) ? this.lastTokStart : -1; + this.labels.push(loopLabel); + this.enterScope(0); + this.expect(types$1.parenL); + if (this.type === types$1.semi) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, null) + } + var isLet = this.isLet(); + if (this.type === types$1._var || this.type === types$1._const || isLet) { + var init$1 = this.startNode(), kind = isLet ? "let" : this.value; + this.next(); + this.parseVar(init$1, true, kind); + this.finishNode(init$1, "VariableDeclaration"); + return this.parseForAfterInit(node, init$1, awaitAt) + } + var startsWithLet = this.isContextual("let"), isForOf = false; + + var usingKind = this.isUsing(true) ? "using" : this.isAwaitUsing(true) ? "await using" : null; + if (usingKind) { + var init$2 = this.startNode(); + this.next(); + if (usingKind === "await using") { this.next(); } + this.parseVar(init$2, true, usingKind); + this.finishNode(init$2, "VariableDeclaration"); + return this.parseForAfterInit(node, init$2, awaitAt) + } + var containsEsc = this.containsEsc; + var refDestructuringErrors = new DestructuringErrors; + var initPos = this.start; + var init = awaitAt > -1 + ? this.parseExprSubscripts(refDestructuringErrors, "await") + : this.parseExpression(true, refDestructuringErrors); + if (this.type === types$1._in || (isForOf = this.options.ecmaVersion >= 6 && this.isContextual("of"))) { + if (awaitAt > -1) { // implies `ecmaVersion >= 9` (see declaration of awaitAt) + if (this.type === types$1._in) { this.unexpected(awaitAt); } + node.await = true; + } else if (isForOf && this.options.ecmaVersion >= 8) { + if (init.start === initPos && !containsEsc && init.type === "Identifier" && init.name === "async") { this.unexpected(); } + else if (this.options.ecmaVersion >= 9) { node.await = false; } + } + if (startsWithLet && isForOf) { this.raise(init.start, "The left-hand side of a for-of loop may not start with 'let'."); } + this.toAssignable(init, false, refDestructuringErrors); + this.checkLValPattern(init); + return this.parseForIn(node, init) + } else { + this.checkExpressionErrors(refDestructuringErrors, true); + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init) + }; + + // Helper method to parse for loop after variable initialization + pp$8.parseForAfterInit = function(node, init, awaitAt) { + if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init.declarations.length === 1) { + if (this.options.ecmaVersion >= 9) { + if (this.type === types$1._in) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + } else { node.await = awaitAt > -1; } + } + return this.parseForIn(node, init) + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init) + }; + + pp$8.parseFunctionStatement = function(node, isAsync, declarationPosition) { + this.next(); + return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync) + }; + + pp$8.parseIfStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + // allow function declarations in branches, but only in non-strict mode + node.consequent = this.parseStatement("if"); + node.alternate = this.eat(types$1._else) ? this.parseStatement("if") : null; + return this.finishNode(node, "IfStatement") + }; + + pp$8.parseReturnStatement = function(node) { + if (!this.inFunction && !this.options.allowReturnOutsideFunction) + { this.raise(this.start, "'return' outside of function"); } + this.next(); + + // In `return` (and `break`/`continue`), the keywords with + // optional arguments, we eagerly look for a semicolon or the + // possibility to insert one. + + if (this.eat(types$1.semi) || this.insertSemicolon()) { node.argument = null; } + else { node.argument = this.parseExpression(); this.semicolon(); } + return this.finishNode(node, "ReturnStatement") + }; + + pp$8.parseSwitchStatement = function(node) { + this.next(); + node.discriminant = this.parseParenExpression(); + node.cases = []; + this.expect(types$1.braceL); + this.labels.push(switchLabel); + this.enterScope(0); + + // Statements under must be grouped (by label) in SwitchCase + // nodes. `cur` is used to keep the node that we are currently + // adding statements to. + + var cur; + for (var sawDefault = false; this.type !== types$1.braceR;) { + if (this.type === types$1._case || this.type === types$1._default) { + var isCase = this.type === types$1._case; + if (cur) { this.finishNode(cur, "SwitchCase"); } + node.cases.push(cur = this.startNode()); + cur.consequent = []; + this.next(); + if (isCase) { + cur.test = this.parseExpression(); + } else { + if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); } + sawDefault = true; + cur.test = null; + } + this.expect(types$1.colon); + } else { + if (!cur) { this.unexpected(); } + cur.consequent.push(this.parseStatement(null)); + } + } + this.exitScope(); + if (cur) { this.finishNode(cur, "SwitchCase"); } + this.next(); // Closing brace + this.labels.pop(); + return this.finishNode(node, "SwitchStatement") + }; + + pp$8.parseThrowStatement = function(node) { + this.next(); + if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) + { this.raise(this.lastTokEnd, "Illegal newline after throw"); } + node.argument = this.parseExpression(); + this.semicolon(); + return this.finishNode(node, "ThrowStatement") + }; + + // Reused empty array added for node fields that are always empty. + + var empty$1 = []; + + pp$8.parseCatchClauseParam = function() { + var param = this.parseBindingAtom(); + var simple = param.type === "Identifier"; + this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0); + this.checkLValPattern(param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL); + this.expect(types$1.parenR); + + return param + }; + + pp$8.parseTryStatement = function(node) { + this.next(); + node.block = this.parseBlock(); + node.handler = null; + if (this.type === types$1._catch) { + var clause = this.startNode(); + this.next(); + if (this.eat(types$1.parenL)) { + clause.param = this.parseCatchClauseParam(); + } else { + if (this.options.ecmaVersion < 10) { this.unexpected(); } + clause.param = null; + this.enterScope(0); + } + clause.body = this.parseBlock(false); + this.exitScope(); + node.handler = this.finishNode(clause, "CatchClause"); + } + node.finalizer = this.eat(types$1._finally) ? this.parseBlock() : null; + if (!node.handler && !node.finalizer) + { this.raise(node.start, "Missing catch or finally clause"); } + return this.finishNode(node, "TryStatement") + }; + + pp$8.parseVarStatement = function(node, kind, allowMissingInitializer) { + this.next(); + this.parseVar(node, false, kind, allowMissingInitializer); + this.semicolon(); + return this.finishNode(node, "VariableDeclaration") + }; + + pp$8.parseWhileStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + this.labels.push(loopLabel); + node.body = this.parseStatement("while"); + this.labels.pop(); + return this.finishNode(node, "WhileStatement") + }; + + pp$8.parseWithStatement = function(node) { + if (this.strict) { this.raise(this.start, "'with' in strict mode"); } + this.next(); + node.object = this.parseParenExpression(); + node.body = this.parseStatement("with"); + return this.finishNode(node, "WithStatement") + }; + + pp$8.parseEmptyStatement = function(node) { + this.next(); + return this.finishNode(node, "EmptyStatement") + }; + + pp$8.parseLabeledStatement = function(node, maybeName, expr, context) { + for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1) + { + var label = list[i$1]; + + if (label.name === maybeName) + { this.raise(expr.start, "Label '" + maybeName + "' is already declared"); + } } + var kind = this.type.isLoop ? "loop" : this.type === types$1._switch ? "switch" : null; + for (var i = this.labels.length - 1; i >= 0; i--) { + var label$1 = this.labels[i]; + if (label$1.statementStart === node.start) { + // Update information about previous labels on this node + label$1.statementStart = this.start; + label$1.kind = kind; + } else { break } + } + this.labels.push({name: maybeName, kind: kind, statementStart: this.start}); + node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label"); + this.labels.pop(); + node.label = expr; + return this.finishNode(node, "LabeledStatement") + }; + + pp$8.parseExpressionStatement = function(node, expr) { + node.expression = expr; + this.semicolon(); + return this.finishNode(node, "ExpressionStatement") + }; + + // Parse a semicolon-enclosed block of statements, handling `"use + // strict"` declarations when `allowStrict` is true (used for + // function bodies). + + pp$8.parseBlock = function(createNewLexicalScope, node, exitStrict) { + if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true; + if ( node === void 0 ) node = this.startNode(); + + node.body = []; + this.expect(types$1.braceL); + if (createNewLexicalScope) { this.enterScope(0); } + while (this.type !== types$1.braceR) { + var stmt = this.parseStatement(null); + node.body.push(stmt); + } + if (exitStrict) { this.strict = false; } + this.next(); + if (createNewLexicalScope) { this.exitScope(); } + return this.finishNode(node, "BlockStatement") + }; + + // Parse a regular `for` loop. The disambiguation code in + // `parseStatement` will already have parsed the init statement or + // expression. + + pp$8.parseFor = function(node, init) { + node.init = init; + this.expect(types$1.semi); + node.test = this.type === types$1.semi ? null : this.parseExpression(); + this.expect(types$1.semi); + node.update = this.type === types$1.parenR ? null : this.parseExpression(); + this.expect(types$1.parenR); + node.body = this.parseStatement("for"); + this.exitScope(); + this.labels.pop(); + return this.finishNode(node, "ForStatement") + }; + + // Parse a `for`/`in` and `for`/`of` loop, which are almost + // same from parser's perspective. + + pp$8.parseForIn = function(node, init) { + var isForIn = this.type === types$1._in; + this.next(); + + if ( + init.type === "VariableDeclaration" && + init.declarations[0].init != null && + ( + !isForIn || + this.options.ecmaVersion < 8 || + this.strict || + init.kind !== "var" || + init.declarations[0].id.type !== "Identifier" + ) + ) { + this.raise( + init.start, + ((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer") + ); + } + node.left = init; + node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign(); + this.expect(types$1.parenR); + node.body = this.parseStatement("for"); + this.exitScope(); + this.labels.pop(); + return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement") + }; + + // Parse a list of variable declarations. + + pp$8.parseVar = function(node, isFor, kind, allowMissingInitializer) { + node.declarations = []; + node.kind = kind; + for (;;) { + var decl = this.startNode(); + this.parseVarId(decl, kind); + if (this.eat(types$1.eq)) { + decl.init = this.parseMaybeAssign(isFor); + } else if (!allowMissingInitializer && kind === "const" && !(this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) { + this.unexpected(); + } else if (!allowMissingInitializer && (kind === "using" || kind === "await using") && this.options.ecmaVersion >= 17 && this.type !== types$1._in && !this.isContextual("of")) { + this.raise(this.lastTokEnd, ("Missing initializer in " + kind + " declaration")); + } else if (!allowMissingInitializer && decl.id.type !== "Identifier" && !(isFor && (this.type === types$1._in || this.isContextual("of")))) { + this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value"); + } else { + decl.init = null; + } + node.declarations.push(this.finishNode(decl, "VariableDeclarator")); + if (!this.eat(types$1.comma)) { break } + } + return node + }; + + pp$8.parseVarId = function(decl, kind) { + decl.id = kind === "using" || kind === "await using" + ? this.parseIdent() + : this.parseBindingAtom(); + + this.checkLValPattern(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false); + }; + + var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4; + + // Parse a function declaration or literal (depending on the + // `statement & FUNC_STATEMENT`). + + // Remove `allowExpressionBody` for 7.0.0, as it is only called with false + pp$8.parseFunction = function(node, statement, allowExpressionBody, isAsync, forInit) { + this.initFunction(node); + if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) { + if (this.type === types$1.star && (statement & FUNC_HANGING_STATEMENT)) + { this.unexpected(); } + node.generator = this.eat(types$1.star); + } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + + if (statement & FUNC_STATEMENT) { + node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types$1.name ? null : this.parseIdent(); + if (node.id && !(statement & FUNC_HANGING_STATEMENT)) + // If it is a regular function declaration in sloppy mode, then it is + // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding + // mode depends on properties of the current scope (see + // treatFunctionsAsVar). + { this.checkLValSimple(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); } + } + + var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + this.enterScope(functionFlags(node.async, node.generator)); + + if (!(statement & FUNC_STATEMENT)) + { node.id = this.type === types$1.name ? this.parseIdent() : null; } + + this.parseFunctionParams(node); + this.parseFunctionBody(node, allowExpressionBody, false, forInit); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression") + }; + + pp$8.parseFunctionParams = function(node) { + this.expect(types$1.parenL); + node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); + }; + + // Parse a class declaration or literal (depending on the + // `isStatement` parameter). + + pp$8.parseClass = function(node, isStatement) { + this.next(); + + // ecma-262 14.6 Class Definitions + // A class definition is always strict mode code. + var oldStrict = this.strict; + this.strict = true; + + this.parseClassId(node, isStatement); + this.parseClassSuper(node); + var privateNameMap = this.enterClassBody(); + var classBody = this.startNode(); + var hadConstructor = false; + classBody.body = []; + this.expect(types$1.braceL); + while (this.type !== types$1.braceR) { + var element = this.parseClassElement(node.superClass !== null); + if (element) { + classBody.body.push(element); + if (element.type === "MethodDefinition" && element.kind === "constructor") { + if (hadConstructor) { this.raiseRecoverable(element.start, "Duplicate constructor in the same class"); } + hadConstructor = true; + } else if (element.key && element.key.type === "PrivateIdentifier" && isPrivateNameConflicted(privateNameMap, element)) { + this.raiseRecoverable(element.key.start, ("Identifier '#" + (element.key.name) + "' has already been declared")); + } + } + } + this.strict = oldStrict; + this.next(); + node.body = this.finishNode(classBody, "ClassBody"); + this.exitClassBody(); + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") + }; + + pp$8.parseClassElement = function(constructorAllowsSuper) { + if (this.eat(types$1.semi)) { return null } + + var ecmaVersion = this.options.ecmaVersion; + var node = this.startNode(); + var keyName = ""; + var isGenerator = false; + var isAsync = false; + var kind = "method"; + var isStatic = false; + + if (this.eatContextual("static")) { + // Parse static init block + if (ecmaVersion >= 13 && this.eat(types$1.braceL)) { + this.parseClassStaticBlock(node); + return node + } + if (this.isClassElementNameStart() || this.type === types$1.star) { + isStatic = true; + } else { + keyName = "static"; + } + } + node.static = isStatic; + if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) { + if ((this.isClassElementNameStart() || this.type === types$1.star) && !this.canInsertSemicolon()) { + isAsync = true; + } else { + keyName = "async"; + } + } + if (!keyName && (ecmaVersion >= 9 || !isAsync) && this.eat(types$1.star)) { + isGenerator = true; + } + if (!keyName && !isAsync && !isGenerator) { + var lastValue = this.value; + if (this.eatContextual("get") || this.eatContextual("set")) { + if (this.isClassElementNameStart()) { + kind = lastValue; + } else { + keyName = lastValue; + } + } + } + + // Parse element name + if (keyName) { + // 'async', 'get', 'set', or 'static' were not a keyword contextually. + // The last token is any of those. Make it the element name. + node.computed = false; + node.key = this.startNodeAt(this.lastTokStart, this.lastTokStartLoc); + node.key.name = keyName; + this.finishNode(node.key, "Identifier"); + } else { + this.parseClassElementName(node); + } + + // Parse element value + if (ecmaVersion < 13 || this.type === types$1.parenL || kind !== "method" || isGenerator || isAsync) { + var isConstructor = !node.static && checkKeyName(node, "constructor"); + var allowsDirectSuper = isConstructor && constructorAllowsSuper; + // Couldn't move this check into the 'parseClassMethod' method for backward compatibility. + if (isConstructor && kind !== "method") { this.raise(node.key.start, "Constructor can't have get/set modifier"); } + node.kind = isConstructor ? "constructor" : kind; + this.parseClassMethod(node, isGenerator, isAsync, allowsDirectSuper); + } else { + this.parseClassField(node); + } + + return node + }; + + pp$8.isClassElementNameStart = function() { + return ( + this.type === types$1.name || + this.type === types$1.privateId || + this.type === types$1.num || + this.type === types$1.string || + this.type === types$1.bracketL || + this.type.keyword + ) + }; + + pp$8.parseClassElementName = function(element) { + if (this.type === types$1.privateId) { + if (this.value === "constructor") { + this.raise(this.start, "Classes can't have an element named '#constructor'"); + } + element.computed = false; + element.key = this.parsePrivateIdent(); + } else { + this.parsePropertyName(element); + } + }; + + pp$8.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) { + // Check key and flags + var key = method.key; + if (method.kind === "constructor") { + if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); } + if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); } + } else if (method.static && checkKeyName(method, "prototype")) { + this.raise(key.start, "Classes may not have a static property named prototype"); + } + + // Parse value + var value = method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper); + + // Check value + if (method.kind === "get" && value.params.length !== 0) + { this.raiseRecoverable(value.start, "getter should have no params"); } + if (method.kind === "set" && value.params.length !== 1) + { this.raiseRecoverable(value.start, "setter should have exactly one param"); } + if (method.kind === "set" && value.params[0].type === "RestElement") + { this.raiseRecoverable(value.params[0].start, "Setter cannot use rest params"); } + + return this.finishNode(method, "MethodDefinition") + }; + + pp$8.parseClassField = function(field) { + if (checkKeyName(field, "constructor")) { + this.raise(field.key.start, "Classes can't have a field named 'constructor'"); + } else if (field.static && checkKeyName(field, "prototype")) { + this.raise(field.key.start, "Classes can't have a static field named 'prototype'"); + } + + if (this.eat(types$1.eq)) { + // To raise SyntaxError if 'arguments' exists in the initializer. + this.enterScope(SCOPE_CLASS_FIELD_INIT | SCOPE_SUPER); + field.value = this.parseMaybeAssign(); + this.exitScope(); + } else { + field.value = null; + } + this.semicolon(); + + return this.finishNode(field, "PropertyDefinition") + }; + + pp$8.parseClassStaticBlock = function(node) { + node.body = []; + + var oldLabels = this.labels; + this.labels = []; + this.enterScope(SCOPE_CLASS_STATIC_BLOCK | SCOPE_SUPER); + while (this.type !== types$1.braceR) { + var stmt = this.parseStatement(null); + node.body.push(stmt); + } + this.next(); + this.exitScope(); + this.labels = oldLabels; + + return this.finishNode(node, "StaticBlock") + }; + + pp$8.parseClassId = function(node, isStatement) { + if (this.type === types$1.name) { + node.id = this.parseIdent(); + if (isStatement) + { this.checkLValSimple(node.id, BIND_LEXICAL, false); } + } else { + if (isStatement === true) + { this.unexpected(); } + node.id = null; + } + }; + + pp$8.parseClassSuper = function(node) { + node.superClass = this.eat(types$1._extends) ? this.parseExprSubscripts(null, false) : null; + }; + + pp$8.enterClassBody = function() { + var element = {declared: Object.create(null), used: []}; + this.privateNameStack.push(element); + return element.declared + }; + + pp$8.exitClassBody = function() { + var ref = this.privateNameStack.pop(); + var declared = ref.declared; + var used = ref.used; + if (!this.options.checkPrivateFields) { return } + var len = this.privateNameStack.length; + var parent = len === 0 ? null : this.privateNameStack[len - 1]; + for (var i = 0; i < used.length; ++i) { + var id = used[i]; + if (!hasOwn(declared, id.name)) { + if (parent) { + parent.used.push(id); + } else { + this.raiseRecoverable(id.start, ("Private field '#" + (id.name) + "' must be declared in an enclosing class")); + } + } + } + }; + + function isPrivateNameConflicted(privateNameMap, element) { + var name = element.key.name; + var curr = privateNameMap[name]; + + var next = "true"; + if (element.type === "MethodDefinition" && (element.kind === "get" || element.kind === "set")) { + next = (element.static ? "s" : "i") + element.kind; + } + + // `class { get #a(){}; static set #a(_){} }` is also conflict. + if ( + curr === "iget" && next === "iset" || + curr === "iset" && next === "iget" || + curr === "sget" && next === "sset" || + curr === "sset" && next === "sget" + ) { + privateNameMap[name] = "true"; + return false + } else if (!curr) { + privateNameMap[name] = next; + return false + } else { + return true + } + } + + function checkKeyName(node, name) { + var computed = node.computed; + var key = node.key; + return !computed && ( + key.type === "Identifier" && key.name === name || + key.type === "Literal" && key.value === name + ) + } + + // Parses module export declaration. + + pp$8.parseExportAllDeclaration = function(node, exports) { + if (this.options.ecmaVersion >= 11) { + if (this.eatContextual("as")) { + node.exported = this.parseModuleExportName(); + this.checkExport(exports, node.exported, this.lastTokStart); + } else { + node.exported = null; + } + } + this.expectContextual("from"); + if (this.type !== types$1.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } + this.semicolon(); + return this.finishNode(node, "ExportAllDeclaration") + }; + + pp$8.parseExport = function(node, exports) { + this.next(); + // export * from '...' + if (this.eat(types$1.star)) { + return this.parseExportAllDeclaration(node, exports) + } + if (this.eat(types$1._default)) { // export default ... + this.checkExport(exports, "default", this.lastTokStart); + node.declaration = this.parseExportDefaultDeclaration(); + return this.finishNode(node, "ExportDefaultDeclaration") + } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseExportDeclaration(node); + if (node.declaration.type === "VariableDeclaration") + { this.checkVariableExport(exports, node.declaration.declarations); } + else + { this.checkExport(exports, node.declaration.id, node.declaration.id.start); } + node.specifiers = []; + node.source = null; + if (this.options.ecmaVersion >= 16) + { node.attributes = []; } + } else { // export { x, y as z } [from '...'] + node.declaration = null; + node.specifiers = this.parseExportSpecifiers(exports); + if (this.eatContextual("from")) { + if (this.type !== types$1.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } + } else { + for (var i = 0, list = node.specifiers; i < list.length; i += 1) { + // check for keywords used as local names + var spec = list[i]; + + this.checkUnreserved(spec.local); + // check if export is defined + this.checkLocalExport(spec.local); + + if (spec.local.type === "Literal") { + this.raise(spec.local.start, "A string literal cannot be used as an exported binding without `from`."); + } + } + + node.source = null; + if (this.options.ecmaVersion >= 16) + { node.attributes = []; } + } + this.semicolon(); + } + return this.finishNode(node, "ExportNamedDeclaration") + }; + + pp$8.parseExportDeclaration = function(node) { + return this.parseStatement(null) + }; + + pp$8.parseExportDefaultDeclaration = function() { + var isAsync; + if (this.type === types$1._function || (isAsync = this.isAsyncFunction())) { + var fNode = this.startNode(); + this.next(); + if (isAsync) { this.next(); } + return this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync) + } else if (this.type === types$1._class) { + var cNode = this.startNode(); + return this.parseClass(cNode, "nullableID") + } else { + var declaration = this.parseMaybeAssign(); + this.semicolon(); + return declaration + } + }; + + pp$8.checkExport = function(exports, name, pos) { + if (!exports) { return } + if (typeof name !== "string") + { name = name.type === "Identifier" ? name.name : name.value; } + if (hasOwn(exports, name)) + { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); } + exports[name] = true; + }; + + pp$8.checkPatternExport = function(exports, pat) { + var type = pat.type; + if (type === "Identifier") + { this.checkExport(exports, pat, pat.start); } + else if (type === "ObjectPattern") + { for (var i = 0, list = pat.properties; i < list.length; i += 1) + { + var prop = list[i]; + + this.checkPatternExport(exports, prop); + } } + else if (type === "ArrayPattern") + { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) { + var elt = list$1[i$1]; + + if (elt) { this.checkPatternExport(exports, elt); } + } } + else if (type === "Property") + { this.checkPatternExport(exports, pat.value); } + else if (type === "AssignmentPattern") + { this.checkPatternExport(exports, pat.left); } + else if (type === "RestElement") + { this.checkPatternExport(exports, pat.argument); } + }; + + pp$8.checkVariableExport = function(exports, decls) { + if (!exports) { return } + for (var i = 0, list = decls; i < list.length; i += 1) + { + var decl = list[i]; + + this.checkPatternExport(exports, decl.id); + } + }; + + pp$8.shouldParseExportStatement = function() { + return this.type.keyword === "var" || + this.type.keyword === "const" || + this.type.keyword === "class" || + this.type.keyword === "function" || + this.isLet() || + this.isAsyncFunction() + }; + + // Parses a comma-separated list of module exports. + + pp$8.parseExportSpecifier = function(exports) { + var node = this.startNode(); + node.local = this.parseModuleExportName(); + + node.exported = this.eatContextual("as") ? this.parseModuleExportName() : node.local; + this.checkExport( + exports, + node.exported, + node.exported.start + ); + + return this.finishNode(node, "ExportSpecifier") + }; + + pp$8.parseExportSpecifiers = function(exports) { + var nodes = [], first = true; + // export { x, y as z } [from '...'] + this.expect(types$1.braceL); + while (!this.eat(types$1.braceR)) { + if (!first) { + this.expect(types$1.comma); + if (this.afterTrailingComma(types$1.braceR)) { break } + } else { first = false; } + + nodes.push(this.parseExportSpecifier(exports)); + } + return nodes + }; + + // Parses import declaration. + + pp$8.parseImport = function(node) { + this.next(); + + // import '...' + if (this.type === types$1.string) { + node.specifiers = empty$1; + node.source = this.parseExprAtom(); + } else { + node.specifiers = this.parseImportSpecifiers(); + this.expectContextual("from"); + node.source = this.type === types$1.string ? this.parseExprAtom() : this.unexpected(); + } + if (this.options.ecmaVersion >= 16) + { node.attributes = this.parseWithClause(); } + this.semicolon(); + return this.finishNode(node, "ImportDeclaration") + }; + + // Parses a comma-separated list of module imports. + + pp$8.parseImportSpecifier = function() { + var node = this.startNode(); + node.imported = this.parseModuleExportName(); + + if (this.eatContextual("as")) { + node.local = this.parseIdent(); + } else { + this.checkUnreserved(node.imported); + node.local = node.imported; + } + this.checkLValSimple(node.local, BIND_LEXICAL); + + return this.finishNode(node, "ImportSpecifier") + }; + + pp$8.parseImportDefaultSpecifier = function() { + // import defaultObj, { x, y as z } from '...' + var node = this.startNode(); + node.local = this.parseIdent(); + this.checkLValSimple(node.local, BIND_LEXICAL); + return this.finishNode(node, "ImportDefaultSpecifier") + }; + + pp$8.parseImportNamespaceSpecifier = function() { + var node = this.startNode(); + this.next(); + this.expectContextual("as"); + node.local = this.parseIdent(); + this.checkLValSimple(node.local, BIND_LEXICAL); + return this.finishNode(node, "ImportNamespaceSpecifier") + }; + + pp$8.parseImportSpecifiers = function() { + var nodes = [], first = true; + if (this.type === types$1.name) { + nodes.push(this.parseImportDefaultSpecifier()); + if (!this.eat(types$1.comma)) { return nodes } + } + if (this.type === types$1.star) { + nodes.push(this.parseImportNamespaceSpecifier()); + return nodes + } + this.expect(types$1.braceL); + while (!this.eat(types$1.braceR)) { + if (!first) { + this.expect(types$1.comma); + if (this.afterTrailingComma(types$1.braceR)) { break } + } else { first = false; } + + nodes.push(this.parseImportSpecifier()); + } + return nodes + }; + + pp$8.parseWithClause = function() { + var nodes = []; + if (!this.eat(types$1._with)) { + return nodes + } + this.expect(types$1.braceL); + var attributeKeys = {}; + var first = true; + while (!this.eat(types$1.braceR)) { + if (!first) { + this.expect(types$1.comma); + if (this.afterTrailingComma(types$1.braceR)) { break } + } else { first = false; } + + var attr = this.parseImportAttribute(); + var keyName = attr.key.type === "Identifier" ? attr.key.name : attr.key.value; + if (hasOwn(attributeKeys, keyName)) + { this.raiseRecoverable(attr.key.start, "Duplicate attribute key '" + keyName + "'"); } + attributeKeys[keyName] = true; + nodes.push(attr); + } + return nodes + }; + + pp$8.parseImportAttribute = function() { + var node = this.startNode(); + node.key = this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never"); + this.expect(types$1.colon); + if (this.type !== types$1.string) { + this.unexpected(); + } + node.value = this.parseExprAtom(); + return this.finishNode(node, "ImportAttribute") + }; + + pp$8.parseModuleExportName = function() { + if (this.options.ecmaVersion >= 13 && this.type === types$1.string) { + var stringLiteral = this.parseLiteral(this.value); + if (loneSurrogate.test(stringLiteral.value)) { + this.raise(stringLiteral.start, "An export name cannot include a lone surrogate."); + } + return stringLiteral + } + return this.parseIdent(true) + }; + + // Set `ExpressionStatement#directive` property for directive prologues. + pp$8.adaptDirectivePrologue = function(statements) { + for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) { + statements[i].directive = statements[i].expression.raw.slice(1, -1); + } + }; + pp$8.isDirectiveCandidate = function(statement) { + return ( + this.options.ecmaVersion >= 5 && + statement.type === "ExpressionStatement" && + statement.expression.type === "Literal" && + typeof statement.expression.value === "string" && + // Reject parenthesized strings. + (this.input[statement.start] === "\"" || this.input[statement.start] === "'") + ) + }; + + var pp$7 = Parser.prototype; + + // Convert existing expression atom to assignable pattern + // if possible. + + pp$7.toAssignable = function(node, isBinding, refDestructuringErrors) { + if (this.options.ecmaVersion >= 6 && node) { + switch (node.type) { + case "Identifier": + if (this.inAsync && node.name === "await") + { this.raise(node.start, "Cannot use 'await' as identifier inside an async function"); } + break + + case "ObjectPattern": + case "ArrayPattern": + case "AssignmentPattern": + case "RestElement": + break + + case "ObjectExpression": + node.type = "ObjectPattern"; + if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + for (var i = 0, list = node.properties; i < list.length; i += 1) { + var prop = list[i]; + + this.toAssignable(prop, isBinding); + // Early error: + // AssignmentRestProperty[Yield, Await] : + // `...` DestructuringAssignmentTarget[Yield, Await] + // + // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|. + if ( + prop.type === "RestElement" && + (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern") + ) { + this.raise(prop.argument.start, "Unexpected token"); + } + } + break + + case "Property": + // AssignmentProperty has type === "Property" + if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); } + this.toAssignable(node.value, isBinding); + break + + case "ArrayExpression": + node.type = "ArrayPattern"; + if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + this.toAssignableList(node.elements, isBinding); + break + + case "SpreadElement": + node.type = "RestElement"; + this.toAssignable(node.argument, isBinding); + if (node.argument.type === "AssignmentPattern") + { this.raise(node.argument.start, "Rest elements cannot have a default value"); } + break + + case "AssignmentExpression": + if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); } + node.type = "AssignmentPattern"; + delete node.operator; + this.toAssignable(node.left, isBinding); + break + + case "ParenthesizedExpression": + this.toAssignable(node.expression, isBinding, refDestructuringErrors); + break + + case "ChainExpression": + this.raiseRecoverable(node.start, "Optional chaining cannot appear in left-hand side"); + break + + case "MemberExpression": + if (!isBinding) { break } + + default: + this.raise(node.start, "Assigning to rvalue"); + } + } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + return node + }; + + // Convert list of expression atoms to binding list. + + pp$7.toAssignableList = function(exprList, isBinding) { + var end = exprList.length; + for (var i = 0; i < end; i++) { + var elt = exprList[i]; + if (elt) { this.toAssignable(elt, isBinding); } + } + if (end) { + var last = exprList[end - 1]; + if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") + { this.unexpected(last.argument.start); } + } + return exprList + }; + + // Parses spread element. + + pp$7.parseSpread = function(refDestructuringErrors) { + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeAssign(false, refDestructuringErrors); + return this.finishNode(node, "SpreadElement") + }; + + pp$7.parseRestBinding = function() { + var node = this.startNode(); + this.next(); + + // RestElement inside of a function parameter must be an identifier + if (this.options.ecmaVersion === 6 && this.type !== types$1.name) + { this.unexpected(); } + + node.argument = this.parseBindingAtom(); + + return this.finishNode(node, "RestElement") + }; + + // Parses lvalue (assignable) atom. + + pp$7.parseBindingAtom = function() { + if (this.options.ecmaVersion >= 6) { + switch (this.type) { + case types$1.bracketL: + var node = this.startNode(); + this.next(); + node.elements = this.parseBindingList(types$1.bracketR, true, true); + return this.finishNode(node, "ArrayPattern") + + case types$1.braceL: + return this.parseObj(true) + } + } + return this.parseIdent() + }; + + pp$7.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowModifiers) { + var elts = [], first = true; + while (!this.eat(close)) { + if (first) { first = false; } + else { this.expect(types$1.comma); } + if (allowEmpty && this.type === types$1.comma) { + elts.push(null); + } else if (allowTrailingComma && this.afterTrailingComma(close)) { + break + } else if (this.type === types$1.ellipsis) { + var rest = this.parseRestBinding(); + this.parseBindingListItem(rest); + elts.push(rest); + if (this.type === types$1.comma) { this.raiseRecoverable(this.start, "Comma is not permitted after the rest element"); } + this.expect(close); + break + } else { + elts.push(this.parseAssignableListItem(allowModifiers)); + } + } + return elts + }; + + pp$7.parseAssignableListItem = function(allowModifiers) { + var elem = this.parseMaybeDefault(this.start, this.startLoc); + this.parseBindingListItem(elem); + return elem + }; + + pp$7.parseBindingListItem = function(param) { + return param + }; + + // Parses assignment pattern around given atom if possible. + + pp$7.parseMaybeDefault = function(startPos, startLoc, left) { + left = left || this.parseBindingAtom(); + if (this.options.ecmaVersion < 6 || !this.eat(types$1.eq)) { return left } + var node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.right = this.parseMaybeAssign(); + return this.finishNode(node, "AssignmentPattern") + }; + + // The following three functions all verify that a node is an lvalue — + // something that can be bound, or assigned to. In order to do so, they perform + // a variety of checks: + // + // - Check that none of the bound/assigned-to identifiers are reserved words. + // - Record name declarations for bindings in the appropriate scope. + // - Check duplicate argument names, if checkClashes is set. + // + // If a complex binding pattern is encountered (e.g., object and array + // destructuring), the entire pattern is recursively checked. + // + // There are three versions of checkLVal*() appropriate for different + // circumstances: + // + // - checkLValSimple() shall be used if the syntactic construct supports + // nothing other than identifiers and member expressions. Parenthesized + // expressions are also correctly handled. This is generally appropriate for + // constructs for which the spec says + // + // > It is a Syntax Error if AssignmentTargetType of [the production] is not + // > simple. + // + // It is also appropriate for checking if an identifier is valid and not + // defined elsewhere, like import declarations or function/class identifiers. + // + // Examples where this is used include: + // a += …; + // import a from '…'; + // where a is the node to be checked. + // + // - checkLValPattern() shall be used if the syntactic construct supports + // anything checkLValSimple() supports, as well as object and array + // destructuring patterns. This is generally appropriate for constructs for + // which the spec says + // + // > It is a Syntax Error if [the production] is neither an ObjectLiteral nor + // > an ArrayLiteral and AssignmentTargetType of [the production] is not + // > simple. + // + // Examples where this is used include: + // (a = …); + // const a = …; + // try { … } catch (a) { … } + // where a is the node to be checked. + // + // - checkLValInnerPattern() shall be used if the syntactic construct supports + // anything checkLValPattern() supports, as well as default assignment + // patterns, rest elements, and other constructs that may appear within an + // object or array destructuring pattern. + // + // As a special case, function parameters also use checkLValInnerPattern(), + // as they also support defaults and rest constructs. + // + // These functions deliberately support both assignment and binding constructs, + // as the logic for both is exceedingly similar. If the node is the target of + // an assignment, then bindingType should be set to BIND_NONE. Otherwise, it + // should be set to the appropriate BIND_* constant, like BIND_VAR or + // BIND_LEXICAL. + // + // If the function is called with a non-BIND_NONE bindingType, then + // additionally a checkClashes object may be specified to allow checking for + // duplicate argument names. checkClashes is ignored if the provided construct + // is an assignment (i.e., bindingType is BIND_NONE). + + pp$7.checkLValSimple = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; + + var isBind = bindingType !== BIND_NONE; + + switch (expr.type) { + case "Identifier": + if (this.strict && this.reservedWordsStrictBind.test(expr.name)) + { this.raiseRecoverable(expr.start, (isBind ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); } + if (isBind) { + if (bindingType === BIND_LEXICAL && expr.name === "let") + { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); } + if (checkClashes) { + if (hasOwn(checkClashes, expr.name)) + { this.raiseRecoverable(expr.start, "Argument name clash"); } + checkClashes[expr.name] = true; + } + if (bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); } + } + break + + case "ChainExpression": + this.raiseRecoverable(expr.start, "Optional chaining cannot appear in left-hand side"); + break + + case "MemberExpression": + if (isBind) { this.raiseRecoverable(expr.start, "Binding member expression"); } + break + + case "ParenthesizedExpression": + if (isBind) { this.raiseRecoverable(expr.start, "Binding parenthesized expression"); } + return this.checkLValSimple(expr.expression, bindingType, checkClashes) + + default: + this.raise(expr.start, (isBind ? "Binding" : "Assigning to") + " rvalue"); + } + }; + + pp$7.checkLValPattern = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; + + switch (expr.type) { + case "ObjectPattern": + for (var i = 0, list = expr.properties; i < list.length; i += 1) { + var prop = list[i]; + + this.checkLValInnerPattern(prop, bindingType, checkClashes); + } + break + + case "ArrayPattern": + for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) { + var elem = list$1[i$1]; + + if (elem) { this.checkLValInnerPattern(elem, bindingType, checkClashes); } + } + break + + default: + this.checkLValSimple(expr, bindingType, checkClashes); + } + }; + + pp$7.checkLValInnerPattern = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; + + switch (expr.type) { + case "Property": + // AssignmentProperty has type === "Property" + this.checkLValInnerPattern(expr.value, bindingType, checkClashes); + break + + case "AssignmentPattern": + this.checkLValPattern(expr.left, bindingType, checkClashes); + break + + case "RestElement": + this.checkLValPattern(expr.argument, bindingType, checkClashes); + break + + default: + this.checkLValPattern(expr, bindingType, checkClashes); + } + }; + + // The algorithm used to determine whether a regexp can appear at a + // given point in the program is loosely based on sweet.js' approach. + // See https://github.com/mozilla/sweet.js/wiki/design + + + var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) { + this.token = token; + this.isExpr = !!isExpr; + this.preserveSpace = !!preserveSpace; + this.override = override; + this.generator = !!generator; + }; + + var types = { + b_stat: new TokContext("{", false), + b_expr: new TokContext("{", true), + b_tmpl: new TokContext("${", false), + p_stat: new TokContext("(", false), + p_expr: new TokContext("(", true), + q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }), + f_stat: new TokContext("function", false), + f_expr: new TokContext("function", true), + f_expr_gen: new TokContext("function", true, false, null, true), + f_gen: new TokContext("function", false, false, null, true) + }; + + var pp$6 = Parser.prototype; + + pp$6.initialContext = function() { + return [types.b_stat] + }; + + pp$6.curContext = function() { + return this.context[this.context.length - 1] + }; + + pp$6.braceIsBlock = function(prevType) { + var parent = this.curContext(); + if (parent === types.f_expr || parent === types.f_stat) + { return true } + if (prevType === types$1.colon && (parent === types.b_stat || parent === types.b_expr)) + { return !parent.isExpr } + + // The check for `tt.name && exprAllowed` detects whether we are + // after a `yield` or `of` construct. See the `updateContext` for + // `tt.name`. + if (prevType === types$1._return || prevType === types$1.name && this.exprAllowed) + { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) } + if (prevType === types$1._else || prevType === types$1.semi || prevType === types$1.eof || prevType === types$1.parenR || prevType === types$1.arrow) + { return true } + if (prevType === types$1.braceL) + { return parent === types.b_stat } + if (prevType === types$1._var || prevType === types$1._const || prevType === types$1.name) + { return false } + return !this.exprAllowed + }; + + pp$6.inGeneratorContext = function() { + for (var i = this.context.length - 1; i >= 1; i--) { + var context = this.context[i]; + if (context.token === "function") + { return context.generator } + } + return false + }; + + pp$6.updateContext = function(prevType) { + var update, type = this.type; + if (type.keyword && prevType === types$1.dot) + { this.exprAllowed = false; } + else if (update = type.updateContext) + { update.call(this, prevType); } + else + { this.exprAllowed = type.beforeExpr; } + }; + + // Used to handle edge cases when token context could not be inferred correctly during tokenization phase + + pp$6.overrideContext = function(tokenCtx) { + if (this.curContext() !== tokenCtx) { + this.context[this.context.length - 1] = tokenCtx; + } + }; + + // Token-specific context update code + + types$1.parenR.updateContext = types$1.braceR.updateContext = function() { + if (this.context.length === 1) { + this.exprAllowed = true; + return + } + var out = this.context.pop(); + if (out === types.b_stat && this.curContext().token === "function") { + out = this.context.pop(); + } + this.exprAllowed = !out.isExpr; + }; + + types$1.braceL.updateContext = function(prevType) { + this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr); + this.exprAllowed = true; + }; + + types$1.dollarBraceL.updateContext = function() { + this.context.push(types.b_tmpl); + this.exprAllowed = true; + }; + + types$1.parenL.updateContext = function(prevType) { + var statementParens = prevType === types$1._if || prevType === types$1._for || prevType === types$1._with || prevType === types$1._while; + this.context.push(statementParens ? types.p_stat : types.p_expr); + this.exprAllowed = true; + }; + + types$1.incDec.updateContext = function() { + // tokExprAllowed stays unchanged + }; + + types$1._function.updateContext = types$1._class.updateContext = function(prevType) { + if (prevType.beforeExpr && prevType !== types$1._else && + !(prevType === types$1.semi && this.curContext() !== types.p_stat) && + !(prevType === types$1._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) && + !((prevType === types$1.colon || prevType === types$1.braceL) && this.curContext() === types.b_stat)) + { this.context.push(types.f_expr); } + else + { this.context.push(types.f_stat); } + this.exprAllowed = false; + }; + + types$1.colon.updateContext = function() { + if (this.curContext().token === "function") { this.context.pop(); } + this.exprAllowed = true; + }; + + types$1.backQuote.updateContext = function() { + if (this.curContext() === types.q_tmpl) + { this.context.pop(); } + else + { this.context.push(types.q_tmpl); } + this.exprAllowed = false; + }; + + types$1.star.updateContext = function(prevType) { + if (prevType === types$1._function) { + var index = this.context.length - 1; + if (this.context[index] === types.f_expr) + { this.context[index] = types.f_expr_gen; } + else + { this.context[index] = types.f_gen; } + } + this.exprAllowed = true; + }; + + types$1.name.updateContext = function(prevType) { + var allowed = false; + if (this.options.ecmaVersion >= 6 && prevType !== types$1.dot) { + if (this.value === "of" && !this.exprAllowed || + this.value === "yield" && this.inGeneratorContext()) + { allowed = true; } + } + this.exprAllowed = allowed; + }; + + // A recursive descent parser operates by defining functions for all + // syntactic elements, and recursively calling those, each function + // advancing the input stream and returning an AST node. Precedence + // of constructs (for example, the fact that `!x[1]` means `!(x[1])` + // instead of `(!x)[1]` is handled by the fact that the parser + // function that parses unary prefix operators is called first, and + // in turn calls the function that parses `[]` subscripts — that + // way, it'll receive the node for `x[1]` already parsed, and wraps + // *that* in the unary operator node. + // + // Acorn uses an [operator precedence parser][opp] to handle binary + // operator precedence, because it is much more compact than using + // the technique outlined above, which uses different, nesting + // functions to specify precedence, for all of the ten binary + // precedence levels that JavaScript defines. + // + // [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser + + + var pp$5 = Parser.prototype; + + // Check if property name clashes with already added. + // Object/class getters and setters are not allowed to clash — + // either with each other or with an init property — and in + // strict mode, init properties are also not allowed to be repeated. + + pp$5.checkPropClash = function(prop, propHash, refDestructuringErrors) { + if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement") + { return } + if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) + { return } + var key = prop.key; + var name; + switch (key.type) { + case "Identifier": name = key.name; break + case "Literal": name = String(key.value); break + default: return + } + var kind = prop.kind; + if (this.options.ecmaVersion >= 6) { + if (name === "__proto__" && kind === "init") { + if (propHash.proto) { + if (refDestructuringErrors) { + if (refDestructuringErrors.doubleProto < 0) { + refDestructuringErrors.doubleProto = key.start; + } + } else { + this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); + } + } + propHash.proto = true; + } + return + } + name = "$" + name; + var other = propHash[name]; + if (other) { + var redefinition; + if (kind === "init") { + redefinition = this.strict && other.init || other.get || other.set; + } else { + redefinition = other.init || other[kind]; + } + if (redefinition) + { this.raiseRecoverable(key.start, "Redefinition of property"); } + } else { + other = propHash[name] = { + init: false, + get: false, + set: false + }; + } + other[kind] = true; + }; + + // ### Expression parsing + + // These nest, from the most general expression type at the top to + // 'atomic', nondivisible expression types at the bottom. Most of + // the functions will simply let the function(s) below them parse, + // and, *if* the syntactic construct they handle is present, wrap + // the AST node that the inner parser gave them in another node. + + // Parse a full expression. The optional arguments are used to + // forbid the `in` operator (in for loops initalization expressions) + // and provide reference for storing '=' operator inside shorthand + // property assignment in contexts where both object expression + // and object pattern might appear (so it's possible to raise + // delayed syntax error at correct position). + + pp$5.parseExpression = function(forInit, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseMaybeAssign(forInit, refDestructuringErrors); + if (this.type === types$1.comma) { + var node = this.startNodeAt(startPos, startLoc); + node.expressions = [expr]; + while (this.eat(types$1.comma)) { node.expressions.push(this.parseMaybeAssign(forInit, refDestructuringErrors)); } + return this.finishNode(node, "SequenceExpression") + } + return expr + }; + + // Parse an assignment expression. This includes applications of + // operators like `+=`. + + pp$5.parseMaybeAssign = function(forInit, refDestructuringErrors, afterLeftParse) { + if (this.isContextual("yield")) { + if (this.inGenerator) { return this.parseYield(forInit) } + // The tokenizer will assume an expression is allowed after + // `yield`, but this isn't that kind of yield + else { this.exprAllowed = false; } + } + + var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1, oldDoubleProto = -1; + if (refDestructuringErrors) { + oldParenAssign = refDestructuringErrors.parenthesizedAssign; + oldTrailingComma = refDestructuringErrors.trailingComma; + oldDoubleProto = refDestructuringErrors.doubleProto; + refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1; + } else { + refDestructuringErrors = new DestructuringErrors; + ownDestructuringErrors = true; + } + + var startPos = this.start, startLoc = this.startLoc; + if (this.type === types$1.parenL || this.type === types$1.name) { + this.potentialArrowAt = this.start; + this.potentialArrowInForAwait = forInit === "await"; + } + var left = this.parseMaybeConditional(forInit, refDestructuringErrors); + if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); } + if (this.type.isAssign) { + var node = this.startNodeAt(startPos, startLoc); + node.operator = this.value; + if (this.type === types$1.eq) + { left = this.toAssignable(left, false, refDestructuringErrors); } + if (!ownDestructuringErrors) { + refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1; + } + if (refDestructuringErrors.shorthandAssign >= left.start) + { refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly + if (this.type === types$1.eq) + { this.checkLValPattern(left); } + else + { this.checkLValSimple(left); } + node.left = left; + this.next(); + node.right = this.parseMaybeAssign(forInit); + if (oldDoubleProto > -1) { refDestructuringErrors.doubleProto = oldDoubleProto; } + return this.finishNode(node, "AssignmentExpression") + } else { + if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); } + } + if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; } + if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; } + return left + }; + + // Parse a ternary conditional (`?:`) operator. + + pp$5.parseMaybeConditional = function(forInit, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprOps(forInit, refDestructuringErrors); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + if (this.eat(types$1.question)) { + var node = this.startNodeAt(startPos, startLoc); + node.test = expr; + node.consequent = this.parseMaybeAssign(); + this.expect(types$1.colon); + node.alternate = this.parseMaybeAssign(forInit); + return this.finishNode(node, "ConditionalExpression") + } + return expr + }; + + // Start the precedence parser. + + pp$5.parseExprOps = function(forInit, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseMaybeUnary(refDestructuringErrors, false, false, forInit); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, forInit) + }; + + // Parse binary operators with the operator precedence parsing + // algorithm. `left` is the left-hand side of the operator. + // `minPrec` provides context that allows the function to stop and + // defer further parser to one of its callers when it encounters an + // operator that has a lower precedence than the set it is parsing. + + pp$5.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, forInit) { + var prec = this.type.binop; + if (prec != null && (!forInit || this.type !== types$1._in)) { + if (prec > minPrec) { + var logical = this.type === types$1.logicalOR || this.type === types$1.logicalAND; + var coalesce = this.type === types$1.coalesce; + if (coalesce) { + // Handle the precedence of `tt.coalesce` as equal to the range of logical expressions. + // In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error. + prec = types$1.logicalAND.binop; + } + var op = this.value; + this.next(); + var startPos = this.start, startLoc = this.startLoc; + var right = this.parseExprOp(this.parseMaybeUnary(null, false, false, forInit), startPos, startLoc, prec, forInit); + var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce); + if ((logical && this.type === types$1.coalesce) || (coalesce && (this.type === types$1.logicalOR || this.type === types$1.logicalAND))) { + this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses"); + } + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, forInit) + } + } + return left + }; + + pp$5.buildBinary = function(startPos, startLoc, left, right, op, logical) { + if (right.type === "PrivateIdentifier") { this.raise(right.start, "Private identifier can only be left side of binary expression"); } + var node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.operator = op; + node.right = right; + return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") + }; + + // Parse unary operators, both prefix and postfix. + + pp$5.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec, forInit) { + var startPos = this.start, startLoc = this.startLoc, expr; + if (this.isContextual("await") && this.canAwait) { + expr = this.parseAwait(forInit); + sawUnary = true; + } else if (this.type.prefix) { + var node = this.startNode(), update = this.type === types$1.incDec; + node.operator = this.value; + node.prefix = true; + this.next(); + node.argument = this.parseMaybeUnary(null, true, update, forInit); + this.checkExpressionErrors(refDestructuringErrors, true); + if (update) { this.checkLValSimple(node.argument); } + else if (this.strict && node.operator === "delete" && isLocalVariableAccess(node.argument)) + { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); } + else if (node.operator === "delete" && isPrivateFieldAccess(node.argument)) + { this.raiseRecoverable(node.start, "Private fields can not be deleted"); } + else { sawUnary = true; } + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); + } else if (!sawUnary && this.type === types$1.privateId) { + if ((forInit || this.privateNameStack.length === 0) && this.options.checkPrivateFields) { this.unexpected(); } + expr = this.parsePrivateIdent(); + // only could be private fields in 'in', such as #x in obj + if (this.type !== types$1._in) { this.unexpected(); } + } else { + expr = this.parseExprSubscripts(refDestructuringErrors, forInit); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + while (this.type.postfix && !this.canInsertSemicolon()) { + var node$1 = this.startNodeAt(startPos, startLoc); + node$1.operator = this.value; + node$1.prefix = false; + node$1.argument = expr; + this.checkLValSimple(expr); + this.next(); + expr = this.finishNode(node$1, "UpdateExpression"); + } + } + + if (!incDec && this.eat(types$1.starstar)) { + if (sawUnary) + { this.unexpected(this.lastTokStart); } + else + { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false, false, forInit), "**", false) } + } else { + return expr + } + }; + + function isLocalVariableAccess(node) { + return ( + node.type === "Identifier" || + node.type === "ParenthesizedExpression" && isLocalVariableAccess(node.expression) + ) + } + + function isPrivateFieldAccess(node) { + return ( + node.type === "MemberExpression" && node.property.type === "PrivateIdentifier" || + node.type === "ChainExpression" && isPrivateFieldAccess(node.expression) || + node.type === "ParenthesizedExpression" && isPrivateFieldAccess(node.expression) + ) + } + + // Parse call, dot, and `[]`-subscript expressions. + + pp$5.parseExprSubscripts = function(refDestructuringErrors, forInit) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprAtom(refDestructuringErrors, forInit); + if (expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")") + { return expr } + var result = this.parseSubscripts(expr, startPos, startLoc, false, forInit); + if (refDestructuringErrors && result.type === "MemberExpression") { + if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; } + if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; } + if (refDestructuringErrors.trailingComma >= result.start) { refDestructuringErrors.trailingComma = -1; } + } + return result + }; + + pp$5.parseSubscripts = function(base, startPos, startLoc, noCalls, forInit) { + var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && + this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 && + this.potentialArrowAt === base.start; + var optionalChained = false; + + while (true) { + var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit); + + if (element.optional) { optionalChained = true; } + if (element === base || element.type === "ArrowFunctionExpression") { + if (optionalChained) { + var chainNode = this.startNodeAt(startPos, startLoc); + chainNode.expression = element; + element = this.finishNode(chainNode, "ChainExpression"); + } + return element + } + + base = element; + } + }; + + pp$5.shouldParseAsyncArrow = function() { + return !this.canInsertSemicolon() && this.eat(types$1.arrow) + }; + + pp$5.parseSubscriptAsyncArrow = function(startPos, startLoc, exprList, forInit) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true, forInit) + }; + + pp$5.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit) { + var optionalSupported = this.options.ecmaVersion >= 11; + var optional = optionalSupported && this.eat(types$1.questionDot); + if (noCalls && optional) { this.raise(this.lastTokStart, "Optional chaining cannot appear in the callee of new expressions"); } + + var computed = this.eat(types$1.bracketL); + if (computed || (optional && this.type !== types$1.parenL && this.type !== types$1.backQuote) || this.eat(types$1.dot)) { + var node = this.startNodeAt(startPos, startLoc); + node.object = base; + if (computed) { + node.property = this.parseExpression(); + this.expect(types$1.bracketR); + } else if (this.type === types$1.privateId && base.type !== "Super") { + node.property = this.parsePrivateIdent(); + } else { + node.property = this.parseIdent(this.options.allowReserved !== "never"); + } + node.computed = !!computed; + if (optionalSupported) { + node.optional = optional; + } + base = this.finishNode(node, "MemberExpression"); + } else if (!noCalls && this.eat(types$1.parenL)) { + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + var exprList = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors); + if (maybeAsyncArrow && !optional && this.shouldParseAsyncArrow()) { + this.checkPatternErrors(refDestructuringErrors, false); + this.checkYieldAwaitInDefaultParams(); + if (this.awaitIdentPos > 0) + { this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); } + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.parseSubscriptAsyncArrow(startPos, startLoc, exprList, forInit) + } + this.checkExpressionErrors(refDestructuringErrors, true); + this.yieldPos = oldYieldPos || this.yieldPos; + this.awaitPos = oldAwaitPos || this.awaitPos; + this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos; + var node$1 = this.startNodeAt(startPos, startLoc); + node$1.callee = base; + node$1.arguments = exprList; + if (optionalSupported) { + node$1.optional = optional; + } + base = this.finishNode(node$1, "CallExpression"); + } else if (this.type === types$1.backQuote) { + if (optional || optionalChained) { + this.raise(this.start, "Optional chaining cannot appear in the tag of tagged template expressions"); + } + var node$2 = this.startNodeAt(startPos, startLoc); + node$2.tag = base; + node$2.quasi = this.parseTemplate({isTagged: true}); + base = this.finishNode(node$2, "TaggedTemplateExpression"); + } + return base + }; + + // Parse an atomic expression — either a single token that is an + // expression, an expression started by a keyword like `function` or + // `new`, or an expression wrapped in punctuation like `()`, `[]`, + // or `{}`. + + pp$5.parseExprAtom = function(refDestructuringErrors, forInit, forNew) { + // If a division operator appears in an expression position, the + // tokenizer got confused, and we force it to read a regexp instead. + if (this.type === types$1.slash) { this.readRegexp(); } + + var node, canBeArrow = this.potentialArrowAt === this.start; + switch (this.type) { + case types$1._super: + if (!this.allowSuper) + { this.raise(this.start, "'super' keyword outside a method"); } + node = this.startNode(); + this.next(); + if (this.type === types$1.parenL && !this.allowDirectSuper) + { this.raise(node.start, "super() call outside constructor of a subclass"); } + // The `super` keyword can appear at below: + // SuperProperty: + // super [ Expression ] + // super . IdentifierName + // SuperCall: + // super ( Arguments ) + if (this.type !== types$1.dot && this.type !== types$1.bracketL && this.type !== types$1.parenL) + { this.unexpected(); } + return this.finishNode(node, "Super") + + case types$1._this: + node = this.startNode(); + this.next(); + return this.finishNode(node, "ThisExpression") + + case types$1.name: + var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc; + var id = this.parseIdent(false); + if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types$1._function)) { + this.overrideContext(types.f_expr); + return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true, forInit) + } + if (canBeArrow && !this.canInsertSemicolon()) { + if (this.eat(types$1.arrow)) + { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false, forInit) } + if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types$1.name && !containsEsc && + (!this.potentialArrowInForAwait || this.value !== "of" || this.containsEsc)) { + id = this.parseIdent(false); + if (this.canInsertSemicolon() || !this.eat(types$1.arrow)) + { this.unexpected(); } + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true, forInit) + } + } + return id + + case types$1.regexp: + var value = this.value; + node = this.parseLiteral(value.value); + node.regex = {pattern: value.pattern, flags: value.flags}; + return node + + case types$1.num: case types$1.string: + return this.parseLiteral(this.value) + + case types$1._null: case types$1._true: case types$1._false: + node = this.startNode(); + node.value = this.type === types$1._null ? null : this.type === types$1._true; + node.raw = this.type.keyword; + this.next(); + return this.finishNode(node, "Literal") + + case types$1.parenL: + var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow, forInit); + if (refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) + { refDestructuringErrors.parenthesizedAssign = start; } + if (refDestructuringErrors.parenthesizedBind < 0) + { refDestructuringErrors.parenthesizedBind = start; } + } + return expr + + case types$1.bracketL: + node = this.startNode(); + this.next(); + node.elements = this.parseExprList(types$1.bracketR, true, true, refDestructuringErrors); + return this.finishNode(node, "ArrayExpression") + + case types$1.braceL: + this.overrideContext(types.b_expr); + return this.parseObj(false, refDestructuringErrors) + + case types$1._function: + node = this.startNode(); + this.next(); + return this.parseFunction(node, 0) + + case types$1._class: + return this.parseClass(this.startNode(), false) + + case types$1._new: + return this.parseNew() + + case types$1.backQuote: + return this.parseTemplate() + + case types$1._import: + if (this.options.ecmaVersion >= 11) { + return this.parseExprImport(forNew) + } else { + return this.unexpected() + } + + default: + return this.parseExprAtomDefault() + } + }; + + pp$5.parseExprAtomDefault = function() { + this.unexpected(); + }; + + pp$5.parseExprImport = function(forNew) { + var node = this.startNode(); + + // Consume `import` as an identifier for `import.meta`. + // Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`. + if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword import"); } + this.next(); + + if (this.type === types$1.parenL && !forNew) { + return this.parseDynamicImport(node) + } else if (this.type === types$1.dot) { + var meta = this.startNodeAt(node.start, node.loc && node.loc.start); + meta.name = "import"; + node.meta = this.finishNode(meta, "Identifier"); + return this.parseImportMeta(node) + } else { + this.unexpected(); + } + }; + + pp$5.parseDynamicImport = function(node) { + this.next(); // skip `(` + + // Parse node.source. + node.source = this.parseMaybeAssign(); + + if (this.options.ecmaVersion >= 16) { + if (!this.eat(types$1.parenR)) { + this.expect(types$1.comma); + if (!this.afterTrailingComma(types$1.parenR)) { + node.options = this.parseMaybeAssign(); + if (!this.eat(types$1.parenR)) { + this.expect(types$1.comma); + if (!this.afterTrailingComma(types$1.parenR)) { + this.unexpected(); + } + } + } else { + node.options = null; + } + } else { + node.options = null; + } + } else { + // Verify ending. + if (!this.eat(types$1.parenR)) { + var errorPos = this.start; + if (this.eat(types$1.comma) && this.eat(types$1.parenR)) { + this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()"); + } else { + this.unexpected(errorPos); + } + } + } + + return this.finishNode(node, "ImportExpression") + }; + + pp$5.parseImportMeta = function(node) { + this.next(); // skip `.` + + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); + + if (node.property.name !== "meta") + { this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); } + if (containsEsc) + { this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); } + if (this.options.sourceType !== "module" && !this.options.allowImportExportEverywhere) + { this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); } + + return this.finishNode(node, "MetaProperty") + }; + + pp$5.parseLiteral = function(value) { + var node = this.startNode(); + node.value = value; + node.raw = this.input.slice(this.start, this.end); + if (node.raw.charCodeAt(node.raw.length - 1) === 110) + { node.bigint = node.value != null ? node.value.toString() : node.raw.slice(0, -1).replace(/_/g, ""); } + this.next(); + return this.finishNode(node, "Literal") + }; + + pp$5.parseParenExpression = function() { + this.expect(types$1.parenL); + var val = this.parseExpression(); + this.expect(types$1.parenR); + return val + }; + + pp$5.shouldParseArrow = function(exprList) { + return !this.canInsertSemicolon() + }; + + pp$5.parseParenAndDistinguishExpression = function(canBeArrow, forInit) { + var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8; + if (this.options.ecmaVersion >= 6) { + this.next(); + + var innerStartPos = this.start, innerStartLoc = this.startLoc; + var exprList = [], first = true, lastIsComma = false; + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart; + this.yieldPos = 0; + this.awaitPos = 0; + // Do not save awaitIdentPos to allow checking awaits nested in parameters + while (this.type !== types$1.parenR) { + first ? first = false : this.expect(types$1.comma); + if (allowTrailingComma && this.afterTrailingComma(types$1.parenR, true)) { + lastIsComma = true; + break + } else if (this.type === types$1.ellipsis) { + spreadStart = this.start; + exprList.push(this.parseParenItem(this.parseRestBinding())); + if (this.type === types$1.comma) { + this.raiseRecoverable( + this.start, + "Comma is not permitted after the rest element" + ); + } + break + } else { + exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem)); + } + } + var innerEndPos = this.lastTokEnd, innerEndLoc = this.lastTokEndLoc; + this.expect(types$1.parenR); + + if (canBeArrow && this.shouldParseArrow(exprList) && this.eat(types$1.arrow)) { + this.checkPatternErrors(refDestructuringErrors, false); + this.checkYieldAwaitInDefaultParams(); + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + return this.parseParenArrowList(startPos, startLoc, exprList, forInit) + } + + if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); } + if (spreadStart) { this.unexpected(spreadStart); } + this.checkExpressionErrors(refDestructuringErrors, true); + this.yieldPos = oldYieldPos || this.yieldPos; + this.awaitPos = oldAwaitPos || this.awaitPos; + + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc); + val.expressions = exprList; + this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); + } else { + val = exprList[0]; + } + } else { + val = this.parseParenExpression(); + } + + if (this.options.preserveParens) { + var par = this.startNodeAt(startPos, startLoc); + par.expression = val; + return this.finishNode(par, "ParenthesizedExpression") + } else { + return val + } + }; + + pp$5.parseParenItem = function(item) { + return item + }; + + pp$5.parseParenArrowList = function(startPos, startLoc, exprList, forInit) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, false, forInit) + }; + + // New's precedence is slightly tricky. It must allow its argument to + // be a `[]` or dot subscript expression, but not a call — at least, + // not without wrapping it in parentheses. Thus, it uses the noCalls + // argument to parseSubscripts to prevent it from consuming the + // argument list. + + var empty = []; + + pp$5.parseNew = function() { + if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword new"); } + var node = this.startNode(); + this.next(); + if (this.options.ecmaVersion >= 6 && this.type === types$1.dot) { + var meta = this.startNodeAt(node.start, node.loc && node.loc.start); + meta.name = "new"; + node.meta = this.finishNode(meta, "Identifier"); + this.next(); + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); + if (node.property.name !== "target") + { this.raiseRecoverable(node.property.start, "The only valid meta property for new is 'new.target'"); } + if (containsEsc) + { this.raiseRecoverable(node.start, "'new.target' must not contain escaped characters"); } + if (!this.allowNewDotTarget) + { this.raiseRecoverable(node.start, "'new.target' can only be used in functions and class static block"); } + return this.finishNode(node, "MetaProperty") + } + var startPos = this.start, startLoc = this.startLoc; + node.callee = this.parseSubscripts(this.parseExprAtom(null, false, true), startPos, startLoc, true, false); + if (this.eat(types$1.parenL)) { node.arguments = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false); } + else { node.arguments = empty; } + return this.finishNode(node, "NewExpression") + }; + + // Parse template expression. + + pp$5.parseTemplateElement = function(ref) { + var isTagged = ref.isTagged; + + var elem = this.startNode(); + if (this.type === types$1.invalidTemplate) { + if (!isTagged) { + this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal"); + } + elem.value = { + raw: this.value.replace(/\r\n?/g, "\n"), + cooked: null + }; + } else { + elem.value = { + raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"), + cooked: this.value + }; + } + this.next(); + elem.tail = this.type === types$1.backQuote; + return this.finishNode(elem, "TemplateElement") + }; + + pp$5.parseTemplate = function(ref) { + if ( ref === void 0 ) ref = {}; + var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false; + + var node = this.startNode(); + this.next(); + node.expressions = []; + var curElt = this.parseTemplateElement({isTagged: isTagged}); + node.quasis = [curElt]; + while (!curElt.tail) { + if (this.type === types$1.eof) { this.raise(this.pos, "Unterminated template literal"); } + this.expect(types$1.dollarBraceL); + node.expressions.push(this.parseExpression()); + this.expect(types$1.braceR); + node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged})); + } + this.next(); + return this.finishNode(node, "TemplateLiteral") + }; + + pp$5.isAsyncProp = function(prop) { + return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && + (this.type === types$1.name || this.type === types$1.num || this.type === types$1.string || this.type === types$1.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types$1.star)) && + !lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + }; + + // Parse an object literal or binding pattern. + + pp$5.parseObj = function(isPattern, refDestructuringErrors) { + var node = this.startNode(), first = true, propHash = {}; + node.properties = []; + this.next(); + while (!this.eat(types$1.braceR)) { + if (!first) { + this.expect(types$1.comma); + if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types$1.braceR)) { break } + } else { first = false; } + + var prop = this.parseProperty(isPattern, refDestructuringErrors); + if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); } + node.properties.push(prop); + } + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") + }; + + pp$5.parseProperty = function(isPattern, refDestructuringErrors) { + var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc; + if (this.options.ecmaVersion >= 9 && this.eat(types$1.ellipsis)) { + if (isPattern) { + prop.argument = this.parseIdent(false); + if (this.type === types$1.comma) { + this.raiseRecoverable(this.start, "Comma is not permitted after the rest element"); + } + return this.finishNode(prop, "RestElement") + } + // Parse argument. + prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); + // To disallow trailing comma via `this.toAssignable()`. + if (this.type === types$1.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { + refDestructuringErrors.trailingComma = this.start; + } + // Finish + return this.finishNode(prop, "SpreadElement") + } + if (this.options.ecmaVersion >= 6) { + prop.method = false; + prop.shorthand = false; + if (isPattern || refDestructuringErrors) { + startPos = this.start; + startLoc = this.startLoc; + } + if (!isPattern) + { isGenerator = this.eat(types$1.star); } + } + var containsEsc = this.containsEsc; + this.parsePropertyName(prop); + if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) { + isAsync = true; + isGenerator = this.options.ecmaVersion >= 9 && this.eat(types$1.star); + this.parsePropertyName(prop); + } else { + isAsync = false; + } + this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc); + return this.finishNode(prop, "Property") + }; + + pp$5.parseGetterSetter = function(prop) { + var kind = prop.key.name; + this.parsePropertyName(prop); + prop.value = this.parseMethod(false); + prop.kind = kind; + var paramCount = prop.kind === "get" ? 0 : 1; + if (prop.value.params.length !== paramCount) { + var start = prop.value.start; + if (prop.kind === "get") + { this.raiseRecoverable(start, "getter should have no params"); } + else + { this.raiseRecoverable(start, "setter should have exactly one param"); } + } else { + if (prop.kind === "set" && prop.value.params[0].type === "RestElement") + { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); } + } + }; + + pp$5.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) { + if ((isGenerator || isAsync) && this.type === types$1.colon) + { this.unexpected(); } + + if (this.eat(types$1.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors); + prop.kind = "init"; + } else if (this.options.ecmaVersion >= 6 && this.type === types$1.parenL) { + if (isPattern) { this.unexpected(); } + prop.method = true; + prop.value = this.parseMethod(isGenerator, isAsync); + prop.kind = "init"; + } else if (!isPattern && !containsEsc && + this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && + (prop.key.name === "get" || prop.key.name === "set") && + (this.type !== types$1.comma && this.type !== types$1.braceR && this.type !== types$1.eq)) { + if (isGenerator || isAsync) { this.unexpected(); } + this.parseGetterSetter(prop); + } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { + if (isGenerator || isAsync) { this.unexpected(); } + this.checkUnreserved(prop.key); + if (prop.key.name === "await" && !this.awaitIdentPos) + { this.awaitIdentPos = startPos; } + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key)); + } else if (this.type === types$1.eq && refDestructuringErrors) { + if (refDestructuringErrors.shorthandAssign < 0) + { refDestructuringErrors.shorthandAssign = this.start; } + prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key)); + } else { + prop.value = this.copyNode(prop.key); + } + prop.kind = "init"; + prop.shorthand = true; + } else { this.unexpected(); } + }; + + pp$5.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(types$1.bracketL)) { + prop.computed = true; + prop.key = this.parseMaybeAssign(); + this.expect(types$1.bracketR); + return prop.key + } else { + prop.computed = false; + } + } + return prop.key = this.type === types$1.num || this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never") + }; + + // Initialize empty function node. + + pp$5.initFunction = function(node) { + node.id = null; + if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; } + if (this.options.ecmaVersion >= 8) { node.async = false; } + }; + + // Parse object or class method. + + pp$5.parseMethod = function(isGenerator, isAsync, allowDirectSuper) { + var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + + this.initFunction(node); + if (this.options.ecmaVersion >= 6) + { node.generator = isGenerator; } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0)); + + this.expect(types$1.parenL); + node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); + this.parseFunctionBody(node, false, true, false); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, "FunctionExpression") + }; + + // Parse arrow function expression with given parameters. + + pp$5.parseArrowExpression = function(node, params, isAsync, forInit) { + var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + + this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW); + this.initFunction(node); + if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; } + + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + + node.params = this.toAssignableList(params, true); + this.parseFunctionBody(node, true, false, forInit); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, "ArrowFunctionExpression") + }; + + // Parse function body and check parameters. + + pp$5.parseFunctionBody = function(node, isArrowFunction, isMethod, forInit) { + var isExpression = isArrowFunction && this.type !== types$1.braceL; + var oldStrict = this.strict, useStrict = false; + + if (isExpression) { + node.body = this.parseMaybeAssign(forInit); + node.expression = true; + this.checkParams(node, false); + } else { + var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params); + if (!oldStrict || nonSimple) { + useStrict = this.strictDirective(this.end); + // If this is a strict mode function, verify that argument names + // are not repeated, and it does not try to bind the words `eval` + // or `arguments`. + if (useStrict && nonSimple) + { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); } + } + // Start a new scope with regard to labels and the `inFunction` + // flag (restore them to their old value afterwards). + var oldLabels = this.labels; + this.labels = []; + if (useStrict) { this.strict = true; } + + // Add the params to varDeclaredNames to ensure that an error is thrown + // if a let/const declaration in the function clashes with one of the params. + this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params)); + // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' + if (this.strict && node.id) { this.checkLValSimple(node.id, BIND_OUTSIDE); } + node.body = this.parseBlock(false, undefined, useStrict && !oldStrict); + node.expression = false; + this.adaptDirectivePrologue(node.body.body); + this.labels = oldLabels; + } + this.exitScope(); + }; + + pp$5.isSimpleParamList = function(params) { + for (var i = 0, list = params; i < list.length; i += 1) + { + var param = list[i]; + + if (param.type !== "Identifier") { return false + } } + return true + }; + + // Checks function params for various disallowed patterns such as using "eval" + // or "arguments" and duplicate parameters. + + pp$5.checkParams = function(node, allowDuplicates) { + var nameHash = Object.create(null); + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; + + this.checkLValInnerPattern(param, BIND_VAR, allowDuplicates ? null : nameHash); + } + }; + + // Parses a comma-separated list of expressions, and returns them as + // an array. `close` is the token type that ends the list, and + // `allowEmpty` can be turned on to allow subsequent commas with + // nothing in between them to be parsed as `null` (which is needed + // for array literals). + + pp$5.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { + var elts = [], first = true; + while (!this.eat(close)) { + if (!first) { + this.expect(types$1.comma); + if (allowTrailingComma && this.afterTrailingComma(close)) { break } + } else { first = false; } + + var elt = (void 0); + if (allowEmpty && this.type === types$1.comma) + { elt = null; } + else if (this.type === types$1.ellipsis) { + elt = this.parseSpread(refDestructuringErrors); + if (refDestructuringErrors && this.type === types$1.comma && refDestructuringErrors.trailingComma < 0) + { refDestructuringErrors.trailingComma = this.start; } + } else { + elt = this.parseMaybeAssign(false, refDestructuringErrors); + } + elts.push(elt); + } + return elts + }; + + pp$5.checkUnreserved = function(ref) { + var start = ref.start; + var end = ref.end; + var name = ref.name; + + if (this.inGenerator && name === "yield") + { this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); } + if (this.inAsync && name === "await") + { this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); } + if (!(this.currentThisScope().flags & SCOPE_VAR) && name === "arguments") + { this.raiseRecoverable(start, "Cannot use 'arguments' in class field initializer"); } + if (this.inClassStaticBlock && (name === "arguments" || name === "await")) + { this.raise(start, ("Cannot use " + name + " in class static initialization block")); } + if (this.keywords.test(name)) + { this.raise(start, ("Unexpected keyword '" + name + "'")); } + if (this.options.ecmaVersion < 6 && + this.input.slice(start, end).indexOf("\\") !== -1) { return } + var re = this.strict ? this.reservedWordsStrict : this.reservedWords; + if (re.test(name)) { + if (!this.inAsync && name === "await") + { this.raiseRecoverable(start, "Cannot use keyword 'await' outside an async function"); } + this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved")); + } + }; + + // Parse the next token as an identifier. If `liberal` is true (used + // when parsing properties), it will also convert keywords into + // identifiers. + + pp$5.parseIdent = function(liberal) { + var node = this.parseIdentNode(); + this.next(!!liberal); + this.finishNode(node, "Identifier"); + if (!liberal) { + this.checkUnreserved(node); + if (node.name === "await" && !this.awaitIdentPos) + { this.awaitIdentPos = node.start; } + } + return node + }; + + pp$5.parseIdentNode = function() { + var node = this.startNode(); + if (this.type === types$1.name) { + node.name = this.value; + } else if (this.type.keyword) { + node.name = this.type.keyword; + + // To fix https://github.com/acornjs/acorn/issues/575 + // `class` and `function` keywords push new context into this.context. + // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name. + // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword + if ((node.name === "class" || node.name === "function") && + (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { + this.context.pop(); + } + this.type = types$1.name; + } else { + this.unexpected(); + } + return node + }; + + pp$5.parsePrivateIdent = function() { + var node = this.startNode(); + if (this.type === types$1.privateId) { + node.name = this.value; + } else { + this.unexpected(); + } + this.next(); + this.finishNode(node, "PrivateIdentifier"); + + // For validating existence + if (this.options.checkPrivateFields) { + if (this.privateNameStack.length === 0) { + this.raise(node.start, ("Private field '#" + (node.name) + "' must be declared in an enclosing class")); + } else { + this.privateNameStack[this.privateNameStack.length - 1].used.push(node); + } + } + + return node + }; + + // Parses yield expression inside generator. + + pp$5.parseYield = function(forInit) { + if (!this.yieldPos) { this.yieldPos = this.start; } + + var node = this.startNode(); + this.next(); + if (this.type === types$1.semi || this.canInsertSemicolon() || (this.type !== types$1.star && !this.type.startsExpr)) { + node.delegate = false; + node.argument = null; + } else { + node.delegate = this.eat(types$1.star); + node.argument = this.parseMaybeAssign(forInit); + } + return this.finishNode(node, "YieldExpression") + }; + + pp$5.parseAwait = function(forInit) { + if (!this.awaitPos) { this.awaitPos = this.start; } + + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeUnary(null, true, false, forInit); + return this.finishNode(node, "AwaitExpression") + }; + + var pp$4 = Parser.prototype; + + // This function is used to raise exceptions on parse errors. It + // takes an offset integer (into the current `input`) to indicate + // the location of the error, attaches the position to the end + // of the error message, and then raises a `SyntaxError` with that + // message. + + pp$4.raise = function(pos, message) { + var loc = getLineInfo(this.input, pos); + message += " (" + loc.line + ":" + loc.column + ")"; + if (this.sourceFile) { + message += " in " + this.sourceFile; + } + var err = new SyntaxError(message); + err.pos = pos; err.loc = loc; err.raisedAt = this.pos; + throw err + }; + + pp$4.raiseRecoverable = pp$4.raise; + + pp$4.curPosition = function() { + if (this.options.locations) { + return new Position(this.curLine, this.pos - this.lineStart) + } + }; + + var pp$3 = Parser.prototype; + + var Scope = function Scope(flags) { + this.flags = flags; + // A list of var-declared names in the current lexical scope + this.var = []; + // A list of lexically-declared names in the current lexical scope + this.lexical = []; + // A list of lexically-declared FunctionDeclaration names in the current lexical scope + this.functions = []; + }; + + // The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names. + + pp$3.enterScope = function(flags) { + this.scopeStack.push(new Scope(flags)); + }; + + pp$3.exitScope = function() { + this.scopeStack.pop(); + }; + + // The spec says: + // > At the top level of a function, or script, function declarations are + // > treated like var declarations rather than like lexical declarations. + pp$3.treatFunctionsAsVarInScope = function(scope) { + return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP) + }; + + pp$3.declareName = function(name, bindingType, pos) { + var redeclared = false; + if (bindingType === BIND_LEXICAL) { + var scope = this.currentScope(); + redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1; + scope.lexical.push(name); + if (this.inModule && (scope.flags & SCOPE_TOP)) + { delete this.undefinedExports[name]; } + } else if (bindingType === BIND_SIMPLE_CATCH) { + var scope$1 = this.currentScope(); + scope$1.lexical.push(name); + } else if (bindingType === BIND_FUNCTION) { + var scope$2 = this.currentScope(); + if (this.treatFunctionsAsVar) + { redeclared = scope$2.lexical.indexOf(name) > -1; } + else + { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; } + scope$2.functions.push(name); + } else { + for (var i = this.scopeStack.length - 1; i >= 0; --i) { + var scope$3 = this.scopeStack[i]; + if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) || + !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) { + redeclared = true; + break + } + scope$3.var.push(name); + if (this.inModule && (scope$3.flags & SCOPE_TOP)) + { delete this.undefinedExports[name]; } + if (scope$3.flags & SCOPE_VAR) { break } + } + } + if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); } + }; + + pp$3.checkLocalExport = function(id) { + // scope.functions must be empty as Module code is always strict. + if (this.scopeStack[0].lexical.indexOf(id.name) === -1 && + this.scopeStack[0].var.indexOf(id.name) === -1) { + this.undefinedExports[id.name] = id; + } + }; + + pp$3.currentScope = function() { + return this.scopeStack[this.scopeStack.length - 1] + }; + + pp$3.currentVarScope = function() { + for (var i = this.scopeStack.length - 1;; i--) { + var scope = this.scopeStack[i]; + if (scope.flags & (SCOPE_VAR | SCOPE_CLASS_FIELD_INIT | SCOPE_CLASS_STATIC_BLOCK)) { return scope } + } + }; + + // Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`. + pp$3.currentThisScope = function() { + for (var i = this.scopeStack.length - 1;; i--) { + var scope = this.scopeStack[i]; + if (scope.flags & (SCOPE_VAR | SCOPE_CLASS_FIELD_INIT | SCOPE_CLASS_STATIC_BLOCK) && + !(scope.flags & SCOPE_ARROW)) { return scope } + } + }; + + var Node = function Node(parser, pos, loc) { + this.type = ""; + this.start = pos; + this.end = 0; + if (parser.options.locations) + { this.loc = new SourceLocation(parser, loc); } + if (parser.options.directSourceFile) + { this.sourceFile = parser.options.directSourceFile; } + if (parser.options.ranges) + { this.range = [pos, 0]; } + }; + + // Start an AST node, attaching a start offset. + + var pp$2 = Parser.prototype; + + pp$2.startNode = function() { + return new Node(this, this.start, this.startLoc) + }; + + pp$2.startNodeAt = function(pos, loc) { + return new Node(this, pos, loc) + }; + + // Finish an AST node, adding `type` and `end` properties. + + function finishNodeAt(node, type, pos, loc) { + node.type = type; + node.end = pos; + if (this.options.locations) + { node.loc.end = loc; } + if (this.options.ranges) + { node.range[1] = pos; } + return node + } + + pp$2.finishNode = function(node, type) { + return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) + }; + + // Finish node at given position + + pp$2.finishNodeAt = function(node, type, pos, loc) { + return finishNodeAt.call(this, node, type, pos, loc) + }; + + pp$2.copyNode = function(node) { + var newNode = new Node(this, node.start, this.startLoc); + for (var prop in node) { newNode[prop] = node[prop]; } + return newNode + }; + + // This file was generated by "bin/generate-unicode-script-values.js". Do not modify manually! + var scriptValuesAddedInUnicode = "Gara Garay Gukh Gurung_Khema Hrkt Katakana_Or_Hiragana Kawi Kirat_Rai Krai Nag_Mundari Nagm Ol_Onal Onao Sunu Sunuwar Todhri Todr Tulu_Tigalari Tutg Unknown Zzzz"; + + // This file contains Unicode properties extracted from the ECMAScript specification. + // The lists are extracted like so: + // $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText) + + // #table-binary-unicode-properties + var ecma9BinaryProperties = "ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS"; + var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic"; + var ecma11BinaryProperties = ecma10BinaryProperties; + var ecma12BinaryProperties = ecma11BinaryProperties + " EBase EComp EMod EPres ExtPict"; + var ecma13BinaryProperties = ecma12BinaryProperties; + var ecma14BinaryProperties = ecma13BinaryProperties; + + var unicodeBinaryProperties = { + 9: ecma9BinaryProperties, + 10: ecma10BinaryProperties, + 11: ecma11BinaryProperties, + 12: ecma12BinaryProperties, + 13: ecma13BinaryProperties, + 14: ecma14BinaryProperties + }; + + // #table-binary-unicode-properties-of-strings + var ecma14BinaryPropertiesOfStrings = "Basic_Emoji Emoji_Keycap_Sequence RGI_Emoji_Modifier_Sequence RGI_Emoji_Flag_Sequence RGI_Emoji_Tag_Sequence RGI_Emoji_ZWJ_Sequence RGI_Emoji"; + + var unicodeBinaryPropertiesOfStrings = { + 9: "", + 10: "", + 11: "", + 12: "", + 13: "", + 14: ecma14BinaryPropertiesOfStrings + }; + + // #table-unicode-general-category-values + var unicodeGeneralCategoryValues = "Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu"; + + // #table-unicode-script-values + var ecma9ScriptValues = "Adlam Adlm Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb"; + var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd"; + var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho"; + var ecma12ScriptValues = ecma11ScriptValues + " Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi"; + var ecma13ScriptValues = ecma12ScriptValues + " Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith"; + var ecma14ScriptValues = ecma13ScriptValues + " " + scriptValuesAddedInUnicode; + + var unicodeScriptValues = { + 9: ecma9ScriptValues, + 10: ecma10ScriptValues, + 11: ecma11ScriptValues, + 12: ecma12ScriptValues, + 13: ecma13ScriptValues, + 14: ecma14ScriptValues + }; + + var data = {}; + function buildUnicodeData(ecmaVersion) { + var d = data[ecmaVersion] = { + binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues), + binaryOfStrings: wordsRegexp(unicodeBinaryPropertiesOfStrings[ecmaVersion]), + nonBinary: { + General_Category: wordsRegexp(unicodeGeneralCategoryValues), + Script: wordsRegexp(unicodeScriptValues[ecmaVersion]) + } + }; + d.nonBinary.Script_Extensions = d.nonBinary.Script; + + d.nonBinary.gc = d.nonBinary.General_Category; + d.nonBinary.sc = d.nonBinary.Script; + d.nonBinary.scx = d.nonBinary.Script_Extensions; + } + + for (var i = 0, list = [9, 10, 11, 12, 13, 14]; i < list.length; i += 1) { + var ecmaVersion = list[i]; + + buildUnicodeData(ecmaVersion); + } + + var pp$1 = Parser.prototype; + + // Track disjunction structure to determine whether a duplicate + // capture group name is allowed because it is in a separate branch. + var BranchID = function BranchID(parent, base) { + // Parent disjunction branch + this.parent = parent; + // Identifies this set of sibling branches + this.base = base || this; + }; + + BranchID.prototype.separatedFrom = function separatedFrom (alt) { + // A branch is separate from another branch if they or any of + // their parents are siblings in a given disjunction + for (var self = this; self; self = self.parent) { + for (var other = alt; other; other = other.parent) { + if (self.base === other.base && self !== other) { return true } + } + } + return false + }; + + BranchID.prototype.sibling = function sibling () { + return new BranchID(this.parent, this.base) + }; + + var RegExpValidationState = function RegExpValidationState(parser) { + this.parser = parser; + this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "") + (parser.options.ecmaVersion >= 13 ? "d" : "") + (parser.options.ecmaVersion >= 15 ? "v" : ""); + this.unicodeProperties = data[parser.options.ecmaVersion >= 14 ? 14 : parser.options.ecmaVersion]; + this.source = ""; + this.flags = ""; + this.start = 0; + this.switchU = false; + this.switchV = false; + this.switchN = false; + this.pos = 0; + this.lastIntValue = 0; + this.lastStringValue = ""; + this.lastAssertionIsQuantifiable = false; + this.numCapturingParens = 0; + this.maxBackReference = 0; + this.groupNames = Object.create(null); + this.backReferenceNames = []; + this.branchID = null; + }; + + RegExpValidationState.prototype.reset = function reset (start, pattern, flags) { + var unicodeSets = flags.indexOf("v") !== -1; + var unicode = flags.indexOf("u") !== -1; + this.start = start | 0; + this.source = pattern + ""; + this.flags = flags; + if (unicodeSets && this.parser.options.ecmaVersion >= 15) { + this.switchU = true; + this.switchV = true; + this.switchN = true; + } else { + this.switchU = unicode && this.parser.options.ecmaVersion >= 6; + this.switchV = false; + this.switchN = unicode && this.parser.options.ecmaVersion >= 9; + } + }; + + RegExpValidationState.prototype.raise = function raise (message) { + this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message)); + }; + + // If u flag is given, this returns the code point at the index (it combines a surrogate pair). + // Otherwise, this returns the code unit of the index (can be a part of a surrogate pair). + RegExpValidationState.prototype.at = function at (i, forceU) { + if ( forceU === void 0 ) forceU = false; + + var s = this.source; + var l = s.length; + if (i >= l) { + return -1 + } + var c = s.charCodeAt(i); + if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { + return c + } + var next = s.charCodeAt(i + 1); + return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c + }; + + RegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) { + if ( forceU === void 0 ) forceU = false; + + var s = this.source; + var l = s.length; + if (i >= l) { + return l + } + var c = s.charCodeAt(i), next; + if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l || + (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) { + return i + 1 + } + return i + 2 + }; + + RegExpValidationState.prototype.current = function current (forceU) { + if ( forceU === void 0 ) forceU = false; + + return this.at(this.pos, forceU) + }; + + RegExpValidationState.prototype.lookahead = function lookahead (forceU) { + if ( forceU === void 0 ) forceU = false; + + return this.at(this.nextIndex(this.pos, forceU), forceU) + }; + + RegExpValidationState.prototype.advance = function advance (forceU) { + if ( forceU === void 0 ) forceU = false; + + this.pos = this.nextIndex(this.pos, forceU); + }; + + RegExpValidationState.prototype.eat = function eat (ch, forceU) { + if ( forceU === void 0 ) forceU = false; + + if (this.current(forceU) === ch) { + this.advance(forceU); + return true + } + return false + }; + + RegExpValidationState.prototype.eatChars = function eatChars (chs, forceU) { + if ( forceU === void 0 ) forceU = false; + + var pos = this.pos; + for (var i = 0, list = chs; i < list.length; i += 1) { + var ch = list[i]; + + var current = this.at(pos, forceU); + if (current === -1 || current !== ch) { + return false + } + pos = this.nextIndex(pos, forceU); + } + this.pos = pos; + return true + }; + + /** + * Validate the flags part of a given RegExpLiteral. + * + * @param {RegExpValidationState} state The state to validate RegExp. + * @returns {void} + */ + pp$1.validateRegExpFlags = function(state) { + var validFlags = state.validFlags; + var flags = state.flags; + + var u = false; + var v = false; + + for (var i = 0; i < flags.length; i++) { + var flag = flags.charAt(i); + if (validFlags.indexOf(flag) === -1) { + this.raise(state.start, "Invalid regular expression flag"); + } + if (flags.indexOf(flag, i + 1) > -1) { + this.raise(state.start, "Duplicate regular expression flag"); + } + if (flag === "u") { u = true; } + if (flag === "v") { v = true; } + } + if (this.options.ecmaVersion >= 15 && u && v) { + this.raise(state.start, "Invalid regular expression flag"); + } + }; + + function hasProp(obj) { + for (var _ in obj) { return true } + return false + } + + /** + * Validate the pattern part of a given RegExpLiteral. + * + * @param {RegExpValidationState} state The state to validate RegExp. + * @returns {void} + */ + pp$1.validateRegExpPattern = function(state) { + this.regexp_pattern(state); + + // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of + // parsing contains a |GroupName|, reparse with the goal symbol + // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError* + // exception if _P_ did not conform to the grammar, if any elements of _P_ + // were not matched by the parse, or if any Early Error conditions exist. + if (!state.switchN && this.options.ecmaVersion >= 9 && hasProp(state.groupNames)) { + state.switchN = true; + this.regexp_pattern(state); + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern + pp$1.regexp_pattern = function(state) { + state.pos = 0; + state.lastIntValue = 0; + state.lastStringValue = ""; + state.lastAssertionIsQuantifiable = false; + state.numCapturingParens = 0; + state.maxBackReference = 0; + state.groupNames = Object.create(null); + state.backReferenceNames.length = 0; + state.branchID = null; + + this.regexp_disjunction(state); + + if (state.pos !== state.source.length) { + // Make the same messages as V8. + if (state.eat(0x29 /* ) */)) { + state.raise("Unmatched ')'"); + } + if (state.eat(0x5D /* ] */) || state.eat(0x7D /* } */)) { + state.raise("Lone quantifier brackets"); + } + } + if (state.maxBackReference > state.numCapturingParens) { + state.raise("Invalid escape"); + } + for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) { + var name = list[i]; + + if (!state.groupNames[name]) { + state.raise("Invalid named capture referenced"); + } + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction + pp$1.regexp_disjunction = function(state) { + var trackDisjunction = this.options.ecmaVersion >= 16; + if (trackDisjunction) { state.branchID = new BranchID(state.branchID, null); } + this.regexp_alternative(state); + while (state.eat(0x7C /* | */)) { + if (trackDisjunction) { state.branchID = state.branchID.sibling(); } + this.regexp_alternative(state); + } + if (trackDisjunction) { state.branchID = state.branchID.parent; } + + // Make the same message as V8. + if (this.regexp_eatQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + if (state.eat(0x7B /* { */)) { + state.raise("Lone quantifier brackets"); + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative + pp$1.regexp_alternative = function(state) { + while (state.pos < state.source.length && this.regexp_eatTerm(state)) {} + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term + pp$1.regexp_eatTerm = function(state) { + if (this.regexp_eatAssertion(state)) { + // Handle `QuantifiableAssertion Quantifier` alternative. + // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion + // is a QuantifiableAssertion. + if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) { + // Make the same message as V8. + if (state.switchU) { + state.raise("Invalid quantifier"); + } + } + return true + } + + if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) { + this.regexp_eatQuantifier(state); + return true + } + + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion + pp$1.regexp_eatAssertion = function(state) { + var start = state.pos; + state.lastAssertionIsQuantifiable = false; + + // ^, $ + if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) { + return true + } + + // \b \B + if (state.eat(0x5C /* \ */)) { + if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) { + return true + } + state.pos = start; + } + + // Lookahead / Lookbehind + if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) { + var lookbehind = false; + if (this.options.ecmaVersion >= 9) { + lookbehind = state.eat(0x3C /* < */); + } + if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) { + this.regexp_disjunction(state); + if (!state.eat(0x29 /* ) */)) { + state.raise("Unterminated group"); + } + state.lastAssertionIsQuantifiable = !lookbehind; + return true + } + } + + state.pos = start; + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier + pp$1.regexp_eatQuantifier = function(state, noError) { + if ( noError === void 0 ) noError = false; + + if (this.regexp_eatQuantifierPrefix(state, noError)) { + state.eat(0x3F /* ? */); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix + pp$1.regexp_eatQuantifierPrefix = function(state, noError) { + return ( + state.eat(0x2A /* * */) || + state.eat(0x2B /* + */) || + state.eat(0x3F /* ? */) || + this.regexp_eatBracedQuantifier(state, noError) + ) + }; + pp$1.regexp_eatBracedQuantifier = function(state, noError) { + var start = state.pos; + if (state.eat(0x7B /* { */)) { + var min = 0, max = -1; + if (this.regexp_eatDecimalDigits(state)) { + min = state.lastIntValue; + if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) { + max = state.lastIntValue; + } + if (state.eat(0x7D /* } */)) { + // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term + if (max !== -1 && max < min && !noError) { + state.raise("numbers out of order in {} quantifier"); + } + return true + } + } + if (state.switchU && !noError) { + state.raise("Incomplete quantifier"); + } + state.pos = start; + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Atom + pp$1.regexp_eatAtom = function(state) { + return ( + this.regexp_eatPatternCharacters(state) || + state.eat(0x2E /* . */) || + this.regexp_eatReverseSolidusAtomEscape(state) || + this.regexp_eatCharacterClass(state) || + this.regexp_eatUncapturingGroup(state) || + this.regexp_eatCapturingGroup(state) + ) + }; + pp$1.regexp_eatReverseSolidusAtomEscape = function(state) { + var start = state.pos; + if (state.eat(0x5C /* \ */)) { + if (this.regexp_eatAtomEscape(state)) { + return true + } + state.pos = start; + } + return false + }; + pp$1.regexp_eatUncapturingGroup = function(state) { + var start = state.pos; + if (state.eat(0x28 /* ( */)) { + if (state.eat(0x3F /* ? */)) { + if (this.options.ecmaVersion >= 16) { + var addModifiers = this.regexp_eatModifiers(state); + var hasHyphen = state.eat(0x2D /* - */); + if (addModifiers || hasHyphen) { + for (var i = 0; i < addModifiers.length; i++) { + var modifier = addModifiers.charAt(i); + if (addModifiers.indexOf(modifier, i + 1) > -1) { + state.raise("Duplicate regular expression modifiers"); + } + } + if (hasHyphen) { + var removeModifiers = this.regexp_eatModifiers(state); + if (!addModifiers && !removeModifiers && state.current() === 0x3A /* : */) { + state.raise("Invalid regular expression modifiers"); + } + for (var i$1 = 0; i$1 < removeModifiers.length; i$1++) { + var modifier$1 = removeModifiers.charAt(i$1); + if ( + removeModifiers.indexOf(modifier$1, i$1 + 1) > -1 || + addModifiers.indexOf(modifier$1) > -1 + ) { + state.raise("Duplicate regular expression modifiers"); + } + } + } + } + } + if (state.eat(0x3A /* : */)) { + this.regexp_disjunction(state); + if (state.eat(0x29 /* ) */)) { + return true + } + state.raise("Unterminated group"); + } + } + state.pos = start; + } + return false + }; + pp$1.regexp_eatCapturingGroup = function(state) { + if (state.eat(0x28 /* ( */)) { + if (this.options.ecmaVersion >= 9) { + this.regexp_groupSpecifier(state); + } else if (state.current() === 0x3F /* ? */) { + state.raise("Invalid group"); + } + this.regexp_disjunction(state); + if (state.eat(0x29 /* ) */)) { + state.numCapturingParens += 1; + return true + } + state.raise("Unterminated group"); + } + return false + }; + // RegularExpressionModifiers :: + // [empty] + // RegularExpressionModifiers RegularExpressionModifier + pp$1.regexp_eatModifiers = function(state) { + var modifiers = ""; + var ch = 0; + while ((ch = state.current()) !== -1 && isRegularExpressionModifier(ch)) { + modifiers += codePointToString(ch); + state.advance(); + } + return modifiers + }; + // RegularExpressionModifier :: one of + // `i` `m` `s` + function isRegularExpressionModifier(ch) { + return ch === 0x69 /* i */ || ch === 0x6d /* m */ || ch === 0x73 /* s */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom + pp$1.regexp_eatExtendedAtom = function(state) { + return ( + state.eat(0x2E /* . */) || + this.regexp_eatReverseSolidusAtomEscape(state) || + this.regexp_eatCharacterClass(state) || + this.regexp_eatUncapturingGroup(state) || + this.regexp_eatCapturingGroup(state) || + this.regexp_eatInvalidBracedQuantifier(state) || + this.regexp_eatExtendedPatternCharacter(state) + ) + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier + pp$1.regexp_eatInvalidBracedQuantifier = function(state) { + if (this.regexp_eatBracedQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter + pp$1.regexp_eatSyntaxCharacter = function(state) { + var ch = state.current(); + if (isSyntaxCharacter(ch)) { + state.lastIntValue = ch; + state.advance(); + return true + } + return false + }; + function isSyntaxCharacter(ch) { + return ( + ch === 0x24 /* $ */ || + ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ || + ch === 0x2E /* . */ || + ch === 0x3F /* ? */ || + ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ || + ch >= 0x7B /* { */ && ch <= 0x7D /* } */ + ) + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter + // But eat eager. + pp$1.regexp_eatPatternCharacters = function(state) { + var start = state.pos; + var ch = 0; + while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) { + state.advance(); + } + return state.pos !== start + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter + pp$1.regexp_eatExtendedPatternCharacter = function(state) { + var ch = state.current(); + if ( + ch !== -1 && + ch !== 0x24 /* $ */ && + !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) && + ch !== 0x2E /* . */ && + ch !== 0x3F /* ? */ && + ch !== 0x5B /* [ */ && + ch !== 0x5E /* ^ */ && + ch !== 0x7C /* | */ + ) { + state.advance(); + return true + } + return false + }; + + // GroupSpecifier :: + // [empty] + // `?` GroupName + pp$1.regexp_groupSpecifier = function(state) { + if (state.eat(0x3F /* ? */)) { + if (!this.regexp_eatGroupName(state)) { state.raise("Invalid group"); } + var trackDisjunction = this.options.ecmaVersion >= 16; + var known = state.groupNames[state.lastStringValue]; + if (known) { + if (trackDisjunction) { + for (var i = 0, list = known; i < list.length; i += 1) { + var altID = list[i]; + + if (!altID.separatedFrom(state.branchID)) + { state.raise("Duplicate capture group name"); } + } + } else { + state.raise("Duplicate capture group name"); + } + } + if (trackDisjunction) { + (known || (state.groupNames[state.lastStringValue] = [])).push(state.branchID); + } else { + state.groupNames[state.lastStringValue] = true; + } + } + }; + + // GroupName :: + // `<` RegExpIdentifierName `>` + // Note: this updates `state.lastStringValue` property with the eaten name. + pp$1.regexp_eatGroupName = function(state) { + state.lastStringValue = ""; + if (state.eat(0x3C /* < */)) { + if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) { + return true + } + state.raise("Invalid capture group name"); + } + return false + }; + + // RegExpIdentifierName :: + // RegExpIdentifierStart + // RegExpIdentifierName RegExpIdentifierPart + // Note: this updates `state.lastStringValue` property with the eaten name. + pp$1.regexp_eatRegExpIdentifierName = function(state) { + state.lastStringValue = ""; + if (this.regexp_eatRegExpIdentifierStart(state)) { + state.lastStringValue += codePointToString(state.lastIntValue); + while (this.regexp_eatRegExpIdentifierPart(state)) { + state.lastStringValue += codePointToString(state.lastIntValue); + } + return true + } + return false + }; + + // RegExpIdentifierStart :: + // UnicodeIDStart + // `$` + // `_` + // `\` RegExpUnicodeEscapeSequence[+U] + pp$1.regexp_eatRegExpIdentifierStart = function(state) { + var start = state.pos; + var forceU = this.options.ecmaVersion >= 11; + var ch = state.current(forceU); + state.advance(forceU); + + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) { + ch = state.lastIntValue; + } + if (isRegExpIdentifierStart(ch)) { + state.lastIntValue = ch; + return true + } + + state.pos = start; + return false + }; + function isRegExpIdentifierStart(ch) { + return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ + } + + // RegExpIdentifierPart :: + // UnicodeIDContinue + // `$` + // `_` + // `\` RegExpUnicodeEscapeSequence[+U] + // + // + pp$1.regexp_eatRegExpIdentifierPart = function(state) { + var start = state.pos; + var forceU = this.options.ecmaVersion >= 11; + var ch = state.current(forceU); + state.advance(forceU); + + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) { + ch = state.lastIntValue; + } + if (isRegExpIdentifierPart(ch)) { + state.lastIntValue = ch; + return true + } + + state.pos = start; + return false + }; + function isRegExpIdentifierPart(ch) { + return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* */ || ch === 0x200D /* */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape + pp$1.regexp_eatAtomEscape = function(state) { + if ( + this.regexp_eatBackReference(state) || + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) || + (state.switchN && this.regexp_eatKGroupName(state)) + ) { + return true + } + if (state.switchU) { + // Make the same message as V8. + if (state.current() === 0x63 /* c */) { + state.raise("Invalid unicode escape"); + } + state.raise("Invalid escape"); + } + return false + }; + pp$1.regexp_eatBackReference = function(state) { + var start = state.pos; + if (this.regexp_eatDecimalEscape(state)) { + var n = state.lastIntValue; + if (state.switchU) { + // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape + if (n > state.maxBackReference) { + state.maxBackReference = n; + } + return true + } + if (n <= state.numCapturingParens) { + return true + } + state.pos = start; + } + return false + }; + pp$1.regexp_eatKGroupName = function(state) { + if (state.eat(0x6B /* k */)) { + if (this.regexp_eatGroupName(state)) { + state.backReferenceNames.push(state.lastStringValue); + return true + } + state.raise("Invalid named reference"); + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape + pp$1.regexp_eatCharacterEscape = function(state) { + return ( + this.regexp_eatControlEscape(state) || + this.regexp_eatCControlLetter(state) || + this.regexp_eatZero(state) || + this.regexp_eatHexEscapeSequence(state) || + this.regexp_eatRegExpUnicodeEscapeSequence(state, false) || + (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) || + this.regexp_eatIdentityEscape(state) + ) + }; + pp$1.regexp_eatCControlLetter = function(state) { + var start = state.pos; + if (state.eat(0x63 /* c */)) { + if (this.regexp_eatControlLetter(state)) { + return true + } + state.pos = start; + } + return false + }; + pp$1.regexp_eatZero = function(state) { + if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) { + state.lastIntValue = 0; + state.advance(); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape + pp$1.regexp_eatControlEscape = function(state) { + var ch = state.current(); + if (ch === 0x74 /* t */) { + state.lastIntValue = 0x09; /* \t */ + state.advance(); + return true + } + if (ch === 0x6E /* n */) { + state.lastIntValue = 0x0A; /* \n */ + state.advance(); + return true + } + if (ch === 0x76 /* v */) { + state.lastIntValue = 0x0B; /* \v */ + state.advance(); + return true + } + if (ch === 0x66 /* f */) { + state.lastIntValue = 0x0C; /* \f */ + state.advance(); + return true + } + if (ch === 0x72 /* r */) { + state.lastIntValue = 0x0D; /* \r */ + state.advance(); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter + pp$1.regexp_eatControlLetter = function(state) { + var ch = state.current(); + if (isControlLetter(ch)) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false + }; + function isControlLetter(ch) { + return ( + (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) || + (ch >= 0x61 /* a */ && ch <= 0x7A /* z */) + ) + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence + pp$1.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) { + if ( forceU === void 0 ) forceU = false; + + var start = state.pos; + var switchU = forceU || state.switchU; + + if (state.eat(0x75 /* u */)) { + if (this.regexp_eatFixedHexDigits(state, 4)) { + var lead = state.lastIntValue; + if (switchU && lead >= 0xD800 && lead <= 0xDBFF) { + var leadSurrogateEnd = state.pos; + if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) { + var trail = state.lastIntValue; + if (trail >= 0xDC00 && trail <= 0xDFFF) { + state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000; + return true + } + } + state.pos = leadSurrogateEnd; + state.lastIntValue = lead; + } + return true + } + if ( + switchU && + state.eat(0x7B /* { */) && + this.regexp_eatHexDigits(state) && + state.eat(0x7D /* } */) && + isValidUnicode(state.lastIntValue) + ) { + return true + } + if (switchU) { + state.raise("Invalid unicode escape"); + } + state.pos = start; + } + + return false + }; + function isValidUnicode(ch) { + return ch >= 0 && ch <= 0x10FFFF + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape + pp$1.regexp_eatIdentityEscape = function(state) { + if (state.switchU) { + if (this.regexp_eatSyntaxCharacter(state)) { + return true + } + if (state.eat(0x2F /* / */)) { + state.lastIntValue = 0x2F; /* / */ + return true + } + return false + } + + var ch = state.current(); + if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) { + state.lastIntValue = ch; + state.advance(); + return true + } + + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape + pp$1.regexp_eatDecimalEscape = function(state) { + state.lastIntValue = 0; + var ch = state.current(); + if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) { + do { + state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); + state.advance(); + } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) + return true + } + return false + }; + + // Return values used by character set parsing methods, needed to + // forbid negation of sets that can match strings. + var CharSetNone = 0; // Nothing parsed + var CharSetOk = 1; // Construct parsed, cannot contain strings + var CharSetString = 2; // Construct parsed, can contain strings + + // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape + pp$1.regexp_eatCharacterClassEscape = function(state) { + var ch = state.current(); + + if (isCharacterClassEscape(ch)) { + state.lastIntValue = -1; + state.advance(); + return CharSetOk + } + + var negate = false; + if ( + state.switchU && + this.options.ecmaVersion >= 9 && + ((negate = ch === 0x50 /* P */) || ch === 0x70 /* p */) + ) { + state.lastIntValue = -1; + state.advance(); + var result; + if ( + state.eat(0x7B /* { */) && + (result = this.regexp_eatUnicodePropertyValueExpression(state)) && + state.eat(0x7D /* } */) + ) { + if (negate && result === CharSetString) { state.raise("Invalid property name"); } + return result + } + state.raise("Invalid property name"); + } + + return CharSetNone + }; + + function isCharacterClassEscape(ch) { + return ( + ch === 0x64 /* d */ || + ch === 0x44 /* D */ || + ch === 0x73 /* s */ || + ch === 0x53 /* S */ || + ch === 0x77 /* w */ || + ch === 0x57 /* W */ + ) + } + + // UnicodePropertyValueExpression :: + // UnicodePropertyName `=` UnicodePropertyValue + // LoneUnicodePropertyNameOrValue + pp$1.regexp_eatUnicodePropertyValueExpression = function(state) { + var start = state.pos; + + // UnicodePropertyName `=` UnicodePropertyValue + if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) { + var name = state.lastStringValue; + if (this.regexp_eatUnicodePropertyValue(state)) { + var value = state.lastStringValue; + this.regexp_validateUnicodePropertyNameAndValue(state, name, value); + return CharSetOk + } + } + state.pos = start; + + // LoneUnicodePropertyNameOrValue + if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) { + var nameOrValue = state.lastStringValue; + return this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue) + } + return CharSetNone + }; + + pp$1.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) { + if (!hasOwn(state.unicodeProperties.nonBinary, name)) + { state.raise("Invalid property name"); } + if (!state.unicodeProperties.nonBinary[name].test(value)) + { state.raise("Invalid property value"); } + }; + + pp$1.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) { + if (state.unicodeProperties.binary.test(nameOrValue)) { return CharSetOk } + if (state.switchV && state.unicodeProperties.binaryOfStrings.test(nameOrValue)) { return CharSetString } + state.raise("Invalid property name"); + }; + + // UnicodePropertyName :: + // UnicodePropertyNameCharacters + pp$1.regexp_eatUnicodePropertyName = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyNameCharacter(ch = state.current())) { + state.lastStringValue += codePointToString(ch); + state.advance(); + } + return state.lastStringValue !== "" + }; + + function isUnicodePropertyNameCharacter(ch) { + return isControlLetter(ch) || ch === 0x5F /* _ */ + } + + // UnicodePropertyValue :: + // UnicodePropertyValueCharacters + pp$1.regexp_eatUnicodePropertyValue = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyValueCharacter(ch = state.current())) { + state.lastStringValue += codePointToString(ch); + state.advance(); + } + return state.lastStringValue !== "" + }; + function isUnicodePropertyValueCharacter(ch) { + return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch) + } + + // LoneUnicodePropertyNameOrValue :: + // UnicodePropertyValueCharacters + pp$1.regexp_eatLoneUnicodePropertyNameOrValue = function(state) { + return this.regexp_eatUnicodePropertyValue(state) + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass + pp$1.regexp_eatCharacterClass = function(state) { + if (state.eat(0x5B /* [ */)) { + var negate = state.eat(0x5E /* ^ */); + var result = this.regexp_classContents(state); + if (!state.eat(0x5D /* ] */)) + { state.raise("Unterminated character class"); } + if (negate && result === CharSetString) + { state.raise("Negated character class may contain strings"); } + return true + } + return false + }; + + // https://tc39.es/ecma262/#prod-ClassContents + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges + pp$1.regexp_classContents = function(state) { + if (state.current() === 0x5D /* ] */) { return CharSetOk } + if (state.switchV) { return this.regexp_classSetExpression(state) } + this.regexp_nonEmptyClassRanges(state); + return CharSetOk + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges + // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash + pp$1.regexp_nonEmptyClassRanges = function(state) { + while (this.regexp_eatClassAtom(state)) { + var left = state.lastIntValue; + if (state.eat(0x2D /* - */) && this.regexp_eatClassAtom(state)) { + var right = state.lastIntValue; + if (state.switchU && (left === -1 || right === -1)) { + state.raise("Invalid character class"); + } + if (left !== -1 && right !== -1 && left > right) { + state.raise("Range out of order in character class"); + } + } + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash + pp$1.regexp_eatClassAtom = function(state) { + var start = state.pos; + + if (state.eat(0x5C /* \ */)) { + if (this.regexp_eatClassEscape(state)) { + return true + } + if (state.switchU) { + // Make the same message as V8. + var ch$1 = state.current(); + if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) { + state.raise("Invalid class escape"); + } + state.raise("Invalid escape"); + } + state.pos = start; + } + + var ch = state.current(); + if (ch !== 0x5D /* ] */) { + state.lastIntValue = ch; + state.advance(); + return true + } + + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape + pp$1.regexp_eatClassEscape = function(state) { + var start = state.pos; + + if (state.eat(0x62 /* b */)) { + state.lastIntValue = 0x08; /* */ + return true + } + + if (state.switchU && state.eat(0x2D /* - */)) { + state.lastIntValue = 0x2D; /* - */ + return true + } + + if (!state.switchU && state.eat(0x63 /* c */)) { + if (this.regexp_eatClassControlLetter(state)) { + return true + } + state.pos = start; + } + + return ( + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) + ) + }; + + // https://tc39.es/ecma262/#prod-ClassSetExpression + // https://tc39.es/ecma262/#prod-ClassUnion + // https://tc39.es/ecma262/#prod-ClassIntersection + // https://tc39.es/ecma262/#prod-ClassSubtraction + pp$1.regexp_classSetExpression = function(state) { + var result = CharSetOk, subResult; + if (this.regexp_eatClassSetRange(state)) ; else if (subResult = this.regexp_eatClassSetOperand(state)) { + if (subResult === CharSetString) { result = CharSetString; } + // https://tc39.es/ecma262/#prod-ClassIntersection + var start = state.pos; + while (state.eatChars([0x26, 0x26] /* && */)) { + if ( + state.current() !== 0x26 /* & */ && + (subResult = this.regexp_eatClassSetOperand(state)) + ) { + if (subResult !== CharSetString) { result = CharSetOk; } + continue + } + state.raise("Invalid character in character class"); + } + if (start !== state.pos) { return result } + // https://tc39.es/ecma262/#prod-ClassSubtraction + while (state.eatChars([0x2D, 0x2D] /* -- */)) { + if (this.regexp_eatClassSetOperand(state)) { continue } + state.raise("Invalid character in character class"); + } + if (start !== state.pos) { return result } + } else { + state.raise("Invalid character in character class"); + } + // https://tc39.es/ecma262/#prod-ClassUnion + for (;;) { + if (this.regexp_eatClassSetRange(state)) { continue } + subResult = this.regexp_eatClassSetOperand(state); + if (!subResult) { return result } + if (subResult === CharSetString) { result = CharSetString; } + } + }; + + // https://tc39.es/ecma262/#prod-ClassSetRange + pp$1.regexp_eatClassSetRange = function(state) { + var start = state.pos; + if (this.regexp_eatClassSetCharacter(state)) { + var left = state.lastIntValue; + if (state.eat(0x2D /* - */) && this.regexp_eatClassSetCharacter(state)) { + var right = state.lastIntValue; + if (left !== -1 && right !== -1 && left > right) { + state.raise("Range out of order in character class"); + } + return true + } + state.pos = start; + } + return false + }; + + // https://tc39.es/ecma262/#prod-ClassSetOperand + pp$1.regexp_eatClassSetOperand = function(state) { + if (this.regexp_eatClassSetCharacter(state)) { return CharSetOk } + return this.regexp_eatClassStringDisjunction(state) || this.regexp_eatNestedClass(state) + }; + + // https://tc39.es/ecma262/#prod-NestedClass + pp$1.regexp_eatNestedClass = function(state) { + var start = state.pos; + if (state.eat(0x5B /* [ */)) { + var negate = state.eat(0x5E /* ^ */); + var result = this.regexp_classContents(state); + if (state.eat(0x5D /* ] */)) { + if (negate && result === CharSetString) { + state.raise("Negated character class may contain strings"); + } + return result + } + state.pos = start; + } + if (state.eat(0x5C /* \ */)) { + var result$1 = this.regexp_eatCharacterClassEscape(state); + if (result$1) { + return result$1 + } + state.pos = start; + } + return null + }; + + // https://tc39.es/ecma262/#prod-ClassStringDisjunction + pp$1.regexp_eatClassStringDisjunction = function(state) { + var start = state.pos; + if (state.eatChars([0x5C, 0x71] /* \q */)) { + if (state.eat(0x7B /* { */)) { + var result = this.regexp_classStringDisjunctionContents(state); + if (state.eat(0x7D /* } */)) { + return result + } + } else { + // Make the same message as V8. + state.raise("Invalid escape"); + } + state.pos = start; + } + return null + }; + + // https://tc39.es/ecma262/#prod-ClassStringDisjunctionContents + pp$1.regexp_classStringDisjunctionContents = function(state) { + var result = this.regexp_classString(state); + while (state.eat(0x7C /* | */)) { + if (this.regexp_classString(state) === CharSetString) { result = CharSetString; } + } + return result + }; + + // https://tc39.es/ecma262/#prod-ClassString + // https://tc39.es/ecma262/#prod-NonEmptyClassString + pp$1.regexp_classString = function(state) { + var count = 0; + while (this.regexp_eatClassSetCharacter(state)) { count++; } + return count === 1 ? CharSetOk : CharSetString + }; + + // https://tc39.es/ecma262/#prod-ClassSetCharacter + pp$1.regexp_eatClassSetCharacter = function(state) { + var start = state.pos; + if (state.eat(0x5C /* \ */)) { + if ( + this.regexp_eatCharacterEscape(state) || + this.regexp_eatClassSetReservedPunctuator(state) + ) { + return true + } + if (state.eat(0x62 /* b */)) { + state.lastIntValue = 0x08; /* */ + return true + } + state.pos = start; + return false + } + var ch = state.current(); + if (ch < 0 || ch === state.lookahead() && isClassSetReservedDoublePunctuatorCharacter(ch)) { return false } + if (isClassSetSyntaxCharacter(ch)) { return false } + state.advance(); + state.lastIntValue = ch; + return true + }; + + // https://tc39.es/ecma262/#prod-ClassSetReservedDoublePunctuator + function isClassSetReservedDoublePunctuatorCharacter(ch) { + return ( + ch === 0x21 /* ! */ || + ch >= 0x23 /* # */ && ch <= 0x26 /* & */ || + ch >= 0x2A /* * */ && ch <= 0x2C /* , */ || + ch === 0x2E /* . */ || + ch >= 0x3A /* : */ && ch <= 0x40 /* @ */ || + ch === 0x5E /* ^ */ || + ch === 0x60 /* ` */ || + ch === 0x7E /* ~ */ + ) + } + + // https://tc39.es/ecma262/#prod-ClassSetSyntaxCharacter + function isClassSetSyntaxCharacter(ch) { + return ( + ch === 0x28 /* ( */ || + ch === 0x29 /* ) */ || + ch === 0x2D /* - */ || + ch === 0x2F /* / */ || + ch >= 0x5B /* [ */ && ch <= 0x5D /* ] */ || + ch >= 0x7B /* { */ && ch <= 0x7D /* } */ + ) + } + + // https://tc39.es/ecma262/#prod-ClassSetReservedPunctuator + pp$1.regexp_eatClassSetReservedPunctuator = function(state) { + var ch = state.current(); + if (isClassSetReservedPunctuator(ch)) { + state.lastIntValue = ch; + state.advance(); + return true + } + return false + }; + + // https://tc39.es/ecma262/#prod-ClassSetReservedPunctuator + function isClassSetReservedPunctuator(ch) { + return ( + ch === 0x21 /* ! */ || + ch === 0x23 /* # */ || + ch === 0x25 /* % */ || + ch === 0x26 /* & */ || + ch === 0x2C /* , */ || + ch === 0x2D /* - */ || + ch >= 0x3A /* : */ && ch <= 0x3E /* > */ || + ch === 0x40 /* @ */ || + ch === 0x60 /* ` */ || + ch === 0x7E /* ~ */ + ) + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter + pp$1.regexp_eatClassControlLetter = function(state) { + var ch = state.current(); + if (isDecimalDigit(ch) || ch === 0x5F /* _ */) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence + pp$1.regexp_eatHexEscapeSequence = function(state) { + var start = state.pos; + if (state.eat(0x78 /* x */)) { + if (this.regexp_eatFixedHexDigits(state, 2)) { + return true + } + if (state.switchU) { + state.raise("Invalid escape"); + } + state.pos = start; + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits + pp$1.regexp_eatDecimalDigits = function(state) { + var start = state.pos; + var ch = 0; + state.lastIntValue = 0; + while (isDecimalDigit(ch = state.current())) { + state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); + state.advance(); + } + return state.pos !== start + }; + function isDecimalDigit(ch) { + return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits + pp$1.regexp_eatHexDigits = function(state) { + var start = state.pos; + var ch = 0; + state.lastIntValue = 0; + while (isHexDigit(ch = state.current())) { + state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); + state.advance(); + } + return state.pos !== start + }; + function isHexDigit(ch) { + return ( + (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) || + (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) || + (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) + ) + } + function hexToInt(ch) { + if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) { + return 10 + (ch - 0x41 /* A */) + } + if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) { + return 10 + (ch - 0x61 /* a */) + } + return ch - 0x30 /* 0 */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence + // Allows only 0-377(octal) i.e. 0-255(decimal). + pp$1.regexp_eatLegacyOctalEscapeSequence = function(state) { + if (this.regexp_eatOctalDigit(state)) { + var n1 = state.lastIntValue; + if (this.regexp_eatOctalDigit(state)) { + var n2 = state.lastIntValue; + if (n1 <= 3 && this.regexp_eatOctalDigit(state)) { + state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue; + } else { + state.lastIntValue = n1 * 8 + n2; + } + } else { + state.lastIntValue = n1; + } + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit + pp$1.regexp_eatOctalDigit = function(state) { + var ch = state.current(); + if (isOctalDigit(ch)) { + state.lastIntValue = ch - 0x30; /* 0 */ + state.advance(); + return true + } + state.lastIntValue = 0; + return false + }; + function isOctalDigit(ch) { + return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit + // And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence + pp$1.regexp_eatFixedHexDigits = function(state, length) { + var start = state.pos; + state.lastIntValue = 0; + for (var i = 0; i < length; ++i) { + var ch = state.current(); + if (!isHexDigit(ch)) { + state.pos = start; + return false + } + state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); + state.advance(); + } + return true + }; + + // Object type used to represent tokens. Note that normally, tokens + // simply exist as properties on the parser object. This is only + // used for the onToken callback and the external tokenizer. + + var Token = function Token(p) { + this.type = p.type; + this.value = p.value; + this.start = p.start; + this.end = p.end; + if (p.options.locations) + { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); } + if (p.options.ranges) + { this.range = [p.start, p.end]; } + }; + + // ## Tokenizer + + var pp = Parser.prototype; + + // Move to the next token + + pp.next = function(ignoreEscapeSequenceInKeyword) { + if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc) + { this.raiseRecoverable(this.start, "Escape sequence in keyword " + this.type.keyword); } + if (this.options.onToken) + { this.options.onToken(new Token(this)); } + + this.lastTokEnd = this.end; + this.lastTokStart = this.start; + this.lastTokEndLoc = this.endLoc; + this.lastTokStartLoc = this.startLoc; + this.nextToken(); + }; + + pp.getToken = function() { + this.next(); + return new Token(this) + }; + + // If we're in an ES6 environment, make parsers iterable + if (typeof Symbol !== "undefined") + { pp[Symbol.iterator] = function() { + var this$1$1 = this; + + return { + next: function () { + var token = this$1$1.getToken(); + return { + done: token.type === types$1.eof, + value: token + } + } + } + }; } + + // Toggle strict mode. Re-reads the next number or string to please + // pedantic tests (`"use strict"; 010;` should fail). + + // Read a single token, updating the parser object's token-related + // properties. + + pp.nextToken = function() { + var curContext = this.curContext(); + if (!curContext || !curContext.preserveSpace) { this.skipSpace(); } + + this.start = this.pos; + if (this.options.locations) { this.startLoc = this.curPosition(); } + if (this.pos >= this.input.length) { return this.finishToken(types$1.eof) } + + if (curContext.override) { return curContext.override(this) } + else { this.readToken(this.fullCharCodeAtPos()); } + }; + + pp.readToken = function(code) { + // Identifier or keyword. '\uXXXX' sequences are allowed in + // identifiers, so '\' also dispatches to that. + if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) + { return this.readWord() } + + return this.getTokenFromCode(code) + }; + + pp.fullCharCodeAtPos = function() { + var code = this.input.charCodeAt(this.pos); + if (code <= 0xd7ff || code >= 0xdc00) { return code } + var next = this.input.charCodeAt(this.pos + 1); + return next <= 0xdbff || next >= 0xe000 ? code : (code << 10) + next - 0x35fdc00 + }; + + pp.skipBlockComment = function() { + var startLoc = this.options.onComment && this.curPosition(); + var start = this.pos, end = this.input.indexOf("*/", this.pos += 2); + if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); } + this.pos = end + 2; + if (this.options.locations) { + for (var nextBreak = (void 0), pos = start; (nextBreak = nextLineBreak(this.input, pos, this.pos)) > -1;) { + ++this.curLine; + pos = this.lineStart = nextBreak; + } + } + if (this.options.onComment) + { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, + startLoc, this.curPosition()); } + }; + + pp.skipLineComment = function(startSkip) { + var start = this.pos; + var startLoc = this.options.onComment && this.curPosition(); + var ch = this.input.charCodeAt(this.pos += startSkip); + while (this.pos < this.input.length && !isNewLine(ch)) { + ch = this.input.charCodeAt(++this.pos); + } + if (this.options.onComment) + { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, + startLoc, this.curPosition()); } + }; + + // Called at the start of the parse and after every token. Skips + // whitespace and comments, and. + + pp.skipSpace = function() { + loop: while (this.pos < this.input.length) { + var ch = this.input.charCodeAt(this.pos); + switch (ch) { + case 32: case 160: // ' ' + ++this.pos; + break + case 13: + if (this.input.charCodeAt(this.pos + 1) === 10) { + ++this.pos; + } + case 10: case 8232: case 8233: + ++this.pos; + if (this.options.locations) { + ++this.curLine; + this.lineStart = this.pos; + } + break + case 47: // '/' + switch (this.input.charCodeAt(this.pos + 1)) { + case 42: // '*' + this.skipBlockComment(); + break + case 47: + this.skipLineComment(2); + break + default: + break loop + } + break + default: + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this.pos; + } else { + break loop + } + } + } + }; + + // Called at the end of every token. Sets `end`, `val`, and + // maintains `context` and `exprAllowed`, and skips the space after + // the token, so that the next one's `start` will point at the + // right position. + + pp.finishToken = function(type, val) { + this.end = this.pos; + if (this.options.locations) { this.endLoc = this.curPosition(); } + var prevType = this.type; + this.type = type; + this.value = val; + + this.updateContext(prevType); + }; + + // ### Token reading + + // This is the function that is called to fetch the next token. It + // is somewhat obscure, because it works in character codes rather + // than characters, and because operator parsing has been inlined + // into it. + // + // All in the name of speed. + // + pp.readToken_dot = function() { + var next = this.input.charCodeAt(this.pos + 1); + if (next >= 48 && next <= 57) { return this.readNumber(true) } + var next2 = this.input.charCodeAt(this.pos + 2); + if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.' + this.pos += 3; + return this.finishToken(types$1.ellipsis) + } else { + ++this.pos; + return this.finishToken(types$1.dot) + } + }; + + pp.readToken_slash = function() { // '/' + var next = this.input.charCodeAt(this.pos + 1); + if (this.exprAllowed) { ++this.pos; return this.readRegexp() } + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(types$1.slash, 1) + }; + + pp.readToken_mult_modulo_exp = function(code) { // '%*' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + var tokentype = code === 42 ? types$1.star : types$1.modulo; + + // exponentiation operator ** and **= + if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) { + ++size; + tokentype = types$1.starstar; + next = this.input.charCodeAt(this.pos + 2); + } + + if (next === 61) { return this.finishOp(types$1.assign, size + 1) } + return this.finishOp(tokentype, size) + }; + + pp.readToken_pipe_amp = function(code) { // '|&' + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { + if (this.options.ecmaVersion >= 12) { + var next2 = this.input.charCodeAt(this.pos + 2); + if (next2 === 61) { return this.finishOp(types$1.assign, 3) } + } + return this.finishOp(code === 124 ? types$1.logicalOR : types$1.logicalAND, 2) + } + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(code === 124 ? types$1.bitwiseOR : types$1.bitwiseAND, 1) + }; + + pp.readToken_caret = function() { // '^' + var next = this.input.charCodeAt(this.pos + 1); + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(types$1.bitwiseXOR, 1) + }; + + pp.readToken_plus_min = function(code) { // '+-' + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { + if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 && + (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) { + // A `-->` line comment + this.skipLineComment(3); + this.skipSpace(); + return this.nextToken() + } + return this.finishOp(types$1.incDec, 2) + } + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(types$1.plusMin, 1) + }; + + pp.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; + if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) } + return this.finishOp(types$1.bitShift, size) + } + if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && + this.input.charCodeAt(this.pos + 3) === 45) { + // `` line comment + this.skipLineComment(3); + this.skipSpace(); + return this.nextToken() + } + return this.finishOp(types$1.incDec, 2) + } + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(types$1.plusMin, 1) +}; + +pp.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; + if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) } + return this.finishOp(types$1.bitShift, size) + } + if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && + this.input.charCodeAt(this.pos + 3) === 45) { + // ` + +You may pull in just the part of this semver utility that you need if you +are sensitive to packing and tree-shaking concerns. The main +`require('semver')` export uses getter functions to lazily load the parts +of the API that are used. + +The following modules are available: + +* `require('semver')` +* `require('semver/classes')` +* `require('semver/classes/comparator')` +* `require('semver/classes/range')` +* `require('semver/classes/semver')` +* `require('semver/functions/clean')` +* `require('semver/functions/cmp')` +* `require('semver/functions/coerce')` +* `require('semver/functions/compare')` +* `require('semver/functions/compare-build')` +* `require('semver/functions/compare-loose')` +* `require('semver/functions/diff')` +* `require('semver/functions/eq')` +* `require('semver/functions/gt')` +* `require('semver/functions/gte')` +* `require('semver/functions/inc')` +* `require('semver/functions/lt')` +* `require('semver/functions/lte')` +* `require('semver/functions/major')` +* `require('semver/functions/minor')` +* `require('semver/functions/neq')` +* `require('semver/functions/parse')` +* `require('semver/functions/patch')` +* `require('semver/functions/prerelease')` +* `require('semver/functions/rcompare')` +* `require('semver/functions/rsort')` +* `require('semver/functions/satisfies')` +* `require('semver/functions/sort')` +* `require('semver/functions/valid')` +* `require('semver/ranges/gtr')` +* `require('semver/ranges/intersects')` +* `require('semver/ranges/ltr')` +* `require('semver/ranges/max-satisfying')` +* `require('semver/ranges/min-satisfying')` +* `require('semver/ranges/min-version')` +* `require('semver/ranges/outside')` +* `require('semver/ranges/simplify')` +* `require('semver/ranges/subset')` +* `require('semver/ranges/to-comparators')` +* `require('semver/ranges/valid')` + diff --git a/node_modules/semver/bin/semver.js b/node_modules/semver/bin/semver.js new file mode 100755 index 0000000..dbb1bf5 --- /dev/null +++ b/node_modules/semver/bin/semver.js @@ -0,0 +1,191 @@ +#!/usr/bin/env node +// Standalone semver comparison program. +// Exits successfully and prints matching version(s) if +// any supplied version is valid and passes all tests. + +'use strict' + +const argv = process.argv.slice(2) + +let versions = [] + +const range = [] + +let inc = null + +const version = require('../package.json').version + +let loose = false + +let includePrerelease = false + +let coerce = false + +let rtl = false + +let identifier + +let identifierBase + +const semver = require('../') +const parseOptions = require('../internal/parse-options') + +let reverse = false + +let options = {} + +const main = () => { + if (!argv.length) { + return help() + } + while (argv.length) { + let a = argv.shift() + const indexOfEqualSign = a.indexOf('=') + if (indexOfEqualSign !== -1) { + const value = a.slice(indexOfEqualSign + 1) + a = a.slice(0, indexOfEqualSign) + argv.unshift(value) + } + switch (a) { + case '-rv': case '-rev': case '--rev': case '--reverse': + reverse = true + break + case '-l': case '--loose': + loose = true + break + case '-p': case '--include-prerelease': + includePrerelease = true + break + case '-v': case '--version': + versions.push(argv.shift()) + break + case '-i': case '--inc': case '--increment': + switch (argv[0]) { + case 'major': case 'minor': case 'patch': case 'prerelease': + case 'premajor': case 'preminor': case 'prepatch': + case 'release': + inc = argv.shift() + break + default: + inc = 'patch' + break + } + break + case '--preid': + identifier = argv.shift() + break + case '-r': case '--range': + range.push(argv.shift()) + break + case '-n': + identifierBase = argv.shift() + if (identifierBase === 'false') { + identifierBase = false + } + break + case '-c': case '--coerce': + coerce = true + break + case '--rtl': + rtl = true + break + case '--ltr': + rtl = false + break + case '-h': case '--help': case '-?': + return help() + default: + versions.push(a) + break + } + } + + options = parseOptions({ loose, includePrerelease, rtl }) + + versions = versions.map((v) => { + return coerce ? (semver.coerce(v, options) || { version: v }).version : v + }).filter((v) => { + return semver.valid(v) + }) + if (!versions.length) { + return fail() + } + if (inc && (versions.length !== 1 || range.length)) { + return failInc() + } + + for (let i = 0, l = range.length; i < l; i++) { + versions = versions.filter((v) => { + return semver.satisfies(v, range[i], options) + }) + if (!versions.length) { + return fail() + } + } + versions + .sort((a, b) => semver[reverse ? 'rcompare' : 'compare'](a, b, options)) + .map(v => semver.clean(v, options)) + .map(v => inc ? semver.inc(v, inc, options, identifier, identifierBase) : v) + .forEach(v => console.log(v)) +} + +const failInc = () => { + console.error('--inc can only be used on a single version with no range') + fail() +} + +const fail = () => process.exit(1) + +const help = () => console.log( +`SemVer ${version} + +A JavaScript implementation of the https://semver.org/ specification +Copyright Isaac Z. Schlueter + +Usage: semver [options] [ [...]] +Prints valid versions sorted by SemVer precedence + +Options: +-r --range + Print versions that match the specified range. + +-i --increment [] + Increment a version by the specified level. Level can + be one of: major, minor, patch, premajor, preminor, + prepatch, prerelease, or release. Default level is 'patch'. + Only one version may be specified. + +--preid + Identifier to be used to prefix premajor, preminor, + prepatch or prerelease version increments. + +-l --loose + Interpret versions and ranges loosely + +-p --include-prerelease + Always include prerelease versions in range matching + +-c --coerce + Coerce a string into SemVer if possible + (does not imply --loose) + +--rtl + Coerce version strings right to left + +--ltr + Coerce version strings left to right (default) + +-n + Base number to be used for the prerelease identifier. + Can be either 0 or 1, or false to omit the number altogether. + Defaults to 0. + +Program exits successfully if any valid version satisfies +all supplied ranges, and prints all satisfying versions. + +If no satisfying versions are found, then exits failure. + +Versions are printed in ascending order, so supplying +multiple versions to the utility will just sort them.`) + +main() diff --git a/node_modules/semver/classes/comparator.js b/node_modules/semver/classes/comparator.js new file mode 100644 index 0000000..647c1f0 --- /dev/null +++ b/node_modules/semver/classes/comparator.js @@ -0,0 +1,143 @@ +'use strict' + +const ANY = Symbol('SemVer ANY') +// hoisted class for cyclic dependency +class Comparator { + static get ANY () { + return ANY + } + + constructor (comp, options) { + options = parseOptions(options) + + if (comp instanceof Comparator) { + if (comp.loose === !!options.loose) { + return comp + } else { + comp = comp.value + } + } + + comp = comp.trim().split(/\s+/).join(' ') + debug('comparator', comp, options) + this.options = options + this.loose = !!options.loose + this.parse(comp) + + if (this.semver === ANY) { + this.value = '' + } else { + this.value = this.operator + this.semver.version + } + + debug('comp', this) + } + + parse (comp) { + const r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR] + const m = comp.match(r) + + if (!m) { + throw new TypeError(`Invalid comparator: ${comp}`) + } + + this.operator = m[1] !== undefined ? m[1] : '' + if (this.operator === '=') { + this.operator = '' + } + + // if it literally is just '>' or '' then allow anything. + if (!m[2]) { + this.semver = ANY + } else { + this.semver = new SemVer(m[2], this.options.loose) + } + } + + toString () { + return this.value + } + + test (version) { + debug('Comparator.test', version, this.options.loose) + + if (this.semver === ANY || version === ANY) { + return true + } + + if (typeof version === 'string') { + try { + version = new SemVer(version, this.options) + } catch (er) { + return false + } + } + + return cmp(version, this.operator, this.semver, this.options) + } + + intersects (comp, options) { + if (!(comp instanceof Comparator)) { + throw new TypeError('a Comparator is required') + } + + if (this.operator === '') { + if (this.value === '') { + return true + } + return new Range(comp.value, options).test(this.value) + } else if (comp.operator === '') { + if (comp.value === '') { + return true + } + return new Range(this.value, options).test(comp.semver) + } + + options = parseOptions(options) + + // Special cases where nothing can possibly be lower + if (options.includePrerelease && + (this.value === '<0.0.0-0' || comp.value === '<0.0.0-0')) { + return false + } + if (!options.includePrerelease && + (this.value.startsWith('<0.0.0') || comp.value.startsWith('<0.0.0'))) { + return false + } + + // Same direction increasing (> or >=) + if (this.operator.startsWith('>') && comp.operator.startsWith('>')) { + return true + } + // Same direction decreasing (< or <=) + if (this.operator.startsWith('<') && comp.operator.startsWith('<')) { + return true + } + // same SemVer and both sides are inclusive (<= or >=) + if ( + (this.semver.version === comp.semver.version) && + this.operator.includes('=') && comp.operator.includes('=')) { + return true + } + // opposite directions less than + if (cmp(this.semver, '<', comp.semver, options) && + this.operator.startsWith('>') && comp.operator.startsWith('<')) { + return true + } + // opposite directions greater than + if (cmp(this.semver, '>', comp.semver, options) && + this.operator.startsWith('<') && comp.operator.startsWith('>')) { + return true + } + return false + } +} + +module.exports = Comparator + +const parseOptions = require('../internal/parse-options') +const { safeRe: re, t } = require('../internal/re') +const cmp = require('../functions/cmp') +const debug = require('../internal/debug') +const SemVer = require('./semver') +const Range = require('./range') diff --git a/node_modules/semver/classes/index.js b/node_modules/semver/classes/index.js new file mode 100644 index 0000000..91c24ec --- /dev/null +++ b/node_modules/semver/classes/index.js @@ -0,0 +1,7 @@ +'use strict' + +module.exports = { + SemVer: require('./semver.js'), + Range: require('./range.js'), + Comparator: require('./comparator.js'), +} diff --git a/node_modules/semver/classes/range.js b/node_modules/semver/classes/range.js new file mode 100644 index 0000000..94629ce --- /dev/null +++ b/node_modules/semver/classes/range.js @@ -0,0 +1,557 @@ +'use strict' + +const SPACE_CHARACTERS = /\s+/g + +// hoisted class for cyclic dependency +class Range { + constructor (range, options) { + options = parseOptions(options) + + if (range instanceof Range) { + if ( + range.loose === !!options.loose && + range.includePrerelease === !!options.includePrerelease + ) { + return range + } else { + return new Range(range.raw, options) + } + } + + if (range instanceof Comparator) { + // just put it in the set and return + this.raw = range.value + this.set = [[range]] + this.formatted = undefined + return this + } + + this.options = options + this.loose = !!options.loose + this.includePrerelease = !!options.includePrerelease + + // First reduce all whitespace as much as possible so we do not have to rely + // on potentially slow regexes like \s*. This is then stored and used for + // future error messages as well. + this.raw = range.trim().replace(SPACE_CHARACTERS, ' ') + + // First, split on || + this.set = this.raw + .split('||') + // map the range to a 2d array of comparators + .map(r => this.parseRange(r.trim())) + // throw out any comparator lists that are empty + // this generally means that it was not a valid range, which is allowed + // in loose mode, but will still throw if the WHOLE range is invalid. + .filter(c => c.length) + + if (!this.set.length) { + throw new TypeError(`Invalid SemVer Range: ${this.raw}`) + } + + // if we have any that are not the null set, throw out null sets. + if (this.set.length > 1) { + // keep the first one, in case they're all null sets + const first = this.set[0] + this.set = this.set.filter(c => !isNullSet(c[0])) + if (this.set.length === 0) { + this.set = [first] + } else if (this.set.length > 1) { + // if we have any that are *, then the range is just * + for (const c of this.set) { + if (c.length === 1 && isAny(c[0])) { + this.set = [c] + break + } + } + } + } + + this.formatted = undefined + } + + get range () { + if (this.formatted === undefined) { + this.formatted = '' + for (let i = 0; i < this.set.length; i++) { + if (i > 0) { + this.formatted += '||' + } + const comps = this.set[i] + for (let k = 0; k < comps.length; k++) { + if (k > 0) { + this.formatted += ' ' + } + this.formatted += comps[k].toString().trim() + } + } + } + return this.formatted + } + + format () { + return this.range + } + + toString () { + return this.range + } + + parseRange (range) { + // memoize range parsing for performance. + // this is a very hot path, and fully deterministic. + const memoOpts = + (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | + (this.options.loose && FLAG_LOOSE) + const memoKey = memoOpts + ':' + range + const cached = cache.get(memoKey) + if (cached) { + return cached + } + + const loose = this.options.loose + // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` + const hr = loose ? re[t.HYPHENRANGELOOSE] : re[t.HYPHENRANGE] + range = range.replace(hr, hyphenReplace(this.options.includePrerelease)) + debug('hyphen replace', range) + + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` + range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace) + debug('comparator trim', range) + + // `~ 1.2.3` => `~1.2.3` + range = range.replace(re[t.TILDETRIM], tildeTrimReplace) + debug('tilde trim', range) + + // `^ 1.2.3` => `^1.2.3` + range = range.replace(re[t.CARETTRIM], caretTrimReplace) + debug('caret trim', range) + + // At this point, the range is completely trimmed and + // ready to be split into comparators. + + let rangeList = range + .split(' ') + .map(comp => parseComparator(comp, this.options)) + .join(' ') + .split(/\s+/) + // >=0.0.0 is equivalent to * + .map(comp => replaceGTE0(comp, this.options)) + + if (loose) { + // in loose mode, throw out any that are not valid comparators + rangeList = rangeList.filter(comp => { + debug('loose invalid filter', comp, this.options) + return !!comp.match(re[t.COMPARATORLOOSE]) + }) + } + debug('range list', rangeList) + + // if any comparators are the null set, then replace with JUST null set + // if more than one comparator, remove any * comparators + // also, don't include the same comparator more than once + const rangeMap = new Map() + const comparators = rangeList.map(comp => new Comparator(comp, this.options)) + for (const comp of comparators) { + if (isNullSet(comp)) { + return [comp] + } + rangeMap.set(comp.value, comp) + } + if (rangeMap.size > 1 && rangeMap.has('')) { + rangeMap.delete('') + } + + const result = [...rangeMap.values()] + cache.set(memoKey, result) + return result + } + + intersects (range, options) { + if (!(range instanceof Range)) { + throw new TypeError('a Range is required') + } + + return this.set.some((thisComparators) => { + return ( + isSatisfiable(thisComparators, options) && + range.set.some((rangeComparators) => { + return ( + isSatisfiable(rangeComparators, options) && + thisComparators.every((thisComparator) => { + return rangeComparators.every((rangeComparator) => { + return thisComparator.intersects(rangeComparator, options) + }) + }) + ) + }) + ) + }) + } + + // if ANY of the sets match ALL of its comparators, then pass + test (version) { + if (!version) { + return false + } + + if (typeof version === 'string') { + try { + version = new SemVer(version, this.options) + } catch (er) { + return false + } + } + + for (let i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version, this.options)) { + return true + } + } + return false + } +} + +module.exports = Range + +const LRU = require('../internal/lrucache') +const cache = new LRU() + +const parseOptions = require('../internal/parse-options') +const Comparator = require('./comparator') +const debug = require('../internal/debug') +const SemVer = require('./semver') +const { + safeRe: re, + t, + comparatorTrimReplace, + tildeTrimReplace, + caretTrimReplace, +} = require('../internal/re') +const { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = require('../internal/constants') + +const isNullSet = c => c.value === '<0.0.0-0' +const isAny = c => c.value === '' + +// take a set of comparators and determine whether there +// exists a version which can satisfy it +const isSatisfiable = (comparators, options) => { + let result = true + const remainingComparators = comparators.slice() + let testComparator = remainingComparators.pop() + + while (result && remainingComparators.length) { + result = remainingComparators.every((otherComparator) => { + return testComparator.intersects(otherComparator, options) + }) + + testComparator = remainingComparators.pop() + } + + return result +} + +// comprised of xranges, tildes, stars, and gtlt's at this point. +// already replaced the hyphen ranges +// turn into a set of JUST comparators. +const parseComparator = (comp, options) => { + comp = comp.replace(re[t.BUILD], '') + debug('comp', comp, options) + comp = replaceCarets(comp, options) + debug('caret', comp) + comp = replaceTildes(comp, options) + debug('tildes', comp) + comp = replaceXRanges(comp, options) + debug('xrange', comp) + comp = replaceStars(comp, options) + debug('stars', comp) + return comp +} + +const isX = id => !id || id.toLowerCase() === 'x' || id === '*' + +// ~, ~> --> * (any, kinda silly) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0-0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0-0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0-0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0 +// ~0.0.1 --> >=0.0.1 <0.1.0-0 +const replaceTildes = (comp, options) => { + return comp + .trim() + .split(/\s+/) + .map((c) => replaceTilde(c, options)) + .join(' ') +} + +const replaceTilde = (comp, options) => { + const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE] + return comp.replace(r, (_, M, m, p, pr) => { + debug('tilde', comp, _, M, m, p, pr) + let ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = `>=${M}.0.0 <${+M + 1}.0.0-0` + } else if (isX(p)) { + // ~1.2 == >=1.2.0 <1.3.0-0 + ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0` + } else if (pr) { + debug('replaceTilde pr', pr) + ret = `>=${M}.${m}.${p}-${pr + } <${M}.${+m + 1}.0-0` + } else { + // ~1.2.3 == >=1.2.3 <1.3.0-0 + ret = `>=${M}.${m}.${p + } <${M}.${+m + 1}.0-0` + } + + debug('tilde return', ret) + return ret + }) +} + +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0-0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0-0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0-0 +// ^1.2.3 --> >=1.2.3 <2.0.0-0 +// ^1.2.0 --> >=1.2.0 <2.0.0-0 +// ^0.0.1 --> >=0.0.1 <0.0.2-0 +// ^0.1.0 --> >=0.1.0 <0.2.0-0 +const replaceCarets = (comp, options) => { + return comp + .trim() + .split(/\s+/) + .map((c) => replaceCaret(c, options)) + .join(' ') +} + +const replaceCaret = (comp, options) => { + debug('caret', comp, options) + const r = options.loose ? re[t.CARETLOOSE] : re[t.CARET] + const z = options.includePrerelease ? '-0' : '' + return comp.replace(r, (_, M, m, p, pr) => { + debug('caret', comp, _, M, m, p, pr) + let ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0` + } else if (isX(p)) { + if (M === '0') { + ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0` + } else { + ret = `>=${M}.${m}.0${z} <${+M + 1}.0.0-0` + } + } else if (pr) { + debug('replaceCaret pr', pr) + if (M === '0') { + if (m === '0') { + ret = `>=${M}.${m}.${p}-${pr + } <${M}.${m}.${+p + 1}-0` + } else { + ret = `>=${M}.${m}.${p}-${pr + } <${M}.${+m + 1}.0-0` + } + } else { + ret = `>=${M}.${m}.${p}-${pr + } <${+M + 1}.0.0-0` + } + } else { + debug('no pr') + if (M === '0') { + if (m === '0') { + ret = `>=${M}.${m}.${p + }${z} <${M}.${m}.${+p + 1}-0` + } else { + ret = `>=${M}.${m}.${p + }${z} <${M}.${+m + 1}.0-0` + } + } else { + ret = `>=${M}.${m}.${p + } <${+M + 1}.0.0-0` + } + } + + debug('caret return', ret) + return ret + }) +} + +const replaceXRanges = (comp, options) => { + debug('replaceXRanges', comp, options) + return comp + .split(/\s+/) + .map((c) => replaceXRange(c, options)) + .join(' ') +} + +const replaceXRange = (comp, options) => { + comp = comp.trim() + const r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE] + return comp.replace(r, (ret, gtlt, M, m, p, pr) => { + debug('xRange', comp, ret, gtlt, M, m, p, pr) + const xM = isX(M) + const xm = xM || isX(m) + const xp = xm || isX(p) + const anyX = xp + + if (gtlt === '=' && anyX) { + gtlt = '' + } + + // if we're including prereleases in the match, then we need + // to fix this to -0, the lowest possible prerelease value + pr = options.includePrerelease ? '-0' : '' + + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<0.0.0-0' + } else { + // nothing is forbidden + ret = '*' + } + } else if (gtlt && anyX) { + // we know patch is an x, because we have any x at all. + // replace X with 0 + if (xm) { + m = 0 + } + p = 0 + + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + gtlt = '>=' + if (xm) { + M = +M + 1 + m = 0 + p = 0 + } else { + m = +m + 1 + p = 0 + } + } else if (gtlt === '<=') { + // <=0.7.x is actually <0.8.0, since any 0.7.x should + // pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = '<' + if (xm) { + M = +M + 1 + } else { + m = +m + 1 + } + } + + if (gtlt === '<') { + pr = '-0' + } + + ret = `${gtlt + M}.${m}.${p}${pr}` + } else if (xm) { + ret = `>=${M}.0.0${pr} <${+M + 1}.0.0-0` + } else if (xp) { + ret = `>=${M}.${m}.0${pr + } <${M}.${+m + 1}.0-0` + } + + debug('xRange return', ret) + + return ret + }) +} + +// Because * is AND-ed with everything else in the comparator, +// and '' means "any version", just remove the *s entirely. +const replaceStars = (comp, options) => { + debug('replaceStars', comp, options) + // Looseness is ignored here. star is always as loose as it gets! + return comp + .trim() + .replace(re[t.STAR], '') +} + +const replaceGTE0 = (comp, options) => { + debug('replaceGTE0', comp, options) + return comp + .trim() + .replace(re[options.includePrerelease ? t.GTE0PRE : t.GTE0], '') +} + +// This function is passed to string.replace(re[t.HYPHENRANGE]) +// M, m, patch, prerelease, build +// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 +// 1.2.3 - 3.4 => >=1.2.0 <3.5.0-0 Any 3.4.x will do +// 1.2 - 3.4 => >=1.2.0 <3.5.0-0 +// TODO build? +const hyphenReplace = incPr => ($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr) => { + if (isX(fM)) { + from = '' + } else if (isX(fm)) { + from = `>=${fM}.0.0${incPr ? '-0' : ''}` + } else if (isX(fp)) { + from = `>=${fM}.${fm}.0${incPr ? '-0' : ''}` + } else if (fpr) { + from = `>=${from}` + } else { + from = `>=${from}${incPr ? '-0' : ''}` + } + + if (isX(tM)) { + to = '' + } else if (isX(tm)) { + to = `<${+tM + 1}.0.0-0` + } else if (isX(tp)) { + to = `<${tM}.${+tm + 1}.0-0` + } else if (tpr) { + to = `<=${tM}.${tm}.${tp}-${tpr}` + } else if (incPr) { + to = `<${tM}.${tm}.${+tp + 1}-0` + } else { + to = `<=${to}` + } + + return `${from} ${to}`.trim() +} + +const testSet = (set, version, options) => { + for (let i = 0; i < set.length; i++) { + if (!set[i].test(version)) { + return false + } + } + + if (version.prerelease.length && !options.includePrerelease) { + // Find the set of versions that are allowed to have prereleases + // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + // That should allow `1.2.3-pr.2` to pass. + // However, `1.2.4-alpha.notready` should NOT be allowed, + // even though it's within the range set by the comparators. + for (let i = 0; i < set.length; i++) { + debug(set[i].semver) + if (set[i].semver === Comparator.ANY) { + continue + } + + if (set[i].semver.prerelease.length > 0) { + const allowed = set[i].semver + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) { + return true + } + } + } + + // Version has a -pre, but it's not one of the ones we like. + return false + } + + return true +} diff --git a/node_modules/semver/classes/semver.js b/node_modules/semver/classes/semver.js new file mode 100644 index 0000000..92254be --- /dev/null +++ b/node_modules/semver/classes/semver.js @@ -0,0 +1,333 @@ +'use strict' + +const debug = require('../internal/debug') +const { MAX_LENGTH, MAX_SAFE_INTEGER } = require('../internal/constants') +const { safeRe: re, t } = require('../internal/re') + +const parseOptions = require('../internal/parse-options') +const { compareIdentifiers } = require('../internal/identifiers') +class SemVer { + constructor (version, options) { + options = parseOptions(options) + + if (version instanceof SemVer) { + if (version.loose === !!options.loose && + version.includePrerelease === !!options.includePrerelease) { + return version + } else { + version = version.version + } + } else if (typeof version !== 'string') { + throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`) + } + + if (version.length > MAX_LENGTH) { + throw new TypeError( + `version is longer than ${MAX_LENGTH} characters` + ) + } + + debug('SemVer', version, options) + this.options = options + this.loose = !!options.loose + // this isn't actually relevant for versions, but keep it so that we + // don't run into trouble passing this.options around. + this.includePrerelease = !!options.includePrerelease + + const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL]) + + if (!m) { + throw new TypeError(`Invalid Version: ${version}`) + } + + this.raw = version + + // these are actually numbers + this.major = +m[1] + this.minor = +m[2] + this.patch = +m[3] + + if (this.major > MAX_SAFE_INTEGER || this.major < 0) { + throw new TypeError('Invalid major version') + } + + if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { + throw new TypeError('Invalid minor version') + } + + if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { + throw new TypeError('Invalid patch version') + } + + // numberify any prerelease numeric ids + if (!m[4]) { + this.prerelease = [] + } else { + this.prerelease = m[4].split('.').map((id) => { + if (/^[0-9]+$/.test(id)) { + const num = +id + if (num >= 0 && num < MAX_SAFE_INTEGER) { + return num + } + } + return id + }) + } + + this.build = m[5] ? m[5].split('.') : [] + this.format() + } + + format () { + this.version = `${this.major}.${this.minor}.${this.patch}` + if (this.prerelease.length) { + this.version += `-${this.prerelease.join('.')}` + } + return this.version + } + + toString () { + return this.version + } + + compare (other) { + debug('SemVer.compare', this.version, this.options, other) + if (!(other instanceof SemVer)) { + if (typeof other === 'string' && other === this.version) { + return 0 + } + other = new SemVer(other, this.options) + } + + if (other.version === this.version) { + return 0 + } + + return this.compareMain(other) || this.comparePre(other) + } + + compareMain (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + if (this.major < other.major) { + return -1 + } + if (this.major > other.major) { + return 1 + } + if (this.minor < other.minor) { + return -1 + } + if (this.minor > other.minor) { + return 1 + } + if (this.patch < other.patch) { + return -1 + } + if (this.patch > other.patch) { + return 1 + } + return 0 + } + + comparePre (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + // NOT having a prerelease is > having one + if (this.prerelease.length && !other.prerelease.length) { + return -1 + } else if (!this.prerelease.length && other.prerelease.length) { + return 1 + } else if (!this.prerelease.length && !other.prerelease.length) { + return 0 + } + + let i = 0 + do { + const a = this.prerelease[i] + const b = other.prerelease[i] + debug('prerelease compare', i, a, b) + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) + } + + compareBuild (other) { + if (!(other instanceof SemVer)) { + other = new SemVer(other, this.options) + } + + let i = 0 + do { + const a = this.build[i] + const b = other.build[i] + debug('build compare', i, a, b) + if (a === undefined && b === undefined) { + return 0 + } else if (b === undefined) { + return 1 + } else if (a === undefined) { + return -1 + } else if (a === b) { + continue + } else { + return compareIdentifiers(a, b) + } + } while (++i) + } + + // preminor will bump the version up to the next minor release, and immediately + // down to pre-release. premajor and prepatch work the same way. + inc (release, identifier, identifierBase) { + if (release.startsWith('pre')) { + if (!identifier && identifierBase === false) { + throw new Error('invalid increment argument: identifier is empty') + } + // Avoid an invalid semver results + if (identifier) { + const match = `-${identifier}`.match(this.options.loose ? re[t.PRERELEASELOOSE] : re[t.PRERELEASE]) + if (!match || match[1] !== identifier) { + throw new Error(`invalid identifier: ${identifier}`) + } + } + } + + switch (release) { + case 'premajor': + this.prerelease.length = 0 + this.patch = 0 + this.minor = 0 + this.major++ + this.inc('pre', identifier, identifierBase) + break + case 'preminor': + this.prerelease.length = 0 + this.patch = 0 + this.minor++ + this.inc('pre', identifier, identifierBase) + break + case 'prepatch': + // If this is already a prerelease, it will bump to the next version + // drop any prereleases that might already exist, since they are not + // relevant at this point. + this.prerelease.length = 0 + this.inc('patch', identifier, identifierBase) + this.inc('pre', identifier, identifierBase) + break + // If the input is a non-prerelease version, this acts the same as + // prepatch. + case 'prerelease': + if (this.prerelease.length === 0) { + this.inc('patch', identifier, identifierBase) + } + this.inc('pre', identifier, identifierBase) + break + case 'release': + if (this.prerelease.length === 0) { + throw new Error(`version ${this.raw} is not a prerelease`) + } + this.prerelease.length = 0 + break + + case 'major': + // If this is a pre-major version, bump up to the same major version. + // Otherwise increment major. + // 1.0.0-5 bumps to 1.0.0 + // 1.1.0 bumps to 2.0.0 + if ( + this.minor !== 0 || + this.patch !== 0 || + this.prerelease.length === 0 + ) { + this.major++ + } + this.minor = 0 + this.patch = 0 + this.prerelease = [] + break + case 'minor': + // If this is a pre-minor version, bump up to the same minor version. + // Otherwise increment minor. + // 1.2.0-5 bumps to 1.2.0 + // 1.2.1 bumps to 1.3.0 + if (this.patch !== 0 || this.prerelease.length === 0) { + this.minor++ + } + this.patch = 0 + this.prerelease = [] + break + case 'patch': + // If this is not a pre-release version, it will increment the patch. + // If it is a pre-release it will bump up to the same patch version. + // 1.2.0-5 patches to 1.2.0 + // 1.2.0 patches to 1.2.1 + if (this.prerelease.length === 0) { + this.patch++ + } + this.prerelease = [] + break + // This probably shouldn't be used publicly. + // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction. + case 'pre': { + const base = Number(identifierBase) ? 1 : 0 + + if (this.prerelease.length === 0) { + this.prerelease = [base] + } else { + let i = this.prerelease.length + while (--i >= 0) { + if (typeof this.prerelease[i] === 'number') { + this.prerelease[i]++ + i = -2 + } + } + if (i === -1) { + // didn't increment anything + if (identifier === this.prerelease.join('.') && identifierBase === false) { + throw new Error('invalid increment argument: identifier already exists') + } + this.prerelease.push(base) + } + } + if (identifier) { + // 1.2.0-beta.1 bumps to 1.2.0-beta.2, + // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + let prerelease = [identifier, base] + if (identifierBase === false) { + prerelease = [identifier] + } + if (compareIdentifiers(this.prerelease[0], identifier) === 0) { + if (isNaN(this.prerelease[1])) { + this.prerelease = prerelease + } + } else { + this.prerelease = prerelease + } + } + break + } + default: + throw new Error(`invalid increment argument: ${release}`) + } + this.raw = this.format() + if (this.build.length) { + this.raw += `+${this.build.join('.')}` + } + return this + } +} + +module.exports = SemVer diff --git a/node_modules/semver/functions/clean.js b/node_modules/semver/functions/clean.js new file mode 100644 index 0000000..79703d6 --- /dev/null +++ b/node_modules/semver/functions/clean.js @@ -0,0 +1,8 @@ +'use strict' + +const parse = require('./parse') +const clean = (version, options) => { + const s = parse(version.trim().replace(/^[=v]+/, ''), options) + return s ? s.version : null +} +module.exports = clean diff --git a/node_modules/semver/functions/cmp.js b/node_modules/semver/functions/cmp.js new file mode 100644 index 0000000..77487dc --- /dev/null +++ b/node_modules/semver/functions/cmp.js @@ -0,0 +1,54 @@ +'use strict' + +const eq = require('./eq') +const neq = require('./neq') +const gt = require('./gt') +const gte = require('./gte') +const lt = require('./lt') +const lte = require('./lte') + +const cmp = (a, op, b, loose) => { + switch (op) { + case '===': + if (typeof a === 'object') { + a = a.version + } + if (typeof b === 'object') { + b = b.version + } + return a === b + + case '!==': + if (typeof a === 'object') { + a = a.version + } + if (typeof b === 'object') { + b = b.version + } + return a !== b + + case '': + case '=': + case '==': + return eq(a, b, loose) + + case '!=': + return neq(a, b, loose) + + case '>': + return gt(a, b, loose) + + case '>=': + return gte(a, b, loose) + + case '<': + return lt(a, b, loose) + + case '<=': + return lte(a, b, loose) + + default: + throw new TypeError(`Invalid operator: ${op}`) + } +} +module.exports = cmp diff --git a/node_modules/semver/functions/coerce.js b/node_modules/semver/functions/coerce.js new file mode 100644 index 0000000..cfe0275 --- /dev/null +++ b/node_modules/semver/functions/coerce.js @@ -0,0 +1,62 @@ +'use strict' + +const SemVer = require('../classes/semver') +const parse = require('./parse') +const { safeRe: re, t } = require('../internal/re') + +const coerce = (version, options) => { + if (version instanceof SemVer) { + return version + } + + if (typeof version === 'number') { + version = String(version) + } + + if (typeof version !== 'string') { + return null + } + + options = options || {} + + let match = null + if (!options.rtl) { + match = version.match(options.includePrerelease ? re[t.COERCEFULL] : re[t.COERCE]) + } else { + // Find the right-most coercible string that does not share + // a terminus with a more left-ward coercible string. + // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' + // With includePrerelease option set, '1.2.3.4-rc' wants to coerce '2.3.4-rc', not '2.3.4' + // + // Walk through the string checking with a /g regexp + // Manually set the index so as to pick up overlapping matches. + // Stop when we get a match that ends at the string end, since no + // coercible string can be more right-ward without the same terminus. + const coerceRtlRegex = options.includePrerelease ? re[t.COERCERTLFULL] : re[t.COERCERTL] + let next + while ((next = coerceRtlRegex.exec(version)) && + (!match || match.index + match[0].length !== version.length) + ) { + if (!match || + next.index + next[0].length !== match.index + match[0].length) { + match = next + } + coerceRtlRegex.lastIndex = next.index + next[1].length + next[2].length + } + // leave it in a clean state + coerceRtlRegex.lastIndex = -1 + } + + if (match === null) { + return null + } + + const major = match[2] + const minor = match[3] || '0' + const patch = match[4] || '0' + const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : '' + const build = options.includePrerelease && match[6] ? `+${match[6]}` : '' + + return parse(`${major}.${minor}.${patch}${prerelease}${build}`, options) +} +module.exports = coerce diff --git a/node_modules/semver/functions/compare-build.js b/node_modules/semver/functions/compare-build.js new file mode 100644 index 0000000..99157cf --- /dev/null +++ b/node_modules/semver/functions/compare-build.js @@ -0,0 +1,9 @@ +'use strict' + +const SemVer = require('../classes/semver') +const compareBuild = (a, b, loose) => { + const versionA = new SemVer(a, loose) + const versionB = new SemVer(b, loose) + return versionA.compare(versionB) || versionA.compareBuild(versionB) +} +module.exports = compareBuild diff --git a/node_modules/semver/functions/compare-loose.js b/node_modules/semver/functions/compare-loose.js new file mode 100644 index 0000000..7531634 --- /dev/null +++ b/node_modules/semver/functions/compare-loose.js @@ -0,0 +1,5 @@ +'use strict' + +const compare = require('./compare') +const compareLoose = (a, b) => compare(a, b, true) +module.exports = compareLoose diff --git a/node_modules/semver/functions/compare.js b/node_modules/semver/functions/compare.js new file mode 100644 index 0000000..63d8090 --- /dev/null +++ b/node_modules/semver/functions/compare.js @@ -0,0 +1,7 @@ +'use strict' + +const SemVer = require('../classes/semver') +const compare = (a, b, loose) => + new SemVer(a, loose).compare(new SemVer(b, loose)) + +module.exports = compare diff --git a/node_modules/semver/functions/diff.js b/node_modules/semver/functions/diff.js new file mode 100644 index 0000000..04e064e --- /dev/null +++ b/node_modules/semver/functions/diff.js @@ -0,0 +1,60 @@ +'use strict' + +const parse = require('./parse.js') + +const diff = (version1, version2) => { + const v1 = parse(version1, null, true) + const v2 = parse(version2, null, true) + const comparison = v1.compare(v2) + + if (comparison === 0) { + return null + } + + const v1Higher = comparison > 0 + const highVersion = v1Higher ? v1 : v2 + const lowVersion = v1Higher ? v2 : v1 + const highHasPre = !!highVersion.prerelease.length + const lowHasPre = !!lowVersion.prerelease.length + + if (lowHasPre && !highHasPre) { + // Going from prerelease -> no prerelease requires some special casing + + // If the low version has only a major, then it will always be a major + // Some examples: + // 1.0.0-1 -> 1.0.0 + // 1.0.0-1 -> 1.1.1 + // 1.0.0-1 -> 2.0.0 + if (!lowVersion.patch && !lowVersion.minor) { + return 'major' + } + + // If the main part has no difference + if (lowVersion.compareMain(highVersion) === 0) { + if (lowVersion.minor && !lowVersion.patch) { + return 'minor' + } + return 'patch' + } + } + + // add the `pre` prefix if we are going to a prerelease version + const prefix = highHasPre ? 'pre' : '' + + if (v1.major !== v2.major) { + return prefix + 'major' + } + + if (v1.minor !== v2.minor) { + return prefix + 'minor' + } + + if (v1.patch !== v2.patch) { + return prefix + 'patch' + } + + // high and low are preleases + return 'prerelease' +} + +module.exports = diff diff --git a/node_modules/semver/functions/eq.js b/node_modules/semver/functions/eq.js new file mode 100644 index 0000000..5f0eead --- /dev/null +++ b/node_modules/semver/functions/eq.js @@ -0,0 +1,5 @@ +'use strict' + +const compare = require('./compare') +const eq = (a, b, loose) => compare(a, b, loose) === 0 +module.exports = eq diff --git a/node_modules/semver/functions/gt.js b/node_modules/semver/functions/gt.js new file mode 100644 index 0000000..84a57dd --- /dev/null +++ b/node_modules/semver/functions/gt.js @@ -0,0 +1,5 @@ +'use strict' + +const compare = require('./compare') +const gt = (a, b, loose) => compare(a, b, loose) > 0 +module.exports = gt diff --git a/node_modules/semver/functions/gte.js b/node_modules/semver/functions/gte.js new file mode 100644 index 0000000..7c52bdf --- /dev/null +++ b/node_modules/semver/functions/gte.js @@ -0,0 +1,5 @@ +'use strict' + +const compare = require('./compare') +const gte = (a, b, loose) => compare(a, b, loose) >= 0 +module.exports = gte diff --git a/node_modules/semver/functions/inc.js b/node_modules/semver/functions/inc.js new file mode 100644 index 0000000..ff999e9 --- /dev/null +++ b/node_modules/semver/functions/inc.js @@ -0,0 +1,21 @@ +'use strict' + +const SemVer = require('../classes/semver') + +const inc = (version, release, options, identifier, identifierBase) => { + if (typeof (options) === 'string') { + identifierBase = identifier + identifier = options + options = undefined + } + + try { + return new SemVer( + version instanceof SemVer ? version.version : version, + options + ).inc(release, identifier, identifierBase).version + } catch (er) { + return null + } +} +module.exports = inc diff --git a/node_modules/semver/functions/lt.js b/node_modules/semver/functions/lt.js new file mode 100644 index 0000000..2fb32a0 --- /dev/null +++ b/node_modules/semver/functions/lt.js @@ -0,0 +1,5 @@ +'use strict' + +const compare = require('./compare') +const lt = (a, b, loose) => compare(a, b, loose) < 0 +module.exports = lt diff --git a/node_modules/semver/functions/lte.js b/node_modules/semver/functions/lte.js new file mode 100644 index 0000000..da9ee8f --- /dev/null +++ b/node_modules/semver/functions/lte.js @@ -0,0 +1,5 @@ +'use strict' + +const compare = require('./compare') +const lte = (a, b, loose) => compare(a, b, loose) <= 0 +module.exports = lte diff --git a/node_modules/semver/functions/major.js b/node_modules/semver/functions/major.js new file mode 100644 index 0000000..e6d08dc --- /dev/null +++ b/node_modules/semver/functions/major.js @@ -0,0 +1,5 @@ +'use strict' + +const SemVer = require('../classes/semver') +const major = (a, loose) => new SemVer(a, loose).major +module.exports = major diff --git a/node_modules/semver/functions/minor.js b/node_modules/semver/functions/minor.js new file mode 100644 index 0000000..9e70ffd --- /dev/null +++ b/node_modules/semver/functions/minor.js @@ -0,0 +1,5 @@ +'use strict' + +const SemVer = require('../classes/semver') +const minor = (a, loose) => new SemVer(a, loose).minor +module.exports = minor diff --git a/node_modules/semver/functions/neq.js b/node_modules/semver/functions/neq.js new file mode 100644 index 0000000..84326b7 --- /dev/null +++ b/node_modules/semver/functions/neq.js @@ -0,0 +1,5 @@ +'use strict' + +const compare = require('./compare') +const neq = (a, b, loose) => compare(a, b, loose) !== 0 +module.exports = neq diff --git a/node_modules/semver/functions/parse.js b/node_modules/semver/functions/parse.js new file mode 100644 index 0000000..d544d33 --- /dev/null +++ b/node_modules/semver/functions/parse.js @@ -0,0 +1,18 @@ +'use strict' + +const SemVer = require('../classes/semver') +const parse = (version, options, throwErrors = false) => { + if (version instanceof SemVer) { + return version + } + try { + return new SemVer(version, options) + } catch (er) { + if (!throwErrors) { + return null + } + throw er + } +} + +module.exports = parse diff --git a/node_modules/semver/functions/patch.js b/node_modules/semver/functions/patch.js new file mode 100644 index 0000000..7675162 --- /dev/null +++ b/node_modules/semver/functions/patch.js @@ -0,0 +1,5 @@ +'use strict' + +const SemVer = require('../classes/semver') +const patch = (a, loose) => new SemVer(a, loose).patch +module.exports = patch diff --git a/node_modules/semver/functions/prerelease.js b/node_modules/semver/functions/prerelease.js new file mode 100644 index 0000000..b8fe1db --- /dev/null +++ b/node_modules/semver/functions/prerelease.js @@ -0,0 +1,8 @@ +'use strict' + +const parse = require('./parse') +const prerelease = (version, options) => { + const parsed = parse(version, options) + return (parsed && parsed.prerelease.length) ? parsed.prerelease : null +} +module.exports = prerelease diff --git a/node_modules/semver/functions/rcompare.js b/node_modules/semver/functions/rcompare.js new file mode 100644 index 0000000..8e1c222 --- /dev/null +++ b/node_modules/semver/functions/rcompare.js @@ -0,0 +1,5 @@ +'use strict' + +const compare = require('./compare') +const rcompare = (a, b, loose) => compare(b, a, loose) +module.exports = rcompare diff --git a/node_modules/semver/functions/rsort.js b/node_modules/semver/functions/rsort.js new file mode 100644 index 0000000..5d3d200 --- /dev/null +++ b/node_modules/semver/functions/rsort.js @@ -0,0 +1,5 @@ +'use strict' + +const compareBuild = require('./compare-build') +const rsort = (list, loose) => list.sort((a, b) => compareBuild(b, a, loose)) +module.exports = rsort diff --git a/node_modules/semver/functions/satisfies.js b/node_modules/semver/functions/satisfies.js new file mode 100644 index 0000000..a0264a2 --- /dev/null +++ b/node_modules/semver/functions/satisfies.js @@ -0,0 +1,12 @@ +'use strict' + +const Range = require('../classes/range') +const satisfies = (version, range, options) => { + try { + range = new Range(range, options) + } catch (er) { + return false + } + return range.test(version) +} +module.exports = satisfies diff --git a/node_modules/semver/functions/sort.js b/node_modules/semver/functions/sort.js new file mode 100644 index 0000000..edb24b1 --- /dev/null +++ b/node_modules/semver/functions/sort.js @@ -0,0 +1,5 @@ +'use strict' + +const compareBuild = require('./compare-build') +const sort = (list, loose) => list.sort((a, b) => compareBuild(a, b, loose)) +module.exports = sort diff --git a/node_modules/semver/functions/valid.js b/node_modules/semver/functions/valid.js new file mode 100644 index 0000000..0db67ed --- /dev/null +++ b/node_modules/semver/functions/valid.js @@ -0,0 +1,8 @@ +'use strict' + +const parse = require('./parse') +const valid = (version, options) => { + const v = parse(version, options) + return v ? v.version : null +} +module.exports = valid diff --git a/node_modules/semver/index.js b/node_modules/semver/index.js new file mode 100644 index 0000000..285662a --- /dev/null +++ b/node_modules/semver/index.js @@ -0,0 +1,91 @@ +'use strict' + +// just pre-load all the stuff that index.js lazily exports +const internalRe = require('./internal/re') +const constants = require('./internal/constants') +const SemVer = require('./classes/semver') +const identifiers = require('./internal/identifiers') +const parse = require('./functions/parse') +const valid = require('./functions/valid') +const clean = require('./functions/clean') +const inc = require('./functions/inc') +const diff = require('./functions/diff') +const major = require('./functions/major') +const minor = require('./functions/minor') +const patch = require('./functions/patch') +const prerelease = require('./functions/prerelease') +const compare = require('./functions/compare') +const rcompare = require('./functions/rcompare') +const compareLoose = require('./functions/compare-loose') +const compareBuild = require('./functions/compare-build') +const sort = require('./functions/sort') +const rsort = require('./functions/rsort') +const gt = require('./functions/gt') +const lt = require('./functions/lt') +const eq = require('./functions/eq') +const neq = require('./functions/neq') +const gte = require('./functions/gte') +const lte = require('./functions/lte') +const cmp = require('./functions/cmp') +const coerce = require('./functions/coerce') +const Comparator = require('./classes/comparator') +const Range = require('./classes/range') +const satisfies = require('./functions/satisfies') +const toComparators = require('./ranges/to-comparators') +const maxSatisfying = require('./ranges/max-satisfying') +const minSatisfying = require('./ranges/min-satisfying') +const minVersion = require('./ranges/min-version') +const validRange = require('./ranges/valid') +const outside = require('./ranges/outside') +const gtr = require('./ranges/gtr') +const ltr = require('./ranges/ltr') +const intersects = require('./ranges/intersects') +const simplifyRange = require('./ranges/simplify') +const subset = require('./ranges/subset') +module.exports = { + parse, + valid, + clean, + inc, + diff, + major, + minor, + patch, + prerelease, + compare, + rcompare, + compareLoose, + compareBuild, + sort, + rsort, + gt, + lt, + eq, + neq, + gte, + lte, + cmp, + coerce, + Comparator, + Range, + satisfies, + toComparators, + maxSatisfying, + minSatisfying, + minVersion, + validRange, + outside, + gtr, + ltr, + intersects, + simplifyRange, + subset, + SemVer, + re: internalRe.re, + src: internalRe.src, + tokens: internalRe.t, + SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION, + RELEASE_TYPES: constants.RELEASE_TYPES, + compareIdentifiers: identifiers.compareIdentifiers, + rcompareIdentifiers: identifiers.rcompareIdentifiers, +} diff --git a/node_modules/semver/internal/constants.js b/node_modules/semver/internal/constants.js new file mode 100644 index 0000000..6d1db91 --- /dev/null +++ b/node_modules/semver/internal/constants.js @@ -0,0 +1,37 @@ +'use strict' + +// Note: this is the semver.org version of the spec that it implements +// Not necessarily the package version of this code. +const SEMVER_SPEC_VERSION = '2.0.0' + +const MAX_LENGTH = 256 +const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || +/* istanbul ignore next */ 9007199254740991 + +// Max safe segment length for coercion. +const MAX_SAFE_COMPONENT_LENGTH = 16 + +// Max safe length for a build identifier. The max length minus 6 characters for +// the shortest version with a build 0.0.0+BUILD. +const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6 + +const RELEASE_TYPES = [ + 'major', + 'premajor', + 'minor', + 'preminor', + 'patch', + 'prepatch', + 'prerelease', +] + +module.exports = { + MAX_LENGTH, + MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, + MAX_SAFE_INTEGER, + RELEASE_TYPES, + SEMVER_SPEC_VERSION, + FLAG_INCLUDE_PRERELEASE: 0b001, + FLAG_LOOSE: 0b010, +} diff --git a/node_modules/semver/internal/debug.js b/node_modules/semver/internal/debug.js new file mode 100644 index 0000000..20d1e9d --- /dev/null +++ b/node_modules/semver/internal/debug.js @@ -0,0 +1,11 @@ +'use strict' + +const debug = ( + typeof process === 'object' && + process.env && + process.env.NODE_DEBUG && + /\bsemver\b/i.test(process.env.NODE_DEBUG) +) ? (...args) => console.error('SEMVER', ...args) + : () => {} + +module.exports = debug diff --git a/node_modules/semver/internal/identifiers.js b/node_modules/semver/internal/identifiers.js new file mode 100644 index 0000000..d053472 --- /dev/null +++ b/node_modules/semver/internal/identifiers.js @@ -0,0 +1,29 @@ +'use strict' + +const numeric = /^[0-9]+$/ +const compareIdentifiers = (a, b) => { + if (typeof a === 'number' && typeof b === 'number') { + return a === b ? 0 : a < b ? -1 : 1 + } + + const anum = numeric.test(a) + const bnum = numeric.test(b) + + if (anum && bnum) { + a = +a + b = +b + } + + return a === b ? 0 + : (anum && !bnum) ? -1 + : (bnum && !anum) ? 1 + : a < b ? -1 + : 1 +} + +const rcompareIdentifiers = (a, b) => compareIdentifiers(b, a) + +module.exports = { + compareIdentifiers, + rcompareIdentifiers, +} diff --git a/node_modules/semver/internal/lrucache.js b/node_modules/semver/internal/lrucache.js new file mode 100644 index 0000000..b8bf526 --- /dev/null +++ b/node_modules/semver/internal/lrucache.js @@ -0,0 +1,42 @@ +'use strict' + +class LRUCache { + constructor () { + this.max = 1000 + this.map = new Map() + } + + get (key) { + const value = this.map.get(key) + if (value === undefined) { + return undefined + } else { + // Remove the key from the map and add it to the end + this.map.delete(key) + this.map.set(key, value) + return value + } + } + + delete (key) { + return this.map.delete(key) + } + + set (key, value) { + const deleted = this.delete(key) + + if (!deleted && value !== undefined) { + // If cache is full, delete the least recently used item + if (this.map.size >= this.max) { + const firstKey = this.map.keys().next().value + this.delete(firstKey) + } + + this.map.set(key, value) + } + + return this + } +} + +module.exports = LRUCache diff --git a/node_modules/semver/internal/parse-options.js b/node_modules/semver/internal/parse-options.js new file mode 100644 index 0000000..5295454 --- /dev/null +++ b/node_modules/semver/internal/parse-options.js @@ -0,0 +1,17 @@ +'use strict' + +// parse out just the options we care about +const looseOption = Object.freeze({ loose: true }) +const emptyOpts = Object.freeze({ }) +const parseOptions = options => { + if (!options) { + return emptyOpts + } + + if (typeof options !== 'object') { + return looseOption + } + + return options +} +module.exports = parseOptions diff --git a/node_modules/semver/internal/re.js b/node_modules/semver/internal/re.js new file mode 100644 index 0000000..4758c58 --- /dev/null +++ b/node_modules/semver/internal/re.js @@ -0,0 +1,223 @@ +'use strict' + +const { + MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, + MAX_LENGTH, +} = require('./constants') +const debug = require('./debug') +exports = module.exports = {} + +// The actual regexps go on exports.re +const re = exports.re = [] +const safeRe = exports.safeRe = [] +const src = exports.src = [] +const safeSrc = exports.safeSrc = [] +const t = exports.t = {} +let R = 0 + +const LETTERDASHNUMBER = '[a-zA-Z0-9-]' + +// Replace some greedy regex tokens to prevent regex dos issues. These regex are +// used internally via the safeRe object since all inputs in this library get +// normalized first to trim and collapse all extra whitespace. The original +// regexes are exported for userland consumption and lower level usage. A +// future breaking change could export the safer regex only with a note that +// all input should have extra whitespace removed. +const safeRegexReplacements = [ + ['\\s', 1], + ['\\d', MAX_LENGTH], + [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH], +] + +const makeSafeRegex = (value) => { + for (const [token, max] of safeRegexReplacements) { + value = value + .split(`${token}*`).join(`${token}{0,${max}}`) + .split(`${token}+`).join(`${token}{1,${max}}`) + } + return value +} + +const createToken = (name, value, isGlobal) => { + const safe = makeSafeRegex(value) + const index = R++ + debug(name, index, value) + t[name] = index + src[index] = value + safeSrc[index] = safe + re[index] = new RegExp(value, isGlobal ? 'g' : undefined) + safeRe[index] = new RegExp(safe, isGlobal ? 'g' : undefined) +} + +// The following Regular Expressions can be used for tokenizing, +// validating, and parsing SemVer version strings. + +// ## Numeric Identifier +// A single `0`, or a non-zero digit followed by zero or more digits. + +createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*') +createToken('NUMERICIDENTIFIERLOOSE', '\\d+') + +// ## Non-numeric Identifier +// Zero or more digits, followed by a letter or hyphen, and then zero or +// more letters, digits, or hyphens. + +createToken('NONNUMERICIDENTIFIER', `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`) + +// ## Main Version +// Three dot-separated numeric identifiers. + +createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` + + `(${src[t.NUMERICIDENTIFIER]})\\.` + + `(${src[t.NUMERICIDENTIFIER]})`) + +createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + + `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + + `(${src[t.NUMERICIDENTIFIERLOOSE]})`) + +// ## Pre-release Version Identifier +// A numeric identifier, or a non-numeric identifier. +// Non-numberic identifiers include numberic identifiers but can be longer. +// Therefore non-numberic identifiers must go first. + +createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NONNUMERICIDENTIFIER] +}|${src[t.NUMERICIDENTIFIER]})`) + +createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NONNUMERICIDENTIFIER] +}|${src[t.NUMERICIDENTIFIERLOOSE]})`) + +// ## Pre-release Version +// Hyphen, followed by one or more dot-separated pre-release version +// identifiers. + +createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER] +}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`) + +createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE] +}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`) + +// ## Build Metadata Identifier +// Any combination of digits, letters, or hyphens. + +createToken('BUILDIDENTIFIER', `${LETTERDASHNUMBER}+`) + +// ## Build Metadata +// Plus sign, followed by one or more period-separated build metadata +// identifiers. + +createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER] +}(?:\\.${src[t.BUILDIDENTIFIER]})*))`) + +// ## Full Version String +// A main version, followed optionally by a pre-release version and +// build metadata. + +// Note that the only major, minor, patch, and pre-release sections of +// the version string are capturing groups. The build metadata is not a +// capturing group, because it should not ever be used in version +// comparison. + +createToken('FULLPLAIN', `v?${src[t.MAINVERSION] +}${src[t.PRERELEASE]}?${ + src[t.BUILD]}?`) + +createToken('FULL', `^${src[t.FULLPLAIN]}$`) + +// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. +// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty +// common in the npm registry. +createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE] +}${src[t.PRERELEASELOOSE]}?${ + src[t.BUILD]}?`) + +createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`) + +createToken('GTLT', '((?:<|>)?=?)') + +// Something like "2.*" or "1.2.x". +// Note that "x.x" is a valid xRange identifer, meaning "any version" +// Only the first item is strictly required. +createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`) +createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`) + +createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` + + `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + + `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + + `(?:${src[t.PRERELEASE]})?${ + src[t.BUILD]}?` + + `)?)?`) + +createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` + + `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + + `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + + `(?:${src[t.PRERELEASELOOSE]})?${ + src[t.BUILD]}?` + + `)?)?`) + +createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`) +createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`) + +// Coercion. +// Extract anything that could conceivably be a part of a valid semver +createToken('COERCEPLAIN', `${'(^|[^\\d])' + + '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` + + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + + `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`) +createToken('COERCE', `${src[t.COERCEPLAIN]}(?:$|[^\\d])`) +createToken('COERCEFULL', src[t.COERCEPLAIN] + + `(?:${src[t.PRERELEASE]})?` + + `(?:${src[t.BUILD]})?` + + `(?:$|[^\\d])`) +createToken('COERCERTL', src[t.COERCE], true) +createToken('COERCERTLFULL', src[t.COERCEFULL], true) + +// Tilde ranges. +// Meaning is "reasonably at or greater than" +createToken('LONETILDE', '(?:~>?)') + +createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true) +exports.tildeTrimReplace = '$1~' + +createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`) +createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`) + +// Caret ranges. +// Meaning is "at least and backwards compatible with" +createToken('LONECARET', '(?:\\^)') + +createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true) +exports.caretTrimReplace = '$1^' + +createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`) +createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`) + +// A simple gt/lt/eq thing, or just "" to indicate "any version" +createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`) +createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`) + +// An expression to strip any whitespace between the gtlt and the thing +// it modifies, so that `> 1.2.3` ==> `>1.2.3` +createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT] +}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true) +exports.comparatorTrimReplace = '$1$2$3' + +// Something like `1.2.3 - 1.2.4` +// Note that these all use the loose form, because they'll be +// checked against either the strict or loose comparator form +// later. +createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` + + `\\s+-\\s+` + + `(${src[t.XRANGEPLAIN]})` + + `\\s*$`) + +createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` + + `\\s+-\\s+` + + `(${src[t.XRANGEPLAINLOOSE]})` + + `\\s*$`) + +// Star ranges basically just allow anything at all. +createToken('STAR', '(<|>)?=?\\s*\\*') +// >=0.0.0 is like a star +createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$') +createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$') diff --git a/node_modules/semver/package.json b/node_modules/semver/package.json new file mode 100644 index 0000000..2b8cada --- /dev/null +++ b/node_modules/semver/package.json @@ -0,0 +1,78 @@ +{ + "name": "semver", + "version": "7.7.3", + "description": "The semantic version parser used by npm.", + "main": "index.js", + "scripts": { + "test": "tap", + "snap": "tap", + "lint": "npm run eslint", + "postlint": "template-oss-check", + "lintfix": "npm run eslint -- --fix", + "posttest": "npm run lint", + "template-oss-apply": "template-oss-apply --force", + "eslint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"" + }, + "devDependencies": { + "@npmcli/eslint-config": "^5.0.0", + "@npmcli/template-oss": "4.25.1", + "benchmark": "^2.1.4", + "tap": "^16.0.0" + }, + "license": "ISC", + "repository": { + "type": "git", + "url": "git+https://github.com/npm/node-semver.git" + }, + "bin": { + "semver": "bin/semver.js" + }, + "files": [ + "bin/", + "lib/", + "classes/", + "functions/", + "internal/", + "ranges/", + "index.js", + "preload.js", + "range.bnf" + ], + "tap": { + "timeout": 30, + "coverage-map": "map.js", + "nyc-arg": [ + "--exclude", + "tap-snapshots/**" + ] + }, + "engines": { + "node": ">=10" + }, + "author": "GitHub Inc.", + "templateOSS": { + "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.", + "version": "4.25.1", + "engines": ">=10", + "distPaths": [ + "classes/", + "functions/", + "internal/", + "ranges/", + "index.js", + "preload.js", + "range.bnf" + ], + "allowPaths": [ + "/classes/", + "/functions/", + "/internal/", + "/ranges/", + "/index.js", + "/preload.js", + "/range.bnf", + "/benchmarks" + ], + "publish": "true" + } +} diff --git a/node_modules/semver/preload.js b/node_modules/semver/preload.js new file mode 100644 index 0000000..e6c47b9 --- /dev/null +++ b/node_modules/semver/preload.js @@ -0,0 +1,4 @@ +'use strict' + +// XXX remove in v8 or beyond +module.exports = require('./index.js') diff --git a/node_modules/semver/range.bnf b/node_modules/semver/range.bnf new file mode 100644 index 0000000..d4c6ae0 --- /dev/null +++ b/node_modules/semver/range.bnf @@ -0,0 +1,16 @@ +range-set ::= range ( logical-or range ) * +logical-or ::= ( ' ' ) * '||' ( ' ' ) * +range ::= hyphen | simple ( ' ' simple ) * | '' +hyphen ::= partial ' - ' partial +simple ::= primitive | partial | tilde | caret +primitive ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial +partial ::= xr ( '.' xr ( '.' xr qualifier ? )? )? +xr ::= 'x' | 'X' | '*' | nr +nr ::= '0' | [1-9] ( [0-9] ) * +tilde ::= '~' partial +caret ::= '^' partial +qualifier ::= ( '-' pre )? ( '+' build )? +pre ::= parts +build ::= parts +parts ::= part ( '.' part ) * +part ::= nr | [-0-9A-Za-z]+ diff --git a/node_modules/semver/ranges/gtr.js b/node_modules/semver/ranges/gtr.js new file mode 100644 index 0000000..0e7601f --- /dev/null +++ b/node_modules/semver/ranges/gtr.js @@ -0,0 +1,6 @@ +'use strict' + +// Determine if version is greater than all the versions possible in the range. +const outside = require('./outside') +const gtr = (version, range, options) => outside(version, range, '>', options) +module.exports = gtr diff --git a/node_modules/semver/ranges/intersects.js b/node_modules/semver/ranges/intersects.js new file mode 100644 index 0000000..917be7e --- /dev/null +++ b/node_modules/semver/ranges/intersects.js @@ -0,0 +1,9 @@ +'use strict' + +const Range = require('../classes/range') +const intersects = (r1, r2, options) => { + r1 = new Range(r1, options) + r2 = new Range(r2, options) + return r1.intersects(r2, options) +} +module.exports = intersects diff --git a/node_modules/semver/ranges/ltr.js b/node_modules/semver/ranges/ltr.js new file mode 100644 index 0000000..aa5e568 --- /dev/null +++ b/node_modules/semver/ranges/ltr.js @@ -0,0 +1,6 @@ +'use strict' + +const outside = require('./outside') +// Determine if version is less than all the versions possible in the range +const ltr = (version, range, options) => outside(version, range, '<', options) +module.exports = ltr diff --git a/node_modules/semver/ranges/max-satisfying.js b/node_modules/semver/ranges/max-satisfying.js new file mode 100644 index 0000000..01fe5ae --- /dev/null +++ b/node_modules/semver/ranges/max-satisfying.js @@ -0,0 +1,27 @@ +'use strict' + +const SemVer = require('../classes/semver') +const Range = require('../classes/range') + +const maxSatisfying = (versions, range, options) => { + let max = null + let maxSV = null + let rangeObj = null + try { + rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach((v) => { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!max || maxSV.compare(v) === -1) { + // compare(max, v, true) + max = v + maxSV = new SemVer(max, options) + } + } + }) + return max +} +module.exports = maxSatisfying diff --git a/node_modules/semver/ranges/min-satisfying.js b/node_modules/semver/ranges/min-satisfying.js new file mode 100644 index 0000000..af89c8e --- /dev/null +++ b/node_modules/semver/ranges/min-satisfying.js @@ -0,0 +1,26 @@ +'use strict' + +const SemVer = require('../classes/semver') +const Range = require('../classes/range') +const minSatisfying = (versions, range, options) => { + let min = null + let minSV = null + let rangeObj = null + try { + rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach((v) => { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!min || minSV.compare(v) === 1) { + // compare(min, v, true) + min = v + minSV = new SemVer(min, options) + } + } + }) + return min +} +module.exports = minSatisfying diff --git a/node_modules/semver/ranges/min-version.js b/node_modules/semver/ranges/min-version.js new file mode 100644 index 0000000..09a65aa --- /dev/null +++ b/node_modules/semver/ranges/min-version.js @@ -0,0 +1,63 @@ +'use strict' + +const SemVer = require('../classes/semver') +const Range = require('../classes/range') +const gt = require('../functions/gt') + +const minVersion = (range, loose) => { + range = new Range(range, loose) + + let minver = new SemVer('0.0.0') + if (range.test(minver)) { + return minver + } + + minver = new SemVer('0.0.0-0') + if (range.test(minver)) { + return minver + } + + minver = null + for (let i = 0; i < range.set.length; ++i) { + const comparators = range.set[i] + + let setMin = null + comparators.forEach((comparator) => { + // Clone to avoid manipulating the comparator's semver object. + const compver = new SemVer(comparator.semver.version) + switch (comparator.operator) { + case '>': + if (compver.prerelease.length === 0) { + compver.patch++ + } else { + compver.prerelease.push(0) + } + compver.raw = compver.format() + /* fallthrough */ + case '': + case '>=': + if (!setMin || gt(compver, setMin)) { + setMin = compver + } + break + case '<': + case '<=': + /* Ignore maximum versions */ + break + /* istanbul ignore next */ + default: + throw new Error(`Unexpected operation: ${comparator.operator}`) + } + }) + if (setMin && (!minver || gt(minver, setMin))) { + minver = setMin + } + } + + if (minver && range.test(minver)) { + return minver + } + + return null +} +module.exports = minVersion diff --git a/node_modules/semver/ranges/outside.js b/node_modules/semver/ranges/outside.js new file mode 100644 index 0000000..ca74421 --- /dev/null +++ b/node_modules/semver/ranges/outside.js @@ -0,0 +1,82 @@ +'use strict' + +const SemVer = require('../classes/semver') +const Comparator = require('../classes/comparator') +const { ANY } = Comparator +const Range = require('../classes/range') +const satisfies = require('../functions/satisfies') +const gt = require('../functions/gt') +const lt = require('../functions/lt') +const lte = require('../functions/lte') +const gte = require('../functions/gte') + +const outside = (version, range, hilo, options) => { + version = new SemVer(version, options) + range = new Range(range, options) + + let gtfn, ltefn, ltfn, comp, ecomp + switch (hilo) { + case '>': + gtfn = gt + ltefn = lte + ltfn = lt + comp = '>' + ecomp = '>=' + break + case '<': + gtfn = lt + ltefn = gte + ltfn = gt + comp = '<' + ecomp = '<=' + break + default: + throw new TypeError('Must provide a hilo val of "<" or ">"') + } + + // If it satisfies the range it is not outside + if (satisfies(version, range, options)) { + return false + } + + // From now on, variable terms are as if we're in "gtr" mode. + // but note that everything is flipped for the "ltr" function. + + for (let i = 0; i < range.set.length; ++i) { + const comparators = range.set[i] + + let high = null + let low = null + + comparators.forEach((comparator) => { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0') + } + high = high || comparator + low = low || comparator + if (gtfn(comparator.semver, high.semver, options)) { + high = comparator + } else if (ltfn(comparator.semver, low.semver, options)) { + low = comparator + } + }) + + // If the edge version comparator has a operator then our version + // isn't outside it + if (high.operator === comp || high.operator === ecomp) { + return false + } + + // If the lowest version comparator has an operator and our version + // is less than it then it isn't higher than the range + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false + } + } + return true +} + +module.exports = outside diff --git a/node_modules/semver/ranges/simplify.js b/node_modules/semver/ranges/simplify.js new file mode 100644 index 0000000..262732e --- /dev/null +++ b/node_modules/semver/ranges/simplify.js @@ -0,0 +1,49 @@ +'use strict' + +// given a set of versions and a range, create a "simplified" range +// that includes the same versions that the original range does +// If the original range is shorter than the simplified one, return that. +const satisfies = require('../functions/satisfies.js') +const compare = require('../functions/compare.js') +module.exports = (versions, range, options) => { + const set = [] + let first = null + let prev = null + const v = versions.sort((a, b) => compare(a, b, options)) + for (const version of v) { + const included = satisfies(version, range, options) + if (included) { + prev = version + if (!first) { + first = version + } + } else { + if (prev) { + set.push([first, prev]) + } + prev = null + first = null + } + } + if (first) { + set.push([first, null]) + } + + const ranges = [] + for (const [min, max] of set) { + if (min === max) { + ranges.push(min) + } else if (!max && min === v[0]) { + ranges.push('*') + } else if (!max) { + ranges.push(`>=${min}`) + } else if (min === v[0]) { + ranges.push(`<=${max}`) + } else { + ranges.push(`${min} - ${max}`) + } + } + const simplified = ranges.join(' || ') + const original = typeof range.raw === 'string' ? range.raw : String(range) + return simplified.length < original.length ? simplified : range +} diff --git a/node_modules/semver/ranges/subset.js b/node_modules/semver/ranges/subset.js new file mode 100644 index 0000000..2c49aef --- /dev/null +++ b/node_modules/semver/ranges/subset.js @@ -0,0 +1,249 @@ +'use strict' + +const Range = require('../classes/range.js') +const Comparator = require('../classes/comparator.js') +const { ANY } = Comparator +const satisfies = require('../functions/satisfies.js') +const compare = require('../functions/compare.js') + +// Complex range `r1 || r2 || ...` is a subset of `R1 || R2 || ...` iff: +// - Every simple range `r1, r2, ...` is a null set, OR +// - Every simple range `r1, r2, ...` which is not a null set is a subset of +// some `R1, R2, ...` +// +// Simple range `c1 c2 ...` is a subset of simple range `C1 C2 ...` iff: +// - If c is only the ANY comparator +// - If C is only the ANY comparator, return true +// - Else if in prerelease mode, return false +// - else replace c with `[>=0.0.0]` +// - If C is only the ANY comparator +// - if in prerelease mode, return true +// - else replace C with `[>=0.0.0]` +// - Let EQ be the set of = comparators in c +// - If EQ is more than one, return true (null set) +// - Let GT be the highest > or >= comparator in c +// - Let LT be the lowest < or <= comparator in c +// - If GT and LT, and GT.semver > LT.semver, return true (null set) +// - If any C is a = range, and GT or LT are set, return false +// - If EQ +// - If GT, and EQ does not satisfy GT, return true (null set) +// - If LT, and EQ does not satisfy LT, return true (null set) +// - If EQ satisfies every C, return true +// - Else return false +// - If GT +// - If GT.semver is lower than any > or >= comp in C, return false +// - If GT is >=, and GT.semver does not satisfy every C, return false +// - If GT.semver has a prerelease, and not in prerelease mode +// - If no C has a prerelease and the GT.semver tuple, return false +// - If LT +// - If LT.semver is greater than any < or <= comp in C, return false +// - If LT is <=, and LT.semver does not satisfy every C, return false +// - If GT.semver has a prerelease, and not in prerelease mode +// - If no C has a prerelease and the LT.semver tuple, return false +// - Else return true + +const subset = (sub, dom, options = {}) => { + if (sub === dom) { + return true + } + + sub = new Range(sub, options) + dom = new Range(dom, options) + let sawNonNull = false + + OUTER: for (const simpleSub of sub.set) { + for (const simpleDom of dom.set) { + const isSub = simpleSubset(simpleSub, simpleDom, options) + sawNonNull = sawNonNull || isSub !== null + if (isSub) { + continue OUTER + } + } + // the null set is a subset of everything, but null simple ranges in + // a complex range should be ignored. so if we saw a non-null range, + // then we know this isn't a subset, but if EVERY simple range was null, + // then it is a subset. + if (sawNonNull) { + return false + } + } + return true +} + +const minimumVersionWithPreRelease = [new Comparator('>=0.0.0-0')] +const minimumVersion = [new Comparator('>=0.0.0')] + +const simpleSubset = (sub, dom, options) => { + if (sub === dom) { + return true + } + + if (sub.length === 1 && sub[0].semver === ANY) { + if (dom.length === 1 && dom[0].semver === ANY) { + return true + } else if (options.includePrerelease) { + sub = minimumVersionWithPreRelease + } else { + sub = minimumVersion + } + } + + if (dom.length === 1 && dom[0].semver === ANY) { + if (options.includePrerelease) { + return true + } else { + dom = minimumVersion + } + } + + const eqSet = new Set() + let gt, lt + for (const c of sub) { + if (c.operator === '>' || c.operator === '>=') { + gt = higherGT(gt, c, options) + } else if (c.operator === '<' || c.operator === '<=') { + lt = lowerLT(lt, c, options) + } else { + eqSet.add(c.semver) + } + } + + if (eqSet.size > 1) { + return null + } + + let gtltComp + if (gt && lt) { + gtltComp = compare(gt.semver, lt.semver, options) + if (gtltComp > 0) { + return null + } else if (gtltComp === 0 && (gt.operator !== '>=' || lt.operator !== '<=')) { + return null + } + } + + // will iterate one or zero times + for (const eq of eqSet) { + if (gt && !satisfies(eq, String(gt), options)) { + return null + } + + if (lt && !satisfies(eq, String(lt), options)) { + return null + } + + for (const c of dom) { + if (!satisfies(eq, String(c), options)) { + return false + } + } + + return true + } + + let higher, lower + let hasDomLT, hasDomGT + // if the subset has a prerelease, we need a comparator in the superset + // with the same tuple and a prerelease, or it's not a subset + let needDomLTPre = lt && + !options.includePrerelease && + lt.semver.prerelease.length ? lt.semver : false + let needDomGTPre = gt && + !options.includePrerelease && + gt.semver.prerelease.length ? gt.semver : false + // exception: <1.2.3-0 is the same as <1.2.3 + if (needDomLTPre && needDomLTPre.prerelease.length === 1 && + lt.operator === '<' && needDomLTPre.prerelease[0] === 0) { + needDomLTPre = false + } + + for (const c of dom) { + hasDomGT = hasDomGT || c.operator === '>' || c.operator === '>=' + hasDomLT = hasDomLT || c.operator === '<' || c.operator === '<=' + if (gt) { + if (needDomGTPre) { + if (c.semver.prerelease && c.semver.prerelease.length && + c.semver.major === needDomGTPre.major && + c.semver.minor === needDomGTPre.minor && + c.semver.patch === needDomGTPre.patch) { + needDomGTPre = false + } + } + if (c.operator === '>' || c.operator === '>=') { + higher = higherGT(gt, c, options) + if (higher === c && higher !== gt) { + return false + } + } else if (gt.operator === '>=' && !satisfies(gt.semver, String(c), options)) { + return false + } + } + if (lt) { + if (needDomLTPre) { + if (c.semver.prerelease && c.semver.prerelease.length && + c.semver.major === needDomLTPre.major && + c.semver.minor === needDomLTPre.minor && + c.semver.patch === needDomLTPre.patch) { + needDomLTPre = false + } + } + if (c.operator === '<' || c.operator === '<=') { + lower = lowerLT(lt, c, options) + if (lower === c && lower !== lt) { + return false + } + } else if (lt.operator === '<=' && !satisfies(lt.semver, String(c), options)) { + return false + } + } + if (!c.operator && (lt || gt) && gtltComp !== 0) { + return false + } + } + + // if there was a < or >, and nothing in the dom, then must be false + // UNLESS it was limited by another range in the other direction. + // Eg, >1.0.0 <1.0.1 is still a subset of <2.0.0 + if (gt && hasDomLT && !lt && gtltComp !== 0) { + return false + } + + if (lt && hasDomGT && !gt && gtltComp !== 0) { + return false + } + + // we needed a prerelease range in a specific tuple, but didn't get one + // then this isn't a subset. eg >=1.2.3-pre is not a subset of >=1.0.0, + // because it includes prereleases in the 1.2.3 tuple + if (needDomGTPre || needDomLTPre) { + return false + } + + return true +} + +// >=1.2.3 is lower than >1.2.3 +const higherGT = (a, b, options) => { + if (!a) { + return b + } + const comp = compare(a.semver, b.semver, options) + return comp > 0 ? a + : comp < 0 ? b + : b.operator === '>' && a.operator === '>=' ? b + : a +} + +// <=1.2.3 is higher than <1.2.3 +const lowerLT = (a, b, options) => { + if (!a) { + return b + } + const comp = compare(a.semver, b.semver, options) + return comp < 0 ? a + : comp > 0 ? b + : b.operator === '<' && a.operator === '<=' ? b + : a +} + +module.exports = subset diff --git a/node_modules/semver/ranges/to-comparators.js b/node_modules/semver/ranges/to-comparators.js new file mode 100644 index 0000000..5be2519 --- /dev/null +++ b/node_modules/semver/ranges/to-comparators.js @@ -0,0 +1,10 @@ +'use strict' + +const Range = require('../classes/range') + +// Mostly just for testing and legacy API reasons +const toComparators = (range, options) => + new Range(range, options).set + .map(comp => comp.map(c => c.value).join(' ').trim().split(' ')) + +module.exports = toComparators diff --git a/node_modules/semver/ranges/valid.js b/node_modules/semver/ranges/valid.js new file mode 100644 index 0000000..cc6b0e9 --- /dev/null +++ b/node_modules/semver/ranges/valid.js @@ -0,0 +1,13 @@ +'use strict' + +const Range = require('../classes/range') +const validRange = (range, options) => { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, options).range || '*' + } catch (er) { + return null + } +} +module.exports = validRange diff --git a/node_modules/sharp/LICENSE b/node_modules/sharp/LICENSE new file mode 100644 index 0000000..37ec93a --- /dev/null +++ b/node_modules/sharp/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/node_modules/sharp/README.md b/node_modules/sharp/README.md new file mode 100644 index 0000000..47da52e --- /dev/null +++ b/node_modules/sharp/README.md @@ -0,0 +1,118 @@ +# sharp + +sharp logo + +The typical use case for this high speed Node-API module +is to convert large images in common formats to +smaller, web-friendly JPEG, PNG, WebP, GIF and AVIF images of varying dimensions. + +It can be used with all JavaScript runtimes +that provide support for Node-API v9, including +Node.js (^18.17.0 or >= 20.3.0), Deno and Bun. + +Resizing an image is typically 4x-5x faster than using the +quickest ImageMagick and GraphicsMagick settings +due to its use of [libvips](https://github.com/libvips/libvips). + +Colour spaces, embedded ICC profiles and alpha transparency channels are all handled correctly. +Lanczos resampling ensures quality is not sacrificed for speed. + +As well as image resizing, operations such as +rotation, extraction, compositing and gamma correction are available. + +Most modern macOS, Windows and Linux systems +do not require any additional install or runtime dependencies. + +## Documentation + +Visit [sharp.pixelplumbing.com](https://sharp.pixelplumbing.com/) for complete +[installation instructions](https://sharp.pixelplumbing.com/install), +[API documentation](https://sharp.pixelplumbing.com/api-constructor), +[benchmark tests](https://sharp.pixelplumbing.com/performance) and +[changelog](https://sharp.pixelplumbing.com/changelog). + +## Examples + +```sh +npm install sharp +``` + +```javascript +const sharp = require('sharp'); +``` + +### Callback + +```javascript +sharp(inputBuffer) + .resize(320, 240) + .toFile('output.webp', (err, info) => { ... }); +``` + +### Promise + +```javascript +sharp('input.jpg') + .rotate() + .resize(200) + .jpeg({ mozjpeg: true }) + .toBuffer() + .then( data => { ... }) + .catch( err => { ... }); +``` + +### Async/await + +```javascript +const semiTransparentRedPng = await sharp({ + create: { + width: 48, + height: 48, + channels: 4, + background: { r: 255, g: 0, b: 0, alpha: 0.5 } + } +}) + .png() + .toBuffer(); +``` + +### Stream + +```javascript +const roundedCorners = Buffer.from( + '' +); + +const roundedCornerResizer = + sharp() + .resize(200, 200) + .composite([{ + input: roundedCorners, + blend: 'dest-in' + }]) + .png(); + +readableStream + .pipe(roundedCornerResizer) + .pipe(writableStream); +``` + +## Contributing + +A [guide for contributors](https://github.com/lovell/sharp/blob/main/.github/CONTRIBUTING.md) +covers reporting bugs, requesting features and submitting code changes. + +## Licensing + +Copyright 2013 Lovell Fuller and others. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at +[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0) + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/node_modules/sharp/install/check.js b/node_modules/sharp/install/check.js new file mode 100644 index 0000000..0e00133 --- /dev/null +++ b/node_modules/sharp/install/check.js @@ -0,0 +1,41 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +'use strict'; + +try { + const { useGlobalLibvips, globalLibvipsVersion, log, spawnRebuild } = require('../lib/libvips'); + + const buildFromSource = (msg) => { + log(msg); + log('Attempting to build from source via node-gyp'); + try { + const addonApi = require('node-addon-api'); + log(`Found node-addon-api ${addonApi.version || ''}`); + } catch (err) { + log('Please add node-addon-api to your dependencies'); + return; + } + try { + const gyp = require('node-gyp'); + log(`Found node-gyp ${gyp().version}`); + } catch (err) { + log('Please add node-gyp to your dependencies'); + return; + } + log('See https://sharp.pixelplumbing.com/install#building-from-source'); + const status = spawnRebuild(); + if (status !== 0) { + process.exit(status); + } + }; + + if (useGlobalLibvips(log)) { + buildFromSource(`Detected globally-installed libvips v${globalLibvipsVersion()}`); + } else if (process.env.npm_config_build_from_source) { + buildFromSource('Detected --build-from-source flag'); + } +} catch (err) { + const summary = err.message.split(/\n/).slice(0, 1); + console.log(`sharp: skipping install check: ${summary}`); +} diff --git a/node_modules/sharp/lib/channel.js b/node_modules/sharp/lib/channel.js new file mode 100644 index 0000000..b6381ae --- /dev/null +++ b/node_modules/sharp/lib/channel.js @@ -0,0 +1,177 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +'use strict'; + +const is = require('./is'); + +/** + * Boolean operations for bandbool. + * @private + */ +const bool = { + and: 'and', + or: 'or', + eor: 'eor' +}; + +/** + * Remove alpha channels, if any. This is a no-op if the image does not have an alpha channel. + * + * See also {@link /api-operation#flatten|flatten}. + * + * @example + * sharp('rgba.png') + * .removeAlpha() + * .toFile('rgb.png', function(err, info) { + * // rgb.png is a 3 channel image without an alpha channel + * }); + * + * @returns {Sharp} + */ +function removeAlpha () { + this.options.removeAlpha = true; + return this; +} + +/** + * Ensure the output image has an alpha transparency channel. + * If missing, the added alpha channel will have the specified + * transparency level, defaulting to fully-opaque (1). + * This is a no-op if the image already has an alpha channel. + * + * @since 0.21.2 + * + * @example + * // rgba.png will be a 4 channel image with a fully-opaque alpha channel + * await sharp('rgb.jpg') + * .ensureAlpha() + * .toFile('rgba.png') + * + * @example + * // rgba is a 4 channel image with a fully-transparent alpha channel + * const rgba = await sharp(rgb) + * .ensureAlpha(0) + * .toBuffer(); + * + * @param {number} [alpha=1] - alpha transparency level (0=fully-transparent, 1=fully-opaque) + * @returns {Sharp} + * @throws {Error} Invalid alpha transparency level + */ +function ensureAlpha (alpha) { + if (is.defined(alpha)) { + if (is.number(alpha) && is.inRange(alpha, 0, 1)) { + this.options.ensureAlpha = alpha; + } else { + throw is.invalidParameterError('alpha', 'number between 0 and 1', alpha); + } + } else { + this.options.ensureAlpha = 1; + } + return this; +} + +/** + * Extract a single channel from a multi-channel image. + * + * The output colourspace will be either `b-w` (8-bit) or `grey16` (16-bit). + * + * @example + * // green.jpg is a greyscale image containing the green channel of the input + * await sharp(input) + * .extractChannel('green') + * .toFile('green.jpg'); + * + * @example + * // red1 is the red value of the first pixel, red2 the second pixel etc. + * const [red1, red2, ...] = await sharp(input) + * .extractChannel(0) + * .raw() + * .toBuffer(); + * + * @param {number|string} channel - zero-indexed channel/band number to extract, or `red`, `green`, `blue` or `alpha`. + * @returns {Sharp} + * @throws {Error} Invalid channel + */ +function extractChannel (channel) { + const channelMap = { red: 0, green: 1, blue: 2, alpha: 3 }; + if (Object.keys(channelMap).includes(channel)) { + channel = channelMap[channel]; + } + if (is.integer(channel) && is.inRange(channel, 0, 4)) { + this.options.extractChannel = channel; + } else { + throw is.invalidParameterError('channel', 'integer or one of: red, green, blue, alpha', channel); + } + return this; +} + +/** + * Join one or more channels to the image. + * The meaning of the added channels depends on the output colourspace, set with `toColourspace()`. + * By default the output image will be web-friendly sRGB, with additional channels interpreted as alpha channels. + * Channel ordering follows vips convention: + * - sRGB: 0: Red, 1: Green, 2: Blue, 3: Alpha. + * - CMYK: 0: Magenta, 1: Cyan, 2: Yellow, 3: Black, 4: Alpha. + * + * Buffers may be any of the image formats supported by sharp. + * For raw pixel input, the `options` object should contain a `raw` attribute, which follows the format of the attribute of the same name in the `sharp()` constructor. + * + * @param {Array|string|Buffer} images - one or more images (file paths, Buffers). + * @param {Object} options - image options, see `sharp()` constructor. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function joinChannel (images, options) { + if (Array.isArray(images)) { + images.forEach(function (image) { + this.options.joinChannelIn.push(this._createInputDescriptor(image, options)); + }, this); + } else { + this.options.joinChannelIn.push(this._createInputDescriptor(images, options)); + } + return this; +} + +/** + * Perform a bitwise boolean operation on all input image channels (bands) to produce a single channel output image. + * + * @example + * sharp('3-channel-rgb-input.png') + * .bandbool(sharp.bool.and) + * .toFile('1-channel-output.png', function (err, info) { + * // The output will be a single channel image where each pixel `P = R & G & B`. + * // If `I(1,1) = [247, 170, 14] = [0b11110111, 0b10101010, 0b00001111]` + * // then `O(1,1) = 0b11110111 & 0b10101010 & 0b00001111 = 0b00000010 = 2`. + * }); + * + * @param {string} boolOp - one of `and`, `or` or `eor` to perform that bitwise operation, like the C logic operators `&`, `|` and `^` respectively. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function bandbool (boolOp) { + if (is.string(boolOp) && is.inArray(boolOp, ['and', 'or', 'eor'])) { + this.options.bandBoolOp = boolOp; + } else { + throw is.invalidParameterError('boolOp', 'one of: and, or, eor', boolOp); + } + return this; +} + +/** + * Decorate the Sharp prototype with channel-related functions. + * @module Sharp + * @private + */ +module.exports = function (Sharp) { + Object.assign(Sharp.prototype, { + // Public instance functions + removeAlpha, + ensureAlpha, + extractChannel, + joinChannel, + bandbool + }); + // Class attributes + Sharp.bool = bool; +}; diff --git a/node_modules/sharp/lib/colour.js b/node_modules/sharp/lib/colour.js new file mode 100644 index 0000000..e17b77b --- /dev/null +++ b/node_modules/sharp/lib/colour.js @@ -0,0 +1,192 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +'use strict'; + +const color = require('@img/colour'); +const is = require('./is'); + +/** + * Colourspaces. + * @private + */ +const colourspace = { + multiband: 'multiband', + 'b-w': 'b-w', + bw: 'b-w', + cmyk: 'cmyk', + srgb: 'srgb' +}; + +/** + * Tint the image using the provided colour. + * An alpha channel may be present and will be unchanged by the operation. + * + * @example + * const output = await sharp(input) + * .tint({ r: 255, g: 240, b: 16 }) + * .toBuffer(); + * + * @param {string|Object} tint - Parsed by the [color](https://www.npmjs.org/package/color) module. + * @returns {Sharp} + * @throws {Error} Invalid parameter + */ +function tint (tint) { + this._setBackgroundColourOption('tint', tint); + return this; +} + +/** + * Convert to 8-bit greyscale; 256 shades of grey. + * This is a linear operation. If the input image is in a non-linear colour space such as sRGB, use `gamma()` with `greyscale()` for the best results. + * By default the output image will be web-friendly sRGB and contain three (identical) colour channels. + * This may be overridden by other sharp operations such as `toColourspace('b-w')`, + * which will produce an output image containing one colour channel. + * An alpha channel may be present, and will be unchanged by the operation. + * + * @example + * const output = await sharp(input).greyscale().toBuffer(); + * + * @param {Boolean} [greyscale=true] + * @returns {Sharp} + */ +function greyscale (greyscale) { + this.options.greyscale = is.bool(greyscale) ? greyscale : true; + return this; +} + +/** + * Alternative spelling of `greyscale`. + * @param {Boolean} [grayscale=true] + * @returns {Sharp} + */ +function grayscale (grayscale) { + return this.greyscale(grayscale); +} + +/** + * Set the pipeline colourspace. + * + * The input image will be converted to the provided colourspace at the start of the pipeline. + * All operations will use this colourspace before converting to the output colourspace, + * as defined by {@link #tocolourspace|toColourspace}. + * + * @since 0.29.0 + * + * @example + * // Run pipeline in 16 bits per channel RGB while converting final result to 8 bits per channel sRGB. + * await sharp(input) + * .pipelineColourspace('rgb16') + * .toColourspace('srgb') + * .toFile('16bpc-pipeline-to-8bpc-output.png') + * + * @param {string} [colourspace] - pipeline colourspace e.g. `rgb16`, `scrgb`, `lab`, `grey16` [...](https://github.com/libvips/libvips/blob/41cff4e9d0838498487a00623462204eb10ee5b8/libvips/iofuncs/enumtypes.c#L774) + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function pipelineColourspace (colourspace) { + if (!is.string(colourspace)) { + throw is.invalidParameterError('colourspace', 'string', colourspace); + } + this.options.colourspacePipeline = colourspace; + return this; +} + +/** + * Alternative spelling of `pipelineColourspace`. + * @param {string} [colorspace] - pipeline colorspace. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function pipelineColorspace (colorspace) { + return this.pipelineColourspace(colorspace); +} + +/** + * Set the output colourspace. + * By default output image will be web-friendly sRGB, with additional channels interpreted as alpha channels. + * + * @example + * // Output 16 bits per pixel RGB + * await sharp(input) + * .toColourspace('rgb16') + * .toFile('16-bpp.png') + * + * @param {string} [colourspace] - output colourspace e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://github.com/libvips/libvips/blob/3c0bfdf74ce1dc37a6429bed47fa76f16e2cd70a/libvips/iofuncs/enumtypes.c#L777-L794) + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function toColourspace (colourspace) { + if (!is.string(colourspace)) { + throw is.invalidParameterError('colourspace', 'string', colourspace); + } + this.options.colourspace = colourspace; + return this; +} + +/** + * Alternative spelling of `toColourspace`. + * @param {string} [colorspace] - output colorspace. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function toColorspace (colorspace) { + return this.toColourspace(colorspace); +} + +/** + * Create a RGBA colour array from a given value. + * @private + * @param {string|Object} value + * @throws {Error} Invalid value + */ +function _getBackgroundColourOption (value) { + if (is.object(value) || is.string(value)) { + const colour = color(value); + return [ + colour.red(), + colour.green(), + colour.blue(), + Math.round(colour.alpha() * 255) + ]; + } else { + throw is.invalidParameterError('background', 'object or string', value); + } +} + +/** + * Update a colour attribute of the this.options Object. + * @private + * @param {string} key + * @param {string|Object} value + * @throws {Error} Invalid value + */ +function _setBackgroundColourOption (key, value) { + if (is.defined(value)) { + this.options[key] = _getBackgroundColourOption(value); + } +} + +/** + * Decorate the Sharp prototype with colour-related functions. + * @module Sharp + * @private + */ +module.exports = function (Sharp) { + Object.assign(Sharp.prototype, { + // Public + tint, + greyscale, + grayscale, + pipelineColourspace, + pipelineColorspace, + toColourspace, + toColorspace, + // Private + _getBackgroundColourOption, + _setBackgroundColourOption + }); + // Class attributes + Sharp.colourspace = colourspace; + Sharp.colorspace = colourspace; +}; diff --git a/node_modules/sharp/lib/composite.js b/node_modules/sharp/lib/composite.js new file mode 100644 index 0000000..98f8aef --- /dev/null +++ b/node_modules/sharp/lib/composite.js @@ -0,0 +1,212 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +'use strict'; + +const is = require('./is'); + +/** + * Blend modes. + * @member + * @private + */ +const blend = { + clear: 'clear', + source: 'source', + over: 'over', + in: 'in', + out: 'out', + atop: 'atop', + dest: 'dest', + 'dest-over': 'dest-over', + 'dest-in': 'dest-in', + 'dest-out': 'dest-out', + 'dest-atop': 'dest-atop', + xor: 'xor', + add: 'add', + saturate: 'saturate', + multiply: 'multiply', + screen: 'screen', + overlay: 'overlay', + darken: 'darken', + lighten: 'lighten', + 'colour-dodge': 'colour-dodge', + 'color-dodge': 'colour-dodge', + 'colour-burn': 'colour-burn', + 'color-burn': 'colour-burn', + 'hard-light': 'hard-light', + 'soft-light': 'soft-light', + difference: 'difference', + exclusion: 'exclusion' +}; + +/** + * Composite image(s) over the processed (resized, extracted etc.) image. + * + * The images to composite must be the same size or smaller than the processed image. + * If both `top` and `left` options are provided, they take precedence over `gravity`. + * + * Other operations in the same processing pipeline (e.g. resize, rotate, flip, + * flop, extract) will always be applied to the input image before composition. + * + * The `blend` option can be one of `clear`, `source`, `over`, `in`, `out`, `atop`, + * `dest`, `dest-over`, `dest-in`, `dest-out`, `dest-atop`, + * `xor`, `add`, `saturate`, `multiply`, `screen`, `overlay`, `darken`, `lighten`, + * `colour-dodge`, `color-dodge`, `colour-burn`,`color-burn`, + * `hard-light`, `soft-light`, `difference`, `exclusion`. + * + * More information about blend modes can be found at + * https://www.libvips.org/API/current/libvips-conversion.html#VipsBlendMode + * and https://www.cairographics.org/operators/ + * + * @since 0.22.0 + * + * @example + * await sharp(background) + * .composite([ + * { input: layer1, gravity: 'northwest' }, + * { input: layer2, gravity: 'southeast' }, + * ]) + * .toFile('combined.png'); + * + * @example + * const output = await sharp('input.gif', { animated: true }) + * .composite([ + * { input: 'overlay.png', tile: true, blend: 'saturate' } + * ]) + * .toBuffer(); + * + * @example + * sharp('input.png') + * .rotate(180) + * .resize(300) + * .flatten( { background: '#ff6600' } ) + * .composite([{ input: 'overlay.png', gravity: 'southeast' }]) + * .sharpen() + * .withMetadata() + * .webp( { quality: 90 } ) + * .toBuffer() + * .then(function(outputBuffer) { + * // outputBuffer contains upside down, 300px wide, alpha channel flattened + * // onto orange background, composited with overlay.png with SE gravity, + * // sharpened, with metadata, 90% quality WebP image data. Phew! + * }); + * + * @param {Object[]} images - Ordered list of images to composite + * @param {Buffer|String} [images[].input] - Buffer containing image data, String containing the path to an image file, or Create object (see below) + * @param {Object} [images[].input.create] - describes a blank overlay to be created. + * @param {Number} [images[].input.create.width] + * @param {Number} [images[].input.create.height] + * @param {Number} [images[].input.create.channels] - 3-4 + * @param {String|Object} [images[].input.create.background] - parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. + * @param {Object} [images[].input.text] - describes a new text image to be created. + * @param {string} [images[].input.text.text] - text to render as a UTF-8 string. It can contain Pango markup, for example `LeMonde`. + * @param {string} [images[].input.text.font] - font name to render with. + * @param {string} [images[].input.text.fontfile] - absolute filesystem path to a font file that can be used by `font`. + * @param {number} [images[].input.text.width=0] - integral number of pixels to word-wrap at. Lines of text wider than this will be broken at word boundaries. + * @param {number} [images[].input.text.height=0] - integral number of pixels high. When defined, `dpi` will be ignored and the text will automatically fit the pixel resolution defined by `width` and `height`. Will be ignored if `width` is not specified or set to 0. + * @param {string} [images[].input.text.align='left'] - text alignment (`'left'`, `'centre'`, `'center'`, `'right'`). + * @param {boolean} [images[].input.text.justify=false] - set this to true to apply justification to the text. + * @param {number} [images[].input.text.dpi=72] - the resolution (size) at which to render the text. Does not take effect if `height` is specified. + * @param {boolean} [images[].input.text.rgba=false] - set this to true to enable RGBA output. This is useful for colour emoji rendering, or support for Pango markup features like `Red!`. + * @param {number} [images[].input.text.spacing=0] - text line height in points. Will use the font line height if none is specified. + * @param {Boolean} [images[].autoOrient=false] - set to true to use EXIF orientation data, if present, to orient the image. + * @param {String} [images[].blend='over'] - how to blend this image with the image below. + * @param {String} [images[].gravity='centre'] - gravity at which to place the overlay. + * @param {Number} [images[].top] - the pixel offset from the top edge. + * @param {Number} [images[].left] - the pixel offset from the left edge. + * @param {Boolean} [images[].tile=false] - set to true to repeat the overlay image across the entire image with the given `gravity`. + * @param {Boolean} [images[].premultiplied=false] - set to true to avoid premultiplying the image below. Equivalent to the `--premultiplied` vips option. + * @param {Number} [images[].density=72] - number representing the DPI for vector overlay image. + * @param {Object} [images[].raw] - describes overlay when using raw pixel data. + * @param {Number} [images[].raw.width] + * @param {Number} [images[].raw.height] + * @param {Number} [images[].raw.channels] + * @param {boolean} [images[].animated=false] - Set to `true` to read all frames/pages of an animated image. + * @param {string} [images[].failOn='warning'] - @see {@link /api-constructor#parameters|constructor parameters} + * @param {number|boolean} [images[].limitInputPixels=268402689] - @see {@link /api-constructor#parameters|constructor parameters} + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function composite (images) { + if (!Array.isArray(images)) { + throw is.invalidParameterError('images to composite', 'array', images); + } + this.options.composite = images.map(image => { + if (!is.object(image)) { + throw is.invalidParameterError('image to composite', 'object', image); + } + const inputOptions = this._inputOptionsFromObject(image); + const composite = { + input: this._createInputDescriptor(image.input, inputOptions, { allowStream: false }), + blend: 'over', + tile: false, + left: 0, + top: 0, + hasOffset: false, + gravity: 0, + premultiplied: false + }; + if (is.defined(image.blend)) { + if (is.string(blend[image.blend])) { + composite.blend = blend[image.blend]; + } else { + throw is.invalidParameterError('blend', 'valid blend name', image.blend); + } + } + if (is.defined(image.tile)) { + if (is.bool(image.tile)) { + composite.tile = image.tile; + } else { + throw is.invalidParameterError('tile', 'boolean', image.tile); + } + } + if (is.defined(image.left)) { + if (is.integer(image.left)) { + composite.left = image.left; + } else { + throw is.invalidParameterError('left', 'integer', image.left); + } + } + if (is.defined(image.top)) { + if (is.integer(image.top)) { + composite.top = image.top; + } else { + throw is.invalidParameterError('top', 'integer', image.top); + } + } + if (is.defined(image.top) !== is.defined(image.left)) { + throw new Error('Expected both left and top to be set'); + } else { + composite.hasOffset = is.integer(image.top) && is.integer(image.left); + } + if (is.defined(image.gravity)) { + if (is.integer(image.gravity) && is.inRange(image.gravity, 0, 8)) { + composite.gravity = image.gravity; + } else if (is.string(image.gravity) && is.integer(this.constructor.gravity[image.gravity])) { + composite.gravity = this.constructor.gravity[image.gravity]; + } else { + throw is.invalidParameterError('gravity', 'valid gravity', image.gravity); + } + } + if (is.defined(image.premultiplied)) { + if (is.bool(image.premultiplied)) { + composite.premultiplied = image.premultiplied; + } else { + throw is.invalidParameterError('premultiplied', 'boolean', image.premultiplied); + } + } + return composite; + }); + return this; +} + +/** + * Decorate the Sharp prototype with composite-related functions. + * @module Sharp + * @private + */ +module.exports = function (Sharp) { + Sharp.prototype.composite = composite; + Sharp.blend = blend; +}; diff --git a/node_modules/sharp/lib/constructor.js b/node_modules/sharp/lib/constructor.js new file mode 100644 index 0000000..a349f42 --- /dev/null +++ b/node_modules/sharp/lib/constructor.js @@ -0,0 +1,495 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +'use strict'; + +const util = require('node:util'); +const stream = require('node:stream'); +const is = require('./is'); + +require('./sharp'); + +// Use NODE_DEBUG=sharp to enable libvips warnings +const debuglog = util.debuglog('sharp'); + +/** + * Constructor factory to create an instance of `sharp`, to which further methods are chained. + * + * JPEG, PNG, WebP, GIF, AVIF or TIFF format image data can be streamed out from this object. + * When using Stream based output, derived attributes are available from the `info` event. + * + * Non-critical problems encountered during processing are emitted as `warning` events. + * + * Implements the [stream.Duplex](http://nodejs.org/api/stream.html#stream_class_stream_duplex) class. + * + * When loading more than one page/frame of an animated image, + * these are combined as a vertically-stacked "toilet roll" image + * where the overall height is the `pageHeight` multiplied by the number of `pages`. + * + * @constructs Sharp + * + * @emits Sharp#info + * @emits Sharp#warning + * + * @example + * sharp('input.jpg') + * .resize(300, 200) + * .toFile('output.jpg', function(err) { + * // output.jpg is a 300 pixels wide and 200 pixels high image + * // containing a scaled and cropped version of input.jpg + * }); + * + * @example + * // Read image data from remote URL, + * // resize to 300 pixels wide, + * // emit an 'info' event with calculated dimensions + * // and finally write image data to writableStream + * const { body } = fetch('https://...'); + * const readableStream = Readable.fromWeb(body); + * const transformer = sharp() + * .resize(300) + * .on('info', ({ height }) => { + * console.log(`Image height is ${height}`); + * }); + * readableStream.pipe(transformer).pipe(writableStream); + * + * @example + * // Create a blank 300x200 PNG image of semi-translucent red pixels + * sharp({ + * create: { + * width: 300, + * height: 200, + * channels: 4, + * background: { r: 255, g: 0, b: 0, alpha: 0.5 } + * } + * }) + * .png() + * .toBuffer() + * .then( ... ); + * + * @example + * // Convert an animated GIF to an animated WebP + * await sharp('in.gif', { animated: true }).toFile('out.webp'); + * + * @example + * // Read a raw array of pixels and save it to a png + * const input = Uint8Array.from([255, 255, 255, 0, 0, 0]); // or Uint8ClampedArray + * const image = sharp(input, { + * // because the input does not contain its dimensions or how many channels it has + * // we need to specify it in the constructor options + * raw: { + * width: 2, + * height: 1, + * channels: 3 + * } + * }); + * await image.toFile('my-two-pixels.png'); + * + * @example + * // Generate RGB Gaussian noise + * await sharp({ + * create: { + * width: 300, + * height: 200, + * channels: 3, + * noise: { + * type: 'gaussian', + * mean: 128, + * sigma: 30 + * } + * } + * }).toFile('noise.png'); + * + * @example + * // Generate an image from text + * await sharp({ + * text: { + * text: 'Hello, world!', + * width: 400, // max width + * height: 300 // max height + * } + * }).toFile('text_bw.png'); + * + * @example + * // Generate an rgba image from text using pango markup and font + * await sharp({ + * text: { + * text: 'Red!blue', + * font: 'sans', + * rgba: true, + * dpi: 300 + * } + * }).toFile('text_rgba.png'); + * + * @example + * // Join four input images as a 2x2 grid with a 4 pixel gutter + * const data = await sharp( + * [image1, image2, image3, image4], + * { join: { across: 2, shim: 4 } } + * ).toBuffer(); + * + * @example + * // Generate a two-frame animated image from emoji + * const images = ['😀', '😛'].map(text => ({ + * text: { text, width: 64, height: 64, channels: 4, rgba: true } + * })); + * await sharp(images, { join: { animated: true } }).toFile('out.gif'); + * + * @param {(Buffer|ArrayBuffer|Uint8Array|Uint8ClampedArray|Int8Array|Uint16Array|Int16Array|Uint32Array|Int32Array|Float32Array|Float64Array|string|Array)} [input] - if present, can be + * a Buffer / ArrayBuffer / Uint8Array / Uint8ClampedArray containing JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image data, or + * a TypedArray containing raw pixel image data, or + * a String containing the filesystem path to an JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image file. + * An array of inputs can be provided, and these will be joined together. + * JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when not present. + * @param {Object} [options] - if present, is an Object with optional attributes. + * @param {string} [options.failOn='warning'] - When to abort processing of invalid pixel data, one of (in order of sensitivity, least to most): 'none', 'truncated', 'error', 'warning'. Higher levels imply lower levels. Invalid metadata will always abort. + * @param {number|boolean} [options.limitInputPixels=268402689] - Do not process input images where the number of pixels + * (width x height) exceeds this limit. Assumes image dimensions contained in the input metadata can be trusted. + * An integral Number of pixels, zero or false to remove limit, true to use default limit of 268402689 (0x3FFF x 0x3FFF). + * @param {boolean} [options.unlimited=false] - Set this to `true` to remove safety features that help prevent memory exhaustion (JPEG, PNG, SVG, HEIF). + * @param {boolean} [options.autoOrient=false] - Set this to `true` to rotate/flip the image to match EXIF `Orientation`, if any. + * @param {boolean} [options.sequentialRead=true] - Set this to `false` to use random access rather than sequential read. Some operations will do this automatically. + * @param {number} [options.density=72] - number representing the DPI for vector images in the range 1 to 100000. + * @param {number} [options.ignoreIcc=false] - should the embedded ICC profile, if any, be ignored. + * @param {number} [options.pages=1] - Number of pages to extract for multi-page input (GIF, WebP, TIFF), use -1 for all pages. + * @param {number} [options.page=0] - Page number to start extracting from for multi-page input (GIF, WebP, TIFF), zero based. + * @param {boolean} [options.animated=false] - Set to `true` to read all frames/pages of an animated image (GIF, WebP, TIFF), equivalent of setting `pages` to `-1`. + * @param {Object} [options.raw] - describes raw pixel input image data. See `raw()` for pixel ordering. + * @param {number} [options.raw.width] - integral number of pixels wide. + * @param {number} [options.raw.height] - integral number of pixels high. + * @param {number} [options.raw.channels] - integral number of channels, between 1 and 4. + * @param {boolean} [options.raw.premultiplied] - specifies that the raw input has already been premultiplied, set to `true` + * to avoid sharp premultiplying the image. (optional, default `false`) + * @param {number} [options.raw.pageHeight] - The pixel height of each page/frame for animated images, must be an integral factor of `raw.height`. + * @param {Object} [options.create] - describes a new image to be created. + * @param {number} [options.create.width] - integral number of pixels wide. + * @param {number} [options.create.height] - integral number of pixels high. + * @param {number} [options.create.channels] - integral number of channels, either 3 (RGB) or 4 (RGBA). + * @param {string|Object} [options.create.background] - parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. + * @param {number} [options.create.pageHeight] - The pixel height of each page/frame for animated images, must be an integral factor of `create.height`. + * @param {Object} [options.create.noise] - describes a noise to be created. + * @param {string} [options.create.noise.type] - type of generated noise, currently only `gaussian` is supported. + * @param {number} [options.create.noise.mean=128] - Mean value of pixels in the generated noise. + * @param {number} [options.create.noise.sigma=30] - Standard deviation of pixel values in the generated noise. + * @param {Object} [options.text] - describes a new text image to be created. + * @param {string} [options.text.text] - text to render as a UTF-8 string. It can contain Pango markup, for example `LeMonde`. + * @param {string} [options.text.font] - font name to render with. + * @param {string} [options.text.fontfile] - absolute filesystem path to a font file that can be used by `font`. + * @param {number} [options.text.width=0] - Integral number of pixels to word-wrap at. Lines of text wider than this will be broken at word boundaries. + * @param {number} [options.text.height=0] - Maximum integral number of pixels high. When defined, `dpi` will be ignored and the text will automatically fit the pixel resolution defined by `width` and `height`. Will be ignored if `width` is not specified or set to 0. + * @param {string} [options.text.align='left'] - Alignment style for multi-line text (`'left'`, `'centre'`, `'center'`, `'right'`). + * @param {boolean} [options.text.justify=false] - set this to true to apply justification to the text. + * @param {number} [options.text.dpi=72] - the resolution (size) at which to render the text. Does not take effect if `height` is specified. + * @param {boolean} [options.text.rgba=false] - set this to true to enable RGBA output. This is useful for colour emoji rendering, or support for pango markup features like `Red!`. + * @param {number} [options.text.spacing=0] - text line height in points. Will use the font line height if none is specified. + * @param {string} [options.text.wrap='word'] - word wrapping style when width is provided, one of: 'word', 'char', 'word-char' (prefer word, fallback to char) or 'none'. + * @param {Object} [options.join] - describes how an array of input images should be joined. + * @param {number} [options.join.across=1] - number of images to join horizontally. + * @param {boolean} [options.join.animated=false] - set this to `true` to join the images as an animated image. + * @param {number} [options.join.shim=0] - number of pixels to insert between joined images. + * @param {string|Object} [options.join.background] - parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. + * @param {string} [options.join.halign='left'] - horizontal alignment style for images joined horizontally (`'left'`, `'centre'`, `'center'`, `'right'`). + * @param {string} [options.join.valign='top'] - vertical alignment style for images joined vertically (`'top'`, `'centre'`, `'center'`, `'bottom'`). + * @param {Object} [options.tiff] - Describes TIFF specific options. + * @param {number} [options.tiff.subifd=-1] - Sub Image File Directory to extract for OME-TIFF, defaults to main image. + * @param {Object} [options.svg] - Describes SVG specific options. + * @param {string} [options.svg.stylesheet] - Custom CSS for SVG input, applied with a User Origin during the CSS cascade. + * @param {boolean} [options.svg.highBitdepth=false] - Set to `true` to render SVG input at 32-bits per channel (128-bit) instead of 8-bits per channel (32-bit) RGBA. + * @param {Object} [options.pdf] - Describes PDF specific options. Requires the use of a globally-installed libvips compiled with support for PDFium, Poppler, ImageMagick or GraphicsMagick. + * @param {string|Object} [options.pdf.background] - Background colour to use when PDF is partially transparent. Parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. + * @param {Object} [options.openSlide] - Describes OpenSlide specific options. Requires the use of a globally-installed libvips compiled with support for OpenSlide. + * @param {number} [options.openSlide.level=0] - Level to extract from a multi-level input, zero based. + * @param {Object} [options.jp2] - Describes JPEG 2000 specific options. Requires the use of a globally-installed libvips compiled with support for OpenJPEG. + * @param {boolean} [options.jp2.oneshot=false] - Set to `true` to decode tiled JPEG 2000 images in a single operation, improving compatibility. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +const Sharp = function (input, options) { + if (arguments.length === 1 && !is.defined(input)) { + throw new Error('Invalid input'); + } + if (!(this instanceof Sharp)) { + return new Sharp(input, options); + } + stream.Duplex.call(this); + this.options = { + // resize options + topOffsetPre: -1, + leftOffsetPre: -1, + widthPre: -1, + heightPre: -1, + topOffsetPost: -1, + leftOffsetPost: -1, + widthPost: -1, + heightPost: -1, + width: -1, + height: -1, + canvas: 'crop', + position: 0, + resizeBackground: [0, 0, 0, 255], + angle: 0, + rotationAngle: 0, + rotationBackground: [0, 0, 0, 255], + rotateBefore: false, + orientBefore: false, + flip: false, + flop: false, + extendTop: 0, + extendBottom: 0, + extendLeft: 0, + extendRight: 0, + extendBackground: [0, 0, 0, 255], + extendWith: 'background', + withoutEnlargement: false, + withoutReduction: false, + affineMatrix: [], + affineBackground: [0, 0, 0, 255], + affineIdx: 0, + affineIdy: 0, + affineOdx: 0, + affineOdy: 0, + affineInterpolator: this.constructor.interpolators.bilinear, + kernel: 'lanczos3', + fastShrinkOnLoad: true, + // operations + tint: [-1, 0, 0, 0], + flatten: false, + flattenBackground: [0, 0, 0], + unflatten: false, + negate: false, + negateAlpha: true, + medianSize: 0, + blurSigma: 0, + precision: 'integer', + minAmpl: 0.2, + sharpenSigma: 0, + sharpenM1: 1, + sharpenM2: 2, + sharpenX1: 2, + sharpenY2: 10, + sharpenY3: 20, + threshold: 0, + thresholdGrayscale: true, + trimBackground: [], + trimThreshold: -1, + trimLineArt: false, + dilateWidth: 0, + erodeWidth: 0, + gamma: 0, + gammaOut: 0, + greyscale: false, + normalise: false, + normaliseLower: 1, + normaliseUpper: 99, + claheWidth: 0, + claheHeight: 0, + claheMaxSlope: 3, + brightness: 1, + saturation: 1, + hue: 0, + lightness: 0, + booleanBufferIn: null, + booleanFileIn: '', + joinChannelIn: [], + extractChannel: -1, + removeAlpha: false, + ensureAlpha: -1, + colourspace: 'srgb', + colourspacePipeline: 'last', + composite: [], + // output + fileOut: '', + formatOut: 'input', + streamOut: false, + keepMetadata: 0, + withMetadataOrientation: -1, + withMetadataDensity: 0, + withIccProfile: '', + withExif: {}, + withExifMerge: true, + withXmp: '', + resolveWithObject: false, + loop: -1, + delay: [], + // output format + jpegQuality: 80, + jpegProgressive: false, + jpegChromaSubsampling: '4:2:0', + jpegTrellisQuantisation: false, + jpegOvershootDeringing: false, + jpegOptimiseScans: false, + jpegOptimiseCoding: true, + jpegQuantisationTable: 0, + pngProgressive: false, + pngCompressionLevel: 6, + pngAdaptiveFiltering: false, + pngPalette: false, + pngQuality: 100, + pngEffort: 7, + pngBitdepth: 8, + pngDither: 1, + jp2Quality: 80, + jp2TileHeight: 512, + jp2TileWidth: 512, + jp2Lossless: false, + jp2ChromaSubsampling: '4:4:4', + webpQuality: 80, + webpAlphaQuality: 100, + webpLossless: false, + webpNearLossless: false, + webpSmartSubsample: false, + webpSmartDeblock: false, + webpPreset: 'default', + webpEffort: 4, + webpMinSize: false, + webpMixed: false, + gifBitdepth: 8, + gifEffort: 7, + gifDither: 1, + gifInterFrameMaxError: 0, + gifInterPaletteMaxError: 3, + gifKeepDuplicateFrames: false, + gifReuse: true, + gifProgressive: false, + tiffQuality: 80, + tiffCompression: 'jpeg', + tiffPredictor: 'horizontal', + tiffPyramid: false, + tiffMiniswhite: false, + tiffBitdepth: 8, + tiffTile: false, + tiffTileHeight: 256, + tiffTileWidth: 256, + tiffXres: 1.0, + tiffYres: 1.0, + tiffResolutionUnit: 'inch', + heifQuality: 50, + heifLossless: false, + heifCompression: 'av1', + heifEffort: 4, + heifChromaSubsampling: '4:4:4', + heifBitdepth: 8, + jxlDistance: 1, + jxlDecodingTier: 0, + jxlEffort: 7, + jxlLossless: false, + rawDepth: 'uchar', + tileSize: 256, + tileOverlap: 0, + tileContainer: 'fs', + tileLayout: 'dz', + tileFormat: 'last', + tileDepth: 'last', + tileAngle: 0, + tileSkipBlanks: -1, + tileBackground: [255, 255, 255, 255], + tileCentre: false, + tileId: 'https://example.com/iiif', + tileBasename: '', + timeoutSeconds: 0, + linearA: [], + linearB: [], + pdfBackground: [255, 255, 255, 255], + // Function to notify of libvips warnings + debuglog: warning => { + this.emit('warning', warning); + debuglog(warning); + }, + // Function to notify of queue length changes + queueListener: function (queueLength) { + Sharp.queue.emit('change', queueLength); + } + }; + this.options.input = this._createInputDescriptor(input, options, { allowStream: true }); + return this; +}; +Object.setPrototypeOf(Sharp.prototype, stream.Duplex.prototype); +Object.setPrototypeOf(Sharp, stream.Duplex); + +/** + * Take a "snapshot" of the Sharp instance, returning a new instance. + * Cloned instances inherit the input of their parent instance. + * This allows multiple output Streams and therefore multiple processing pipelines to share a single input Stream. + * + * @example + * const pipeline = sharp().rotate(); + * pipeline.clone().resize(800, 600).pipe(firstWritableStream); + * pipeline.clone().extract({ left: 20, top: 20, width: 100, height: 100 }).pipe(secondWritableStream); + * readableStream.pipe(pipeline); + * // firstWritableStream receives auto-rotated, resized readableStream + * // secondWritableStream receives auto-rotated, extracted region of readableStream + * + * @example + * // Create a pipeline that will download an image, resize it and format it to different files + * // Using Promises to know when the pipeline is complete + * const fs = require("fs"); + * const got = require("got"); + * const sharpStream = sharp({ failOn: 'none' }); + * + * const promises = []; + * + * promises.push( + * sharpStream + * .clone() + * .jpeg({ quality: 100 }) + * .toFile("originalFile.jpg") + * ); + * + * promises.push( + * sharpStream + * .clone() + * .resize({ width: 500 }) + * .jpeg({ quality: 80 }) + * .toFile("optimized-500.jpg") + * ); + * + * promises.push( + * sharpStream + * .clone() + * .resize({ width: 500 }) + * .webp({ quality: 80 }) + * .toFile("optimized-500.webp") + * ); + * + * // https://github.com/sindresorhus/got/blob/main/documentation/3-streams.md + * got.stream("https://www.example.com/some-file.jpg").pipe(sharpStream); + * + * Promise.all(promises) + * .then(res => { console.log("Done!", res); }) + * .catch(err => { + * console.error("Error processing files, let's clean it up", err); + * try { + * fs.unlinkSync("originalFile.jpg"); + * fs.unlinkSync("optimized-500.jpg"); + * fs.unlinkSync("optimized-500.webp"); + * } catch (e) {} + * }); + * + * @returns {Sharp} + */ +function clone () { + // Clone existing options + const clone = this.constructor.call(); + const { debuglog, queueListener, ...options } = this.options; + clone.options = structuredClone(options); + clone.options.debuglog = debuglog; + clone.options.queueListener = queueListener; + // Pass 'finish' event to clone for Stream-based input + if (this._isStreamInput()) { + this.on('finish', () => { + // Clone inherits input data + this._flattenBufferIn(); + clone.options.input.buffer = this.options.input.buffer; + clone.emit('finish'); + }); + } + return clone; +} +Object.assign(Sharp.prototype, { clone }); + +/** + * Export constructor. + * @module Sharp + * @private + */ +module.exports = Sharp; diff --git a/node_modules/sharp/lib/index.d.ts b/node_modules/sharp/lib/index.d.ts new file mode 100644 index 0000000..4123634 --- /dev/null +++ b/node_modules/sharp/lib/index.d.ts @@ -0,0 +1,1964 @@ +/** + * Copyright 2017 François Nguyen and others. + * + * Billy Kwok + * Bradley Odell + * Espen Hovlandsdal + * Floris de Bijl + * François Nguyen + * Jamie Woodbury + * Wooseop Kim + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +// SPDX-License-Identifier: MIT + +/// + +import { Duplex } from 'stream'; + +//#region Constructor functions + +/** + * Creates a sharp instance from an image + * @param input Buffer containing JPEG, PNG, WebP, AVIF, GIF, SVG, TIFF or raw pixel image data, or String containing the path to an JPEG, PNG, WebP, AVIF, GIF, SVG or TIFF image file. + * @param options Object with optional attributes. + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ +declare function sharp(options?: sharp.SharpOptions): sharp.Sharp; +declare function sharp( + input?: sharp.SharpInput | Array, + options?: sharp.SharpOptions, +): sharp.Sharp; + +declare namespace sharp { + /** Object containing nested boolean values representing the available input and output formats/methods. */ + const format: FormatEnum; + + /** An Object containing the version numbers of sharp, libvips and its dependencies. */ + const versions: { + aom?: string | undefined; + archive?: string | undefined; + cairo?: string | undefined; + cgif?: string | undefined; + exif?: string | undefined; + expat?: string | undefined; + ffi?: string | undefined; + fontconfig?: string | undefined; + freetype?: string | undefined; + fribidi?: string | undefined; + glib?: string | undefined; + harfbuzz?: string | undefined; + heif?: string | undefined; + highway?: string | undefined; + imagequant?: string | undefined; + lcms?: string | undefined; + mozjpeg?: string | undefined; + pango?: string | undefined; + pixman?: string | undefined; + png?: string | undefined; + "proxy-libintl"?: string | undefined; + rsvg?: string | undefined; + sharp: string; + spng?: string | undefined; + tiff?: string | undefined; + vips: string; + webp?: string | undefined; + xml?: string | undefined; + "zlib-ng"?: string | undefined; + }; + + /** An Object containing the available interpolators and their proper values */ + const interpolators: Interpolators; + + /** An EventEmitter that emits a change event when a task is either queued, waiting for libuv to provide a worker thread, complete */ + const queue: NodeJS.EventEmitter; + + //#endregion + + //#region Utility functions + + /** + * Gets or, when options are provided, sets the limits of libvips' operation cache. + * Existing entries in the cache will be trimmed after any change in limits. + * This method always returns cache statistics, useful for determining how much working memory is required for a particular task. + * @param options Object with the following attributes, or Boolean where true uses default cache settings and false removes all caching (optional, default true) + * @returns The cache results. + */ + function cache(options?: boolean | CacheOptions): CacheResult; + + /** + * Gets or sets the number of threads libvips' should create to process each image. + * The default value is the number of CPU cores. A value of 0 will reset to this default. + * The maximum number of images that can be processed in parallel is limited by libuv's UV_THREADPOOL_SIZE environment variable. + * @param concurrency The new concurrency value. + * @returns The current concurrency value. + */ + function concurrency(concurrency?: number): number; + + /** + * Provides access to internal task counters. + * @returns Object containing task counters + */ + function counters(): SharpCounters; + + /** + * Get and set use of SIMD vector unit instructions. Requires libvips to have been compiled with highway support. + * Improves the performance of resize, blur and sharpen operations by taking advantage of the SIMD vector unit of the CPU, e.g. Intel SSE and ARM NEON. + * @param enable enable or disable use of SIMD vector unit instructions + * @returns true if usage of SIMD vector unit instructions is enabled + */ + function simd(enable?: boolean): boolean; + + /** + * Block libvips operations at runtime. + * + * This is in addition to the `VIPS_BLOCK_UNTRUSTED` environment variable, + * which when set will block all "untrusted" operations. + * + * @since 0.32.4 + * + * @example Block all TIFF input. + * sharp.block({ + * operation: ['VipsForeignLoadTiff'] + * }); + * + * @param {Object} options + * @param {Array} options.operation - List of libvips low-level operation names to block. + */ + function block(options: { operation: string[] }): void; + + /** + * Unblock libvips operations at runtime. + * + * This is useful for defining a list of allowed operations. + * + * @since 0.32.4 + * + * @example Block all input except WebP from the filesystem. + * sharp.block({ + * operation: ['VipsForeignLoad'] + * }); + * sharp.unblock({ + * operation: ['VipsForeignLoadWebpFile'] + * }); + * + * @example Block all input except JPEG and PNG from a Buffer or Stream. + * sharp.block({ + * operation: ['VipsForeignLoad'] + * }); + * sharp.unblock({ + * operation: ['VipsForeignLoadJpegBuffer', 'VipsForeignLoadPngBuffer'] + * }); + * + * @param {Object} options + * @param {Array} options.operation - List of libvips low-level operation names to unblock. + */ + function unblock(options: { operation: string[] }): void; + + //#endregion + + const gravity: GravityEnum; + const strategy: StrategyEnum; + const kernel: KernelEnum; + const fit: FitEnum; + const bool: BoolEnum; + + interface Sharp extends Duplex { + //#region Channel functions + + /** + * Remove alpha channel, if any. This is a no-op if the image does not have an alpha channel. + * @returns A sharp instance that can be used to chain operations + */ + removeAlpha(): Sharp; + + /** + * Ensure alpha channel, if missing. The added alpha channel will be fully opaque. This is a no-op if the image already has an alpha channel. + * @param alpha transparency level (0=fully-transparent, 1=fully-opaque) (optional, default 1). + * @returns A sharp instance that can be used to chain operations + */ + ensureAlpha(alpha?: number): Sharp; + + /** + * Extract a single channel from a multi-channel image. + * @param channel zero-indexed channel/band number to extract, or red, green, blue or alpha. + * @throws {Error} Invalid channel + * @returns A sharp instance that can be used to chain operations + */ + extractChannel(channel: 0 | 1 | 2 | 3 | 'red' | 'green' | 'blue' | 'alpha'): Sharp; + + /** + * Join one or more channels to the image. The meaning of the added channels depends on the output colourspace, set with toColourspace(). + * By default the output image will be web-friendly sRGB, with additional channels interpreted as alpha channels. Channel ordering follows vips convention: + * - sRGB: 0: Red, 1: Green, 2: Blue, 3: Alpha. + * - CMYK: 0: Magenta, 1: Cyan, 2: Yellow, 3: Black, 4: Alpha. + * + * Buffers may be any of the image formats supported by sharp. + * For raw pixel input, the options object should contain a raw attribute, which follows the format of the attribute of the same name in the sharp() constructor. + * @param images one or more images (file paths, Buffers). + * @param options image options, see sharp() constructor. + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + joinChannel(images: string | Buffer | ArrayLike, options?: SharpOptions): Sharp; + + /** + * Perform a bitwise boolean operation on all input image channels (bands) to produce a single channel output image. + * @param boolOp one of "and", "or" or "eor" to perform that bitwise operation, like the C logic operators &, | and ^ respectively. + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + bandbool(boolOp: keyof BoolEnum): Sharp; + + //#endregion + + //#region Color functions + + /** + * Tint the image using the provided colour. + * An alpha channel may be present and will be unchanged by the operation. + * @param tint Parsed by the color module. + * @returns A sharp instance that can be used to chain operations + */ + tint(tint: Colour | Color): Sharp; + + /** + * Convert to 8-bit greyscale; 256 shades of grey. + * This is a linear operation. + * If the input image is in a non-linear colour space such as sRGB, use gamma() with greyscale() for the best results. + * By default the output image will be web-friendly sRGB and contain three (identical) colour channels. + * This may be overridden by other sharp operations such as toColourspace('b-w'), which will produce an output image containing one colour channel. + * An alpha channel may be present, and will be unchanged by the operation. + * @param greyscale true to enable and false to disable (defaults to true) + * @returns A sharp instance that can be used to chain operations + */ + greyscale(greyscale?: boolean): Sharp; + + /** + * Alternative spelling of greyscale(). + * @param grayscale true to enable and false to disable (defaults to true) + * @returns A sharp instance that can be used to chain operations + */ + grayscale(grayscale?: boolean): Sharp; + + /** + * Set the pipeline colourspace. + * The input image will be converted to the provided colourspace at the start of the pipeline. + * All operations will use this colourspace before converting to the output colourspace, as defined by toColourspace. + * This feature is experimental and has not yet been fully-tested with all operations. + * + * @param colourspace pipeline colourspace e.g. rgb16, scrgb, lab, grey16 ... + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + pipelineColourspace(colourspace?: string): Sharp; + + /** + * Alternative spelling of pipelineColourspace + * @param colorspace pipeline colourspace e.g. rgb16, scrgb, lab, grey16 ... + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + pipelineColorspace(colorspace?: string): Sharp; + + /** + * Set the output colourspace. + * By default output image will be web-friendly sRGB, with additional channels interpreted as alpha channels. + * @param colourspace output colourspace e.g. srgb, rgb, cmyk, lab, b-w ... + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + toColourspace(colourspace?: string): Sharp; + + /** + * Alternative spelling of toColourspace(). + * @param colorspace output colorspace e.g. srgb, rgb, cmyk, lab, b-w ... + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + toColorspace(colorspace: string): Sharp; + + //#endregion + + //#region Composite functions + + /** + * Composite image(s) over the processed (resized, extracted etc.) image. + * + * The images to composite must be the same size or smaller than the processed image. + * If both `top` and `left` options are provided, they take precedence over `gravity`. + * @param images - Ordered list of images to composite + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + composite(images: OverlayOptions[]): Sharp; + + //#endregion + + //#region Input functions + + /** + * Take a "snapshot" of the Sharp instance, returning a new instance. + * Cloned instances inherit the input of their parent instance. + * This allows multiple output Streams and therefore multiple processing pipelines to share a single input Stream. + * @returns A sharp instance that can be used to chain operations + */ + clone(): Sharp; + + /** + * Fast access to (uncached) image metadata without decoding any compressed image data. + * @returns A sharp instance that can be used to chain operations + */ + metadata(callback: (err: Error, metadata: Metadata) => void): Sharp; + + /** + * Fast access to (uncached) image metadata without decoding any compressed image data. + * @returns A promise that resolves with a metadata object + */ + metadata(): Promise; + + /** + * Keep all metadata (EXIF, ICC, XMP, IPTC) from the input image in the output image. + * @returns A sharp instance that can be used to chain operations + */ + keepMetadata(): Sharp; + + /** + * Access to pixel-derived image statistics for every channel in the image. + * @returns A sharp instance that can be used to chain operations + */ + stats(callback: (err: Error, stats: Stats) => void): Sharp; + + /** + * Access to pixel-derived image statistics for every channel in the image. + * @returns A promise that resolves with a stats object + */ + stats(): Promise; + + //#endregion + + //#region Operation functions + + /** + * Rotate the output image by either an explicit angle + * or auto-orient based on the EXIF `Orientation` tag. + * + * If an angle is provided, it is converted to a valid positive degree rotation. + * For example, `-450` will produce a 270 degree rotation. + * + * When rotating by an angle other than a multiple of 90, + * the background colour can be provided with the `background` option. + * + * If no angle is provided, it is determined from the EXIF data. + * Mirroring is supported and may infer the use of a flip operation. + * + * The use of `rotate` without an angle will remove the EXIF `Orientation` tag, if any. + * + * Only one rotation can occur per pipeline (aside from an initial call without + * arguments to orient via EXIF data). Previous calls to `rotate` in the same + * pipeline will be ignored. + * + * Multi-page images can only be rotated by 180 degrees. + * + * Method order is important when rotating, resizing and/or extracting regions, + * for example `.rotate(x).extract(y)` will produce a different result to `.extract(y).rotate(x)`. + * + * @example + * const pipeline = sharp() + * .rotate() + * .resize(null, 200) + * .toBuffer(function (err, outputBuffer, info) { + * // outputBuffer contains 200px high JPEG image data, + * // auto-rotated using EXIF Orientation tag + * // info.width and info.height contain the dimensions of the resized image + * }); + * readableStream.pipe(pipeline); + * + * @example + * const rotateThenResize = await sharp(input) + * .rotate(90) + * .resize({ width: 16, height: 8, fit: 'fill' }) + * .toBuffer(); + * const resizeThenRotate = await sharp(input) + * .resize({ width: 16, height: 8, fit: 'fill' }) + * .rotate(90) + * .toBuffer(); + * + * @param {number} [angle=auto] angle of rotation. + * @param {Object} [options] - if present, is an Object with optional attributes. + * @param {string|Object} [options.background="#000000"] parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ + rotate(angle?: number, options?: RotateOptions): Sharp; + + /** + * Alias for calling `rotate()` with no arguments, which orients the image based + * on EXIF orientsion. + * + * This operation is aliased to emphasize its purpose, helping to remove any + * confusion between rotation and orientation. + * + * @example + * const output = await sharp(input).autoOrient().toBuffer(); + * + * @returns {Sharp} + */ + autoOrient(): Sharp + + /** + * Flip the image about the vertical Y axis. This always occurs after rotation, if any. + * The use of flip implies the removal of the EXIF Orientation tag, if any. + * @param flip true to enable and false to disable (defaults to true) + * @returns A sharp instance that can be used to chain operations + */ + flip(flip?: boolean): Sharp; + + /** + * Flop the image about the horizontal X axis. This always occurs after rotation, if any. + * The use of flop implies the removal of the EXIF Orientation tag, if any. + * @param flop true to enable and false to disable (defaults to true) + * @returns A sharp instance that can be used to chain operations + */ + flop(flop?: boolean): Sharp; + + /** + * Perform an affine transform on an image. This operation will always occur after resizing, extraction and rotation, if any. + * You must provide an array of length 4 or a 2x2 affine transformation matrix. + * By default, new pixels are filled with a black background. You can provide a background colour with the `background` option. + * A particular interpolator may also be specified. Set the `interpolator` option to an attribute of the `sharp.interpolators` Object e.g. `sharp.interpolators.nohalo`. + * + * In the case of a 2x2 matrix, the transform is: + * X = matrix[0, 0] * (x + idx) + matrix[0, 1] * (y + idy) + odx + * Y = matrix[1, 0] * (x + idx) + matrix[1, 1] * (y + idy) + ody + * + * where: + * + * x and y are the coordinates in input image. + * X and Y are the coordinates in output image. + * (0,0) is the upper left corner. + * + * @param matrix Affine transformation matrix, may either by a array of length four or a 2x2 matrix array + * @param options if present, is an Object with optional attributes. + * + * @returns A sharp instance that can be used to chain operations + */ + affine(matrix: [number, number, number, number] | Matrix2x2, options?: AffineOptions): Sharp; + + /** + * Sharpen the image. + * When used without parameters, performs a fast, mild sharpen of the output image. + * When a sigma is provided, performs a slower, more accurate sharpen of the L channel in the LAB colour space. + * Fine-grained control over the level of sharpening in "flat" (m1) and "jagged" (m2) areas is available. + * @param options if present, is an Object with optional attributes + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + sharpen(options?: SharpenOptions): Sharp; + + /** + * Sharpen the image. + * When used without parameters, performs a fast, mild sharpen of the output image. + * When a sigma is provided, performs a slower, more accurate sharpen of the L channel in the LAB colour space. + * Fine-grained control over the level of sharpening in "flat" (m1) and "jagged" (m2) areas is available. + * @param sigma the sigma of the Gaussian mask, where sigma = 1 + radius / 2. + * @param flat the level of sharpening to apply to "flat" areas. (optional, default 1.0) + * @param jagged the level of sharpening to apply to "jagged" areas. (optional, default 2.0) + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + * + * @deprecated Use the object parameter `sharpen({sigma, m1, m2, x1, y2, y3})` instead + */ + sharpen(sigma?: number, flat?: number, jagged?: number): Sharp; + + /** + * Apply median filter. When used without parameters the default window is 3x3. + * @param size square mask size: size x size (optional, default 3) + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + median(size?: number): Sharp; + + /** + * Blur the image. + * When used without parameters, performs a fast, mild blur of the output image. + * When a sigma is provided, performs a slower, more accurate Gaussian blur. + * When a boolean sigma is provided, ether blur mild or disable blur + * @param sigma a value between 0.3 and 1000 representing the sigma of the Gaussian mask, where sigma = 1 + radius / 2. + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + blur(sigma?: number | boolean | BlurOptions): Sharp; + + /** + * Expand foreground objects using the dilate morphological operator. + * @param {Number} [width=1] dilation width in pixels. + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + dilate(width?: number): Sharp; + + /** + * Shrink foreground objects using the erode morphological operator. + * @param {Number} [width=1] erosion width in pixels. + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + erode(width?: number): Sharp; + + /** + * Merge alpha transparency channel, if any, with background. + * @param flatten true to enable and false to disable (defaults to true) + * @returns A sharp instance that can be used to chain operations + */ + flatten(flatten?: boolean | FlattenOptions): Sharp; + + /** + * Ensure the image has an alpha channel with all white pixel values made fully transparent. + * Existing alpha channel values for non-white pixels remain unchanged. + * @returns A sharp instance that can be used to chain operations + */ + unflatten(): Sharp; + + /** + * Apply a gamma correction by reducing the encoding (darken) pre-resize at a factor of 1/gamma then increasing the encoding (brighten) post-resize at a factor of gamma. + * This can improve the perceived brightness of a resized image in non-linear colour spaces. + * JPEG and WebP input images will not take advantage of the shrink-on-load performance optimisation when applying a gamma correction. + * Supply a second argument to use a different output gamma value, otherwise the first value is used in both cases. + * @param gamma value between 1.0 and 3.0. (optional, default 2.2) + * @param gammaOut value between 1.0 and 3.0. (optional, defaults to same as gamma) + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + gamma(gamma?: number, gammaOut?: number): Sharp; + + /** + * Produce the "negative" of the image. + * @param negate true to enable and false to disable, or an object of options (defaults to true) + * @returns A sharp instance that can be used to chain operations + */ + negate(negate?: boolean | NegateOptions): Sharp; + + /** + * Enhance output image contrast by stretching its luminance to cover a full dynamic range. + * + * Uses a histogram-based approach, taking a default range of 1% to 99% to reduce sensitivity to noise at the extremes. + * + * Luminance values below the `lower` percentile will be underexposed by clipping to zero. + * Luminance values above the `upper` percentile will be overexposed by clipping to the max pixel value. + * + * @param normalise options + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + normalise(normalise?: NormaliseOptions): Sharp; + + /** + * Alternative spelling of normalise. + * @param normalize options + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + normalize(normalize?: NormaliseOptions): Sharp; + + /** + * Perform contrast limiting adaptive histogram equalization (CLAHE) + * + * This will, in general, enhance the clarity of the image by bringing out + * darker details. Please read more about CLAHE here: + * https://en.wikipedia.org/wiki/Adaptive_histogram_equalization#Contrast_Limited_AHE + * + * @param options clahe options + */ + clahe(options: ClaheOptions): Sharp; + + /** + * Convolve the image with the specified kernel. + * @param kernel the specified kernel + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + convolve(kernel: Kernel): Sharp; + + /** + * Any pixel value greather than or equal to the threshold value will be set to 255, otherwise it will be set to 0. + * @param threshold a value in the range 0-255 representing the level at which the threshold will be applied. (optional, default 128) + * @param options threshold options + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + threshold(threshold?: number, options?: ThresholdOptions): Sharp; + + /** + * Perform a bitwise boolean operation with operand image. + * This operation creates an output image where each pixel is the result of the selected bitwise boolean operation between the corresponding pixels of the input images. + * @param operand Buffer containing image data or String containing the path to an image file. + * @param operator one of "and", "or" or "eor" to perform that bitwise operation, like the C logic operators &, | and ^ respectively. + * @param options describes operand when using raw pixel data. + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + boolean(operand: string | Buffer, operator: keyof BoolEnum, options?: { raw: Raw }): Sharp; + + /** + * Apply the linear formula a * input + b to the image (levels adjustment) + * @param a multiplier (optional, default 1.0) + * @param b offset (optional, default 0.0) + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + linear(a?: number | number[] | null, b?: number | number[]): Sharp; + + /** + * Recomb the image with the specified matrix. + * @param inputMatrix 3x3 Recombination matrix or 4x4 Recombination matrix + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + recomb(inputMatrix: Matrix3x3 | Matrix4x4): Sharp; + + /** + * Transforms the image using brightness, saturation, hue rotation and lightness. + * Brightness and lightness both operate on luminance, with the difference being that brightness is multiplicative whereas lightness is additive. + * @param options describes the modulation + * @returns A sharp instance that can be used to chain operations + */ + modulate(options?: { + brightness?: number | undefined; + saturation?: number | undefined; + hue?: number | undefined; + lightness?: number | undefined; + }): Sharp; + + //#endregion + + //#region Output functions + + /** + * Write output image data to a file. + * If an explicit output format is not selected, it will be inferred from the extension, with JPEG, PNG, WebP, AVIF, TIFF, DZI, and libvips' V format supported. + * Note that raw pixel data is only supported for buffer output. + * @param fileOut The path to write the image data to. + * @param callback Callback function called on completion with two arguments (err, info). info contains the output image format, size (bytes), width, height and channels. + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + toFile(fileOut: string, callback: (err: Error, info: OutputInfo) => void): Sharp; + + /** + * Write output image data to a file. + * @param fileOut The path to write the image data to. + * @throws {Error} Invalid parameters + * @returns A promise that fulfills with an object containing information on the resulting file + */ + toFile(fileOut: string): Promise; + + /** + * Write output to a Buffer. JPEG, PNG, WebP, AVIF, TIFF, GIF and RAW output are supported. + * By default, the format will match the input image, except SVG input which becomes PNG output. + * @param callback Callback function called on completion with three arguments (err, buffer, info). + * @returns A sharp instance that can be used to chain operations + */ + toBuffer(callback: (err: Error, buffer: Buffer, info: OutputInfo) => void): Sharp; + + /** + * Write output to a Buffer. JPEG, PNG, WebP, AVIF, TIFF, GIF and RAW output are supported. + * By default, the format will match the input image, except SVG input which becomes PNG output. + * @param options resolve options + * @param options.resolveWithObject Resolve the Promise with an Object containing data and info properties instead of resolving only with data. + * @returns A promise that resolves with the Buffer data. + */ + toBuffer(options?: { resolveWithObject: false }): Promise; + + /** + * Write output to a Buffer. JPEG, PNG, WebP, AVIF, TIFF, GIF and RAW output are supported. + * By default, the format will match the input image, except SVG input which becomes PNG output. + * @param options resolve options + * @param options.resolveWithObject Resolve the Promise with an Object containing data and info properties instead of resolving only with data. + * @returns A promise that resolves with an object containing the Buffer data and an info object containing the output image format, size (bytes), width, height and channels + */ + toBuffer(options: { resolveWithObject: true }): Promise<{ data: Buffer; info: OutputInfo }>; + + /** + * Keep all EXIF metadata from the input image in the output image. + * EXIF metadata is unsupported for TIFF output. + * @returns A sharp instance that can be used to chain operations + */ + keepExif(): Sharp; + + /** + * Set EXIF metadata in the output image, ignoring any EXIF in the input image. + * @param {Exif} exif Object keyed by IFD0, IFD1 etc. of key/value string pairs to write as EXIF data. + * @returns A sharp instance that can be used to chain operations + * @throws {Error} Invalid parameters + */ + withExif(exif: Exif): Sharp; + + /** + * Update EXIF metadata from the input image in the output image. + * @param {Exif} exif Object keyed by IFD0, IFD1 etc. of key/value string pairs to write as EXIF data. + * @returns A sharp instance that can be used to chain operations + * @throws {Error} Invalid parameters + */ + withExifMerge(exif: Exif): Sharp; + + /** + * Keep ICC profile from the input image in the output image where possible. + * @returns A sharp instance that can be used to chain operations + */ + keepIccProfile(): Sharp; + + /** + * Transform using an ICC profile and attach to the output image. + * @param {string} icc - Absolute filesystem path to output ICC profile or built-in profile name (srgb, p3, cmyk). + * @returns A sharp instance that can be used to chain operations + * @throws {Error} Invalid parameters + */ + withIccProfile(icc: string, options?: WithIccProfileOptions): Sharp; + + /** + * Keep all XMP metadata from the input image in the output image. + * @returns A sharp instance that can be used to chain operations + */ + keepXmp(): Sharp; + + /** + * Set XMP metadata in the output image. + * @param {string} xmp - String containing XMP metadata to be embedded in the output image. + * @returns A sharp instance that can be used to chain operations + * @throws {Error} Invalid parameters + */ + withXmp(xmp: string): Sharp; + + /** + * Include all metadata (EXIF, XMP, IPTC) from the input image in the output image. + * The default behaviour, when withMetadata is not used, is to strip all metadata and convert to the device-independent sRGB colour space. + * This will also convert to and add a web-friendly sRGB ICC profile. + * @param withMetadata + * @throws {Error} Invalid parameters. + */ + withMetadata(withMetadata?: WriteableMetadata): Sharp; + + /** + * Use these JPEG options for output image. + * @param options Output options. + * @throws {Error} Invalid options + * @returns A sharp instance that can be used to chain operations + */ + jpeg(options?: JpegOptions): Sharp; + + /** + * Use these JP2 (JPEG 2000) options for output image. + * @param options Output options. + * @throws {Error} Invalid options + * @returns A sharp instance that can be used to chain operations + */ + jp2(options?: Jp2Options): Sharp; + + /** + * Use these JPEG-XL (JXL) options for output image. + * This feature is experimental, please do not use in production systems. + * Requires libvips compiled with support for libjxl. + * The prebuilt binaries do not include this. + * Image metadata (EXIF, XMP) is unsupported. + * @param options Output options. + * @throws {Error} Invalid options + * @returns A sharp instance that can be used to chain operations + */ + jxl(options?: JxlOptions): Sharp; + + /** + * Use these PNG options for output image. + * PNG output is always full colour at 8 or 16 bits per pixel. + * Indexed PNG input at 1, 2 or 4 bits per pixel is converted to 8 bits per pixel. + * @param options Output options. + * @throws {Error} Invalid options + * @returns A sharp instance that can be used to chain operations + */ + png(options?: PngOptions): Sharp; + + /** + * Use these WebP options for output image. + * @param options Output options. + * @throws {Error} Invalid options + * @returns A sharp instance that can be used to chain operations + */ + webp(options?: WebpOptions): Sharp; + + /** + * Use these GIF options for output image. + * Requires libvips compiled with support for ImageMagick or GraphicsMagick. The prebuilt binaries do not include this - see installing a custom libvips. + * @param options Output options. + * @throws {Error} Invalid options + * @returns A sharp instance that can be used to chain operations + */ + gif(options?: GifOptions): Sharp; + + /** + * Use these AVIF options for output image. + * @param options Output options. + * @throws {Error} Invalid options + * @returns A sharp instance that can be used to chain operations + */ + avif(options?: AvifOptions): Sharp; + + /** + * Use these HEIF options for output image. + * Support for patent-encumbered HEIC images requires the use of a globally-installed libvips compiled with support for libheif, libde265 and x265. + * @param options Output options. + * @throws {Error} Invalid options + * @returns A sharp instance that can be used to chain operations + */ + heif(options?: HeifOptions): Sharp; + + /** + * Use these TIFF options for output image. + * @param options Output options. + * @throws {Error} Invalid options + * @returns A sharp instance that can be used to chain operations + */ + tiff(options?: TiffOptions): Sharp; + + /** + * Force output to be raw, uncompressed uint8 pixel data. + * @param options Raw output options. + * @throws {Error} Invalid options + * @returns A sharp instance that can be used to chain operations + */ + raw(options?: RawOptions): Sharp; + + /** + * Force output to a given format. + * @param format a String or an Object with an 'id' attribute + * @param options output options + * @throws {Error} Unsupported format or options + * @returns A sharp instance that can be used to chain operations + */ + toFormat( + format: keyof FormatEnum | AvailableFormatInfo, + options?: + | OutputOptions + | JpegOptions + | PngOptions + | WebpOptions + | AvifOptions + | HeifOptions + | JxlOptions + | GifOptions + | Jp2Options + | TiffOptions, + ): Sharp; + + /** + * Use tile-based deep zoom (image pyramid) output. + * Set the format and options for tile images via the toFormat, jpeg, png or webp functions. + * Use a .zip or .szi file extension with toFile to write to a compressed archive file format. + * @param tile tile options + * @throws {Error} Invalid options + * @returns A sharp instance that can be used to chain operations + */ + tile(tile?: TileOptions): Sharp; + + /** + * Set a timeout for processing, in seconds. Use a value of zero to continue processing indefinitely, the default behaviour. + * The clock starts when libvips opens an input image for processing. Time spent waiting for a libuv thread to become available is not included. + * @param options Object with a `seconds` attribute between 0 and 3600 (number) + * @throws {Error} Invalid options + * @returns A sharp instance that can be used to chain operations + */ + timeout(options: TimeoutOptions): Sharp; + + //#endregion + + //#region Resize functions + + /** + * Resize image to width, height or width x height. + * + * When both a width and height are provided, the possible methods by which the image should fit these are: + * - cover: Crop to cover both provided dimensions (the default). + * - contain: Embed within both provided dimensions. + * - fill: Ignore the aspect ratio of the input and stretch to both provided dimensions. + * - inside: Preserving aspect ratio, resize the image to be as large as possible while ensuring its dimensions are less than or equal to both those specified. + * - outside: Preserving aspect ratio, resize the image to be as small as possible while ensuring its dimensions are greater than or equal to both those specified. + * Some of these values are based on the object-fit CSS property. + * + * When using a fit of cover or contain, the default position is centre. Other options are: + * - sharp.position: top, right top, right, right bottom, bottom, left bottom, left, left top. + * - sharp.gravity: north, northeast, east, southeast, south, southwest, west, northwest, center or centre. + * - sharp.strategy: cover only, dynamically crop using either the entropy or attention strategy. Some of these values are based on the object-position CSS property. + * + * The experimental strategy-based approach resizes so one dimension is at its target length then repeatedly ranks edge regions, + * discarding the edge with the lowest score based on the selected strategy. + * - entropy: focus on the region with the highest Shannon entropy. + * - attention: focus on the region with the highest luminance frequency, colour saturation and presence of skin tones. + * + * Possible interpolation kernels are: + * - nearest: Use nearest neighbour interpolation. + * - cubic: Use a Catmull-Rom spline. + * - lanczos2: Use a Lanczos kernel with a=2. + * - lanczos3: Use a Lanczos kernel with a=3 (the default). + * + * @param width pixels wide the resultant image should be. Use null or undefined to auto-scale the width to match the height. + * @param height pixels high the resultant image should be. Use null or undefined to auto-scale the height to match the width. + * @param options resize options + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + resize(widthOrOptions?: number | ResizeOptions | null, height?: number | null, options?: ResizeOptions): Sharp; + + /** + * Shorthand for resize(null, null, options); + * + * @param options resize options + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + resize(options: ResizeOptions): Sharp; + + /** + * Extend / pad / extrude one or more edges of the image with either + * the provided background colour or pixels derived from the image. + * This operation will always occur after resizing and extraction, if any. + * @param extend single pixel count to add to all edges or an Object with per-edge counts + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + extend(extend: number | ExtendOptions): Sharp; + + /** + * Extract a region of the image. + * - Use extract() before resize() for pre-resize extraction. + * - Use extract() after resize() for post-resize extraction. + * - Use extract() before and after for both. + * + * @param region The region to extract + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + extract(region: Region): Sharp; + + /** + * Trim pixels from all edges that contain values similar to the given background colour, which defaults to that of the top-left pixel. + * Images with an alpha channel will use the combined bounding box of alpha and non-alpha channels. + * The info response Object will contain trimOffsetLeft and trimOffsetTop properties. + * @param options trim options + * @throws {Error} Invalid parameters + * @returns A sharp instance that can be used to chain operations + */ + trim(options?: TrimOptions): Sharp; + + //#endregion + } + + type SharpInput = Buffer + | ArrayBuffer + | Uint8Array + | Uint8ClampedArray + | Int8Array + | Uint16Array + | Int16Array + | Uint32Array + | Int32Array + | Float32Array + | Float64Array + | string; + + interface SharpOptions { + /** + * Auto-orient based on the EXIF `Orientation` tag, if present. + * Mirroring is supported and may infer the use of a flip operation. + * + * Using this option will remove the EXIF `Orientation` tag, if any. + */ + autoOrient?: boolean | undefined; + /** + * When to abort processing of invalid pixel data, one of (in order of sensitivity): + * 'none' (least), 'truncated', 'error' or 'warning' (most), highers level imply lower levels, invalid metadata will always abort. (optional, default 'warning') + */ + failOn?: FailOnOptions | undefined; + /** + * By default halt processing and raise an error when loading invalid images. + * Set this flag to false if you'd rather apply a "best effort" to decode images, + * even if the data is corrupt or invalid. (optional, default true) + * + * @deprecated Use `failOn` instead + */ + failOnError?: boolean | undefined; + /** + * Do not process input images where the number of pixels (width x height) exceeds this limit. + * Assumes image dimensions contained in the input metadata can be trusted. + * An integral Number of pixels, zero or false to remove limit, true to use default limit of 268402689 (0x3FFF x 0x3FFF). (optional, default 268402689) + */ + limitInputPixels?: number | boolean | undefined; + /** Set this to true to remove safety features that help prevent memory exhaustion (SVG, PNG). (optional, default false) */ + unlimited?: boolean | undefined; + /** Set this to false to use random access rather than sequential read. Some operations will do this automatically. */ + sequentialRead?: boolean | undefined; + /** Number representing the DPI for vector images in the range 1 to 100000. (optional, default 72) */ + density?: number | undefined; + /** Should the embedded ICC profile, if any, be ignored. */ + ignoreIcc?: boolean | undefined; + /** Number of pages to extract for multi-page input (GIF, TIFF, PDF), use -1 for all pages */ + pages?: number | undefined; + /** Page number to start extracting from for multi-page input (GIF, TIFF, PDF), zero based. (optional, default 0) */ + page?: number | undefined; + /** TIFF specific input options */ + tiff?: TiffInputOptions | undefined; + /** SVG specific input options */ + svg?: SvgInputOptions | undefined; + /** PDF specific input options */ + pdf?: PdfInputOptions | undefined; + /** OpenSlide specific input options */ + openSlide?: OpenSlideInputOptions | undefined; + /** JPEG 2000 specific input options */ + jp2?: Jp2InputOptions | undefined; + /** Deprecated: use tiff.subifd instead */ + subifd?: number | undefined; + /** Deprecated: use pdf.background instead */ + pdfBackground?: Colour | Color | undefined; + /** Deprecated: use openSlide.level instead */ + level?: number | undefined; + /** Set to `true` to read all frames/pages of an animated image (equivalent of setting `pages` to `-1`). (optional, default false) */ + animated?: boolean | undefined; + /** Describes raw pixel input image data. See raw() for pixel ordering. */ + raw?: CreateRaw | undefined; + /** Describes a new image to be created. */ + create?: Create | undefined; + /** Describes a new text image to be created. */ + text?: CreateText | undefined; + /** Describes how array of input images should be joined. */ + join?: Join | undefined; + } + + interface CacheOptions { + /** Is the maximum memory in MB to use for this cache (optional, default 50) */ + memory?: number | undefined; + /** Is the maximum number of files to hold open (optional, default 20) */ + files?: number | undefined; + /** Is the maximum number of operations to cache (optional, default 100) */ + items?: number | undefined; + } + + interface TimeoutOptions { + /** Number of seconds after which processing will be stopped (default 0, eg disabled) */ + seconds: number; + } + + interface SharpCounters { + /** The number of tasks this module has queued waiting for libuv to provide a worker thread from its pool. */ + queue: number; + /** The number of resize tasks currently being processed. */ + process: number; + } + + interface Raw { + width: number; + height: number; + channels: Channels; + } + + interface CreateRaw extends Raw { + /** Specifies that the raw input has already been premultiplied, set to true to avoid sharp premultiplying the image. (optional, default false) */ + premultiplied?: boolean | undefined; + /** The height of each page/frame for animated images, must be an integral factor of the overall image height. */ + pageHeight?: number | undefined; + } + + type CreateChannels = 3 | 4; + + interface Create { + /** Number of pixels wide. */ + width: number; + /** Number of pixels high. */ + height: number; + /** Number of bands, 3 for RGB, 4 for RGBA */ + channels: CreateChannels; + /** Parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. */ + background: Colour | Color; + /** Describes a noise to be created. */ + noise?: Noise | undefined; + /** The height of each page/frame for animated images, must be an integral factor of the overall image height. */ + pageHeight?: number | undefined; + + } + + interface CreateText { + /** Text to render as a UTF-8 string. It can contain Pango markup, for example `LeMonde`. */ + text: string; + /** Font name to render with. */ + font?: string; + /** Absolute filesystem path to a font file that can be used by `font`. */ + fontfile?: string; + /** Integral number of pixels to word-wrap at. Lines of text wider than this will be broken at word boundaries. (optional, default `0`) */ + width?: number; + /** + * Integral number of pixels high. When defined, `dpi` will be ignored and the text will automatically fit the pixel resolution + * defined by `width` and `height`. Will be ignored if `width` is not specified or set to 0. (optional, default `0`) + */ + height?: number; + /** Text alignment ('left', 'centre', 'center', 'right'). (optional, default 'left') */ + align?: TextAlign; + /** Set this to true to apply justification to the text. (optional, default `false`) */ + justify?: boolean; + /** The resolution (size) at which to render the text. Does not take effect if `height` is specified. (optional, default `72`) */ + dpi?: number; + /** + * Set this to true to enable RGBA output. This is useful for colour emoji rendering, + * or support for pango markup features like `Red!`. (optional, default `false`) + */ + rgba?: boolean; + /** Text line height in points. Will use the font line height if none is specified. (optional, default `0`) */ + spacing?: number; + /** Word wrapping style when width is provided, one of: 'word', 'char', 'word-char' (prefer word, fallback to char) or 'none' */ + wrap?: TextWrap; + } + + interface Join { + /** Number of images per row. */ + across?: number | undefined; + /** Treat input as frames of an animated image. */ + animated?: boolean | undefined; + /** Space between images, in pixels. */ + shim?: number | undefined; + /** Background colour. */ + background?: Colour | Color | undefined; + /** Horizontal alignment. */ + halign?: HorizontalAlignment | undefined; + /** Vertical alignment. */ + valign?: VerticalAlignment | undefined; + } + + interface TiffInputOptions { + /** Sub Image File Directory to extract, defaults to main image. Use -1 for all subifds. */ + subifd?: number | undefined; + } + + interface SvgInputOptions { + /** Custom CSS for SVG input, applied with a User Origin during the CSS cascade. */ + stylesheet?: string | undefined; + /** Set to `true` to render SVG input at 32-bits per channel (128-bit) instead of 8-bits per channel (32-bit) RGBA. */ + highBitdepth?: boolean | undefined; + } + + interface PdfInputOptions { + /** Background colour to use when PDF is partially transparent. Requires the use of a globally-installed libvips compiled with support for PDFium, Poppler, ImageMagick or GraphicsMagick. */ + background?: Colour | Color | undefined; + } + + interface OpenSlideInputOptions { + /** Level to extract from a multi-level input, zero based. (optional, default 0) */ + level?: number | undefined; + } + + interface Jp2InputOptions { + /** Set to `true` to load JPEG 2000 images using [oneshot mode](https://github.com/libvips/libvips/issues/4205) */ + oneshot?: boolean | undefined; + } + + interface ExifDir { + [k: string]: string; + } + + interface Exif { + 'IFD0'?: ExifDir; + 'IFD1'?: ExifDir; + 'IFD2'?: ExifDir; + 'IFD3'?: ExifDir; + } + + interface WriteableMetadata { + /** Number of pixels per inch (DPI) */ + density?: number | undefined; + /** Value between 1 and 8, used to update the EXIF Orientation tag. */ + orientation?: number | undefined; + /** + * Filesystem path to output ICC profile, defaults to sRGB. + * @deprecated Use `withIccProfile()` instead. + */ + icc?: string | undefined; + /** + * Object keyed by IFD0, IFD1 etc. of key/value string pairs to write as EXIF data. + * @deprecated Use `withExif()` or `withExifMerge()` instead. + */ + exif?: Exif | undefined; + } + + interface Metadata { + /** Number value of the EXIF Orientation header, if present */ + orientation?: number | undefined; + /** Name of decoder used to decompress image data e.g. jpeg, png, webp, gif, svg */ + format: keyof FormatEnum; + /** Total size of image in bytes, for Stream and Buffer input only */ + size?: number | undefined; + /** Number of pixels wide (EXIF orientation is not taken into consideration) */ + width: number; + /** Number of pixels high (EXIF orientation is not taken into consideration) */ + height: number; + /** Any changed metadata after the image orientation is applied. */ + autoOrient: { + /** Number of pixels wide (EXIF orientation is taken into consideration) */ + width: number; + /** Number of pixels high (EXIF orientation is taken into consideration) */ + height: number; + }; + /** Name of colour space interpretation */ + space: keyof ColourspaceEnum; + /** Number of bands e.g. 3 for sRGB, 4 for CMYK */ + channels: Channels; + /** Name of pixel depth format e.g. uchar, char, ushort, float ... */ + depth: keyof DepthEnum; + /** Number of pixels per inch (DPI), if present */ + density?: number | undefined; + /** String containing JPEG chroma subsampling, 4:2:0 or 4:4:4 for RGB, 4:2:0:4 or 4:4:4:4 for CMYK */ + chromaSubsampling?: string | undefined; + /** Boolean indicating whether the image is interlaced using a progressive scan */ + isProgressive: boolean; + /** Boolean indicating whether the image is palette-based (GIF, PNG). */ + isPalette: boolean; + /** Number of bits per sample for each channel (GIF, PNG). */ + bitsPerSample?: number | undefined; + /** Number of pages/frames contained within the image, with support for TIFF, HEIF, PDF, animated GIF and animated WebP */ + pages?: number | undefined; + /** Number of pixels high each page in a multi-page image will be. */ + pageHeight?: number | undefined; + /** Number of times to loop an animated image, zero refers to a continuous loop. */ + loop?: number | undefined; + /** Delay in ms between each page in an animated image, provided as an array of integers. */ + delay?: number[] | undefined; + /** Number of the primary page in a HEIF image */ + pagePrimary?: number | undefined; + /** Boolean indicating the presence of an embedded ICC profile */ + hasProfile: boolean; + /** Boolean indicating the presence of an alpha transparency channel */ + hasAlpha: boolean; + /** Buffer containing raw EXIF data, if present */ + exif?: Buffer | undefined; + /** Buffer containing raw ICC profile data, if present */ + icc?: Buffer | undefined; + /** Buffer containing raw IPTC data, if present */ + iptc?: Buffer | undefined; + /** Buffer containing raw XMP data, if present */ + xmp?: Buffer | undefined; + /** String containing XMP data, if valid UTF-8 */ + xmpAsString?: string | undefined; + /** Buffer containing raw TIFFTAG_PHOTOSHOP data, if present */ + tifftagPhotoshop?: Buffer | undefined; + /** The encoder used to compress an HEIF file, `av1` (AVIF) or `hevc` (HEIC) */ + compression?: 'av1' | 'hevc'; + /** Default background colour, if present, for PNG (bKGD) and GIF images */ + background?: { r: number; g: number; b: number } | { gray: number }; + /** Details of each level in a multi-level image provided as an array of objects, requires libvips compiled with support for OpenSlide */ + levels?: LevelMetadata[] | undefined; + /** Number of Sub Image File Directories in an OME-TIFF image */ + subifds?: number | undefined; + /** The unit of resolution (density) */ + resolutionUnit?: 'inch' | 'cm' | undefined; + /** String containing format for images loaded via *magick */ + formatMagick?: string | undefined; + /** Array of keyword/text pairs representing PNG text blocks, if present. */ + comments?: CommentsMetadata[] | undefined; + } + + interface LevelMetadata { + width: number; + height: number; + } + + interface CommentsMetadata { + keyword: string; + text: string; + } + + interface Stats { + /** Array of channel statistics for each channel in the image. */ + channels: ChannelStats[]; + /** Value to identify if the image is opaque or transparent, based on the presence and use of alpha channel */ + isOpaque: boolean; + /** Histogram-based estimation of greyscale entropy, discarding alpha channel if any (experimental) */ + entropy: number; + /** Estimation of greyscale sharpness based on the standard deviation of a Laplacian convolution, discarding alpha channel if any (experimental) */ + sharpness: number; + /** Object containing most dominant sRGB colour based on a 4096-bin 3D histogram (experimental) */ + dominant: { r: number; g: number; b: number }; + } + + interface ChannelStats { + /** minimum value in the channel */ + min: number; + /** maximum value in the channel */ + max: number; + /** sum of all values in a channel */ + sum: number; + /** sum of squared values in a channel */ + squaresSum: number; + /** mean of the values in a channel */ + mean: number; + /** standard deviation for the values in a channel */ + stdev: number; + /** x-coordinate of one of the pixel where the minimum lies */ + minX: number; + /** y-coordinate of one of the pixel where the minimum lies */ + minY: number; + /** x-coordinate of one of the pixel where the maximum lies */ + maxX: number; + /** y-coordinate of one of the pixel where the maximum lies */ + maxY: number; + } + + interface OutputOptions { + /** Force format output, otherwise attempt to use input format (optional, default true) */ + force?: boolean | undefined; + } + + interface WithIccProfileOptions { + /** Should the ICC profile be included in the output image metadata? (optional, default true) */ + attach?: boolean | undefined; + } + + interface JpegOptions extends OutputOptions { + /** Quality, integer 1-100 (optional, default 80) */ + quality?: number | undefined; + /** Use progressive (interlace) scan (optional, default false) */ + progressive?: boolean | undefined; + /** Set to '4:4:4' to prevent chroma subsampling when quality <= 90 (optional, default '4:2:0') */ + chromaSubsampling?: string | undefined; + /** Apply trellis quantisation (optional, default false) */ + trellisQuantisation?: boolean | undefined; + /** Apply overshoot deringing (optional, default false) */ + overshootDeringing?: boolean | undefined; + /** Optimise progressive scans, forces progressive (optional, default false) */ + optimiseScans?: boolean | undefined; + /** Alternative spelling of optimiseScans (optional, default false) */ + optimizeScans?: boolean | undefined; + /** Optimise Huffman coding tables (optional, default true) */ + optimiseCoding?: boolean | undefined; + /** Alternative spelling of optimiseCoding (optional, default true) */ + optimizeCoding?: boolean | undefined; + /** Quantization table to use, integer 0-8 (optional, default 0) */ + quantisationTable?: number | undefined; + /** Alternative spelling of quantisationTable (optional, default 0) */ + quantizationTable?: number | undefined; + /** Use mozjpeg defaults (optional, default false) */ + mozjpeg?: boolean | undefined; + } + + interface Jp2Options extends OutputOptions { + /** Quality, integer 1-100 (optional, default 80) */ + quality?: number; + /** Use lossless compression mode (optional, default false) */ + lossless?: boolean; + /** Horizontal tile size (optional, default 512) */ + tileWidth?: number; + /** Vertical tile size (optional, default 512) */ + tileHeight?: number; + /** Set to '4:2:0' to enable chroma subsampling (optional, default '4:4:4') */ + chromaSubsampling?: '4:4:4' | '4:2:0'; + } + + interface JxlOptions extends OutputOptions { + /** Maximum encoding error, between 0 (highest quality) and 15 (lowest quality) (optional, default 1.0) */ + distance?: number; + /** Calculate distance based on JPEG-like quality, between 1 and 100, overrides distance if specified */ + quality?: number; + /** Target decode speed tier, between 0 (highest quality) and 4 (lowest quality) (optional, default 0) */ + decodingTier?: number; + /** Use lossless compression (optional, default false) */ + lossless?: boolean; + /** CPU effort, between 3 (fastest) and 9 (slowest) (optional, default 7) */ + effort?: number | undefined; + } + + interface WebpOptions extends OutputOptions, AnimationOptions { + /** Quality, integer 1-100 (optional, default 80) */ + quality?: number | undefined; + /** Quality of alpha layer, number from 0-100 (optional, default 100) */ + alphaQuality?: number | undefined; + /** Use lossless compression mode (optional, default false) */ + lossless?: boolean | undefined; + /** Use near_lossless compression mode (optional, default false) */ + nearLossless?: boolean | undefined; + /** Use high quality chroma subsampling (optional, default false) */ + smartSubsample?: boolean | undefined; + /** Auto-adjust the deblocking filter, slow but can improve low contrast edges (optional, default false) */ + smartDeblock?: boolean | undefined; + /** Level of CPU effort to reduce file size, integer 0-6 (optional, default 4) */ + effort?: number | undefined; + /** Prevent use of animation key frames to minimise file size (slow) (optional, default false) */ + minSize?: boolean; + /** Allow mixture of lossy and lossless animation frames (slow) (optional, default false) */ + mixed?: boolean; + /** Preset options: one of default, photo, picture, drawing, icon, text (optional, default 'default') */ + preset?: keyof PresetEnum | undefined; + } + + interface AvifOptions extends OutputOptions { + /** quality, integer 1-100 (optional, default 50) */ + quality?: number | undefined; + /** use lossless compression (optional, default false) */ + lossless?: boolean | undefined; + /** Level of CPU effort to reduce file size, between 0 (fastest) and 9 (slowest) (optional, default 4) */ + effort?: number | undefined; + /** set to '4:2:0' to use chroma subsampling, requires libvips v8.11.0 (optional, default '4:4:4') */ + chromaSubsampling?: string | undefined; + /** Set bitdepth to 8, 10 or 12 bit (optional, default 8) */ + bitdepth?: 8 | 10 | 12 | undefined; + } + + interface HeifOptions extends OutputOptions { + /** quality, integer 1-100 (optional, default 50) */ + quality?: number | undefined; + /** compression format: av1, hevc (optional, default 'av1') */ + compression?: 'av1' | 'hevc' | undefined; + /** use lossless compression (optional, default false) */ + lossless?: boolean | undefined; + /** Level of CPU effort to reduce file size, between 0 (fastest) and 9 (slowest) (optional, default 4) */ + effort?: number | undefined; + /** set to '4:2:0' to use chroma subsampling (optional, default '4:4:4') */ + chromaSubsampling?: string | undefined; + /** Set bitdepth to 8, 10 or 12 bit (optional, default 8) */ + bitdepth?: 8 | 10 | 12 | undefined; + } + + interface GifOptions extends OutputOptions, AnimationOptions { + /** Re-use existing palette, otherwise generate new (slow) */ + reuse?: boolean | undefined; + /** Use progressive (interlace) scan */ + progressive?: boolean | undefined; + /** Maximum number of palette entries, including transparency, between 2 and 256 (optional, default 256) */ + colours?: number | undefined; + /** Alternative spelling of "colours". Maximum number of palette entries, including transparency, between 2 and 256 (optional, default 256) */ + colors?: number | undefined; + /** Level of CPU effort to reduce file size, between 1 (fastest) and 10 (slowest) (optional, default 7) */ + effort?: number | undefined; + /** Level of Floyd-Steinberg error diffusion, between 0 (least) and 1 (most) (optional, default 1.0) */ + dither?: number | undefined; + /** Maximum inter-frame error for transparency, between 0 (lossless) and 32 (optional, default 0) */ + interFrameMaxError?: number | undefined; + /** Maximum inter-palette error for palette reuse, between 0 and 256 (optional, default 3) */ + interPaletteMaxError?: number | undefined; + /** Keep duplicate frames in the output instead of combining them (optional, default false) */ + keepDuplicateFrames?: boolean | undefined; + } + + interface TiffOptions extends OutputOptions { + /** Quality, integer 1-100 (optional, default 80) */ + quality?: number | undefined; + /** Compression options: none, jpeg, deflate, packbits, ccittfax4, lzw, webp, zstd, jp2k (optional, default 'jpeg') */ + compression?: string | undefined; + /** Compression predictor options: none, horizontal, float (optional, default 'horizontal') */ + predictor?: string | undefined; + /** Write an image pyramid (optional, default false) */ + pyramid?: boolean | undefined; + /** Write a tiled tiff (optional, default false) */ + tile?: boolean | undefined; + /** Horizontal tile size (optional, default 256) */ + tileWidth?: number | undefined; + /** Vertical tile size (optional, default 256) */ + tileHeight?: number | undefined; + /** Horizontal resolution in pixels/mm (optional, default 1.0) */ + xres?: number | undefined; + /** Vertical resolution in pixels/mm (optional, default 1.0) */ + yres?: number | undefined; + /** Reduce bitdepth to 1, 2 or 4 bit (optional, default 8) */ + bitdepth?: 1 | 2 | 4 | 8 | undefined; + /** Write 1-bit images as miniswhite (optional, default false) */ + miniswhite?: boolean | undefined; + /** Resolution unit options: inch, cm (optional, default 'inch') */ + resolutionUnit?: 'inch' | 'cm' | undefined; + } + + interface PngOptions extends OutputOptions { + /** Use progressive (interlace) scan (optional, default false) */ + progressive?: boolean | undefined; + /** zlib compression level, 0-9 (optional, default 6) */ + compressionLevel?: number | undefined; + /** Use adaptive row filtering (optional, default false) */ + adaptiveFiltering?: boolean | undefined; + /** Use the lowest number of colours needed to achieve given quality (optional, default `100`) */ + quality?: number | undefined; + /** Level of CPU effort to reduce file size, between 1 (fastest) and 10 (slowest), sets palette to true (optional, default 7) */ + effort?: number | undefined; + /** Quantise to a palette-based image with alpha transparency support (optional, default false) */ + palette?: boolean | undefined; + /** Maximum number of palette entries (optional, default 256) */ + colours?: number | undefined; + /** Alternative Spelling of "colours". Maximum number of palette entries (optional, default 256) */ + colors?: number | undefined; + /** Level of Floyd-Steinberg error diffusion (optional, default 1.0) */ + dither?: number | undefined; + } + + interface RotateOptions { + /** parsed by the color module to extract values for red, green, blue and alpha. (optional, default "#000000") */ + background?: Colour | Color | undefined; + } + + type Precision = 'integer' | 'float' | 'approximate'; + + interface BlurOptions { + /** A value between 0.3 and 1000 representing the sigma of the Gaussian mask, where `sigma = 1 + radius / 2` */ + sigma: number; + /** A value between 0.001 and 1. A smaller value will generate a larger, more accurate mask. */ + minAmplitude?: number; + /** How accurate the operation should be, one of: integer, float, approximate. (optional, default "integer") */ + precision?: Precision | undefined; + } + + interface FlattenOptions { + /** background colour, parsed by the color module, defaults to black. (optional, default {r:0,g:0,b:0}) */ + background?: Colour | Color | undefined; + } + + interface NegateOptions { + /** whether or not to negate any alpha channel. (optional, default true) */ + alpha?: boolean | undefined; + } + + interface NormaliseOptions { + /** Percentile below which luminance values will be underexposed. */ + lower?: number | undefined; + /** Percentile above which luminance values will be overexposed. */ + upper?: number | undefined; + } + + interface ResizeOptions { + /** Alternative means of specifying width. If both are present this takes priority. */ + width?: number | undefined; + /** Alternative means of specifying height. If both are present this takes priority. */ + height?: number | undefined; + /** How the image should be resized to fit both provided dimensions, one of cover, contain, fill, inside or outside. (optional, default 'cover') */ + fit?: keyof FitEnum | undefined; + /** Position, gravity or strategy to use when fit is cover or contain. (optional, default 'centre') */ + position?: number | string | undefined; + /** Background colour when using a fit of contain, parsed by the color module, defaults to black without transparency. (optional, default {r:0,g:0,b:0,alpha:1}) */ + background?: Colour | Color | undefined; + /** The kernel to use for image reduction. (optional, default 'lanczos3') */ + kernel?: keyof KernelEnum | undefined; + /** Do not enlarge if the width or height are already less than the specified dimensions, equivalent to GraphicsMagick's > geometry option. (optional, default false) */ + withoutEnlargement?: boolean | undefined; + /** Do not reduce if the width or height are already greater than the specified dimensions, equivalent to GraphicsMagick's < geometry option. (optional, default false) */ + withoutReduction?: boolean | undefined; + /** Take greater advantage of the JPEG and WebP shrink-on-load feature, which can lead to a slight moiré pattern on some images. (optional, default true) */ + fastShrinkOnLoad?: boolean | undefined; + } + + interface Region { + /** zero-indexed offset from left edge */ + left: number; + /** zero-indexed offset from top edge */ + top: number; + /** dimension of extracted image */ + width: number; + /** dimension of extracted image */ + height: number; + } + + interface Noise { + /** type of generated noise, currently only gaussian is supported. */ + type: 'gaussian'; + /** mean of pixels in generated noise. */ + mean?: number | undefined; + /** standard deviation of pixels in generated noise. */ + sigma?: number | undefined; + } + + type ExtendWith = 'background' | 'copy' | 'repeat' | 'mirror'; + + interface ExtendOptions { + /** single pixel count to top edge (optional, default 0) */ + top?: number | undefined; + /** single pixel count to left edge (optional, default 0) */ + left?: number | undefined; + /** single pixel count to bottom edge (optional, default 0) */ + bottom?: number | undefined; + /** single pixel count to right edge (optional, default 0) */ + right?: number | undefined; + /** background colour, parsed by the color module, defaults to black without transparency. (optional, default {r:0,g:0,b:0,alpha:1}) */ + background?: Colour | Color | undefined; + /** how the extension is done, one of: "background", "copy", "repeat", "mirror" (optional, default `'background'`) */ + extendWith?: ExtendWith | undefined; + } + + interface TrimOptions { + /** Background colour, parsed by the color module, defaults to that of the top-left pixel. (optional) */ + background?: Colour | Color | undefined; + /** Allowed difference from the above colour, a positive number. (optional, default 10) */ + threshold?: number | undefined; + /** Does the input more closely resemble line art (e.g. vector) rather than being photographic? (optional, default false) */ + lineArt?: boolean | undefined; + } + + interface RawOptions { + depth?: 'char' | 'uchar' | 'short' | 'ushort' | 'int' | 'uint' | 'float' | 'complex' | 'double' | 'dpcomplex'; + } + + /** 1 for grayscale, 2 for grayscale + alpha, 3 for sRGB, 4 for CMYK or RGBA */ + type Channels = 1 | 2 | 3 | 4; + + interface RGBA { + r?: number | undefined; + g?: number | undefined; + b?: number | undefined; + alpha?: number | undefined; + } + + type Colour = string | RGBA; + type Color = Colour; + + interface Kernel { + /** width of the kernel in pixels. */ + width: number; + /** height of the kernel in pixels. */ + height: number; + /** Array of length width*height containing the kernel values. */ + kernel: ArrayLike; + /** the scale of the kernel in pixels. (optional, default sum) */ + scale?: number | undefined; + /** the offset of the kernel in pixels. (optional, default 0) */ + offset?: number | undefined; + } + + interface ClaheOptions { + /** width of the region */ + width: number; + /** height of the region */ + height: number; + /** max slope of the cumulative contrast. A value of 0 disables contrast limiting. Valid values are integers in the range 0-100 (inclusive) (optional, default 3) */ + maxSlope?: number | undefined; + } + + interface ThresholdOptions { + /** convert to single channel greyscale. (optional, default true) */ + greyscale?: boolean | undefined; + /** alternative spelling for greyscale. (optional, default true) */ + grayscale?: boolean | undefined; + } + + interface OverlayOptions extends SharpOptions { + /** Buffer containing image data, String containing the path to an image file, or Create object */ + input?: string | Buffer | { create: Create } | { text: CreateText } | { raw: CreateRaw } | undefined; + /** how to blend this image with the image below. (optional, default `'over'`) */ + blend?: Blend | undefined; + /** gravity at which to place the overlay. (optional, default 'centre') */ + gravity?: Gravity | undefined; + /** the pixel offset from the top edge. */ + top?: number | undefined; + /** the pixel offset from the left edge. */ + left?: number | undefined; + /** set to true to repeat the overlay image across the entire image with the given gravity. (optional, default false) */ + tile?: boolean | undefined; + /** Set to true to avoid premultipling the image below. Equivalent to the --premultiplied vips option. */ + premultiplied?: boolean | undefined; + /** number representing the DPI for vector overlay image. (optional, default 72)*/ + density?: number | undefined; + /** Set to true to read all frames/pages of an animated image. (optional, default false) */ + animated?: boolean | undefined; + /** see sharp() constructor, (optional, default 'warning') */ + failOn?: FailOnOptions | undefined; + /** see sharp() constructor, (optional, default 268402689) */ + limitInputPixels?: number | boolean | undefined; + /** see sharp() constructor, (optional, default false) */ + autoOrient?: boolean | undefined; + } + + interface TileOptions { + /** Tile size in pixels, a value between 1 and 8192. (optional, default 256) */ + size?: number | undefined; + /** Tile overlap in pixels, a value between 0 and 8192. (optional, default 0) */ + overlap?: number | undefined; + /** Tile angle of rotation, must be a multiple of 90. (optional, default 0) */ + angle?: number | undefined; + /** background colour, parsed by the color module, defaults to white without transparency. (optional, default {r:255,g:255,b:255,alpha:1}) */ + background?: string | RGBA | undefined; + /** How deep to make the pyramid, possible values are "onepixel", "onetile" or "one" (default based on layout) */ + depth?: string | undefined; + /** Threshold to skip tile generation, a value 0 - 255 for 8-bit images or 0 - 65535 for 16-bit images */ + skipBlanks?: number | undefined; + /** Tile container, with value fs (filesystem) or zip (compressed file). (optional, default 'fs') */ + container?: TileContainer | undefined; + /** Filesystem layout, possible values are dz, iiif, iiif3, zoomify or google. (optional, default 'dz') */ + layout?: TileLayout | undefined; + /** Centre image in tile. (optional, default false) */ + centre?: boolean | undefined; + /** Alternative spelling of centre. (optional, default false) */ + center?: boolean | undefined; + /** When layout is iiif/iiif3, sets the @id/id attribute of info.json (optional, default 'https://example.com/iiif') */ + id?: string | undefined; + /** The name of the directory within the zip file when container is `zip`. */ + basename?: string | undefined; + } + + interface AnimationOptions { + /** Number of animation iterations, a value between 0 and 65535. Use 0 for infinite animation. (optional, default 0) */ + loop?: number | undefined; + /** delay(s) between animation frames (in milliseconds), each value between 0 and 65535. (optional) */ + delay?: number | number[] | undefined; + } + + interface SharpenOptions { + /** The sigma of the Gaussian mask, where sigma = 1 + radius / 2, between 0.000001 and 10000 */ + sigma: number; + /** The level of sharpening to apply to "flat" areas, between 0 and 1000000 (optional, default 1.0) */ + m1?: number | undefined; + /** The level of sharpening to apply to "jagged" areas, between 0 and 1000000 (optional, default 2.0) */ + m2?: number | undefined; + /** Threshold between "flat" and "jagged", between 0 and 1000000 (optional, default 2.0) */ + x1?: number | undefined; + /** Maximum amount of brightening, between 0 and 1000000 (optional, default 10.0) */ + y2?: number | undefined; + /** Maximum amount of darkening, between 0 and 1000000 (optional, default 20.0) */ + y3?: number | undefined; + } + + interface AffineOptions { + /** Parsed by the color module to extract values for red, green, blue and alpha. (optional, default "#000000") */ + background?: string | object | undefined; + /** Input horizontal offset (optional, default 0) */ + idx?: number | undefined; + /** Input vertical offset (optional, default 0) */ + idy?: number | undefined; + /** Output horizontal offset (optional, default 0) */ + odx?: number | undefined; + /** Output horizontal offset (optional, default 0) */ + ody?: number | undefined; + /** Interpolator (optional, default sharp.interpolators.bicubic) */ + interpolator?: Interpolators[keyof Interpolators] | undefined; + } + + interface OutputInfo { + format: string; + size: number; + width: number; + height: number; + channels: Channels; + /** indicating if premultiplication was used */ + premultiplied: boolean; + /** Only defined when using a crop strategy */ + cropOffsetLeft?: number | undefined; + /** Only defined when using a crop strategy */ + cropOffsetTop?: number | undefined; + /** Only defined when using a trim method */ + trimOffsetLeft?: number | undefined; + /** Only defined when using a trim method */ + trimOffsetTop?: number | undefined; + /** DPI the font was rendered at, only defined when using `text` input */ + textAutofitDpi?: number | undefined; + /** When using the attention crop strategy, the focal point of the cropped region */ + attentionX?: number | undefined; + attentionY?: number | undefined; + /** Number of pages/frames contained within the image, with support for TIFF, HEIF, PDF, animated GIF and animated WebP */ + pages?: number | undefined; + /** Number of pixels high each page in a multi-page image will be. */ + pageHeight?: number | undefined; + } + + interface AvailableFormatInfo { + id: string; + input: { file: boolean; buffer: boolean; stream: boolean; fileSuffix?: string[] }; + output: { file: boolean; buffer: boolean; stream: boolean; alias?: string[] }; + } + + interface FitEnum { + contain: 'contain'; + cover: 'cover'; + fill: 'fill'; + inside: 'inside'; + outside: 'outside'; + } + + interface KernelEnum { + nearest: 'nearest'; + cubic: 'cubic'; + linear: 'linear'; + mitchell: 'mitchell'; + lanczos2: 'lanczos2'; + lanczos3: 'lanczos3'; + mks2013: 'mks2013'; + mks2021: 'mks2021'; + } + + interface PresetEnum { + default: 'default'; + picture: 'picture'; + photo: 'photo'; + drawing: 'drawing'; + icon: 'icon'; + text: 'text'; + } + + interface BoolEnum { + and: 'and'; + or: 'or'; + eor: 'eor'; + } + + interface ColourspaceEnum { + 'b-w': string; + cmc: string; + cmyk: string; + fourier: string; + grey16: string; + histogram: string; + hsv: string; + lab: string; + labq: string; + labs: string; + lch: string; + matrix: string; + multiband: string; + rgb: string; + rgb16: string; + scrgb: string; + srgb: string; + xyz: string; + yxy: string; + } + + interface DepthEnum { + char: string; + complex: string; + double: string; + dpcomplex: string; + float: string; + int: string; + short: string; + uchar: string; + uint: string; + ushort: string; + } + + type FailOnOptions = 'none' | 'truncated' | 'error' | 'warning'; + + type TextAlign = 'left' | 'centre' | 'center' | 'right'; + + type TextWrap = 'word' | 'char' | 'word-char' | 'none'; + + type HorizontalAlignment = 'left' | 'centre' | 'center' | 'right'; + + type VerticalAlignment = 'top' | 'centre' | 'center' | 'bottom'; + + type TileContainer = 'fs' | 'zip'; + + type TileLayout = 'dz' | 'iiif' | 'iiif3' | 'zoomify' | 'google'; + + type Blend = + | 'clear' + | 'source' + | 'over' + | 'in' + | 'out' + | 'atop' + | 'dest' + | 'dest-over' + | 'dest-in' + | 'dest-out' + | 'dest-atop' + | 'xor' + | 'add' + | 'saturate' + | 'multiply' + | 'screen' + | 'overlay' + | 'darken' + | 'lighten' + | 'color-dodge' + | 'colour-dodge' + | 'color-burn' + | 'colour-burn' + | 'hard-light' + | 'soft-light' + | 'difference' + | 'exclusion'; + + type Gravity = number | string; + + interface GravityEnum { + north: number; + northeast: number; + southeast: number; + south: number; + southwest: number; + west: number; + northwest: number; + east: number; + center: number; + centre: number; + } + + interface StrategyEnum { + entropy: number; + attention: number; + } + + interface FormatEnum { + avif: AvailableFormatInfo; + dcraw: AvailableFormatInfo; + dz: AvailableFormatInfo; + exr: AvailableFormatInfo; + fits: AvailableFormatInfo; + gif: AvailableFormatInfo; + heif: AvailableFormatInfo; + input: AvailableFormatInfo; + jpeg: AvailableFormatInfo; + jpg: AvailableFormatInfo; + jp2: AvailableFormatInfo; + jxl: AvailableFormatInfo; + magick: AvailableFormatInfo; + openslide: AvailableFormatInfo; + pdf: AvailableFormatInfo; + png: AvailableFormatInfo; + ppm: AvailableFormatInfo; + rad: AvailableFormatInfo; + raw: AvailableFormatInfo; + svg: AvailableFormatInfo; + tiff: AvailableFormatInfo; + tif: AvailableFormatInfo; + v: AvailableFormatInfo; + webp: AvailableFormatInfo; + } + + interface CacheResult { + memory: { current: number; high: number; max: number }; + files: { current: number; max: number }; + items: { current: number; max: number }; + } + + interface Interpolators { + /** [Nearest neighbour interpolation](http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation). Suitable for image enlargement only. */ + nearest: 'nearest'; + /** [Bilinear interpolation](http://en.wikipedia.org/wiki/Bilinear_interpolation). Faster than bicubic but with less smooth results. */ + bilinear: 'bilinear'; + /** [Bicubic interpolation](http://en.wikipedia.org/wiki/Bicubic_interpolation) (the default). */ + bicubic: 'bicubic'; + /** + * [LBB interpolation](https://github.com/libvips/libvips/blob/master/libvips/resample/lbb.cpp#L100). + * Prevents some "[acutance](http://en.wikipedia.org/wiki/Acutance)" but typically reduces performance by a factor of 2. + */ + locallyBoundedBicubic: 'lbb'; + /** [Nohalo interpolation](http://eprints.soton.ac.uk/268086/). Prevents acutance but typically reduces performance by a factor of 3. */ + nohalo: 'nohalo'; + /** [VSQBS interpolation](https://github.com/libvips/libvips/blob/master/libvips/resample/vsqbs.cpp#L48). Prevents "staircasing" when enlarging. */ + vertexSplitQuadraticBasisSpline: 'vsqbs'; + } + + type Matrix2x2 = [[number, number], [number, number]]; + type Matrix3x3 = [[number, number, number], [number, number, number], [number, number, number]]; + type Matrix4x4 = [[number, number, number, number], [number, number, number, number], [number, number, number, number], [number, number, number, number]]; +} + +export = sharp; diff --git a/node_modules/sharp/lib/index.js b/node_modules/sharp/lib/index.js new file mode 100644 index 0000000..8cfc08a --- /dev/null +++ b/node_modules/sharp/lib/index.js @@ -0,0 +1,16 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +'use strict'; + +const Sharp = require('./constructor'); +require('./input')(Sharp); +require('./resize')(Sharp); +require('./composite')(Sharp); +require('./operation')(Sharp); +require('./colour')(Sharp); +require('./channel')(Sharp); +require('./output')(Sharp); +require('./utility')(Sharp); + +module.exports = Sharp; diff --git a/node_modules/sharp/lib/input.js b/node_modules/sharp/lib/input.js new file mode 100644 index 0000000..aca0b16 --- /dev/null +++ b/node_modules/sharp/lib/input.js @@ -0,0 +1,811 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +'use strict'; + +const is = require('./is'); +const sharp = require('./sharp'); + +/** + * Justification alignment + * @member + * @private + */ +const align = { + left: 'low', + top: 'low', + low: 'low', + center: 'centre', + centre: 'centre', + right: 'high', + bottom: 'high', + high: 'high' +}; + +const inputStreamParameters = [ + // Limits and error handling + 'failOn', 'limitInputPixels', 'unlimited', + // Format-generic + 'animated', 'autoOrient', 'density', 'ignoreIcc', 'page', 'pages', 'sequentialRead', + // Format-specific + 'jp2', 'openSlide', 'pdf', 'raw', 'svg', 'tiff', + // Deprecated + 'failOnError', 'openSlideLevel', 'pdfBackground', 'tiffSubifd' +]; + +/** + * Extract input options, if any, from an object. + * @private + */ +function _inputOptionsFromObject (obj) { + const params = inputStreamParameters + .filter(p => is.defined(obj[p])) + .map(p => ([p, obj[p]])); + return params.length + ? Object.fromEntries(params) + : undefined; +} + +/** + * Create Object containing input and input-related options. + * @private + */ +function _createInputDescriptor (input, inputOptions, containerOptions) { + const inputDescriptor = { + autoOrient: false, + failOn: 'warning', + limitInputPixels: Math.pow(0x3FFF, 2), + ignoreIcc: false, + unlimited: false, + sequentialRead: true + }; + if (is.string(input)) { + // filesystem + inputDescriptor.file = input; + } else if (is.buffer(input)) { + // Buffer + if (input.length === 0) { + throw Error('Input Buffer is empty'); + } + inputDescriptor.buffer = input; + } else if (is.arrayBuffer(input)) { + if (input.byteLength === 0) { + throw Error('Input bit Array is empty'); + } + inputDescriptor.buffer = Buffer.from(input, 0, input.byteLength); + } else if (is.typedArray(input)) { + if (input.length === 0) { + throw Error('Input Bit Array is empty'); + } + inputDescriptor.buffer = Buffer.from(input.buffer, input.byteOffset, input.byteLength); + } else if (is.plainObject(input) && !is.defined(inputOptions)) { + // Plain Object descriptor, e.g. create + inputOptions = input; + if (_inputOptionsFromObject(inputOptions)) { + // Stream with options + inputDescriptor.buffer = []; + } + } else if (!is.defined(input) && !is.defined(inputOptions) && is.object(containerOptions) && containerOptions.allowStream) { + // Stream without options + inputDescriptor.buffer = []; + } else if (Array.isArray(input)) { + if (input.length > 1) { + // Join images together + if (!this.options.joining) { + this.options.joining = true; + this.options.join = input.map(i => this._createInputDescriptor(i)); + } else { + throw new Error('Recursive join is unsupported'); + } + } else { + throw new Error('Expected at least two images to join'); + } + } else { + throw new Error(`Unsupported input '${input}' of type ${typeof input}${ + is.defined(inputOptions) ? ` when also providing options of type ${typeof inputOptions}` : '' + }`); + } + if (is.object(inputOptions)) { + // Deprecated: failOnError + if (is.defined(inputOptions.failOnError)) { + if (is.bool(inputOptions.failOnError)) { + inputDescriptor.failOn = inputOptions.failOnError ? 'warning' : 'none'; + } else { + throw is.invalidParameterError('failOnError', 'boolean', inputOptions.failOnError); + } + } + // failOn + if (is.defined(inputOptions.failOn)) { + if (is.string(inputOptions.failOn) && is.inArray(inputOptions.failOn, ['none', 'truncated', 'error', 'warning'])) { + inputDescriptor.failOn = inputOptions.failOn; + } else { + throw is.invalidParameterError('failOn', 'one of: none, truncated, error, warning', inputOptions.failOn); + } + } + // autoOrient + if (is.defined(inputOptions.autoOrient)) { + if (is.bool(inputOptions.autoOrient)) { + inputDescriptor.autoOrient = inputOptions.autoOrient; + } else { + throw is.invalidParameterError('autoOrient', 'boolean', inputOptions.autoOrient); + } + } + // Density + if (is.defined(inputOptions.density)) { + if (is.inRange(inputOptions.density, 1, 100000)) { + inputDescriptor.density = inputOptions.density; + } else { + throw is.invalidParameterError('density', 'number between 1 and 100000', inputOptions.density); + } + } + // Ignore embeddded ICC profile + if (is.defined(inputOptions.ignoreIcc)) { + if (is.bool(inputOptions.ignoreIcc)) { + inputDescriptor.ignoreIcc = inputOptions.ignoreIcc; + } else { + throw is.invalidParameterError('ignoreIcc', 'boolean', inputOptions.ignoreIcc); + } + } + // limitInputPixels + if (is.defined(inputOptions.limitInputPixels)) { + if (is.bool(inputOptions.limitInputPixels)) { + inputDescriptor.limitInputPixels = inputOptions.limitInputPixels + ? Math.pow(0x3FFF, 2) + : 0; + } else if (is.integer(inputOptions.limitInputPixels) && is.inRange(inputOptions.limitInputPixels, 0, Number.MAX_SAFE_INTEGER)) { + inputDescriptor.limitInputPixels = inputOptions.limitInputPixels; + } else { + throw is.invalidParameterError('limitInputPixels', 'positive integer', inputOptions.limitInputPixels); + } + } + // unlimited + if (is.defined(inputOptions.unlimited)) { + if (is.bool(inputOptions.unlimited)) { + inputDescriptor.unlimited = inputOptions.unlimited; + } else { + throw is.invalidParameterError('unlimited', 'boolean', inputOptions.unlimited); + } + } + // sequentialRead + if (is.defined(inputOptions.sequentialRead)) { + if (is.bool(inputOptions.sequentialRead)) { + inputDescriptor.sequentialRead = inputOptions.sequentialRead; + } else { + throw is.invalidParameterError('sequentialRead', 'boolean', inputOptions.sequentialRead); + } + } + // Raw pixel input + if (is.defined(inputOptions.raw)) { + if ( + is.object(inputOptions.raw) && + is.integer(inputOptions.raw.width) && inputOptions.raw.width > 0 && + is.integer(inputOptions.raw.height) && inputOptions.raw.height > 0 && + is.integer(inputOptions.raw.channels) && is.inRange(inputOptions.raw.channels, 1, 4) + ) { + inputDescriptor.rawWidth = inputOptions.raw.width; + inputDescriptor.rawHeight = inputOptions.raw.height; + inputDescriptor.rawChannels = inputOptions.raw.channels; + switch (input.constructor) { + case Uint8Array: + case Uint8ClampedArray: + inputDescriptor.rawDepth = 'uchar'; + break; + case Int8Array: + inputDescriptor.rawDepth = 'char'; + break; + case Uint16Array: + inputDescriptor.rawDepth = 'ushort'; + break; + case Int16Array: + inputDescriptor.rawDepth = 'short'; + break; + case Uint32Array: + inputDescriptor.rawDepth = 'uint'; + break; + case Int32Array: + inputDescriptor.rawDepth = 'int'; + break; + case Float32Array: + inputDescriptor.rawDepth = 'float'; + break; + case Float64Array: + inputDescriptor.rawDepth = 'double'; + break; + default: + inputDescriptor.rawDepth = 'uchar'; + break; + } + } else { + throw new Error('Expected width, height and channels for raw pixel input'); + } + inputDescriptor.rawPremultiplied = false; + if (is.defined(inputOptions.raw.premultiplied)) { + if (is.bool(inputOptions.raw.premultiplied)) { + inputDescriptor.rawPremultiplied = inputOptions.raw.premultiplied; + } else { + throw is.invalidParameterError('raw.premultiplied', 'boolean', inputOptions.raw.premultiplied); + } + } + inputDescriptor.rawPageHeight = 0; + if (is.defined(inputOptions.raw.pageHeight)) { + if (is.integer(inputOptions.raw.pageHeight) && inputOptions.raw.pageHeight > 0 && inputOptions.raw.pageHeight <= inputOptions.raw.height) { + if (inputOptions.raw.height % inputOptions.raw.pageHeight !== 0) { + throw new Error(`Expected raw.height ${inputOptions.raw.height} to be a multiple of raw.pageHeight ${inputOptions.raw.pageHeight}`); + } + inputDescriptor.rawPageHeight = inputOptions.raw.pageHeight; + } else { + throw is.invalidParameterError('raw.pageHeight', 'positive integer', inputOptions.raw.pageHeight); + } + } + } + // Multi-page input (GIF, TIFF, PDF) + if (is.defined(inputOptions.animated)) { + if (is.bool(inputOptions.animated)) { + inputDescriptor.pages = inputOptions.animated ? -1 : 1; + } else { + throw is.invalidParameterError('animated', 'boolean', inputOptions.animated); + } + } + if (is.defined(inputOptions.pages)) { + if (is.integer(inputOptions.pages) && is.inRange(inputOptions.pages, -1, 100000)) { + inputDescriptor.pages = inputOptions.pages; + } else { + throw is.invalidParameterError('pages', 'integer between -1 and 100000', inputOptions.pages); + } + } + if (is.defined(inputOptions.page)) { + if (is.integer(inputOptions.page) && is.inRange(inputOptions.page, 0, 100000)) { + inputDescriptor.page = inputOptions.page; + } else { + throw is.invalidParameterError('page', 'integer between 0 and 100000', inputOptions.page); + } + } + // OpenSlide specific options + if (is.object(inputOptions.openSlide) && is.defined(inputOptions.openSlide.level)) { + if (is.integer(inputOptions.openSlide.level) && is.inRange(inputOptions.openSlide.level, 0, 256)) { + inputDescriptor.openSlideLevel = inputOptions.openSlide.level; + } else { + throw is.invalidParameterError('openSlide.level', 'integer between 0 and 256', inputOptions.openSlide.level); + } + } else if (is.defined(inputOptions.level)) { + // Deprecated + if (is.integer(inputOptions.level) && is.inRange(inputOptions.level, 0, 256)) { + inputDescriptor.openSlideLevel = inputOptions.level; + } else { + throw is.invalidParameterError('level', 'integer between 0 and 256', inputOptions.level); + } + } + // TIFF specific options + if (is.object(inputOptions.tiff) && is.defined(inputOptions.tiff.subifd)) { + if (is.integer(inputOptions.tiff.subifd) && is.inRange(inputOptions.tiff.subifd, -1, 100000)) { + inputDescriptor.tiffSubifd = inputOptions.tiff.subifd; + } else { + throw is.invalidParameterError('tiff.subifd', 'integer between -1 and 100000', inputOptions.tiff.subifd); + } + } else if (is.defined(inputOptions.subifd)) { + // Deprecated + if (is.integer(inputOptions.subifd) && is.inRange(inputOptions.subifd, -1, 100000)) { + inputDescriptor.tiffSubifd = inputOptions.subifd; + } else { + throw is.invalidParameterError('subifd', 'integer between -1 and 100000', inputOptions.subifd); + } + } + // SVG specific options + if (is.object(inputOptions.svg)) { + if (is.defined(inputOptions.svg.stylesheet)) { + if (is.string(inputOptions.svg.stylesheet)) { + inputDescriptor.svgStylesheet = inputOptions.svg.stylesheet; + } else { + throw is.invalidParameterError('svg.stylesheet', 'string', inputOptions.svg.stylesheet); + } + } + if (is.defined(inputOptions.svg.highBitdepth)) { + if (is.bool(inputOptions.svg.highBitdepth)) { + inputDescriptor.svgHighBitdepth = inputOptions.svg.highBitdepth; + } else { + throw is.invalidParameterError('svg.highBitdepth', 'boolean', inputOptions.svg.highBitdepth); + } + } + } + // PDF specific options + if (is.object(inputOptions.pdf) && is.defined(inputOptions.pdf.background)) { + inputDescriptor.pdfBackground = this._getBackgroundColourOption(inputOptions.pdf.background); + } else if (is.defined(inputOptions.pdfBackground)) { + // Deprecated + inputDescriptor.pdfBackground = this._getBackgroundColourOption(inputOptions.pdfBackground); + } + // JPEG 2000 specific options + if (is.object(inputOptions.jp2) && is.defined(inputOptions.jp2.oneshot)) { + if (is.bool(inputOptions.jp2.oneshot)) { + inputDescriptor.jp2Oneshot = inputOptions.jp2.oneshot; + } else { + throw is.invalidParameterError('jp2.oneshot', 'boolean', inputOptions.jp2.oneshot); + } + } + // Create new image + if (is.defined(inputOptions.create)) { + if ( + is.object(inputOptions.create) && + is.integer(inputOptions.create.width) && inputOptions.create.width > 0 && + is.integer(inputOptions.create.height) && inputOptions.create.height > 0 && + is.integer(inputOptions.create.channels) + ) { + inputDescriptor.createWidth = inputOptions.create.width; + inputDescriptor.createHeight = inputOptions.create.height; + inputDescriptor.createChannels = inputOptions.create.channels; + inputDescriptor.createPageHeight = 0; + if (is.defined(inputOptions.create.pageHeight)) { + if (is.integer(inputOptions.create.pageHeight) && inputOptions.create.pageHeight > 0 && inputOptions.create.pageHeight <= inputOptions.create.height) { + if (inputOptions.create.height % inputOptions.create.pageHeight !== 0) { + throw new Error(`Expected create.height ${inputOptions.create.height} to be a multiple of create.pageHeight ${inputOptions.create.pageHeight}`); + } + inputDescriptor.createPageHeight = inputOptions.create.pageHeight; + } else { + throw is.invalidParameterError('create.pageHeight', 'positive integer', inputOptions.create.pageHeight); + } + } + // Noise + if (is.defined(inputOptions.create.noise)) { + if (!is.object(inputOptions.create.noise)) { + throw new Error('Expected noise to be an object'); + } + if (inputOptions.create.noise.type !== 'gaussian') { + throw new Error('Only gaussian noise is supported at the moment'); + } + inputDescriptor.createNoiseType = inputOptions.create.noise.type; + if (!is.inRange(inputOptions.create.channels, 1, 4)) { + throw is.invalidParameterError('create.channels', 'number between 1 and 4', inputOptions.create.channels); + } + inputDescriptor.createNoiseMean = 128; + if (is.defined(inputOptions.create.noise.mean)) { + if (is.number(inputOptions.create.noise.mean) && is.inRange(inputOptions.create.noise.mean, 0, 10000)) { + inputDescriptor.createNoiseMean = inputOptions.create.noise.mean; + } else { + throw is.invalidParameterError('create.noise.mean', 'number between 0 and 10000', inputOptions.create.noise.mean); + } + } + inputDescriptor.createNoiseSigma = 30; + if (is.defined(inputOptions.create.noise.sigma)) { + if (is.number(inputOptions.create.noise.sigma) && is.inRange(inputOptions.create.noise.sigma, 0, 10000)) { + inputDescriptor.createNoiseSigma = inputOptions.create.noise.sigma; + } else { + throw is.invalidParameterError('create.noise.sigma', 'number between 0 and 10000', inputOptions.create.noise.sigma); + } + } + } else if (is.defined(inputOptions.create.background)) { + if (!is.inRange(inputOptions.create.channels, 3, 4)) { + throw is.invalidParameterError('create.channels', 'number between 3 and 4', inputOptions.create.channels); + } + inputDescriptor.createBackground = this._getBackgroundColourOption(inputOptions.create.background); + } else { + throw new Error('Expected valid noise or background to create a new input image'); + } + delete inputDescriptor.buffer; + } else { + throw new Error('Expected valid width, height and channels to create a new input image'); + } + } + // Create a new image with text + if (is.defined(inputOptions.text)) { + if (is.object(inputOptions.text) && is.string(inputOptions.text.text)) { + inputDescriptor.textValue = inputOptions.text.text; + if (is.defined(inputOptions.text.height) && is.defined(inputOptions.text.dpi)) { + throw new Error('Expected only one of dpi or height'); + } + if (is.defined(inputOptions.text.font)) { + if (is.string(inputOptions.text.font)) { + inputDescriptor.textFont = inputOptions.text.font; + } else { + throw is.invalidParameterError('text.font', 'string', inputOptions.text.font); + } + } + if (is.defined(inputOptions.text.fontfile)) { + if (is.string(inputOptions.text.fontfile)) { + inputDescriptor.textFontfile = inputOptions.text.fontfile; + } else { + throw is.invalidParameterError('text.fontfile', 'string', inputOptions.text.fontfile); + } + } + if (is.defined(inputOptions.text.width)) { + if (is.integer(inputOptions.text.width) && inputOptions.text.width > 0) { + inputDescriptor.textWidth = inputOptions.text.width; + } else { + throw is.invalidParameterError('text.width', 'positive integer', inputOptions.text.width); + } + } + if (is.defined(inputOptions.text.height)) { + if (is.integer(inputOptions.text.height) && inputOptions.text.height > 0) { + inputDescriptor.textHeight = inputOptions.text.height; + } else { + throw is.invalidParameterError('text.height', 'positive integer', inputOptions.text.height); + } + } + if (is.defined(inputOptions.text.align)) { + if (is.string(inputOptions.text.align) && is.string(this.constructor.align[inputOptions.text.align])) { + inputDescriptor.textAlign = this.constructor.align[inputOptions.text.align]; + } else { + throw is.invalidParameterError('text.align', 'valid alignment', inputOptions.text.align); + } + } + if (is.defined(inputOptions.text.justify)) { + if (is.bool(inputOptions.text.justify)) { + inputDescriptor.textJustify = inputOptions.text.justify; + } else { + throw is.invalidParameterError('text.justify', 'boolean', inputOptions.text.justify); + } + } + if (is.defined(inputOptions.text.dpi)) { + if (is.integer(inputOptions.text.dpi) && is.inRange(inputOptions.text.dpi, 1, 1000000)) { + inputDescriptor.textDpi = inputOptions.text.dpi; + } else { + throw is.invalidParameterError('text.dpi', 'integer between 1 and 1000000', inputOptions.text.dpi); + } + } + if (is.defined(inputOptions.text.rgba)) { + if (is.bool(inputOptions.text.rgba)) { + inputDescriptor.textRgba = inputOptions.text.rgba; + } else { + throw is.invalidParameterError('text.rgba', 'bool', inputOptions.text.rgba); + } + } + if (is.defined(inputOptions.text.spacing)) { + if (is.integer(inputOptions.text.spacing) && is.inRange(inputOptions.text.spacing, -1000000, 1000000)) { + inputDescriptor.textSpacing = inputOptions.text.spacing; + } else { + throw is.invalidParameterError('text.spacing', 'integer between -1000000 and 1000000', inputOptions.text.spacing); + } + } + if (is.defined(inputOptions.text.wrap)) { + if (is.string(inputOptions.text.wrap) && is.inArray(inputOptions.text.wrap, ['word', 'char', 'word-char', 'none'])) { + inputDescriptor.textWrap = inputOptions.text.wrap; + } else { + throw is.invalidParameterError('text.wrap', 'one of: word, char, word-char, none', inputOptions.text.wrap); + } + } + delete inputDescriptor.buffer; + } else { + throw new Error('Expected a valid string to create an image with text.'); + } + } + // Join images together + if (is.defined(inputOptions.join)) { + if (is.defined(this.options.join)) { + if (is.defined(inputOptions.join.animated)) { + if (is.bool(inputOptions.join.animated)) { + inputDescriptor.joinAnimated = inputOptions.join.animated; + } else { + throw is.invalidParameterError('join.animated', 'boolean', inputOptions.join.animated); + } + } + if (is.defined(inputOptions.join.across)) { + if (is.integer(inputOptions.join.across) && is.inRange(inputOptions.join.across, 1, 1000000)) { + inputDescriptor.joinAcross = inputOptions.join.across; + } else { + throw is.invalidParameterError('join.across', 'integer between 1 and 100000', inputOptions.join.across); + } + } + if (is.defined(inputOptions.join.shim)) { + if (is.integer(inputOptions.join.shim) && is.inRange(inputOptions.join.shim, 0, 1000000)) { + inputDescriptor.joinShim = inputOptions.join.shim; + } else { + throw is.invalidParameterError('join.shim', 'integer between 0 and 100000', inputOptions.join.shim); + } + } + if (is.defined(inputOptions.join.background)) { + inputDescriptor.joinBackground = this._getBackgroundColourOption(inputOptions.join.background); + } + if (is.defined(inputOptions.join.halign)) { + if (is.string(inputOptions.join.halign) && is.string(this.constructor.align[inputOptions.join.halign])) { + inputDescriptor.joinHalign = this.constructor.align[inputOptions.join.halign]; + } else { + throw is.invalidParameterError('join.halign', 'valid alignment', inputOptions.join.halign); + } + } + if (is.defined(inputOptions.join.valign)) { + if (is.string(inputOptions.join.valign) && is.string(this.constructor.align[inputOptions.join.valign])) { + inputDescriptor.joinValign = this.constructor.align[inputOptions.join.valign]; + } else { + throw is.invalidParameterError('join.valign', 'valid alignment', inputOptions.join.valign); + } + } + } else { + throw new Error('Expected input to be an array of images to join'); + } + } + } else if (is.defined(inputOptions)) { + throw new Error('Invalid input options ' + inputOptions); + } + return inputDescriptor; +} + +/** + * Handle incoming Buffer chunk on Writable Stream. + * @private + * @param {Buffer} chunk + * @param {string} encoding - unused + * @param {Function} callback + */ +function _write (chunk, encoding, callback) { + /* istanbul ignore else */ + if (Array.isArray(this.options.input.buffer)) { + /* istanbul ignore else */ + if (is.buffer(chunk)) { + if (this.options.input.buffer.length === 0) { + this.on('finish', () => { + this.streamInFinished = true; + }); + } + this.options.input.buffer.push(chunk); + callback(); + } else { + callback(new Error('Non-Buffer data on Writable Stream')); + } + } else { + callback(new Error('Unexpected data on Writable Stream')); + } +} + +/** + * Flattens the array of chunks accumulated in input.buffer. + * @private + */ +function _flattenBufferIn () { + if (this._isStreamInput()) { + this.options.input.buffer = Buffer.concat(this.options.input.buffer); + } +} + +/** + * Are we expecting Stream-based input? + * @private + * @returns {boolean} + */ +function _isStreamInput () { + return Array.isArray(this.options.input.buffer); +} + +/** + * Fast access to (uncached) image metadata without decoding any compressed pixel data. + * + * This is read from the header of the input image. + * It does not take into consideration any operations to be applied to the output image, + * such as resize or rotate. + * + * Dimensions in the response will respect the `page` and `pages` properties of the + * {@link /api-constructor#parameters|constructor parameters}. + * + * A `Promise` is returned when `callback` is not provided. + * + * - `format`: Name of decoder used to decompress image data e.g. `jpeg`, `png`, `webp`, `gif`, `svg` + * - `size`: Total size of image in bytes, for Stream and Buffer input only + * - `width`: Number of pixels wide (EXIF orientation is not taken into consideration, see example below) + * - `height`: Number of pixels high (EXIF orientation is not taken into consideration, see example below) + * - `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `cmyk`, `lab`, `b-w` [...](https://www.libvips.org/API/current/VipsImage.html#VipsInterpretation) + * - `channels`: Number of bands e.g. `3` for sRGB, `4` for CMYK + * - `depth`: Name of pixel depth format e.g. `uchar`, `char`, `ushort`, `float` [...](https://www.libvips.org/API/current/VipsImage.html#VipsBandFormat) + * - `density`: Number of pixels per inch (DPI), if present + * - `chromaSubsampling`: String containing JPEG chroma subsampling, `4:2:0` or `4:4:4` for RGB, `4:2:0:4` or `4:4:4:4` for CMYK + * - `isProgressive`: Boolean indicating whether the image is interlaced using a progressive scan + * - `isPalette`: Boolean indicating whether the image is palette-based (GIF, PNG). + * - `bitsPerSample`: Number of bits per sample for each channel (GIF, PNG, HEIF). + * - `pages`: Number of pages/frames contained within the image, with support for TIFF, HEIF, PDF, animated GIF and animated WebP + * - `pageHeight`: Number of pixels high each page in a multi-page image will be. + * - `loop`: Number of times to loop an animated image, zero refers to a continuous loop. + * - `delay`: Delay in ms between each page in an animated image, provided as an array of integers. + * - `pagePrimary`: Number of the primary page in a HEIF image + * - `levels`: Details of each level in a multi-level image provided as an array of objects, requires libvips compiled with support for OpenSlide + * - `subifds`: Number of Sub Image File Directories in an OME-TIFF image + * - `background`: Default background colour, if present, for PNG (bKGD) and GIF images + * - `compression`: The encoder used to compress an HEIF file, `av1` (AVIF) or `hevc` (HEIC) + * - `resolutionUnit`: The unit of resolution (density), either `inch` or `cm`, if present + * - `hasProfile`: Boolean indicating the presence of an embedded ICC profile + * - `hasAlpha`: Boolean indicating the presence of an alpha transparency channel + * - `orientation`: Number value of the EXIF Orientation header, if present + * - `exif`: Buffer containing raw EXIF data, if present + * - `icc`: Buffer containing raw [ICC](https://www.npmjs.com/package/icc) profile data, if present + * - `iptc`: Buffer containing raw IPTC data, if present + * - `xmp`: Buffer containing raw XMP data, if present + * - `xmpAsString`: String containing XMP data, if valid UTF-8. + * - `tifftagPhotoshop`: Buffer containing raw TIFFTAG_PHOTOSHOP data, if present + * - `formatMagick`: String containing format for images loaded via *magick + * - `comments`: Array of keyword/text pairs representing PNG text blocks, if present. + * + * @example + * const metadata = await sharp(input).metadata(); + * + * @example + * const image = sharp(inputJpg); + * image + * .metadata() + * .then(function(metadata) { + * return image + * .resize(Math.round(metadata.width / 2)) + * .webp() + * .toBuffer(); + * }) + * .then(function(data) { + * // data contains a WebP image half the width and height of the original JPEG + * }); + * + * @example + * // Get dimensions taking EXIF Orientation into account. + * const { autoOrient } = await sharp(input).metadata(); + * const { width, height } = autoOrient; + * + * @param {Function} [callback] - called with the arguments `(err, metadata)` + * @returns {Promise|Sharp} + */ +function metadata (callback) { + const stack = Error(); + if (is.fn(callback)) { + if (this._isStreamInput()) { + this.on('finish', () => { + this._flattenBufferIn(); + sharp.metadata(this.options, (err, metadata) => { + if (err) { + callback(is.nativeError(err, stack)); + } else { + callback(null, metadata); + } + }); + }); + } else { + sharp.metadata(this.options, (err, metadata) => { + if (err) { + callback(is.nativeError(err, stack)); + } else { + callback(null, metadata); + } + }); + } + return this; + } else { + if (this._isStreamInput()) { + return new Promise((resolve, reject) => { + const finished = () => { + this._flattenBufferIn(); + sharp.metadata(this.options, (err, metadata) => { + if (err) { + reject(is.nativeError(err, stack)); + } else { + resolve(metadata); + } + }); + }; + if (this.writableFinished) { + finished(); + } else { + this.once('finish', finished); + } + }); + } else { + return new Promise((resolve, reject) => { + sharp.metadata(this.options, (err, metadata) => { + if (err) { + reject(is.nativeError(err, stack)); + } else { + resolve(metadata); + } + }); + }); + } + } +} + +/** + * Access to pixel-derived image statistics for every channel in the image. + * A `Promise` is returned when `callback` is not provided. + * + * - `channels`: Array of channel statistics for each channel in the image. Each channel statistic contains + * - `min` (minimum value in the channel) + * - `max` (maximum value in the channel) + * - `sum` (sum of all values in a channel) + * - `squaresSum` (sum of squared values in a channel) + * - `mean` (mean of the values in a channel) + * - `stdev` (standard deviation for the values in a channel) + * - `minX` (x-coordinate of one of the pixel where the minimum lies) + * - `minY` (y-coordinate of one of the pixel where the minimum lies) + * - `maxX` (x-coordinate of one of the pixel where the maximum lies) + * - `maxY` (y-coordinate of one of the pixel where the maximum lies) + * - `isOpaque`: Is the image fully opaque? Will be `true` if the image has no alpha channel or if every pixel is fully opaque. + * - `entropy`: Histogram-based estimation of greyscale entropy, discarding alpha channel if any. + * - `sharpness`: Estimation of greyscale sharpness based on the standard deviation of a Laplacian convolution, discarding alpha channel if any. + * - `dominant`: Object containing most dominant sRGB colour based on a 4096-bin 3D histogram. + * + * **Note**: Statistics are derived from the original input image. Any operations performed on the image must first be + * written to a buffer in order to run `stats` on the result (see third example). + * + * @example + * const image = sharp(inputJpg); + * image + * .stats() + * .then(function(stats) { + * // stats contains the channel-wise statistics array and the isOpaque value + * }); + * + * @example + * const { entropy, sharpness, dominant } = await sharp(input).stats(); + * const { r, g, b } = dominant; + * + * @example + * const image = sharp(input); + * // store intermediate result + * const part = await image.extract(region).toBuffer(); + * // create new instance to obtain statistics of extracted region + * const stats = await sharp(part).stats(); + * + * @param {Function} [callback] - called with the arguments `(err, stats)` + * @returns {Promise} + */ +function stats (callback) { + const stack = Error(); + if (is.fn(callback)) { + if (this._isStreamInput()) { + this.on('finish', () => { + this._flattenBufferIn(); + sharp.stats(this.options, (err, stats) => { + if (err) { + callback(is.nativeError(err, stack)); + } else { + callback(null, stats); + } + }); + }); + } else { + sharp.stats(this.options, (err, stats) => { + if (err) { + callback(is.nativeError(err, stack)); + } else { + callback(null, stats); + } + }); + } + return this; + } else { + if (this._isStreamInput()) { + return new Promise((resolve, reject) => { + this.on('finish', function () { + this._flattenBufferIn(); + sharp.stats(this.options, (err, stats) => { + if (err) { + reject(is.nativeError(err, stack)); + } else { + resolve(stats); + } + }); + }); + }); + } else { + return new Promise((resolve, reject) => { + sharp.stats(this.options, (err, stats) => { + if (err) { + reject(is.nativeError(err, stack)); + } else { + resolve(stats); + } + }); + }); + } + } +} + +/** + * Decorate the Sharp prototype with input-related functions. + * @module Sharp + * @private + */ +module.exports = function (Sharp) { + Object.assign(Sharp.prototype, { + // Private + _inputOptionsFromObject, + _createInputDescriptor, + _write, + _flattenBufferIn, + _isStreamInput, + // Public + metadata, + stats + }); + // Class attributes + Sharp.align = align; +}; diff --git a/node_modules/sharp/lib/is.js b/node_modules/sharp/lib/is.js new file mode 100644 index 0000000..a63cb20 --- /dev/null +++ b/node_modules/sharp/lib/is.js @@ -0,0 +1,169 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +'use strict'; + +/** + * Is this value defined and not null? + * @private + */ +const defined = function (val) { + return typeof val !== 'undefined' && val !== null; +}; + +/** + * Is this value an object? + * @private + */ +const object = function (val) { + return typeof val === 'object'; +}; + +/** + * Is this value a plain object? + * @private + */ +const plainObject = function (val) { + return Object.prototype.toString.call(val) === '[object Object]'; +}; + +/** + * Is this value a function? + * @private + */ +const fn = function (val) { + return typeof val === 'function'; +}; + +/** + * Is this value a boolean? + * @private + */ +const bool = function (val) { + return typeof val === 'boolean'; +}; + +/** + * Is this value a Buffer object? + * @private + */ +const buffer = function (val) { + return val instanceof Buffer; +}; + +/** + * Is this value a typed array object?. E.g. Uint8Array or Uint8ClampedArray? + * @private + */ +const typedArray = function (val) { + if (defined(val)) { + switch (val.constructor) { + case Uint8Array: + case Uint8ClampedArray: + case Int8Array: + case Uint16Array: + case Int16Array: + case Uint32Array: + case Int32Array: + case Float32Array: + case Float64Array: + return true; + } + } + + return false; +}; + +/** + * Is this value an ArrayBuffer object? + * @private + */ +const arrayBuffer = function (val) { + return val instanceof ArrayBuffer; +}; + +/** + * Is this value a non-empty string? + * @private + */ +const string = function (val) { + return typeof val === 'string' && val.length > 0; +}; + +/** + * Is this value a real number? + * @private + */ +const number = function (val) { + return typeof val === 'number' && !Number.isNaN(val); +}; + +/** + * Is this value an integer? + * @private + */ +const integer = function (val) { + return Number.isInteger(val); +}; + +/** + * Is this value within an inclusive given range? + * @private + */ +const inRange = function (val, min, max) { + return val >= min && val <= max; +}; + +/** + * Is this value within the elements of an array? + * @private + */ +const inArray = function (val, list) { + return list.includes(val); +}; + +/** + * Create an Error with a message relating to an invalid parameter. + * + * @param {string} name - parameter name. + * @param {string} expected - description of the type/value/range expected. + * @param {*} actual - the value received. + * @returns {Error} Containing the formatted message. + * @private + */ +const invalidParameterError = function (name, expected, actual) { + return new Error( + `Expected ${expected} for ${name} but received ${actual} of type ${typeof actual}` + ); +}; + +/** + * Ensures an Error from C++ contains a JS stack. + * + * @param {Error} native - Error with message from C++. + * @param {Error} context - Error with stack from JS. + * @returns {Error} Error with message and stack. + * @private + */ +const nativeError = function (native, context) { + context.message = native.message; + return context; +}; + +module.exports = { + defined, + object, + plainObject, + fn, + bool, + buffer, + typedArray, + arrayBuffer, + string, + number, + integer, + inRange, + inArray, + invalidParameterError, + nativeError +}; diff --git a/node_modules/sharp/lib/libvips.js b/node_modules/sharp/lib/libvips.js new file mode 100644 index 0000000..1bab0ca --- /dev/null +++ b/node_modules/sharp/lib/libvips.js @@ -0,0 +1,205 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +'use strict'; + +const { spawnSync } = require('node:child_process'); +const { createHash } = require('node:crypto'); +const semverCoerce = require('semver/functions/coerce'); +const semverGreaterThanOrEqualTo = require('semver/functions/gte'); +const semverSatisfies = require('semver/functions/satisfies'); +const detectLibc = require('detect-libc'); + +const { config, engines, optionalDependencies } = require('../package.json'); + +const minimumLibvipsVersionLabelled = process.env.npm_package_config_libvips || /* istanbul ignore next */ + config.libvips; +const minimumLibvipsVersion = semverCoerce(minimumLibvipsVersionLabelled).version; + +const prebuiltPlatforms = [ + 'darwin-arm64', 'darwin-x64', + 'linux-arm', 'linux-arm64', 'linux-ppc64', 'linux-s390x', 'linux-x64', + 'linuxmusl-arm64', 'linuxmusl-x64', + 'win32-arm64', 'win32-ia32', 'win32-x64' +]; + +const spawnSyncOptions = { + encoding: 'utf8', + shell: true +}; + +const log = (item) => { + if (item instanceof Error) { + console.error(`sharp: Installation error: ${item.message}`); + } else { + console.log(`sharp: ${item}`); + } +}; + +/* istanbul ignore next */ +const runtimeLibc = () => detectLibc.isNonGlibcLinuxSync() ? detectLibc.familySync() : ''; + +const runtimePlatformArch = () => `${process.platform}${runtimeLibc()}-${process.arch}`; + +/* istanbul ignore next */ +const buildPlatformArch = () => { + if (isEmscripten()) { + return 'wasm32'; + } + /* eslint camelcase: ["error", { allow: ["^npm_config_"] }] */ + const { npm_config_arch, npm_config_platform, npm_config_libc } = process.env; + const libc = typeof npm_config_libc === 'string' ? npm_config_libc : runtimeLibc(); + return `${npm_config_platform || process.platform}${libc}-${npm_config_arch || process.arch}`; +}; + +const buildSharpLibvipsIncludeDir = () => { + try { + return require(`@img/sharp-libvips-dev-${buildPlatformArch()}/include`); + } catch { + try { + return require('@img/sharp-libvips-dev/include'); + } catch {} + } + /* istanbul ignore next */ + return ''; +}; + +const buildSharpLibvipsCPlusPlusDir = () => { + try { + return require('@img/sharp-libvips-dev/cplusplus'); + } catch {} + /* istanbul ignore next */ + return ''; +}; + +const buildSharpLibvipsLibDir = () => { + try { + return require(`@img/sharp-libvips-dev-${buildPlatformArch()}/lib`); + } catch { + try { + return require(`@img/sharp-libvips-${buildPlatformArch()}/lib`); + } catch {} + } + /* istanbul ignore next */ + return ''; +}; + +const isUnsupportedNodeRuntime = () => { + /* istanbul ignore next */ + if (process.release?.name === 'node' && process.versions) { + if (!semverSatisfies(process.versions.node, engines.node)) { + return { found: process.versions.node, expected: engines.node }; + } + } +}; + +/* istanbul ignore next */ +const isEmscripten = () => { + const { CC } = process.env; + return Boolean(CC && CC.endsWith('/emcc')); +}; + +const isRosetta = () => { + /* istanbul ignore next */ + if (process.platform === 'darwin' && process.arch === 'x64') { + const translated = spawnSync('sysctl sysctl.proc_translated', spawnSyncOptions).stdout; + return (translated || '').trim() === 'sysctl.proc_translated: 1'; + } + return false; +}; + +const sha512 = (s) => createHash('sha512').update(s).digest('hex'); + +const yarnLocator = () => { + try { + const identHash = sha512(`imgsharp-libvips-${buildPlatformArch()}`); + const npmVersion = semverCoerce(optionalDependencies[`@img/sharp-libvips-${buildPlatformArch()}`], { + includePrerelease: true + }).version; + return sha512(`${identHash}npm:${npmVersion}`).slice(0, 10); + } catch {} + return ''; +}; + +/* istanbul ignore next */ +const spawnRebuild = () => + spawnSync(`node-gyp rebuild --directory=src ${isEmscripten() ? '--nodedir=emscripten' : ''}`, { + ...spawnSyncOptions, + stdio: 'inherit' + }).status; + +const globalLibvipsVersion = () => { + if (process.platform !== 'win32') { + const globalLibvipsVersion = spawnSync('pkg-config --modversion vips-cpp', { + ...spawnSyncOptions, + env: { + ...process.env, + PKG_CONFIG_PATH: pkgConfigPath() + } + }).stdout; + /* istanbul ignore next */ + return (globalLibvipsVersion || '').trim(); + } else { + return ''; + } +}; + +/* istanbul ignore next */ +const pkgConfigPath = () => { + if (process.platform !== 'win32') { + const brewPkgConfigPath = spawnSync( + 'which brew >/dev/null 2>&1 && brew environment --plain | grep PKG_CONFIG_LIBDIR | cut -d" " -f2', + spawnSyncOptions + ).stdout || ''; + return [ + brewPkgConfigPath.trim(), + process.env.PKG_CONFIG_PATH, + '/usr/local/lib/pkgconfig', + '/usr/lib/pkgconfig', + '/usr/local/libdata/pkgconfig', + '/usr/libdata/pkgconfig' + ].filter(Boolean).join(':'); + } else { + return ''; + } +}; + +const skipSearch = (status, reason, logger) => { + if (logger) { + logger(`Detected ${reason}, skipping search for globally-installed libvips`); + } + return status; +}; + +const useGlobalLibvips = (logger) => { + if (Boolean(process.env.SHARP_IGNORE_GLOBAL_LIBVIPS) === true) { + return skipSearch(false, 'SHARP_IGNORE_GLOBAL_LIBVIPS', logger); + } + if (Boolean(process.env.SHARP_FORCE_GLOBAL_LIBVIPS) === true) { + return skipSearch(true, 'SHARP_FORCE_GLOBAL_LIBVIPS', logger); + } + /* istanbul ignore next */ + if (isRosetta()) { + return skipSearch(false, 'Rosetta', logger); + } + const globalVipsVersion = globalLibvipsVersion(); + return !!globalVipsVersion && /* istanbul ignore next */ + semverGreaterThanOrEqualTo(globalVipsVersion, minimumLibvipsVersion); +}; + +module.exports = { + minimumLibvipsVersion, + prebuiltPlatforms, + buildPlatformArch, + buildSharpLibvipsIncludeDir, + buildSharpLibvipsCPlusPlusDir, + buildSharpLibvipsLibDir, + isUnsupportedNodeRuntime, + runtimePlatformArch, + log, + yarnLocator, + spawnRebuild, + globalLibvipsVersion, + pkgConfigPath, + useGlobalLibvips +}; diff --git a/node_modules/sharp/lib/operation.js b/node_modules/sharp/lib/operation.js new file mode 100644 index 0000000..f76f65d --- /dev/null +++ b/node_modules/sharp/lib/operation.js @@ -0,0 +1,1018 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +'use strict'; + +const is = require('./is'); + +/** + * How accurate an operation should be. + * @member + * @private + */ +const vipsPrecision = { + integer: 'integer', + float: 'float', + approximate: 'approximate' +}; + +/** + * Rotate the output image. + * + * The provided angle is converted to a valid positive degree rotation. + * For example, `-450` will produce a 270 degree rotation. + * + * When rotating by an angle other than a multiple of 90, + * the background colour can be provided with the `background` option. + * + * For backwards compatibility, if no angle is provided, `.autoOrient()` will be called. + * + * Only one rotation can occur per pipeline (aside from an initial call without + * arguments to orient via EXIF data). Previous calls to `rotate` in the same + * pipeline will be ignored. + * + * Multi-page images can only be rotated by 180 degrees. + * + * Method order is important when rotating, resizing and/or extracting regions, + * for example `.rotate(x).extract(y)` will produce a different result to `.extract(y).rotate(x)`. + * + * @example + * const rotateThenResize = await sharp(input) + * .rotate(90) + * .resize({ width: 16, height: 8, fit: 'fill' }) + * .toBuffer(); + * const resizeThenRotate = await sharp(input) + * .resize({ width: 16, height: 8, fit: 'fill' }) + * .rotate(90) + * .toBuffer(); + * + * @param {number} [angle=auto] angle of rotation. + * @param {Object} [options] - if present, is an Object with optional attributes. + * @param {string|Object} [options.background="#000000"] parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function rotate (angle, options) { + if (!is.defined(angle)) { + return this.autoOrient(); + } + if (this.options.angle || this.options.rotationAngle) { + this.options.debuglog('ignoring previous rotate options'); + this.options.angle = 0; + this.options.rotationAngle = 0; + } + if (is.integer(angle) && !(angle % 90)) { + this.options.angle = angle; + } else if (is.number(angle)) { + this.options.rotationAngle = angle; + if (is.object(options) && options.background) { + this._setBackgroundColourOption('rotationBackground', options.background); + } + } else { + throw is.invalidParameterError('angle', 'numeric', angle); + } + return this; +} + +/** + * Auto-orient based on the EXIF `Orientation` tag, then remove the tag. + * Mirroring is supported and may infer the use of a flip operation. + * + * Previous or subsequent use of `rotate(angle)` and either `flip()` or `flop()` + * will logically occur after auto-orientation, regardless of call order. + * + * @example + * const output = await sharp(input).autoOrient().toBuffer(); + * + * @example + * const pipeline = sharp() + * .autoOrient() + * .resize(null, 200) + * .toBuffer(function (err, outputBuffer, info) { + * // outputBuffer contains 200px high JPEG image data, + * // auto-oriented using EXIF Orientation tag + * // info.width and info.height contain the dimensions of the resized image + * }); + * readableStream.pipe(pipeline); + * + * @returns {Sharp} + */ +function autoOrient () { + this.options.input.autoOrient = true; + return this; +} + +/** + * Mirror the image vertically (up-down) about the x-axis. + * This always occurs before rotation, if any. + * + * This operation does not work correctly with multi-page images. + * + * @example + * const output = await sharp(input).flip().toBuffer(); + * + * @param {Boolean} [flip=true] + * @returns {Sharp} + */ +function flip (flip) { + this.options.flip = is.bool(flip) ? flip : true; + return this; +} + +/** + * Mirror the image horizontally (left-right) about the y-axis. + * This always occurs before rotation, if any. + * + * @example + * const output = await sharp(input).flop().toBuffer(); + * + * @param {Boolean} [flop=true] + * @returns {Sharp} + */ +function flop (flop) { + this.options.flop = is.bool(flop) ? flop : true; + return this; +} + +/** + * Perform an affine transform on an image. This operation will always occur after resizing, extraction and rotation, if any. + * + * You must provide an array of length 4 or a 2x2 affine transformation matrix. + * By default, new pixels are filled with a black background. You can provide a background colour with the `background` option. + * A particular interpolator may also be specified. Set the `interpolator` option to an attribute of the `sharp.interpolators` Object e.g. `sharp.interpolators.nohalo`. + * + * In the case of a 2x2 matrix, the transform is: + * - X = `matrix[0, 0]` \* (x + `idx`) + `matrix[0, 1]` \* (y + `idy`) + `odx` + * - Y = `matrix[1, 0]` \* (x + `idx`) + `matrix[1, 1]` \* (y + `idy`) + `ody` + * + * where: + * - x and y are the coordinates in input image. + * - X and Y are the coordinates in output image. + * - (0,0) is the upper left corner. + * + * @since 0.27.0 + * + * @example + * const pipeline = sharp() + * .affine([[1, 0.3], [0.1, 0.7]], { + * background: 'white', + * interpolator: sharp.interpolators.nohalo + * }) + * .toBuffer((err, outputBuffer, info) => { + * // outputBuffer contains the transformed image + * // info.width and info.height contain the new dimensions + * }); + * + * inputStream + * .pipe(pipeline); + * + * @param {Array>|Array} matrix - affine transformation matrix + * @param {Object} [options] - if present, is an Object with optional attributes. + * @param {String|Object} [options.background="#000000"] - parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. + * @param {Number} [options.idx=0] - input horizontal offset + * @param {Number} [options.idy=0] - input vertical offset + * @param {Number} [options.odx=0] - output horizontal offset + * @param {Number} [options.ody=0] - output vertical offset + * @param {String} [options.interpolator=sharp.interpolators.bicubic] - interpolator + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function affine (matrix, options) { + const flatMatrix = [].concat(...matrix); + if (flatMatrix.length === 4 && flatMatrix.every(is.number)) { + this.options.affineMatrix = flatMatrix; + } else { + throw is.invalidParameterError('matrix', '1x4 or 2x2 array', matrix); + } + + if (is.defined(options)) { + if (is.object(options)) { + this._setBackgroundColourOption('affineBackground', options.background); + if (is.defined(options.idx)) { + if (is.number(options.idx)) { + this.options.affineIdx = options.idx; + } else { + throw is.invalidParameterError('options.idx', 'number', options.idx); + } + } + if (is.defined(options.idy)) { + if (is.number(options.idy)) { + this.options.affineIdy = options.idy; + } else { + throw is.invalidParameterError('options.idy', 'number', options.idy); + } + } + if (is.defined(options.odx)) { + if (is.number(options.odx)) { + this.options.affineOdx = options.odx; + } else { + throw is.invalidParameterError('options.odx', 'number', options.odx); + } + } + if (is.defined(options.ody)) { + if (is.number(options.ody)) { + this.options.affineOdy = options.ody; + } else { + throw is.invalidParameterError('options.ody', 'number', options.ody); + } + } + if (is.defined(options.interpolator)) { + if (is.inArray(options.interpolator, Object.values(this.constructor.interpolators))) { + this.options.affineInterpolator = options.interpolator; + } else { + throw is.invalidParameterError('options.interpolator', 'valid interpolator name', options.interpolator); + } + } + } else { + throw is.invalidParameterError('options', 'object', options); + } + } + + return this; +} + +/** + * Sharpen the image. + * + * When used without parameters, performs a fast, mild sharpen of the output image. + * + * When a `sigma` is provided, performs a slower, more accurate sharpen of the L channel in the LAB colour space. + * Fine-grained control over the level of sharpening in "flat" (m1) and "jagged" (m2) areas is available. + * + * See {@link https://www.libvips.org/API/current/libvips-convolution.html#vips-sharpen|libvips sharpen} operation. + * + * @example + * const data = await sharp(input).sharpen().toBuffer(); + * + * @example + * const data = await sharp(input).sharpen({ sigma: 2 }).toBuffer(); + * + * @example + * const data = await sharp(input) + * .sharpen({ + * sigma: 2, + * m1: 0, + * m2: 3, + * x1: 3, + * y2: 15, + * y3: 15, + * }) + * .toBuffer(); + * + * @param {Object|number} [options] - if present, is an Object with attributes + * @param {number} [options.sigma] - the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`, between 0.000001 and 10 + * @param {number} [options.m1=1.0] - the level of sharpening to apply to "flat" areas, between 0 and 1000000 + * @param {number} [options.m2=2.0] - the level of sharpening to apply to "jagged" areas, between 0 and 1000000 + * @param {number} [options.x1=2.0] - threshold between "flat" and "jagged", between 0 and 1000000 + * @param {number} [options.y2=10.0] - maximum amount of brightening, between 0 and 1000000 + * @param {number} [options.y3=20.0] - maximum amount of darkening, between 0 and 1000000 + * @param {number} [flat] - (deprecated) see `options.m1`. + * @param {number} [jagged] - (deprecated) see `options.m2`. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function sharpen (options, flat, jagged) { + if (!is.defined(options)) { + // No arguments: default to mild sharpen + this.options.sharpenSigma = -1; + } else if (is.bool(options)) { + // Deprecated boolean argument: apply mild sharpen? + this.options.sharpenSigma = options ? -1 : 0; + } else if (is.number(options) && is.inRange(options, 0.01, 10000)) { + // Deprecated numeric argument: specific sigma + this.options.sharpenSigma = options; + // Deprecated control over flat areas + if (is.defined(flat)) { + if (is.number(flat) && is.inRange(flat, 0, 10000)) { + this.options.sharpenM1 = flat; + } else { + throw is.invalidParameterError('flat', 'number between 0 and 10000', flat); + } + } + // Deprecated control over jagged areas + if (is.defined(jagged)) { + if (is.number(jagged) && is.inRange(jagged, 0, 10000)) { + this.options.sharpenM2 = jagged; + } else { + throw is.invalidParameterError('jagged', 'number between 0 and 10000', jagged); + } + } + } else if (is.plainObject(options)) { + if (is.number(options.sigma) && is.inRange(options.sigma, 0.000001, 10)) { + this.options.sharpenSigma = options.sigma; + } else { + throw is.invalidParameterError('options.sigma', 'number between 0.000001 and 10', options.sigma); + } + if (is.defined(options.m1)) { + if (is.number(options.m1) && is.inRange(options.m1, 0, 1000000)) { + this.options.sharpenM1 = options.m1; + } else { + throw is.invalidParameterError('options.m1', 'number between 0 and 1000000', options.m1); + } + } + if (is.defined(options.m2)) { + if (is.number(options.m2) && is.inRange(options.m2, 0, 1000000)) { + this.options.sharpenM2 = options.m2; + } else { + throw is.invalidParameterError('options.m2', 'number between 0 and 1000000', options.m2); + } + } + if (is.defined(options.x1)) { + if (is.number(options.x1) && is.inRange(options.x1, 0, 1000000)) { + this.options.sharpenX1 = options.x1; + } else { + throw is.invalidParameterError('options.x1', 'number between 0 and 1000000', options.x1); + } + } + if (is.defined(options.y2)) { + if (is.number(options.y2) && is.inRange(options.y2, 0, 1000000)) { + this.options.sharpenY2 = options.y2; + } else { + throw is.invalidParameterError('options.y2', 'number between 0 and 1000000', options.y2); + } + } + if (is.defined(options.y3)) { + if (is.number(options.y3) && is.inRange(options.y3, 0, 1000000)) { + this.options.sharpenY3 = options.y3; + } else { + throw is.invalidParameterError('options.y3', 'number between 0 and 1000000', options.y3); + } + } + } else { + throw is.invalidParameterError('sigma', 'number between 0.01 and 10000', options); + } + return this; +} + +/** + * Apply median filter. + * When used without parameters the default window is 3x3. + * + * @example + * const output = await sharp(input).median().toBuffer(); + * + * @example + * const output = await sharp(input).median(5).toBuffer(); + * + * @param {number} [size=3] square mask size: size x size + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function median (size) { + if (!is.defined(size)) { + // No arguments: default to 3x3 + this.options.medianSize = 3; + } else if (is.integer(size) && is.inRange(size, 1, 1000)) { + // Numeric argument: specific sigma + this.options.medianSize = size; + } else { + throw is.invalidParameterError('size', 'integer between 1 and 1000', size); + } + return this; +} + +/** + * Blur the image. + * + * When used without parameters, performs a fast 3x3 box blur (equivalent to a box linear filter). + * + * When a `sigma` is provided, performs a slower, more accurate Gaussian blur. + * + * @example + * const boxBlurred = await sharp(input) + * .blur() + * .toBuffer(); + * + * @example + * const gaussianBlurred = await sharp(input) + * .blur(5) + * .toBuffer(); + * + * @param {Object|number|Boolean} [options] + * @param {number} [options.sigma] a value between 0.3 and 1000 representing the sigma of the Gaussian mask, where `sigma = 1 + radius / 2`. + * @param {string} [options.precision='integer'] How accurate the operation should be, one of: integer, float, approximate. + * @param {number} [options.minAmplitude=0.2] A value between 0.001 and 1. A smaller value will generate a larger, more accurate mask. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function blur (options) { + let sigma; + if (is.number(options)) { + sigma = options; + } else if (is.plainObject(options)) { + if (!is.number(options.sigma)) { + throw is.invalidParameterError('options.sigma', 'number between 0.3 and 1000', sigma); + } + sigma = options.sigma; + if ('precision' in options) { + if (is.string(vipsPrecision[options.precision])) { + this.options.precision = vipsPrecision[options.precision]; + } else { + throw is.invalidParameterError('precision', 'one of: integer, float, approximate', options.precision); + } + } + if ('minAmplitude' in options) { + if (is.number(options.minAmplitude) && is.inRange(options.minAmplitude, 0.001, 1)) { + this.options.minAmpl = options.minAmplitude; + } else { + throw is.invalidParameterError('minAmplitude', 'number between 0.001 and 1', options.minAmplitude); + } + } + } + + if (!is.defined(options)) { + // No arguments: default to mild blur + this.options.blurSigma = -1; + } else if (is.bool(options)) { + // Boolean argument: apply mild blur? + this.options.blurSigma = options ? -1 : 0; + } else if (is.number(sigma) && is.inRange(sigma, 0.3, 1000)) { + // Numeric argument: specific sigma + this.options.blurSigma = sigma; + } else { + throw is.invalidParameterError('sigma', 'number between 0.3 and 1000', sigma); + } + + return this; +} + +/** + * Expand foreground objects using the dilate morphological operator. + * + * @example + * const output = await sharp(input) + * .dilate() + * .toBuffer(); + * + * @param {Number} [width=1] dilation width in pixels. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function dilate (width) { + if (!is.defined(width)) { + this.options.dilateWidth = 1; + } else if (is.integer(width) && width > 0) { + this.options.dilateWidth = width; + } else { + throw is.invalidParameterError('dilate', 'positive integer', dilate); + } + return this; +} + +/** + * Shrink foreground objects using the erode morphological operator. + * + * @example + * const output = await sharp(input) + * .erode() + * .toBuffer(); + * + * @param {Number} [width=1] erosion width in pixels. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function erode (width) { + if (!is.defined(width)) { + this.options.erodeWidth = 1; + } else if (is.integer(width) && width > 0) { + this.options.erodeWidth = width; + } else { + throw is.invalidParameterError('erode', 'positive integer', erode); + } + return this; +} + +/** + * Merge alpha transparency channel, if any, with a background, then remove the alpha channel. + * + * See also {@link /api-channel#removealpha|removeAlpha}. + * + * @example + * await sharp(rgbaInput) + * .flatten({ background: '#F0A703' }) + * .toBuffer(); + * + * @param {Object} [options] + * @param {string|Object} [options.background={r: 0, g: 0, b: 0}] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to black. + * @returns {Sharp} + */ +function flatten (options) { + this.options.flatten = is.bool(options) ? options : true; + if (is.object(options)) { + this._setBackgroundColourOption('flattenBackground', options.background); + } + return this; +} + +/** + * Ensure the image has an alpha channel + * with all white pixel values made fully transparent. + * + * Existing alpha channel values for non-white pixels remain unchanged. + * + * This feature is experimental and the API may change. + * + * @since 0.32.1 + * + * @example + * await sharp(rgbInput) + * .unflatten() + * .toBuffer(); + * + * @example + * await sharp(rgbInput) + * .threshold(128, { grayscale: false }) // converter bright pixels to white + * .unflatten() + * .toBuffer(); + */ +function unflatten () { + this.options.unflatten = true; + return this; +} + +/** + * Apply a gamma correction by reducing the encoding (darken) pre-resize at a factor of `1/gamma` + * then increasing the encoding (brighten) post-resize at a factor of `gamma`. + * This can improve the perceived brightness of a resized image in non-linear colour spaces. + * JPEG and WebP input images will not take advantage of the shrink-on-load performance optimisation + * when applying a gamma correction. + * + * Supply a second argument to use a different output gamma value, otherwise the first value is used in both cases. + * + * @param {number} [gamma=2.2] value between 1.0 and 3.0. + * @param {number} [gammaOut] value between 1.0 and 3.0. (optional, defaults to same as `gamma`) + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function gamma (gamma, gammaOut) { + if (!is.defined(gamma)) { + // Default gamma correction of 2.2 (sRGB) + this.options.gamma = 2.2; + } else if (is.number(gamma) && is.inRange(gamma, 1, 3)) { + this.options.gamma = gamma; + } else { + throw is.invalidParameterError('gamma', 'number between 1.0 and 3.0', gamma); + } + if (!is.defined(gammaOut)) { + // Default gamma correction for output is same as input + this.options.gammaOut = this.options.gamma; + } else if (is.number(gammaOut) && is.inRange(gammaOut, 1, 3)) { + this.options.gammaOut = gammaOut; + } else { + throw is.invalidParameterError('gammaOut', 'number between 1.0 and 3.0', gammaOut); + } + return this; +} + +/** + * Produce the "negative" of the image. + * + * @example + * const output = await sharp(input) + * .negate() + * .toBuffer(); + * + * @example + * const output = await sharp(input) + * .negate({ alpha: false }) + * .toBuffer(); + * + * @param {Object} [options] + * @param {Boolean} [options.alpha=true] Whether or not to negate any alpha channel + * @returns {Sharp} + */ +function negate (options) { + this.options.negate = is.bool(options) ? options : true; + if (is.plainObject(options) && 'alpha' in options) { + if (!is.bool(options.alpha)) { + throw is.invalidParameterError('alpha', 'should be boolean value', options.alpha); + } else { + this.options.negateAlpha = options.alpha; + } + } + return this; +} + +/** + * Enhance output image contrast by stretching its luminance to cover a full dynamic range. + * + * Uses a histogram-based approach, taking a default range of 1% to 99% to reduce sensitivity to noise at the extremes. + * + * Luminance values below the `lower` percentile will be underexposed by clipping to zero. + * Luminance values above the `upper` percentile will be overexposed by clipping to the max pixel value. + * + * @example + * const output = await sharp(input) + * .normalise() + * .toBuffer(); + * + * @example + * const output = await sharp(input) + * .normalise({ lower: 0, upper: 100 }) + * .toBuffer(); + * + * @param {Object} [options] + * @param {number} [options.lower=1] - Percentile below which luminance values will be underexposed. + * @param {number} [options.upper=99] - Percentile above which luminance values will be overexposed. + * @returns {Sharp} + */ +function normalise (options) { + if (is.plainObject(options)) { + if (is.defined(options.lower)) { + if (is.number(options.lower) && is.inRange(options.lower, 0, 99)) { + this.options.normaliseLower = options.lower; + } else { + throw is.invalidParameterError('lower', 'number between 0 and 99', options.lower); + } + } + if (is.defined(options.upper)) { + if (is.number(options.upper) && is.inRange(options.upper, 1, 100)) { + this.options.normaliseUpper = options.upper; + } else { + throw is.invalidParameterError('upper', 'number between 1 and 100', options.upper); + } + } + } + if (this.options.normaliseLower >= this.options.normaliseUpper) { + throw is.invalidParameterError('range', 'lower to be less than upper', + `${this.options.normaliseLower} >= ${this.options.normaliseUpper}`); + } + this.options.normalise = true; + return this; +} + +/** + * Alternative spelling of normalise. + * + * @example + * const output = await sharp(input) + * .normalize() + * .toBuffer(); + * + * @param {Object} [options] + * @param {number} [options.lower=1] - Percentile below which luminance values will be underexposed. + * @param {number} [options.upper=99] - Percentile above which luminance values will be overexposed. + * @returns {Sharp} + */ +function normalize (options) { + return this.normalise(options); +} + +/** + * Perform contrast limiting adaptive histogram equalization + * {@link https://en.wikipedia.org/wiki/Adaptive_histogram_equalization#Contrast_Limited_AHE|CLAHE}. + * + * This will, in general, enhance the clarity of the image by bringing out darker details. + * + * @since 0.28.3 + * + * @example + * const output = await sharp(input) + * .clahe({ + * width: 3, + * height: 3, + * }) + * .toBuffer(); + * + * @param {Object} options + * @param {number} options.width - Integral width of the search window, in pixels. + * @param {number} options.height - Integral height of the search window, in pixels. + * @param {number} [options.maxSlope=3] - Integral level of brightening, between 0 and 100, where 0 disables contrast limiting. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function clahe (options) { + if (is.plainObject(options)) { + if (is.integer(options.width) && options.width > 0) { + this.options.claheWidth = options.width; + } else { + throw is.invalidParameterError('width', 'integer greater than zero', options.width); + } + if (is.integer(options.height) && options.height > 0) { + this.options.claheHeight = options.height; + } else { + throw is.invalidParameterError('height', 'integer greater than zero', options.height); + } + if (is.defined(options.maxSlope)) { + if (is.integer(options.maxSlope) && is.inRange(options.maxSlope, 0, 100)) { + this.options.claheMaxSlope = options.maxSlope; + } else { + throw is.invalidParameterError('maxSlope', 'integer between 0 and 100', options.maxSlope); + } + } + } else { + throw is.invalidParameterError('options', 'plain object', options); + } + return this; +} + +/** + * Convolve the image with the specified kernel. + * + * @example + * sharp(input) + * .convolve({ + * width: 3, + * height: 3, + * kernel: [-1, 0, 1, -2, 0, 2, -1, 0, 1] + * }) + * .raw() + * .toBuffer(function(err, data, info) { + * // data contains the raw pixel data representing the convolution + * // of the input image with the horizontal Sobel operator + * }); + * + * @param {Object} kernel + * @param {number} kernel.width - width of the kernel in pixels. + * @param {number} kernel.height - height of the kernel in pixels. + * @param {Array} kernel.kernel - Array of length `width*height` containing the kernel values. + * @param {number} [kernel.scale=sum] - the scale of the kernel in pixels. + * @param {number} [kernel.offset=0] - the offset of the kernel in pixels. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function convolve (kernel) { + if (!is.object(kernel) || !Array.isArray(kernel.kernel) || + !is.integer(kernel.width) || !is.integer(kernel.height) || + !is.inRange(kernel.width, 3, 1001) || !is.inRange(kernel.height, 3, 1001) || + kernel.height * kernel.width !== kernel.kernel.length + ) { + // must pass in a kernel + throw new Error('Invalid convolution kernel'); + } + // Default scale is sum of kernel values + if (!is.integer(kernel.scale)) { + kernel.scale = kernel.kernel.reduce(function (a, b) { + return a + b; + }, 0); + } + // Clip scale to a minimum value of 1 + if (kernel.scale < 1) { + kernel.scale = 1; + } + if (!is.integer(kernel.offset)) { + kernel.offset = 0; + } + this.options.convKernel = kernel; + return this; +} + +/** + * Any pixel value greater than or equal to the threshold value will be set to 255, otherwise it will be set to 0. + * @param {number} [threshold=128] - a value in the range 0-255 representing the level at which the threshold will be applied. + * @param {Object} [options] + * @param {Boolean} [options.greyscale=true] - convert to single channel greyscale. + * @param {Boolean} [options.grayscale=true] - alternative spelling for greyscale. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function threshold (threshold, options) { + if (!is.defined(threshold)) { + this.options.threshold = 128; + } else if (is.bool(threshold)) { + this.options.threshold = threshold ? 128 : 0; + } else if (is.integer(threshold) && is.inRange(threshold, 0, 255)) { + this.options.threshold = threshold; + } else { + throw is.invalidParameterError('threshold', 'integer between 0 and 255', threshold); + } + if (!is.object(options) || options.greyscale === true || options.grayscale === true) { + this.options.thresholdGrayscale = true; + } else { + this.options.thresholdGrayscale = false; + } + return this; +} + +/** + * Perform a bitwise boolean operation with operand image. + * + * This operation creates an output image where each pixel is the result of + * the selected bitwise boolean `operation` between the corresponding pixels of the input images. + * + * @param {Buffer|string} operand - Buffer containing image data or string containing the path to an image file. + * @param {string} operator - one of `and`, `or` or `eor` to perform that bitwise operation, like the C logic operators `&`, `|` and `^` respectively. + * @param {Object} [options] + * @param {Object} [options.raw] - describes operand when using raw pixel data. + * @param {number} [options.raw.width] + * @param {number} [options.raw.height] + * @param {number} [options.raw.channels] + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function boolean (operand, operator, options) { + this.options.boolean = this._createInputDescriptor(operand, options); + if (is.string(operator) && is.inArray(operator, ['and', 'or', 'eor'])) { + this.options.booleanOp = operator; + } else { + throw is.invalidParameterError('operator', 'one of: and, or, eor', operator); + } + return this; +} + +/** + * Apply the linear formula `a` * input + `b` to the image to adjust image levels. + * + * When a single number is provided, it will be used for all image channels. + * When an array of numbers is provided, the array length must match the number of channels. + * + * @example + * await sharp(input) + * .linear(0.5, 2) + * .toBuffer(); + * + * @example + * await sharp(rgbInput) + * .linear( + * [0.25, 0.5, 0.75], + * [150, 100, 50] + * ) + * .toBuffer(); + * + * @param {(number|number[])} [a=[]] multiplier + * @param {(number|number[])} [b=[]] offset + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function linear (a, b) { + if (!is.defined(a) && is.number(b)) { + a = 1.0; + } else if (is.number(a) && !is.defined(b)) { + b = 0.0; + } + if (!is.defined(a)) { + this.options.linearA = []; + } else if (is.number(a)) { + this.options.linearA = [a]; + } else if (Array.isArray(a) && a.length && a.every(is.number)) { + this.options.linearA = a; + } else { + throw is.invalidParameterError('a', 'number or array of numbers', a); + } + if (!is.defined(b)) { + this.options.linearB = []; + } else if (is.number(b)) { + this.options.linearB = [b]; + } else if (Array.isArray(b) && b.length && b.every(is.number)) { + this.options.linearB = b; + } else { + throw is.invalidParameterError('b', 'number or array of numbers', b); + } + if (this.options.linearA.length !== this.options.linearB.length) { + throw new Error('Expected a and b to be arrays of the same length'); + } + return this; +} + +/** + * Recombine the image with the specified matrix. + * + * @since 0.21.1 + * + * @example + * sharp(input) + * .recomb([ + * [0.3588, 0.7044, 0.1368], + * [0.2990, 0.5870, 0.1140], + * [0.2392, 0.4696, 0.0912], + * ]) + * .raw() + * .toBuffer(function(err, data, info) { + * // data contains the raw pixel data after applying the matrix + * // With this example input, a sepia filter has been applied + * }); + * + * @param {Array>} inputMatrix - 3x3 or 4x4 Recombination matrix + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function recomb (inputMatrix) { + if (!Array.isArray(inputMatrix)) { + throw is.invalidParameterError('inputMatrix', 'array', inputMatrix); + } + if (inputMatrix.length !== 3 && inputMatrix.length !== 4) { + throw is.invalidParameterError('inputMatrix', '3x3 or 4x4 array', inputMatrix.length); + } + const recombMatrix = inputMatrix.flat().map(Number); + if (recombMatrix.length !== 9 && recombMatrix.length !== 16) { + throw is.invalidParameterError('inputMatrix', 'cardinality of 9 or 16', recombMatrix.length); + } + this.options.recombMatrix = recombMatrix; + return this; +} + +/** + * Transforms the image using brightness, saturation, hue rotation, and lightness. + * Brightness and lightness both operate on luminance, with the difference being that + * brightness is multiplicative whereas lightness is additive. + * + * @since 0.22.1 + * + * @example + * // increase brightness by a factor of 2 + * const output = await sharp(input) + * .modulate({ + * brightness: 2 + * }) + * .toBuffer(); + * + * @example + * // hue-rotate by 180 degrees + * const output = await sharp(input) + * .modulate({ + * hue: 180 + * }) + * .toBuffer(); + * + * @example + * // increase lightness by +50 + * const output = await sharp(input) + * .modulate({ + * lightness: 50 + * }) + * .toBuffer(); + * + * @example + * // decrease brightness and saturation while also hue-rotating by 90 degrees + * const output = await sharp(input) + * .modulate({ + * brightness: 0.5, + * saturation: 0.5, + * hue: 90, + * }) + * .toBuffer(); + * + * @param {Object} [options] + * @param {number} [options.brightness] Brightness multiplier + * @param {number} [options.saturation] Saturation multiplier + * @param {number} [options.hue] Degrees for hue rotation + * @param {number} [options.lightness] Lightness addend + * @returns {Sharp} + */ +function modulate (options) { + if (!is.plainObject(options)) { + throw is.invalidParameterError('options', 'plain object', options); + } + if ('brightness' in options) { + if (is.number(options.brightness) && options.brightness >= 0) { + this.options.brightness = options.brightness; + } else { + throw is.invalidParameterError('brightness', 'number above zero', options.brightness); + } + } + if ('saturation' in options) { + if (is.number(options.saturation) && options.saturation >= 0) { + this.options.saturation = options.saturation; + } else { + throw is.invalidParameterError('saturation', 'number above zero', options.saturation); + } + } + if ('hue' in options) { + if (is.integer(options.hue)) { + this.options.hue = options.hue % 360; + } else { + throw is.invalidParameterError('hue', 'number', options.hue); + } + } + if ('lightness' in options) { + if (is.number(options.lightness)) { + this.options.lightness = options.lightness; + } else { + throw is.invalidParameterError('lightness', 'number', options.lightness); + } + } + return this; +} + +/** + * Decorate the Sharp prototype with operation-related functions. + * @module Sharp + * @private + */ +module.exports = function (Sharp) { + Object.assign(Sharp.prototype, { + autoOrient, + rotate, + flip, + flop, + affine, + sharpen, + erode, + dilate, + median, + blur, + flatten, + unflatten, + gamma, + negate, + normalise, + normalize, + clahe, + convolve, + threshold, + boolean, + linear, + recomb, + modulate + }); +}; diff --git a/node_modules/sharp/lib/output.js b/node_modules/sharp/lib/output.js new file mode 100644 index 0000000..f1cdaf8 --- /dev/null +++ b/node_modules/sharp/lib/output.js @@ -0,0 +1,1655 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +'use strict'; + +const path = require('node:path'); +const is = require('./is'); +const sharp = require('./sharp'); + +const formats = new Map([ + ['heic', 'heif'], + ['heif', 'heif'], + ['avif', 'avif'], + ['jpeg', 'jpeg'], + ['jpg', 'jpeg'], + ['jpe', 'jpeg'], + ['tile', 'tile'], + ['dz', 'tile'], + ['png', 'png'], + ['raw', 'raw'], + ['tiff', 'tiff'], + ['tif', 'tiff'], + ['webp', 'webp'], + ['gif', 'gif'], + ['jp2', 'jp2'], + ['jpx', 'jp2'], + ['j2k', 'jp2'], + ['j2c', 'jp2'], + ['jxl', 'jxl'] +]); + +const jp2Regex = /\.(jp[2x]|j2[kc])$/i; + +const errJp2Save = () => new Error('JP2 output requires libvips with support for OpenJPEG'); + +const bitdepthFromColourCount = (colours) => 1 << 31 - Math.clz32(Math.ceil(Math.log2(colours))); + +/** + * Write output image data to a file. + * + * If an explicit output format is not selected, it will be inferred from the extension, + * with JPEG, PNG, WebP, AVIF, TIFF, GIF, DZI, and libvips' V format supported. + * Note that raw pixel data is only supported for buffer output. + * + * By default all metadata will be removed, which includes EXIF-based orientation. + * See {@link #withmetadata|withMetadata} for control over this. + * + * The caller is responsible for ensuring directory structures and permissions exist. + * + * A `Promise` is returned when `callback` is not provided. + * + * @example + * sharp(input) + * .toFile('output.png', (err, info) => { ... }); + * + * @example + * sharp(input) + * .toFile('output.png') + * .then(info => { ... }) + * .catch(err => { ... }); + * + * @param {string} fileOut - the path to write the image data to. + * @param {Function} [callback] - called on completion with two arguments `(err, info)`. + * `info` contains the output image `format`, `size` (bytes), `width`, `height`, + * `channels` and `premultiplied` (indicating if premultiplication was used). + * When using a crop strategy also contains `cropOffsetLeft` and `cropOffsetTop`. + * When using the attention crop strategy also contains `attentionX` and `attentionY`, the focal point of the cropped region. + * Animated output will also contain `pageHeight` and `pages`. + * May also contain `textAutofitDpi` (dpi the font was rendered at) if image was created from text. + * @returns {Promise} - when no callback is provided + * @throws {Error} Invalid parameters + */ +function toFile (fileOut, callback) { + let err; + if (!is.string(fileOut)) { + err = new Error('Missing output file path'); + } else if (is.string(this.options.input.file) && path.resolve(this.options.input.file) === path.resolve(fileOut)) { + err = new Error('Cannot use same file for input and output'); + } else if (jp2Regex.test(path.extname(fileOut)) && !this.constructor.format.jp2k.output.file) { + err = errJp2Save(); + } + if (err) { + if (is.fn(callback)) { + callback(err); + } else { + return Promise.reject(err); + } + } else { + this.options.fileOut = fileOut; + const stack = Error(); + return this._pipeline(callback, stack); + } + return this; +} + +/** + * Write output to a Buffer. + * JPEG, PNG, WebP, AVIF, TIFF, GIF and raw pixel data output are supported. + * + * Use {@link #toformat|toFormat} or one of the format-specific functions such as {@link jpeg}, {@link png} etc. to set the output format. + * + * If no explicit format is set, the output format will match the input image, except SVG input which becomes PNG output. + * + * By default all metadata will be removed, which includes EXIF-based orientation. + * See {@link #withmetadata|withMetadata} for control over this. + * + * `callback`, if present, gets three arguments `(err, data, info)` where: + * - `err` is an error, if any. + * - `data` is the output image data. + * - `info` contains the output image `format`, `size` (bytes), `width`, `height`, + * `channels` and `premultiplied` (indicating if premultiplication was used). + * When using a crop strategy also contains `cropOffsetLeft` and `cropOffsetTop`. + * Animated output will also contain `pageHeight` and `pages`. + * May also contain `textAutofitDpi` (dpi the font was rendered at) if image was created from text. + * + * A `Promise` is returned when `callback` is not provided. + * + * @example + * sharp(input) + * .toBuffer((err, data, info) => { ... }); + * + * @example + * sharp(input) + * .toBuffer() + * .then(data => { ... }) + * .catch(err => { ... }); + * + * @example + * sharp(input) + * .png() + * .toBuffer({ resolveWithObject: true }) + * .then(({ data, info }) => { ... }) + * .catch(err => { ... }); + * + * @example + * const { data, info } = await sharp('my-image.jpg') + * // output the raw pixels + * .raw() + * .toBuffer({ resolveWithObject: true }); + * + * // create a more type safe way to work with the raw pixel data + * // this will not copy the data, instead it will change `data`s underlying ArrayBuffer + * // so `data` and `pixelArray` point to the same memory location + * const pixelArray = new Uint8ClampedArray(data.buffer); + * + * // When you are done changing the pixelArray, sharp takes the `pixelArray` as an input + * const { width, height, channels } = info; + * await sharp(pixelArray, { raw: { width, height, channels } }) + * .toFile('my-changed-image.jpg'); + * + * @param {Object} [options] + * @param {boolean} [options.resolveWithObject] Resolve the Promise with an Object containing `data` and `info` properties instead of resolving only with `data`. + * @param {Function} [callback] + * @returns {Promise} - when no callback is provided + */ +function toBuffer (options, callback) { + if (is.object(options)) { + this._setBooleanOption('resolveWithObject', options.resolveWithObject); + } else if (this.options.resolveWithObject) { + this.options.resolveWithObject = false; + } + this.options.fileOut = ''; + const stack = Error(); + return this._pipeline(is.fn(options) ? options : callback, stack); +} + +/** + * Keep all EXIF metadata from the input image in the output image. + * + * EXIF metadata is unsupported for TIFF output. + * + * @since 0.33.0 + * + * @example + * const outputWithExif = await sharp(inputWithExif) + * .keepExif() + * .toBuffer(); + * + * @returns {Sharp} + */ +function keepExif () { + this.options.keepMetadata |= 0b00001; + return this; +} + +/** + * Set EXIF metadata in the output image, ignoring any EXIF in the input image. + * + * @since 0.33.0 + * + * @example + * const dataWithExif = await sharp(input) + * .withExif({ + * IFD0: { + * Copyright: 'The National Gallery' + * }, + * IFD3: { + * GPSLatitudeRef: 'N', + * GPSLatitude: '51/1 30/1 3230/100', + * GPSLongitudeRef: 'W', + * GPSLongitude: '0/1 7/1 4366/100' + * } + * }) + * .toBuffer(); + * + * @param {Object>} exif Object keyed by IFD0, IFD1 etc. of key/value string pairs to write as EXIF data. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function withExif (exif) { + if (is.object(exif)) { + for (const [ifd, entries] of Object.entries(exif)) { + if (is.object(entries)) { + for (const [k, v] of Object.entries(entries)) { + if (is.string(v)) { + this.options.withExif[`exif-${ifd.toLowerCase()}-${k}`] = v; + } else { + throw is.invalidParameterError(`${ifd}.${k}`, 'string', v); + } + } + } else { + throw is.invalidParameterError(ifd, 'object', entries); + } + } + } else { + throw is.invalidParameterError('exif', 'object', exif); + } + this.options.withExifMerge = false; + return this.keepExif(); +} + +/** + * Update EXIF metadata from the input image in the output image. + * + * @since 0.33.0 + * + * @example + * const dataWithMergedExif = await sharp(inputWithExif) + * .withExifMerge({ + * IFD0: { + * Copyright: 'The National Gallery' + * } + * }) + * .toBuffer(); + * + * @param {Object>} exif Object keyed by IFD0, IFD1 etc. of key/value string pairs to write as EXIF data. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function withExifMerge (exif) { + this.withExif(exif); + this.options.withExifMerge = true; + return this; +} + +/** + * Keep ICC profile from the input image in the output image. + * + * Where necessary, will attempt to convert the output colour space to match the profile. + * + * @since 0.33.0 + * + * @example + * const outputWithIccProfile = await sharp(inputWithIccProfile) + * .keepIccProfile() + * .toBuffer(); + * + * @returns {Sharp} + */ +function keepIccProfile () { + this.options.keepMetadata |= 0b01000; + return this; +} + +/** + * Transform using an ICC profile and attach to the output image. + * + * This can either be an absolute filesystem path or + * built-in profile name (`srgb`, `p3`, `cmyk`). + * + * @since 0.33.0 + * + * @example + * const outputWithP3 = await sharp(input) + * .withIccProfile('p3') + * .toBuffer(); + * + * @param {string} icc - Absolute filesystem path to output ICC profile or built-in profile name (srgb, p3, cmyk). + * @param {Object} [options] + * @param {number} [options.attach=true] Should the ICC profile be included in the output image metadata? + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function withIccProfile (icc, options) { + if (is.string(icc)) { + this.options.withIccProfile = icc; + } else { + throw is.invalidParameterError('icc', 'string', icc); + } + this.keepIccProfile(); + if (is.object(options)) { + if (is.defined(options.attach)) { + if (is.bool(options.attach)) { + if (!options.attach) { + this.options.keepMetadata &= ~0b01000; + } + } else { + throw is.invalidParameterError('attach', 'boolean', options.attach); + } + } + } + return this; +} + +/** + * Keep XMP metadata from the input image in the output image. + * + * @since 0.34.3 + * + * @example + * const outputWithXmp = await sharp(inputWithXmp) + * .keepXmp() + * .toBuffer(); + * + * @returns {Sharp} + */ +function keepXmp () { + this.options.keepMetadata |= 0b00010; + return this; +} + +/** + * Set XMP metadata in the output image. + * + * Supported by PNG, JPEG, WebP, and TIFF output. + * + * @since 0.34.3 + * + * @example + * const xmpString = ` + * + * + * + * + * John Doe + * + * + * `; + * + * const data = await sharp(input) + * .withXmp(xmpString) + * .toBuffer(); + * + * @param {string} xmp String containing XMP metadata to be embedded in the output image. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function withXmp (xmp) { + if (is.string(xmp) && xmp.length > 0) { + this.options.withXmp = xmp; + this.options.keepMetadata |= 0b00010; + } else { + throw is.invalidParameterError('xmp', 'non-empty string', xmp); + } + return this; +} + +/** + * Keep all metadata (EXIF, ICC, XMP, IPTC) from the input image in the output image. + * + * The default behaviour, when `keepMetadata` is not used, is to convert to the device-independent + * sRGB colour space and strip all metadata, including the removal of any ICC profile. + * + * @since 0.33.0 + * + * @example + * const outputWithMetadata = await sharp(inputWithMetadata) + * .keepMetadata() + * .toBuffer(); + * + * @returns {Sharp} + */ +function keepMetadata () { + this.options.keepMetadata = 0b11111; + return this; +} + +/** + * Keep most metadata (EXIF, XMP, IPTC) from the input image in the output image. + * + * This will also convert to and add a web-friendly sRGB ICC profile if appropriate. + * + * Allows orientation and density to be set or updated. + * + * @example + * const outputSrgbWithMetadata = await sharp(inputRgbWithMetadata) + * .withMetadata() + * .toBuffer(); + * + * @example + * // Set output metadata to 96 DPI + * const data = await sharp(input) + * .withMetadata({ density: 96 }) + * .toBuffer(); + * + * @param {Object} [options] + * @param {number} [options.orientation] Used to update the EXIF `Orientation` tag, integer between 1 and 8. + * @param {number} [options.density] Number of pixels per inch (DPI). + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function withMetadata (options) { + this.keepMetadata(); + this.withIccProfile('srgb'); + if (is.object(options)) { + if (is.defined(options.orientation)) { + if (is.integer(options.orientation) && is.inRange(options.orientation, 1, 8)) { + this.options.withMetadataOrientation = options.orientation; + } else { + throw is.invalidParameterError('orientation', 'integer between 1 and 8', options.orientation); + } + } + if (is.defined(options.density)) { + if (is.number(options.density) && options.density > 0) { + this.options.withMetadataDensity = options.density; + } else { + throw is.invalidParameterError('density', 'positive number', options.density); + } + } + if (is.defined(options.icc)) { + this.withIccProfile(options.icc); + } + if (is.defined(options.exif)) { + this.withExifMerge(options.exif); + } + } + return this; +} + +/** + * Force output to a given format. + * + * @example + * // Convert any input to PNG output + * const data = await sharp(input) + * .toFormat('png') + * .toBuffer(); + * + * @param {(string|Object)} format - as a string or an Object with an 'id' attribute + * @param {Object} options - output options + * @returns {Sharp} + * @throws {Error} unsupported format or options + */ +function toFormat (format, options) { + const actualFormat = formats.get((is.object(format) && is.string(format.id) ? format.id : format).toLowerCase()); + if (!actualFormat) { + throw is.invalidParameterError('format', `one of: ${[...formats.keys()].join(', ')}`, format); + } + return this[actualFormat](options); +} + +/** + * Use these JPEG options for output image. + * + * @example + * // Convert any input to very high quality JPEG output + * const data = await sharp(input) + * .jpeg({ + * quality: 100, + * chromaSubsampling: '4:4:4' + * }) + * .toBuffer(); + * + * @example + * // Use mozjpeg to reduce output JPEG file size (slower) + * const data = await sharp(input) + * .jpeg({ mozjpeg: true }) + * .toBuffer(); + * + * @param {Object} [options] - output options + * @param {number} [options.quality=80] - quality, integer 1-100 + * @param {boolean} [options.progressive=false] - use progressive (interlace) scan + * @param {string} [options.chromaSubsampling='4:2:0'] - set to '4:4:4' to prevent chroma subsampling otherwise defaults to '4:2:0' chroma subsampling + * @param {boolean} [options.optimiseCoding=true] - optimise Huffman coding tables + * @param {boolean} [options.optimizeCoding=true] - alternative spelling of optimiseCoding + * @param {boolean} [options.mozjpeg=false] - use mozjpeg defaults, equivalent to `{ trellisQuantisation: true, overshootDeringing: true, optimiseScans: true, quantisationTable: 3 }` + * @param {boolean} [options.trellisQuantisation=false] - apply trellis quantisation + * @param {boolean} [options.overshootDeringing=false] - apply overshoot deringing + * @param {boolean} [options.optimiseScans=false] - optimise progressive scans, forces progressive + * @param {boolean} [options.optimizeScans=false] - alternative spelling of optimiseScans + * @param {number} [options.quantisationTable=0] - quantization table to use, integer 0-8 + * @param {number} [options.quantizationTable=0] - alternative spelling of quantisationTable + * @param {boolean} [options.force=true] - force JPEG output, otherwise attempt to use input format + * @returns {Sharp} + * @throws {Error} Invalid options + */ +function jpeg (options) { + if (is.object(options)) { + if (is.defined(options.quality)) { + if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) { + this.options.jpegQuality = options.quality; + } else { + throw is.invalidParameterError('quality', 'integer between 1 and 100', options.quality); + } + } + if (is.defined(options.progressive)) { + this._setBooleanOption('jpegProgressive', options.progressive); + } + if (is.defined(options.chromaSubsampling)) { + if (is.string(options.chromaSubsampling) && is.inArray(options.chromaSubsampling, ['4:2:0', '4:4:4'])) { + this.options.jpegChromaSubsampling = options.chromaSubsampling; + } else { + throw is.invalidParameterError('chromaSubsampling', 'one of: 4:2:0, 4:4:4', options.chromaSubsampling); + } + } + const optimiseCoding = is.bool(options.optimizeCoding) ? options.optimizeCoding : options.optimiseCoding; + if (is.defined(optimiseCoding)) { + this._setBooleanOption('jpegOptimiseCoding', optimiseCoding); + } + if (is.defined(options.mozjpeg)) { + if (is.bool(options.mozjpeg)) { + if (options.mozjpeg) { + this.options.jpegTrellisQuantisation = true; + this.options.jpegOvershootDeringing = true; + this.options.jpegOptimiseScans = true; + this.options.jpegProgressive = true; + this.options.jpegQuantisationTable = 3; + } + } else { + throw is.invalidParameterError('mozjpeg', 'boolean', options.mozjpeg); + } + } + const trellisQuantisation = is.bool(options.trellisQuantization) ? options.trellisQuantization : options.trellisQuantisation; + if (is.defined(trellisQuantisation)) { + this._setBooleanOption('jpegTrellisQuantisation', trellisQuantisation); + } + if (is.defined(options.overshootDeringing)) { + this._setBooleanOption('jpegOvershootDeringing', options.overshootDeringing); + } + const optimiseScans = is.bool(options.optimizeScans) ? options.optimizeScans : options.optimiseScans; + if (is.defined(optimiseScans)) { + this._setBooleanOption('jpegOptimiseScans', optimiseScans); + if (optimiseScans) { + this.options.jpegProgressive = true; + } + } + const quantisationTable = is.number(options.quantizationTable) ? options.quantizationTable : options.quantisationTable; + if (is.defined(quantisationTable)) { + if (is.integer(quantisationTable) && is.inRange(quantisationTable, 0, 8)) { + this.options.jpegQuantisationTable = quantisationTable; + } else { + throw is.invalidParameterError('quantisationTable', 'integer between 0 and 8', quantisationTable); + } + } + } + return this._updateFormatOut('jpeg', options); +} + +/** + * Use these PNG options for output image. + * + * By default, PNG output is full colour at 8 bits per pixel. + * + * Indexed PNG input at 1, 2 or 4 bits per pixel is converted to 8 bits per pixel. + * Set `palette` to `true` for slower, indexed PNG output. + * + * For 16 bits per pixel output, convert to `rgb16` via + * {@link /api-colour#tocolourspace|toColourspace}. + * + * @example + * // Convert any input to full colour PNG output + * const data = await sharp(input) + * .png() + * .toBuffer(); + * + * @example + * // Convert any input to indexed PNG output (slower) + * const data = await sharp(input) + * .png({ palette: true }) + * .toBuffer(); + * + * @example + * // Output 16 bits per pixel RGB(A) + * const data = await sharp(input) + * .toColourspace('rgb16') + * .png() + * .toBuffer(); + * + * @param {Object} [options] + * @param {boolean} [options.progressive=false] - use progressive (interlace) scan + * @param {number} [options.compressionLevel=6] - zlib compression level, 0 (fastest, largest) to 9 (slowest, smallest) + * @param {boolean} [options.adaptiveFiltering=false] - use adaptive row filtering + * @param {boolean} [options.palette=false] - quantise to a palette-based image with alpha transparency support + * @param {number} [options.quality=100] - use the lowest number of colours needed to achieve given quality, sets `palette` to `true` + * @param {number} [options.effort=7] - CPU effort, between 1 (fastest) and 10 (slowest), sets `palette` to `true` + * @param {number} [options.colours=256] - maximum number of palette entries, sets `palette` to `true` + * @param {number} [options.colors=256] - alternative spelling of `options.colours`, sets `palette` to `true` + * @param {number} [options.dither=1.0] - level of Floyd-Steinberg error diffusion, sets `palette` to `true` + * @param {boolean} [options.force=true] - force PNG output, otherwise attempt to use input format + * @returns {Sharp} + * @throws {Error} Invalid options + */ +function png (options) { + if (is.object(options)) { + if (is.defined(options.progressive)) { + this._setBooleanOption('pngProgressive', options.progressive); + } + if (is.defined(options.compressionLevel)) { + if (is.integer(options.compressionLevel) && is.inRange(options.compressionLevel, 0, 9)) { + this.options.pngCompressionLevel = options.compressionLevel; + } else { + throw is.invalidParameterError('compressionLevel', 'integer between 0 and 9', options.compressionLevel); + } + } + if (is.defined(options.adaptiveFiltering)) { + this._setBooleanOption('pngAdaptiveFiltering', options.adaptiveFiltering); + } + const colours = options.colours || options.colors; + if (is.defined(colours)) { + if (is.integer(colours) && is.inRange(colours, 2, 256)) { + this.options.pngBitdepth = bitdepthFromColourCount(colours); + } else { + throw is.invalidParameterError('colours', 'integer between 2 and 256', colours); + } + } + if (is.defined(options.palette)) { + this._setBooleanOption('pngPalette', options.palette); + } else if ([options.quality, options.effort, options.colours, options.colors, options.dither].some(is.defined)) { + this._setBooleanOption('pngPalette', true); + } + if (this.options.pngPalette) { + if (is.defined(options.quality)) { + if (is.integer(options.quality) && is.inRange(options.quality, 0, 100)) { + this.options.pngQuality = options.quality; + } else { + throw is.invalidParameterError('quality', 'integer between 0 and 100', options.quality); + } + } + if (is.defined(options.effort)) { + if (is.integer(options.effort) && is.inRange(options.effort, 1, 10)) { + this.options.pngEffort = options.effort; + } else { + throw is.invalidParameterError('effort', 'integer between 1 and 10', options.effort); + } + } + if (is.defined(options.dither)) { + if (is.number(options.dither) && is.inRange(options.dither, 0, 1)) { + this.options.pngDither = options.dither; + } else { + throw is.invalidParameterError('dither', 'number between 0.0 and 1.0', options.dither); + } + } + } + } + return this._updateFormatOut('png', options); +} + +/** + * Use these WebP options for output image. + * + * @example + * // Convert any input to lossless WebP output + * const data = await sharp(input) + * .webp({ lossless: true }) + * .toBuffer(); + * + * @example + * // Optimise the file size of an animated WebP + * const outputWebp = await sharp(inputWebp, { animated: true }) + * .webp({ effort: 6 }) + * .toBuffer(); + * + * @param {Object} [options] - output options + * @param {number} [options.quality=80] - quality, integer 1-100 + * @param {number} [options.alphaQuality=100] - quality of alpha layer, integer 0-100 + * @param {boolean} [options.lossless=false] - use lossless compression mode + * @param {boolean} [options.nearLossless=false] - use near_lossless compression mode + * @param {boolean} [options.smartSubsample=false] - use high quality chroma subsampling + * @param {boolean} [options.smartDeblock=false] - auto-adjust the deblocking filter, can improve low contrast edges (slow) + * @param {string} [options.preset='default'] - named preset for preprocessing/filtering, one of: default, photo, picture, drawing, icon, text + * @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 6 (slowest) + * @param {number} [options.loop=0] - number of animation iterations, use 0 for infinite animation + * @param {number|number[]} [options.delay] - delay(s) between animation frames (in milliseconds) + * @param {boolean} [options.minSize=false] - prevent use of animation key frames to minimise file size (slow) + * @param {boolean} [options.mixed=false] - allow mixture of lossy and lossless animation frames (slow) + * @param {boolean} [options.force=true] - force WebP output, otherwise attempt to use input format + * @returns {Sharp} + * @throws {Error} Invalid options + */ +function webp (options) { + if (is.object(options)) { + if (is.defined(options.quality)) { + if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) { + this.options.webpQuality = options.quality; + } else { + throw is.invalidParameterError('quality', 'integer between 1 and 100', options.quality); + } + } + if (is.defined(options.alphaQuality)) { + if (is.integer(options.alphaQuality) && is.inRange(options.alphaQuality, 0, 100)) { + this.options.webpAlphaQuality = options.alphaQuality; + } else { + throw is.invalidParameterError('alphaQuality', 'integer between 0 and 100', options.alphaQuality); + } + } + if (is.defined(options.lossless)) { + this._setBooleanOption('webpLossless', options.lossless); + } + if (is.defined(options.nearLossless)) { + this._setBooleanOption('webpNearLossless', options.nearLossless); + } + if (is.defined(options.smartSubsample)) { + this._setBooleanOption('webpSmartSubsample', options.smartSubsample); + } + if (is.defined(options.smartDeblock)) { + this._setBooleanOption('webpSmartDeblock', options.smartDeblock); + } + if (is.defined(options.preset)) { + if (is.string(options.preset) && is.inArray(options.preset, ['default', 'photo', 'picture', 'drawing', 'icon', 'text'])) { + this.options.webpPreset = options.preset; + } else { + throw is.invalidParameterError('preset', 'one of: default, photo, picture, drawing, icon, text', options.preset); + } + } + if (is.defined(options.effort)) { + if (is.integer(options.effort) && is.inRange(options.effort, 0, 6)) { + this.options.webpEffort = options.effort; + } else { + throw is.invalidParameterError('effort', 'integer between 0 and 6', options.effort); + } + } + if (is.defined(options.minSize)) { + this._setBooleanOption('webpMinSize', options.minSize); + } + if (is.defined(options.mixed)) { + this._setBooleanOption('webpMixed', options.mixed); + } + } + trySetAnimationOptions(options, this.options); + return this._updateFormatOut('webp', options); +} + +/** + * Use these GIF options for the output image. + * + * The first entry in the palette is reserved for transparency. + * + * The palette of the input image will be re-used if possible. + * + * @since 0.30.0 + * + * @example + * // Convert PNG to GIF + * await sharp(pngBuffer) + * .gif() + * .toBuffer(); + * + * @example + * // Convert animated WebP to animated GIF + * await sharp('animated.webp', { animated: true }) + * .toFile('animated.gif'); + * + * @example + * // Create a 128x128, cropped, non-dithered, animated thumbnail of an animated GIF + * const out = await sharp('in.gif', { animated: true }) + * .resize({ width: 128, height: 128 }) + * .gif({ dither: 0 }) + * .toBuffer(); + * + * @example + * // Lossy file size reduction of animated GIF + * await sharp('in.gif', { animated: true }) + * .gif({ interFrameMaxError: 8 }) + * .toFile('optim.gif'); + * + * @param {Object} [options] - output options + * @param {boolean} [options.reuse=true] - re-use existing palette, otherwise generate new (slow) + * @param {boolean} [options.progressive=false] - use progressive (interlace) scan + * @param {number} [options.colours=256] - maximum number of palette entries, including transparency, between 2 and 256 + * @param {number} [options.colors=256] - alternative spelling of `options.colours` + * @param {number} [options.effort=7] - CPU effort, between 1 (fastest) and 10 (slowest) + * @param {number} [options.dither=1.0] - level of Floyd-Steinberg error diffusion, between 0 (least) and 1 (most) + * @param {number} [options.interFrameMaxError=0] - maximum inter-frame error for transparency, between 0 (lossless) and 32 + * @param {number} [options.interPaletteMaxError=3] - maximum inter-palette error for palette reuse, between 0 and 256 + * @param {boolean} [options.keepDuplicateFrames=false] - keep duplicate frames in the output instead of combining them + * @param {number} [options.loop=0] - number of animation iterations, use 0 for infinite animation + * @param {number|number[]} [options.delay] - delay(s) between animation frames (in milliseconds) + * @param {boolean} [options.force=true] - force GIF output, otherwise attempt to use input format + * @returns {Sharp} + * @throws {Error} Invalid options + */ +function gif (options) { + if (is.object(options)) { + if (is.defined(options.reuse)) { + this._setBooleanOption('gifReuse', options.reuse); + } + if (is.defined(options.progressive)) { + this._setBooleanOption('gifProgressive', options.progressive); + } + const colours = options.colours || options.colors; + if (is.defined(colours)) { + if (is.integer(colours) && is.inRange(colours, 2, 256)) { + this.options.gifBitdepth = bitdepthFromColourCount(colours); + } else { + throw is.invalidParameterError('colours', 'integer between 2 and 256', colours); + } + } + if (is.defined(options.effort)) { + if (is.number(options.effort) && is.inRange(options.effort, 1, 10)) { + this.options.gifEffort = options.effort; + } else { + throw is.invalidParameterError('effort', 'integer between 1 and 10', options.effort); + } + } + if (is.defined(options.dither)) { + if (is.number(options.dither) && is.inRange(options.dither, 0, 1)) { + this.options.gifDither = options.dither; + } else { + throw is.invalidParameterError('dither', 'number between 0.0 and 1.0', options.dither); + } + } + if (is.defined(options.interFrameMaxError)) { + if (is.number(options.interFrameMaxError) && is.inRange(options.interFrameMaxError, 0, 32)) { + this.options.gifInterFrameMaxError = options.interFrameMaxError; + } else { + throw is.invalidParameterError('interFrameMaxError', 'number between 0.0 and 32.0', options.interFrameMaxError); + } + } + if (is.defined(options.interPaletteMaxError)) { + if (is.number(options.interPaletteMaxError) && is.inRange(options.interPaletteMaxError, 0, 256)) { + this.options.gifInterPaletteMaxError = options.interPaletteMaxError; + } else { + throw is.invalidParameterError('interPaletteMaxError', 'number between 0.0 and 256.0', options.interPaletteMaxError); + } + } + if (is.defined(options.keepDuplicateFrames)) { + if (is.bool(options.keepDuplicateFrames)) { + this._setBooleanOption('gifKeepDuplicateFrames', options.keepDuplicateFrames); + } else { + throw is.invalidParameterError('keepDuplicateFrames', 'boolean', options.keepDuplicateFrames); + } + } + } + trySetAnimationOptions(options, this.options); + return this._updateFormatOut('gif', options); +} + +/* istanbul ignore next */ +/** + * Use these JP2 options for output image. + * + * Requires libvips compiled with support for OpenJPEG. + * The prebuilt binaries do not include this - see + * {@link https://sharp.pixelplumbing.com/install#custom-libvips installing a custom libvips}. + * + * @example + * // Convert any input to lossless JP2 output + * const data = await sharp(input) + * .jp2({ lossless: true }) + * .toBuffer(); + * + * @example + * // Convert any input to very high quality JP2 output + * const data = await sharp(input) + * .jp2({ + * quality: 100, + * chromaSubsampling: '4:4:4' + * }) + * .toBuffer(); + * + * @since 0.29.1 + * + * @param {Object} [options] - output options + * @param {number} [options.quality=80] - quality, integer 1-100 + * @param {boolean} [options.lossless=false] - use lossless compression mode + * @param {number} [options.tileWidth=512] - horizontal tile size + * @param {number} [options.tileHeight=512] - vertical tile size + * @param {string} [options.chromaSubsampling='4:4:4'] - set to '4:2:0' to use chroma subsampling + * @returns {Sharp} + * @throws {Error} Invalid options + */ +function jp2 (options) { + if (!this.constructor.format.jp2k.output.buffer) { + throw errJp2Save(); + } + if (is.object(options)) { + if (is.defined(options.quality)) { + if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) { + this.options.jp2Quality = options.quality; + } else { + throw is.invalidParameterError('quality', 'integer between 1 and 100', options.quality); + } + } + if (is.defined(options.lossless)) { + if (is.bool(options.lossless)) { + this.options.jp2Lossless = options.lossless; + } else { + throw is.invalidParameterError('lossless', 'boolean', options.lossless); + } + } + if (is.defined(options.tileWidth)) { + if (is.integer(options.tileWidth) && is.inRange(options.tileWidth, 1, 32768)) { + this.options.jp2TileWidth = options.tileWidth; + } else { + throw is.invalidParameterError('tileWidth', 'integer between 1 and 32768', options.tileWidth); + } + } + if (is.defined(options.tileHeight)) { + if (is.integer(options.tileHeight) && is.inRange(options.tileHeight, 1, 32768)) { + this.options.jp2TileHeight = options.tileHeight; + } else { + throw is.invalidParameterError('tileHeight', 'integer between 1 and 32768', options.tileHeight); + } + } + if (is.defined(options.chromaSubsampling)) { + if (is.string(options.chromaSubsampling) && is.inArray(options.chromaSubsampling, ['4:2:0', '4:4:4'])) { + this.options.jp2ChromaSubsampling = options.chromaSubsampling; + } else { + throw is.invalidParameterError('chromaSubsampling', 'one of: 4:2:0, 4:4:4', options.chromaSubsampling); + } + } + } + return this._updateFormatOut('jp2', options); +} + +/** + * Set animation options if available. + * @private + * + * @param {Object} [source] - output options + * @param {number} [source.loop=0] - number of animation iterations, use 0 for infinite animation + * @param {number[]} [source.delay] - list of delays between animation frames (in milliseconds) + * @param {Object} [target] - target object for valid options + * @throws {Error} Invalid options + */ +function trySetAnimationOptions (source, target) { + if (is.object(source) && is.defined(source.loop)) { + if (is.integer(source.loop) && is.inRange(source.loop, 0, 65535)) { + target.loop = source.loop; + } else { + throw is.invalidParameterError('loop', 'integer between 0 and 65535', source.loop); + } + } + if (is.object(source) && is.defined(source.delay)) { + // We allow singular values as well + if (is.integer(source.delay) && is.inRange(source.delay, 0, 65535)) { + target.delay = [source.delay]; + } else if ( + Array.isArray(source.delay) && + source.delay.every(is.integer) && + source.delay.every(v => is.inRange(v, 0, 65535))) { + target.delay = source.delay; + } else { + throw is.invalidParameterError('delay', 'integer or an array of integers between 0 and 65535', source.delay); + } + } +} + +/** + * Use these TIFF options for output image. + * + * The `density` can be set in pixels/inch via {@link #withmetadata|withMetadata} + * instead of providing `xres` and `yres` in pixels/mm. + * + * @example + * // Convert SVG input to LZW-compressed, 1 bit per pixel TIFF output + * sharp('input.svg') + * .tiff({ + * compression: 'lzw', + * bitdepth: 1 + * }) + * .toFile('1-bpp-output.tiff') + * .then(info => { ... }); + * + * @param {Object} [options] - output options + * @param {number} [options.quality=80] - quality, integer 1-100 + * @param {boolean} [options.force=true] - force TIFF output, otherwise attempt to use input format + * @param {string} [options.compression='jpeg'] - compression options: none, jpeg, deflate, packbits, ccittfax4, lzw, webp, zstd, jp2k + * @param {string} [options.predictor='horizontal'] - compression predictor options: none, horizontal, float + * @param {boolean} [options.pyramid=false] - write an image pyramid + * @param {boolean} [options.tile=false] - write a tiled tiff + * @param {number} [options.tileWidth=256] - horizontal tile size + * @param {number} [options.tileHeight=256] - vertical tile size + * @param {number} [options.xres=1.0] - horizontal resolution in pixels/mm + * @param {number} [options.yres=1.0] - vertical resolution in pixels/mm + * @param {string} [options.resolutionUnit='inch'] - resolution unit options: inch, cm + * @param {number} [options.bitdepth=8] - reduce bitdepth to 1, 2 or 4 bit + * @param {boolean} [options.miniswhite=false] - write 1-bit images as miniswhite + * @returns {Sharp} + * @throws {Error} Invalid options + */ +function tiff (options) { + if (is.object(options)) { + if (is.defined(options.quality)) { + if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) { + this.options.tiffQuality = options.quality; + } else { + throw is.invalidParameterError('quality', 'integer between 1 and 100', options.quality); + } + } + if (is.defined(options.bitdepth)) { + if (is.integer(options.bitdepth) && is.inArray(options.bitdepth, [1, 2, 4, 8])) { + this.options.tiffBitdepth = options.bitdepth; + } else { + throw is.invalidParameterError('bitdepth', '1, 2, 4 or 8', options.bitdepth); + } + } + // tiling + if (is.defined(options.tile)) { + this._setBooleanOption('tiffTile', options.tile); + } + if (is.defined(options.tileWidth)) { + if (is.integer(options.tileWidth) && options.tileWidth > 0) { + this.options.tiffTileWidth = options.tileWidth; + } else { + throw is.invalidParameterError('tileWidth', 'integer greater than zero', options.tileWidth); + } + } + if (is.defined(options.tileHeight)) { + if (is.integer(options.tileHeight) && options.tileHeight > 0) { + this.options.tiffTileHeight = options.tileHeight; + } else { + throw is.invalidParameterError('tileHeight', 'integer greater than zero', options.tileHeight); + } + } + // miniswhite + if (is.defined(options.miniswhite)) { + this._setBooleanOption('tiffMiniswhite', options.miniswhite); + } + // pyramid + if (is.defined(options.pyramid)) { + this._setBooleanOption('tiffPyramid', options.pyramid); + } + // resolution + if (is.defined(options.xres)) { + if (is.number(options.xres) && options.xres > 0) { + this.options.tiffXres = options.xres; + } else { + throw is.invalidParameterError('xres', 'number greater than zero', options.xres); + } + } + if (is.defined(options.yres)) { + if (is.number(options.yres) && options.yres > 0) { + this.options.tiffYres = options.yres; + } else { + throw is.invalidParameterError('yres', 'number greater than zero', options.yres); + } + } + // compression + if (is.defined(options.compression)) { + if (is.string(options.compression) && is.inArray(options.compression, ['none', 'jpeg', 'deflate', 'packbits', 'ccittfax4', 'lzw', 'webp', 'zstd', 'jp2k'])) { + this.options.tiffCompression = options.compression; + } else { + throw is.invalidParameterError('compression', 'one of: none, jpeg, deflate, packbits, ccittfax4, lzw, webp, zstd, jp2k', options.compression); + } + } + // predictor + if (is.defined(options.predictor)) { + if (is.string(options.predictor) && is.inArray(options.predictor, ['none', 'horizontal', 'float'])) { + this.options.tiffPredictor = options.predictor; + } else { + throw is.invalidParameterError('predictor', 'one of: none, horizontal, float', options.predictor); + } + } + // resolutionUnit + if (is.defined(options.resolutionUnit)) { + if (is.string(options.resolutionUnit) && is.inArray(options.resolutionUnit, ['inch', 'cm'])) { + this.options.tiffResolutionUnit = options.resolutionUnit; + } else { + throw is.invalidParameterError('resolutionUnit', 'one of: inch, cm', options.resolutionUnit); + } + } + } + return this._updateFormatOut('tiff', options); +} + +/** + * Use these AVIF options for output image. + * + * AVIF image sequences are not supported. + * Prebuilt binaries support a bitdepth of 8 only. + * + * This feature is experimental on the Windows ARM64 platform + * and requires a CPU with ARM64v8.4 or later. + * + * @example + * const data = await sharp(input) + * .avif({ effort: 2 }) + * .toBuffer(); + * + * @example + * const data = await sharp(input) + * .avif({ lossless: true }) + * .toBuffer(); + * + * @since 0.27.0 + * + * @param {Object} [options] - output options + * @param {number} [options.quality=50] - quality, integer 1-100 + * @param {boolean} [options.lossless=false] - use lossless compression + * @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 9 (slowest) + * @param {string} [options.chromaSubsampling='4:4:4'] - set to '4:2:0' to use chroma subsampling + * @param {number} [options.bitdepth=8] - set bitdepth to 8, 10 or 12 bit + * @returns {Sharp} + * @throws {Error} Invalid options + */ +function avif (options) { + return this.heif({ ...options, compression: 'av1' }); +} + +/** + * Use these HEIF options for output image. + * + * Support for patent-encumbered HEIC images using `hevc` compression requires the use of a + * globally-installed libvips compiled with support for libheif, libde265 and x265. + * + * @example + * const data = await sharp(input) + * .heif({ compression: 'hevc' }) + * .toBuffer(); + * + * @since 0.23.0 + * + * @param {Object} options - output options + * @param {string} options.compression - compression format: av1, hevc + * @param {number} [options.quality=50] - quality, integer 1-100 + * @param {boolean} [options.lossless=false] - use lossless compression + * @param {number} [options.effort=4] - CPU effort, between 0 (fastest) and 9 (slowest) + * @param {string} [options.chromaSubsampling='4:4:4'] - set to '4:2:0' to use chroma subsampling + * @param {number} [options.bitdepth=8] - set bitdepth to 8, 10 or 12 bit + * @returns {Sharp} + * @throws {Error} Invalid options + */ +function heif (options) { + if (is.object(options)) { + if (is.string(options.compression) && is.inArray(options.compression, ['av1', 'hevc'])) { + this.options.heifCompression = options.compression; + } else { + throw is.invalidParameterError('compression', 'one of: av1, hevc', options.compression); + } + if (is.defined(options.quality)) { + if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) { + this.options.heifQuality = options.quality; + } else { + throw is.invalidParameterError('quality', 'integer between 1 and 100', options.quality); + } + } + if (is.defined(options.lossless)) { + if (is.bool(options.lossless)) { + this.options.heifLossless = options.lossless; + } else { + throw is.invalidParameterError('lossless', 'boolean', options.lossless); + } + } + if (is.defined(options.effort)) { + if (is.integer(options.effort) && is.inRange(options.effort, 0, 9)) { + this.options.heifEffort = options.effort; + } else { + throw is.invalidParameterError('effort', 'integer between 0 and 9', options.effort); + } + } + if (is.defined(options.chromaSubsampling)) { + if (is.string(options.chromaSubsampling) && is.inArray(options.chromaSubsampling, ['4:2:0', '4:4:4'])) { + this.options.heifChromaSubsampling = options.chromaSubsampling; + } else { + throw is.invalidParameterError('chromaSubsampling', 'one of: 4:2:0, 4:4:4', options.chromaSubsampling); + } + } + if (is.defined(options.bitdepth)) { + if (is.integer(options.bitdepth) && is.inArray(options.bitdepth, [8, 10, 12])) { + if (options.bitdepth !== 8 && this.constructor.versions.heif) { + throw is.invalidParameterError('bitdepth when using prebuilt binaries', 8, options.bitdepth); + } + this.options.heifBitdepth = options.bitdepth; + } else { + throw is.invalidParameterError('bitdepth', '8, 10 or 12', options.bitdepth); + } + } + } else { + throw is.invalidParameterError('options', 'Object', options); + } + return this._updateFormatOut('heif', options); +} + +/** + * Use these JPEG-XL (JXL) options for output image. + * + * This feature is experimental, please do not use in production systems. + * + * Requires libvips compiled with support for libjxl. + * The prebuilt binaries do not include this - see + * {@link https://sharp.pixelplumbing.com/install#custom-libvips installing a custom libvips}. + * + * @since 0.31.3 + * + * @param {Object} [options] - output options + * @param {number} [options.distance=1.0] - maximum encoding error, between 0 (highest quality) and 15 (lowest quality) + * @param {number} [options.quality] - calculate `distance` based on JPEG-like quality, between 1 and 100, overrides distance if specified + * @param {number} [options.decodingTier=0] - target decode speed tier, between 0 (highest quality) and 4 (lowest quality) + * @param {boolean} [options.lossless=false] - use lossless compression + * @param {number} [options.effort=7] - CPU effort, between 1 (fastest) and 9 (slowest) + * @param {number} [options.loop=0] - number of animation iterations, use 0 for infinite animation + * @param {number|number[]} [options.delay] - delay(s) between animation frames (in milliseconds) + * @returns {Sharp} + * @throws {Error} Invalid options + */ +function jxl (options) { + if (is.object(options)) { + if (is.defined(options.quality)) { + if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) { + // https://github.com/libjxl/libjxl/blob/0aeea7f180bafd6893c1db8072dcb67d2aa5b03d/tools/cjxl_main.cc#L640-L644 + this.options.jxlDistance = options.quality >= 30 + ? 0.1 + (100 - options.quality) * 0.09 + : 53 / 3000 * options.quality * options.quality - 23 / 20 * options.quality + 25; + } else { + throw is.invalidParameterError('quality', 'integer between 1 and 100', options.quality); + } + } else if (is.defined(options.distance)) { + if (is.number(options.distance) && is.inRange(options.distance, 0, 15)) { + this.options.jxlDistance = options.distance; + } else { + throw is.invalidParameterError('distance', 'number between 0.0 and 15.0', options.distance); + } + } + if (is.defined(options.decodingTier)) { + if (is.integer(options.decodingTier) && is.inRange(options.decodingTier, 0, 4)) { + this.options.jxlDecodingTier = options.decodingTier; + } else { + throw is.invalidParameterError('decodingTier', 'integer between 0 and 4', options.decodingTier); + } + } + if (is.defined(options.lossless)) { + if (is.bool(options.lossless)) { + this.options.jxlLossless = options.lossless; + } else { + throw is.invalidParameterError('lossless', 'boolean', options.lossless); + } + } + if (is.defined(options.effort)) { + if (is.integer(options.effort) && is.inRange(options.effort, 1, 9)) { + this.options.jxlEffort = options.effort; + } else { + throw is.invalidParameterError('effort', 'integer between 1 and 9', options.effort); + } + } + } + trySetAnimationOptions(options, this.options); + return this._updateFormatOut('jxl', options); +} + +/** + * Force output to be raw, uncompressed pixel data. + * Pixel ordering is left-to-right, top-to-bottom, without padding. + * Channel ordering will be RGB or RGBA for non-greyscale colourspaces. + * + * @example + * // Extract raw, unsigned 8-bit RGB pixel data from JPEG input + * const { data, info } = await sharp('input.jpg') + * .raw() + * .toBuffer({ resolveWithObject: true }); + * + * @example + * // Extract alpha channel as raw, unsigned 16-bit pixel data from PNG input + * const data = await sharp('input.png') + * .ensureAlpha() + * .extractChannel(3) + * .toColourspace('b-w') + * .raw({ depth: 'ushort' }) + * .toBuffer(); + * + * @param {Object} [options] - output options + * @param {string} [options.depth='uchar'] - bit depth, one of: char, uchar (default), short, ushort, int, uint, float, complex, double, dpcomplex + * @returns {Sharp} + * @throws {Error} Invalid options + */ +function raw (options) { + if (is.object(options)) { + if (is.defined(options.depth)) { + if (is.string(options.depth) && is.inArray(options.depth, + ['char', 'uchar', 'short', 'ushort', 'int', 'uint', 'float', 'complex', 'double', 'dpcomplex'] + )) { + this.options.rawDepth = options.depth; + } else { + throw is.invalidParameterError('depth', 'one of: char, uchar, short, ushort, int, uint, float, complex, double, dpcomplex', options.depth); + } + } + } + return this._updateFormatOut('raw'); +} + +/** + * Use tile-based deep zoom (image pyramid) output. + * + * Set the format and options for tile images via the `toFormat`, `jpeg`, `png` or `webp` functions. + * Use a `.zip` or `.szi` file extension with `toFile` to write to a compressed archive file format. + * + * The container will be set to `zip` when the output is a Buffer or Stream, otherwise it will default to `fs`. + * + * @example + * sharp('input.tiff') + * .png() + * .tile({ + * size: 512 + * }) + * .toFile('output.dz', function(err, info) { + * // output.dzi is the Deep Zoom XML definition + * // output_files contains 512x512 tiles grouped by zoom level + * }); + * + * @example + * const zipFileWithTiles = await sharp(input) + * .tile({ basename: "tiles" }) + * .toBuffer(); + * + * @example + * const iiififier = sharp().tile({ layout: "iiif" }); + * readableStream + * .pipe(iiififier) + * .pipe(writeableStream); + * + * @param {Object} [options] + * @param {number} [options.size=256] tile size in pixels, a value between 1 and 8192. + * @param {number} [options.overlap=0] tile overlap in pixels, a value between 0 and 8192. + * @param {number} [options.angle=0] tile angle of rotation, must be a multiple of 90. + * @param {string|Object} [options.background={r: 255, g: 255, b: 255, alpha: 1}] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to white without transparency. + * @param {string} [options.depth] how deep to make the pyramid, possible values are `onepixel`, `onetile` or `one`, default based on layout. + * @param {number} [options.skipBlanks=-1] Threshold to skip tile generation. Range is 0-255 for 8-bit images, 0-65535 for 16-bit images. Default is 5 for `google` layout, -1 (no skip) otherwise. + * @param {string} [options.container='fs'] tile container, with value `fs` (filesystem) or `zip` (compressed file). + * @param {string} [options.layout='dz'] filesystem layout, possible values are `dz`, `iiif`, `iiif3`, `zoomify` or `google`. + * @param {boolean} [options.centre=false] centre image in tile. + * @param {boolean} [options.center=false] alternative spelling of centre. + * @param {string} [options.id='https://example.com/iiif'] when `layout` is `iiif`/`iiif3`, sets the `@id`/`id` attribute of `info.json` + * @param {string} [options.basename] the name of the directory within the zip file when container is `zip`. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function tile (options) { + if (is.object(options)) { + // Size of square tiles, in pixels + if (is.defined(options.size)) { + if (is.integer(options.size) && is.inRange(options.size, 1, 8192)) { + this.options.tileSize = options.size; + } else { + throw is.invalidParameterError('size', 'integer between 1 and 8192', options.size); + } + } + // Overlap of tiles, in pixels + if (is.defined(options.overlap)) { + if (is.integer(options.overlap) && is.inRange(options.overlap, 0, 8192)) { + if (options.overlap > this.options.tileSize) { + throw is.invalidParameterError('overlap', `<= size (${this.options.tileSize})`, options.overlap); + } + this.options.tileOverlap = options.overlap; + } else { + throw is.invalidParameterError('overlap', 'integer between 0 and 8192', options.overlap); + } + } + // Container + if (is.defined(options.container)) { + if (is.string(options.container) && is.inArray(options.container, ['fs', 'zip'])) { + this.options.tileContainer = options.container; + } else { + throw is.invalidParameterError('container', 'one of: fs, zip', options.container); + } + } + // Layout + if (is.defined(options.layout)) { + if (is.string(options.layout) && is.inArray(options.layout, ['dz', 'google', 'iiif', 'iiif3', 'zoomify'])) { + this.options.tileLayout = options.layout; + } else { + throw is.invalidParameterError('layout', 'one of: dz, google, iiif, iiif3, zoomify', options.layout); + } + } + // Angle of rotation, + if (is.defined(options.angle)) { + if (is.integer(options.angle) && !(options.angle % 90)) { + this.options.tileAngle = options.angle; + } else { + throw is.invalidParameterError('angle', 'positive/negative multiple of 90', options.angle); + } + } + // Background colour + this._setBackgroundColourOption('tileBackground', options.background); + // Depth of tiles + if (is.defined(options.depth)) { + if (is.string(options.depth) && is.inArray(options.depth, ['onepixel', 'onetile', 'one'])) { + this.options.tileDepth = options.depth; + } else { + throw is.invalidParameterError('depth', 'one of: onepixel, onetile, one', options.depth); + } + } + // Threshold to skip blank tiles + if (is.defined(options.skipBlanks)) { + if (is.integer(options.skipBlanks) && is.inRange(options.skipBlanks, -1, 65535)) { + this.options.tileSkipBlanks = options.skipBlanks; + } else { + throw is.invalidParameterError('skipBlanks', 'integer between -1 and 255/65535', options.skipBlanks); + } + } else if (is.defined(options.layout) && options.layout === 'google') { + this.options.tileSkipBlanks = 5; + } + // Center image in tile + const centre = is.bool(options.center) ? options.center : options.centre; + if (is.defined(centre)) { + this._setBooleanOption('tileCentre', centre); + } + // @id attribute for IIIF layout + if (is.defined(options.id)) { + if (is.string(options.id)) { + this.options.tileId = options.id; + } else { + throw is.invalidParameterError('id', 'string', options.id); + } + } + // Basename for zip container + if (is.defined(options.basename)) { + if (is.string(options.basename)) { + this.options.tileBasename = options.basename; + } else { + throw is.invalidParameterError('basename', 'string', options.basename); + } + } + } + // Format + if (is.inArray(this.options.formatOut, ['jpeg', 'png', 'webp'])) { + this.options.tileFormat = this.options.formatOut; + } else if (this.options.formatOut !== 'input') { + throw is.invalidParameterError('format', 'one of: jpeg, png, webp', this.options.formatOut); + } + return this._updateFormatOut('dz'); +} + +/** + * Set a timeout for processing, in seconds. + * Use a value of zero to continue processing indefinitely, the default behaviour. + * + * The clock starts when libvips opens an input image for processing. + * Time spent waiting for a libuv thread to become available is not included. + * + * @example + * // Ensure processing takes no longer than 3 seconds + * try { + * const data = await sharp(input) + * .blur(1000) + * .timeout({ seconds: 3 }) + * .toBuffer(); + * } catch (err) { + * if (err.message.includes('timeout')) { ... } + * } + * + * @since 0.29.2 + * + * @param {Object} options + * @param {number} options.seconds - Number of seconds after which processing will be stopped + * @returns {Sharp} + */ +function timeout (options) { + if (!is.plainObject(options)) { + throw is.invalidParameterError('options', 'object', options); + } + if (is.integer(options.seconds) && is.inRange(options.seconds, 0, 3600)) { + this.options.timeoutSeconds = options.seconds; + } else { + throw is.invalidParameterError('seconds', 'integer between 0 and 3600', options.seconds); + } + return this; +} + +/** + * Update the output format unless options.force is false, + * in which case revert to input format. + * @private + * @param {string} formatOut + * @param {Object} [options] + * @param {boolean} [options.force=true] - force output format, otherwise attempt to use input format + * @returns {Sharp} + */ +function _updateFormatOut (formatOut, options) { + if (!(is.object(options) && options.force === false)) { + this.options.formatOut = formatOut; + } + return this; +} + +/** + * Update a boolean attribute of the this.options Object. + * @private + * @param {string} key + * @param {boolean} val + * @throws {Error} Invalid key + */ +function _setBooleanOption (key, val) { + if (is.bool(val)) { + this.options[key] = val; + } else { + throw is.invalidParameterError(key, 'boolean', val); + } +} + +/** + * Called by a WriteableStream to notify us it is ready for data. + * @private + */ +function _read () { + /* istanbul ignore else */ + if (!this.options.streamOut) { + this.options.streamOut = true; + const stack = Error(); + this._pipeline(undefined, stack); + } +} + +/** + * Invoke the C++ image processing pipeline + * Supports callback, stream and promise variants + * @private + */ +function _pipeline (callback, stack) { + if (typeof callback === 'function') { + // output=file/buffer + if (this._isStreamInput()) { + // output=file/buffer, input=stream + this.on('finish', () => { + this._flattenBufferIn(); + sharp.pipeline(this.options, (err, data, info) => { + if (err) { + callback(is.nativeError(err, stack)); + } else { + callback(null, data, info); + } + }); + }); + } else { + // output=file/buffer, input=file/buffer + sharp.pipeline(this.options, (err, data, info) => { + if (err) { + callback(is.nativeError(err, stack)); + } else { + callback(null, data, info); + } + }); + } + return this; + } else if (this.options.streamOut) { + // output=stream + if (this._isStreamInput()) { + // output=stream, input=stream + this.once('finish', () => { + this._flattenBufferIn(); + sharp.pipeline(this.options, (err, data, info) => { + if (err) { + this.emit('error', is.nativeError(err, stack)); + } else { + this.emit('info', info); + this.push(data); + } + this.push(null); + this.on('end', () => this.emit('close')); + }); + }); + if (this.streamInFinished) { + this.emit('finish'); + } + } else { + // output=stream, input=file/buffer + sharp.pipeline(this.options, (err, data, info) => { + if (err) { + this.emit('error', is.nativeError(err, stack)); + } else { + this.emit('info', info); + this.push(data); + } + this.push(null); + this.on('end', () => this.emit('close')); + }); + } + return this; + } else { + // output=promise + if (this._isStreamInput()) { + // output=promise, input=stream + return new Promise((resolve, reject) => { + this.once('finish', () => { + this._flattenBufferIn(); + sharp.pipeline(this.options, (err, data, info) => { + if (err) { + reject(is.nativeError(err, stack)); + } else { + if (this.options.resolveWithObject) { + resolve({ data, info }); + } else { + resolve(data); + } + } + }); + }); + }); + } else { + // output=promise, input=file/buffer + return new Promise((resolve, reject) => { + sharp.pipeline(this.options, (err, data, info) => { + if (err) { + reject(is.nativeError(err, stack)); + } else { + if (this.options.resolveWithObject) { + resolve({ data, info }); + } else { + resolve(data); + } + } + }); + }); + } + } +} + +/** + * Decorate the Sharp prototype with output-related functions. + * @module Sharp + * @private + */ +module.exports = function (Sharp) { + Object.assign(Sharp.prototype, { + // Public + toFile, + toBuffer, + keepExif, + withExif, + withExifMerge, + keepIccProfile, + withIccProfile, + keepXmp, + withXmp, + keepMetadata, + withMetadata, + toFormat, + jpeg, + jp2, + png, + webp, + tiff, + avif, + heif, + jxl, + gif, + raw, + tile, + timeout, + // Private + _updateFormatOut, + _setBooleanOption, + _read, + _pipeline + }); +}; diff --git a/node_modules/sharp/lib/resize.js b/node_modules/sharp/lib/resize.js new file mode 100644 index 0000000..9e4aa78 --- /dev/null +++ b/node_modules/sharp/lib/resize.js @@ -0,0 +1,595 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +'use strict'; + +const is = require('./is'); + +/** + * Weighting to apply when using contain/cover fit. + * @member + * @private + */ +const gravity = { + center: 0, + centre: 0, + north: 1, + east: 2, + south: 3, + west: 4, + northeast: 5, + southeast: 6, + southwest: 7, + northwest: 8 +}; + +/** + * Position to apply when using contain/cover fit. + * @member + * @private + */ +const position = { + top: 1, + right: 2, + bottom: 3, + left: 4, + 'right top': 5, + 'right bottom': 6, + 'left bottom': 7, + 'left top': 8 +}; + +/** + * How to extend the image. + * @member + * @private + */ +const extendWith = { + background: 'background', + copy: 'copy', + repeat: 'repeat', + mirror: 'mirror' +}; + +/** + * Strategies for automagic cover behaviour. + * @member + * @private + */ +const strategy = { + entropy: 16, + attention: 17 +}; + +/** + * Reduction kernels. + * @member + * @private + */ +const kernel = { + nearest: 'nearest', + linear: 'linear', + cubic: 'cubic', + mitchell: 'mitchell', + lanczos2: 'lanczos2', + lanczos3: 'lanczos3', + mks2013: 'mks2013', + mks2021: 'mks2021' +}; + +/** + * Methods by which an image can be resized to fit the provided dimensions. + * @member + * @private + */ +const fit = { + contain: 'contain', + cover: 'cover', + fill: 'fill', + inside: 'inside', + outside: 'outside' +}; + +/** + * Map external fit property to internal canvas property. + * @member + * @private + */ +const mapFitToCanvas = { + contain: 'embed', + cover: 'crop', + fill: 'ignore_aspect', + inside: 'max', + outside: 'min' +}; + +/** + * @private + */ +function isRotationExpected (options) { + return (options.angle % 360) !== 0 || options.rotationAngle !== 0; +} + +/** + * @private + */ +function isResizeExpected (options) { + return options.width !== -1 || options.height !== -1; +} + +/** + * Resize image to `width`, `height` or `width x height`. + * + * When both a `width` and `height` are provided, the possible methods by which the image should **fit** these are: + * - `cover`: (default) Preserving aspect ratio, attempt to ensure the image covers both provided dimensions by cropping/clipping to fit. + * - `contain`: Preserving aspect ratio, contain within both provided dimensions using "letterboxing" where necessary. + * - `fill`: Ignore the aspect ratio of the input and stretch to both provided dimensions. + * - `inside`: Preserving aspect ratio, resize the image to be as large as possible while ensuring its dimensions are less than or equal to both those specified. + * - `outside`: Preserving aspect ratio, resize the image to be as small as possible while ensuring its dimensions are greater than or equal to both those specified. + * + * Some of these values are based on the [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit) CSS property. + * + * Examples of various values for the fit property when resizing + * + * When using a **fit** of `cover` or `contain`, the default **position** is `centre`. Other options are: + * - `sharp.position`: `top`, `right top`, `right`, `right bottom`, `bottom`, `left bottom`, `left`, `left top`. + * - `sharp.gravity`: `north`, `northeast`, `east`, `southeast`, `south`, `southwest`, `west`, `northwest`, `center` or `centre`. + * - `sharp.strategy`: `cover` only, dynamically crop using either the `entropy` or `attention` strategy. + * + * Some of these values are based on the [object-position](https://developer.mozilla.org/en-US/docs/Web/CSS/object-position) CSS property. + * + * The strategy-based approach initially resizes so one dimension is at its target length + * then repeatedly ranks edge regions, discarding the edge with the lowest score based on the selected strategy. + * - `entropy`: focus on the region with the highest [Shannon entropy](https://en.wikipedia.org/wiki/Entropy_%28information_theory%29). + * - `attention`: focus on the region with the highest luminance frequency, colour saturation and presence of skin tones. + * + * Possible downsizing kernels are: + * - `nearest`: Use [nearest neighbour interpolation](http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation). + * - `linear`: Use a [triangle filter](https://en.wikipedia.org/wiki/Triangular_function). + * - `cubic`: Use a [Catmull-Rom spline](https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline). + * - `mitchell`: Use a [Mitchell-Netravali spline](https://www.cs.utexas.edu/~fussell/courses/cs384g-fall2013/lectures/mitchell/Mitchell.pdf). + * - `lanczos2`: Use a [Lanczos kernel](https://en.wikipedia.org/wiki/Lanczos_resampling#Lanczos_kernel) with `a=2`. + * - `lanczos3`: Use a Lanczos kernel with `a=3` (the default). + * - `mks2013`: Use a [Magic Kernel Sharp](https://johncostella.com/magic/mks.pdf) 2013 kernel, as adopted by Facebook. + * - `mks2021`: Use a Magic Kernel Sharp 2021 kernel, with more accurate (reduced) sharpening than the 2013 version. + * + * When upsampling, these kernels map to `nearest`, `linear` and `cubic` interpolators. + * Downsampling kernels without a matching upsampling interpolator map to `cubic`. + * + * Only one resize can occur per pipeline. + * Previous calls to `resize` in the same pipeline will be ignored. + * + * @example + * sharp(input) + * .resize({ width: 100 }) + * .toBuffer() + * .then(data => { + * // 100 pixels wide, auto-scaled height + * }); + * + * @example + * sharp(input) + * .resize({ height: 100 }) + * .toBuffer() + * .then(data => { + * // 100 pixels high, auto-scaled width + * }); + * + * @example + * sharp(input) + * .resize(200, 300, { + * kernel: sharp.kernel.nearest, + * fit: 'contain', + * position: 'right top', + * background: { r: 255, g: 255, b: 255, alpha: 0.5 } + * }) + * .toFile('output.png') + * .then(() => { + * // output.png is a 200 pixels wide and 300 pixels high image + * // containing a nearest-neighbour scaled version + * // contained within the north-east corner of a semi-transparent white canvas + * }); + * + * @example + * const transformer = sharp() + * .resize({ + * width: 200, + * height: 200, + * fit: sharp.fit.cover, + * position: sharp.strategy.entropy + * }); + * // Read image data from readableStream + * // Write 200px square auto-cropped image data to writableStream + * readableStream + * .pipe(transformer) + * .pipe(writableStream); + * + * @example + * sharp(input) + * .resize(200, 200, { + * fit: sharp.fit.inside, + * withoutEnlargement: true + * }) + * .toFormat('jpeg') + * .toBuffer() + * .then(function(outputBuffer) { + * // outputBuffer contains JPEG image data + * // no wider and no higher than 200 pixels + * // and no larger than the input image + * }); + * + * @example + * sharp(input) + * .resize(200, 200, { + * fit: sharp.fit.outside, + * withoutReduction: true + * }) + * .toFormat('jpeg') + * .toBuffer() + * .then(function(outputBuffer) { + * // outputBuffer contains JPEG image data + * // of at least 200 pixels wide and 200 pixels high while maintaining aspect ratio + * // and no smaller than the input image + * }); + * + * @example + * const scaleByHalf = await sharp(input) + * .metadata() + * .then(({ width }) => sharp(input) + * .resize(Math.round(width * 0.5)) + * .toBuffer() + * ); + * + * @param {number} [width] - How many pixels wide the resultant image should be. Use `null` or `undefined` to auto-scale the width to match the height. + * @param {number} [height] - How many pixels high the resultant image should be. Use `null` or `undefined` to auto-scale the height to match the width. + * @param {Object} [options] + * @param {number} [options.width] - An alternative means of specifying `width`. If both are present this takes priority. + * @param {number} [options.height] - An alternative means of specifying `height`. If both are present this takes priority. + * @param {String} [options.fit='cover'] - How the image should be resized/cropped to fit the target dimension(s), one of `cover`, `contain`, `fill`, `inside` or `outside`. + * @param {String} [options.position='centre'] - A position, gravity or strategy to use when `fit` is `cover` or `contain`. + * @param {String|Object} [options.background={r: 0, g: 0, b: 0, alpha: 1}] - background colour when `fit` is `contain`, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to black without transparency. + * @param {String} [options.kernel='lanczos3'] - The kernel to use for image reduction and the inferred interpolator to use for upsampling. Use the `fastShrinkOnLoad` option to control kernel vs shrink-on-load. + * @param {Boolean} [options.withoutEnlargement=false] - Do not scale up if the width *or* height are already less than the target dimensions, equivalent to GraphicsMagick's `>` geometry option. This may result in output dimensions smaller than the target dimensions. + * @param {Boolean} [options.withoutReduction=false] - Do not scale down if the width *or* height are already greater than the target dimensions, equivalent to GraphicsMagick's `<` geometry option. This may still result in a crop to reach the target dimensions. + * @param {Boolean} [options.fastShrinkOnLoad=true] - Take greater advantage of the JPEG and WebP shrink-on-load feature, which can lead to a slight moiré pattern or round-down of an auto-scaled dimension. + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function resize (widthOrOptions, height, options) { + if (isResizeExpected(this.options)) { + this.options.debuglog('ignoring previous resize options'); + } + if (this.options.widthPost !== -1) { + this.options.debuglog('operation order will be: extract, resize, extract'); + } + if (is.defined(widthOrOptions)) { + if (is.object(widthOrOptions) && !is.defined(options)) { + options = widthOrOptions; + } else if (is.integer(widthOrOptions) && widthOrOptions > 0) { + this.options.width = widthOrOptions; + } else { + throw is.invalidParameterError('width', 'positive integer', widthOrOptions); + } + } else { + this.options.width = -1; + } + if (is.defined(height)) { + if (is.integer(height) && height > 0) { + this.options.height = height; + } else { + throw is.invalidParameterError('height', 'positive integer', height); + } + } else { + this.options.height = -1; + } + if (is.object(options)) { + // Width + if (is.defined(options.width)) { + if (is.integer(options.width) && options.width > 0) { + this.options.width = options.width; + } else { + throw is.invalidParameterError('width', 'positive integer', options.width); + } + } + // Height + if (is.defined(options.height)) { + if (is.integer(options.height) && options.height > 0) { + this.options.height = options.height; + } else { + throw is.invalidParameterError('height', 'positive integer', options.height); + } + } + // Fit + if (is.defined(options.fit)) { + const canvas = mapFitToCanvas[options.fit]; + if (is.string(canvas)) { + this.options.canvas = canvas; + } else { + throw is.invalidParameterError('fit', 'valid fit', options.fit); + } + } + // Position + if (is.defined(options.position)) { + const pos = is.integer(options.position) + ? options.position + : strategy[options.position] || position[options.position] || gravity[options.position]; + if (is.integer(pos) && (is.inRange(pos, 0, 8) || is.inRange(pos, 16, 17))) { + this.options.position = pos; + } else { + throw is.invalidParameterError('position', 'valid position/gravity/strategy', options.position); + } + } + // Background + this._setBackgroundColourOption('resizeBackground', options.background); + // Kernel + if (is.defined(options.kernel)) { + if (is.string(kernel[options.kernel])) { + this.options.kernel = kernel[options.kernel]; + } else { + throw is.invalidParameterError('kernel', 'valid kernel name', options.kernel); + } + } + // Without enlargement + if (is.defined(options.withoutEnlargement)) { + this._setBooleanOption('withoutEnlargement', options.withoutEnlargement); + } + // Without reduction + if (is.defined(options.withoutReduction)) { + this._setBooleanOption('withoutReduction', options.withoutReduction); + } + // Shrink on load + if (is.defined(options.fastShrinkOnLoad)) { + this._setBooleanOption('fastShrinkOnLoad', options.fastShrinkOnLoad); + } + } + if (isRotationExpected(this.options) && isResizeExpected(this.options)) { + this.options.rotateBefore = true; + } + return this; +} + +/** + * Extend / pad / extrude one or more edges of the image with either + * the provided background colour or pixels derived from the image. + * This operation will always occur after resizing and extraction, if any. + * + * @example + * // Resize to 140 pixels wide, then add 10 transparent pixels + * // to the top, left and right edges and 20 to the bottom edge + * sharp(input) + * .resize(140) + * .extend({ + * top: 10, + * bottom: 20, + * left: 10, + * right: 10, + * background: { r: 0, g: 0, b: 0, alpha: 0 } + * }) + * ... + * +* @example + * // Add a row of 10 red pixels to the bottom + * sharp(input) + * .extend({ + * bottom: 10, + * background: 'red' + * }) + * ... + * + * @example + * // Extrude image by 8 pixels to the right, mirroring existing right hand edge + * sharp(input) + * .extend({ + * right: 8, + * background: 'mirror' + * }) + * ... + * + * @param {(number|Object)} extend - single pixel count to add to all edges or an Object with per-edge counts + * @param {number} [extend.top=0] + * @param {number} [extend.left=0] + * @param {number} [extend.bottom=0] + * @param {number} [extend.right=0] + * @param {String} [extend.extendWith='background'] - populate new pixels using this method, one of: background, copy, repeat, mirror. + * @param {String|Object} [extend.background={r: 0, g: 0, b: 0, alpha: 1}] - background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to black without transparency. + * @returns {Sharp} + * @throws {Error} Invalid parameters +*/ +function extend (extend) { + if (is.integer(extend) && extend > 0) { + this.options.extendTop = extend; + this.options.extendBottom = extend; + this.options.extendLeft = extend; + this.options.extendRight = extend; + } else if (is.object(extend)) { + if (is.defined(extend.top)) { + if (is.integer(extend.top) && extend.top >= 0) { + this.options.extendTop = extend.top; + } else { + throw is.invalidParameterError('top', 'positive integer', extend.top); + } + } + if (is.defined(extend.bottom)) { + if (is.integer(extend.bottom) && extend.bottom >= 0) { + this.options.extendBottom = extend.bottom; + } else { + throw is.invalidParameterError('bottom', 'positive integer', extend.bottom); + } + } + if (is.defined(extend.left)) { + if (is.integer(extend.left) && extend.left >= 0) { + this.options.extendLeft = extend.left; + } else { + throw is.invalidParameterError('left', 'positive integer', extend.left); + } + } + if (is.defined(extend.right)) { + if (is.integer(extend.right) && extend.right >= 0) { + this.options.extendRight = extend.right; + } else { + throw is.invalidParameterError('right', 'positive integer', extend.right); + } + } + this._setBackgroundColourOption('extendBackground', extend.background); + if (is.defined(extend.extendWith)) { + if (is.string(extendWith[extend.extendWith])) { + this.options.extendWith = extendWith[extend.extendWith]; + } else { + throw is.invalidParameterError('extendWith', 'one of: background, copy, repeat, mirror', extend.extendWith); + } + } + } else { + throw is.invalidParameterError('extend', 'integer or object', extend); + } + return this; +} + +/** + * Extract/crop a region of the image. + * + * - Use `extract` before `resize` for pre-resize extraction. + * - Use `extract` after `resize` for post-resize extraction. + * - Use `extract` twice and `resize` once for extract-then-resize-then-extract in a fixed operation order. + * + * @example + * sharp(input) + * .extract({ left: left, top: top, width: width, height: height }) + * .toFile(output, function(err) { + * // Extract a region of the input image, saving in the same format. + * }); + * @example + * sharp(input) + * .extract({ left: leftOffsetPre, top: topOffsetPre, width: widthPre, height: heightPre }) + * .resize(width, height) + * .extract({ left: leftOffsetPost, top: topOffsetPost, width: widthPost, height: heightPost }) + * .toFile(output, function(err) { + * // Extract a region, resize, then extract from the resized image + * }); + * + * @param {Object} options - describes the region to extract using integral pixel values + * @param {number} options.left - zero-indexed offset from left edge + * @param {number} options.top - zero-indexed offset from top edge + * @param {number} options.width - width of region to extract + * @param {number} options.height - height of region to extract + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function extract (options) { + const suffix = isResizeExpected(this.options) || this.options.widthPre !== -1 ? 'Post' : 'Pre'; + if (this.options[`width${suffix}`] !== -1) { + this.options.debuglog('ignoring previous extract options'); + } + ['left', 'top', 'width', 'height'].forEach(function (name) { + const value = options[name]; + if (is.integer(value) && value >= 0) { + this.options[name + (name === 'left' || name === 'top' ? 'Offset' : '') + suffix] = value; + } else { + throw is.invalidParameterError(name, 'integer', value); + } + }, this); + // Ensure existing rotation occurs before pre-resize extraction + if (isRotationExpected(this.options) && !isResizeExpected(this.options)) { + if (this.options.widthPre === -1 || this.options.widthPost === -1) { + this.options.rotateBefore = true; + } + } + if (this.options.input.autoOrient) { + this.options.orientBefore = true; + } + return this; +} + +/** + * Trim pixels from all edges that contain values similar to the given background colour, which defaults to that of the top-left pixel. + * + * Images with an alpha channel will use the combined bounding box of alpha and non-alpha channels. + * + * If the result of this operation would trim an image to nothing then no change is made. + * + * The `info` response Object will contain `trimOffsetLeft` and `trimOffsetTop` properties. + * + * @example + * // Trim pixels with a colour similar to that of the top-left pixel. + * await sharp(input) + * .trim() + * .toFile(output); + * + * @example + * // Trim pixels with the exact same colour as that of the top-left pixel. + * await sharp(input) + * .trim({ + * threshold: 0 + * }) + * .toFile(output); + * + * @example + * // Assume input is line art and trim only pixels with a similar colour to red. + * const output = await sharp(input) + * .trim({ + * background: "#FF0000", + * lineArt: true + * }) + * .toBuffer(); + * + * @example + * // Trim all "yellow-ish" pixels, being more lenient with the higher threshold. + * const output = await sharp(input) + * .trim({ + * background: "yellow", + * threshold: 42, + * }) + * .toBuffer(); + * + * @param {Object} [options] + * @param {string|Object} [options.background='top-left pixel'] - Background colour, parsed by the [color](https://www.npmjs.org/package/color) module, defaults to that of the top-left pixel. + * @param {number} [options.threshold=10] - Allowed difference from the above colour, a positive number. + * @param {boolean} [options.lineArt=false] - Does the input more closely resemble line art (e.g. vector) rather than being photographic? + * @returns {Sharp} + * @throws {Error} Invalid parameters + */ +function trim (options) { + this.options.trimThreshold = 10; + if (is.defined(options)) { + if (is.object(options)) { + if (is.defined(options.background)) { + this._setBackgroundColourOption('trimBackground', options.background); + } + if (is.defined(options.threshold)) { + if (is.number(options.threshold) && options.threshold >= 0) { + this.options.trimThreshold = options.threshold; + } else { + throw is.invalidParameterError('threshold', 'positive number', options.threshold); + } + } + if (is.defined(options.lineArt)) { + this._setBooleanOption('trimLineArt', options.lineArt); + } + } else { + throw is.invalidParameterError('trim', 'object', options); + } + } + if (isRotationExpected(this.options)) { + this.options.rotateBefore = true; + } + return this; +} + +/** + * Decorate the Sharp prototype with resize-related functions. + * @module Sharp + * @private + */ +module.exports = function (Sharp) { + Object.assign(Sharp.prototype, { + resize, + extend, + extract, + trim + }); + // Class attributes + Sharp.gravity = gravity; + Sharp.strategy = strategy; + Sharp.kernel = kernel; + Sharp.fit = fit; + Sharp.position = position; +}; diff --git a/node_modules/sharp/lib/sharp.js b/node_modules/sharp/lib/sharp.js new file mode 100644 index 0000000..78853e9 --- /dev/null +++ b/node_modules/sharp/lib/sharp.js @@ -0,0 +1,122 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +'use strict'; + +// Inspects the runtime environment and exports the relevant sharp.node binary + +const { familySync, versionSync } = require('detect-libc'); + +const { runtimePlatformArch, isUnsupportedNodeRuntime, prebuiltPlatforms, minimumLibvipsVersion } = require('./libvips'); +const runtimePlatform = runtimePlatformArch(); + +const paths = [ + `../src/build/Release/sharp-${runtimePlatform}.node`, + '../src/build/Release/sharp-wasm32.node', + `@img/sharp-${runtimePlatform}/sharp.node`, + '@img/sharp-wasm32/sharp.node' +]; + +let path, sharp; +const errors = []; +for (path of paths) { + try { + sharp = require(path); + break; + } catch (err) { + /* istanbul ignore next */ + errors.push(err); + } +} + +/* istanbul ignore next */ +if (sharp && path.startsWith('@img/sharp-linux-x64') && !sharp._isUsingX64V2()) { + const err = new Error('Prebuilt binaries for linux-x64 require v2 microarchitecture'); + err.code = 'Unsupported CPU'; + errors.push(err); + sharp = null; +} + +/* istanbul ignore next */ +if (sharp) { + module.exports = sharp; +} else { + const [isLinux, isMacOs, isWindows] = ['linux', 'darwin', 'win32'].map(os => runtimePlatform.startsWith(os)); + + const help = [`Could not load the "sharp" module using the ${runtimePlatform} runtime`]; + errors.forEach(err => { + if (err.code !== 'MODULE_NOT_FOUND') { + help.push(`${err.code}: ${err.message}`); + } + }); + const messages = errors.map(err => err.message).join(' '); + help.push('Possible solutions:'); + // Common error messages + if (isUnsupportedNodeRuntime()) { + const { found, expected } = isUnsupportedNodeRuntime(); + help.push( + '- Please upgrade Node.js:', + ` Found ${found}`, + ` Requires ${expected}` + ); + } else if (prebuiltPlatforms.includes(runtimePlatform)) { + const [os, cpu] = runtimePlatform.split('-'); + const libc = os.endsWith('musl') ? ' --libc=musl' : ''; + help.push( + '- Ensure optional dependencies can be installed:', + ' npm install --include=optional sharp', + '- Ensure your package manager supports multi-platform installation:', + ' See https://sharp.pixelplumbing.com/install#cross-platform', + '- Add platform-specific dependencies:', + ` npm install --os=${os.replace('musl', '')}${libc} --cpu=${cpu} sharp` + ); + } else { + help.push( + `- Manually install libvips >= ${minimumLibvipsVersion}`, + '- Add experimental WebAssembly-based dependencies:', + ' npm install --cpu=wasm32 sharp', + ' npm install @img/sharp-wasm32' + ); + } + if (isLinux && /(symbol not found|CXXABI_)/i.test(messages)) { + try { + const { config } = require(`@img/sharp-libvips-${runtimePlatform}/package`); + const libcFound = `${familySync()} ${versionSync()}`; + const libcRequires = `${config.musl ? 'musl' : 'glibc'} ${config.musl || config.glibc}`; + help.push( + '- Update your OS:', + ` Found ${libcFound}`, + ` Requires ${libcRequires}` + ); + } catch (errEngines) {} + } + if (isLinux && /\/snap\/core[0-9]{2}/.test(messages)) { + help.push( + '- Remove the Node.js Snap, which does not support native modules', + ' snap remove node' + ); + } + if (isMacOs && /Incompatible library version/.test(messages)) { + help.push( + '- Update Homebrew:', + ' brew update && brew upgrade vips' + ); + } + if (errors.some(err => err.code === 'ERR_DLOPEN_DISABLED')) { + help.push('- Run Node.js without using the --no-addons flag'); + } + // Link to installation docs + if (isWindows && /The specified procedure could not be found/.test(messages)) { + help.push( + '- Using the canvas package on Windows?', + ' See https://sharp.pixelplumbing.com/install#canvas-and-windows', + '- Check for outdated versions of sharp in the dependency tree:', + ' npm ls sharp' + ); + } + help.push( + '- Consult the installation documentation:', + ' See https://sharp.pixelplumbing.com/install' + ); + throw new Error(help.join('\n')); +} diff --git a/node_modules/sharp/lib/utility.js b/node_modules/sharp/lib/utility.js new file mode 100644 index 0000000..4b11892 --- /dev/null +++ b/node_modules/sharp/lib/utility.js @@ -0,0 +1,291 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +'use strict'; + +const events = require('node:events'); +const detectLibc = require('detect-libc'); + +const is = require('./is'); +const { runtimePlatformArch } = require('./libvips'); +const sharp = require('./sharp'); + +const runtimePlatform = runtimePlatformArch(); +const libvipsVersion = sharp.libvipsVersion(); + +/** + * An Object containing nested boolean values representing the available input and output formats/methods. + * @member + * @example + * console.log(sharp.format); + * @returns {Object} + */ +const format = sharp.format(); +format.heif.output.alias = ['avif', 'heic']; +format.jpeg.output.alias = ['jpe', 'jpg']; +format.tiff.output.alias = ['tif']; +format.jp2k.output.alias = ['j2c', 'j2k', 'jp2', 'jpx']; + +/** + * An Object containing the available interpolators and their proper values + * @readonly + * @enum {string} + */ +const interpolators = { + /** [Nearest neighbour interpolation](http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation). Suitable for image enlargement only. */ + nearest: 'nearest', + /** [Bilinear interpolation](http://en.wikipedia.org/wiki/Bilinear_interpolation). Faster than bicubic but with less smooth results. */ + bilinear: 'bilinear', + /** [Bicubic interpolation](http://en.wikipedia.org/wiki/Bicubic_interpolation) (the default). */ + bicubic: 'bicubic', + /** [LBB interpolation](https://github.com/libvips/libvips/blob/master/libvips/resample/lbb.cpp#L100). Prevents some "[acutance](http://en.wikipedia.org/wiki/Acutance)" but typically reduces performance by a factor of 2. */ + locallyBoundedBicubic: 'lbb', + /** [Nohalo interpolation](http://eprints.soton.ac.uk/268086/). Prevents acutance but typically reduces performance by a factor of 3. */ + nohalo: 'nohalo', + /** [VSQBS interpolation](https://github.com/libvips/libvips/blob/master/libvips/resample/vsqbs.cpp#L48). Prevents "staircasing" when enlarging. */ + vertexSplitQuadraticBasisSpline: 'vsqbs' +}; + +/** + * An Object containing the version numbers of sharp, libvips + * and (when using prebuilt binaries) its dependencies. + * + * @member + * @example + * console.log(sharp.versions); + */ +let versions = { + vips: libvipsVersion.semver +}; +/* istanbul ignore next */ +if (!libvipsVersion.isGlobal) { + if (!libvipsVersion.isWasm) { + try { + versions = require(`@img/sharp-${runtimePlatform}/versions`); + } catch (_) { + try { + versions = require(`@img/sharp-libvips-${runtimePlatform}/versions`); + } catch (_) {} + } + } else { + try { + versions = require('@img/sharp-wasm32/versions'); + } catch (_) {} + } +} +versions.sharp = require('../package.json').version; + +/* istanbul ignore next */ +if (versions.heif && format.heif) { + // Prebuilt binaries provide AV1 + format.heif.input.fileSuffix = ['.avif']; + format.heif.output.alias = ['avif']; +} + +/** + * Gets or, when options are provided, sets the limits of _libvips'_ operation cache. + * Existing entries in the cache will be trimmed after any change in limits. + * This method always returns cache statistics, + * useful for determining how much working memory is required for a particular task. + * + * @example + * const stats = sharp.cache(); + * @example + * sharp.cache( { items: 200 } ); + * sharp.cache( { files: 0 } ); + * sharp.cache(false); + * + * @param {Object|boolean} [options=true] - Object with the following attributes, or boolean where true uses default cache settings and false removes all caching + * @param {number} [options.memory=50] - is the maximum memory in MB to use for this cache + * @param {number} [options.files=20] - is the maximum number of files to hold open + * @param {number} [options.items=100] - is the maximum number of operations to cache + * @returns {Object} + */ +function cache (options) { + if (is.bool(options)) { + if (options) { + // Default cache settings of 50MB, 20 files, 100 items + return sharp.cache(50, 20, 100); + } else { + return sharp.cache(0, 0, 0); + } + } else if (is.object(options)) { + return sharp.cache(options.memory, options.files, options.items); + } else { + return sharp.cache(); + } +} +cache(true); + +/** + * Gets or, when a concurrency is provided, sets + * the maximum number of threads _libvips_ should use to process _each image_. + * These are from a thread pool managed by glib, + * which helps avoid the overhead of creating new threads. + * + * This method always returns the current concurrency. + * + * The default value is the number of CPU cores, + * except when using glibc-based Linux without jemalloc, + * where the default is `1` to help reduce memory fragmentation. + * + * A value of `0` will reset this to the number of CPU cores. + * + * Some image format libraries spawn additional threads, + * e.g. libaom manages its own 4 threads when encoding AVIF images, + * and these are independent of the value set here. + * + * :::note + * Further {@link /performance|control over performance} is available. + * ::: + * + * @example + * const threads = sharp.concurrency(); // 4 + * sharp.concurrency(2); // 2 + * sharp.concurrency(0); // 4 + * + * @param {number} [concurrency] + * @returns {number} concurrency + */ +function concurrency (concurrency) { + return sharp.concurrency(is.integer(concurrency) ? concurrency : null); +} +/* istanbul ignore next */ +if (detectLibc.familySync() === detectLibc.GLIBC && !sharp._isUsingJemalloc()) { + // Reduce default concurrency to 1 when using glibc memory allocator + sharp.concurrency(1); +} else if (detectLibc.familySync() === detectLibc.MUSL && sharp.concurrency() === 1024) { + // Reduce default concurrency when musl thread over-subscription detected + sharp.concurrency(require('node:os').availableParallelism()); +} + +/** + * An EventEmitter that emits a `change` event when a task is either: + * - queued, waiting for _libuv_ to provide a worker thread + * - complete + * @member + * @example + * sharp.queue.on('change', function(queueLength) { + * console.log('Queue contains ' + queueLength + ' task(s)'); + * }); + */ +const queue = new events.EventEmitter(); + +/** + * Provides access to internal task counters. + * - queue is the number of tasks this module has queued waiting for _libuv_ to provide a worker thread from its pool. + * - process is the number of resize tasks currently being processed. + * + * @example + * const counters = sharp.counters(); // { queue: 2, process: 4 } + * + * @returns {Object} + */ +function counters () { + return sharp.counters(); +} + +/** + * Get and set use of SIMD vector unit instructions. + * Requires libvips to have been compiled with highway support. + * + * Improves the performance of `resize`, `blur` and `sharpen` operations + * by taking advantage of the SIMD vector unit of the CPU, e.g. Intel SSE and ARM NEON. + * + * @example + * const simd = sharp.simd(); + * // simd is `true` if the runtime use of highway is currently enabled + * @example + * const simd = sharp.simd(false); + * // prevent libvips from using highway at runtime + * + * @param {boolean} [simd=true] + * @returns {boolean} + */ +function simd (simd) { + return sharp.simd(is.bool(simd) ? simd : null); +} + +/** + * Block libvips operations at runtime. + * + * This is in addition to the `VIPS_BLOCK_UNTRUSTED` environment variable, + * which when set will block all "untrusted" operations. + * + * @since 0.32.4 + * + * @example Block all TIFF input. + * sharp.block({ + * operation: ['VipsForeignLoadTiff'] + * }); + * + * @param {Object} options + * @param {Array} options.operation - List of libvips low-level operation names to block. + */ +function block (options) { + if (is.object(options)) { + if (Array.isArray(options.operation) && options.operation.every(is.string)) { + sharp.block(options.operation, true); + } else { + throw is.invalidParameterError('operation', 'Array', options.operation); + } + } else { + throw is.invalidParameterError('options', 'object', options); + } +} + +/** + * Unblock libvips operations at runtime. + * + * This is useful for defining a list of allowed operations. + * + * @since 0.32.4 + * + * @example Block all input except WebP from the filesystem. + * sharp.block({ + * operation: ['VipsForeignLoad'] + * }); + * sharp.unblock({ + * operation: ['VipsForeignLoadWebpFile'] + * }); + * + * @example Block all input except JPEG and PNG from a Buffer or Stream. + * sharp.block({ + * operation: ['VipsForeignLoad'] + * }); + * sharp.unblock({ + * operation: ['VipsForeignLoadJpegBuffer', 'VipsForeignLoadPngBuffer'] + * }); + * + * @param {Object} options + * @param {Array} options.operation - List of libvips low-level operation names to unblock. + */ +function unblock (options) { + if (is.object(options)) { + if (Array.isArray(options.operation) && options.operation.every(is.string)) { + sharp.block(options.operation, false); + } else { + throw is.invalidParameterError('operation', 'Array', options.operation); + } + } else { + throw is.invalidParameterError('options', 'object', options); + } +} + +/** + * Decorate the Sharp class with utility-related functions. + * @module Sharp + * @private + */ +module.exports = function (Sharp) { + Sharp.cache = cache; + Sharp.concurrency = concurrency; + Sharp.counters = counters; + Sharp.simd = simd; + Sharp.format = format; + Sharp.interpolators = interpolators; + Sharp.versions = versions; + Sharp.queue = queue; + Sharp.block = block; + Sharp.unblock = unblock; +}; diff --git a/node_modules/sharp/package.json b/node_modules/sharp/package.json new file mode 100644 index 0000000..39547c8 --- /dev/null +++ b/node_modules/sharp/package.json @@ -0,0 +1,220 @@ +{ + "name": "sharp", + "description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, GIF, AVIF and TIFF images", + "version": "0.34.4", + "author": "Lovell Fuller ", + "homepage": "https://sharp.pixelplumbing.com", + "contributors": [ + "Pierre Inglebert ", + "Jonathan Ong ", + "Chanon Sajjamanochai ", + "Juliano Julio ", + "Daniel Gasienica ", + "Julian Walker ", + "Amit Pitaru ", + "Brandon Aaron ", + "Andreas Lind ", + "Maurus Cuelenaere ", + "Linus Unnebäck ", + "Victor Mateevitsi ", + "Alaric Holloway ", + "Bernhard K. Weisshuhn ", + "Chris Riley ", + "David Carley ", + "John Tobin ", + "Kenton Gray ", + "Felix Bünemann ", + "Samy Al Zahrani ", + "Chintan Thakkar ", + "F. Orlando Galashan ", + "Kleis Auke Wolthuizen ", + "Matt Hirsch ", + "Matthias Thoemmes ", + "Patrick Paskaris ", + "Jérémy Lal ", + "Rahul Nanwani ", + "Alice Monday ", + "Kristo Jorgenson ", + "YvesBos ", + "Guy Maliar ", + "Nicolas Coden ", + "Matt Parrish ", + "Marcel Bretschneider ", + "Matthew McEachen ", + "Jarda Kotěšovec ", + "Kenric D'Souza ", + "Oleh Aleinyk ", + "Marcel Bretschneider ", + "Andrea Bianco ", + "Rik Heywood ", + "Thomas Parisot ", + "Nathan Graves ", + "Tom Lokhorst ", + "Espen Hovlandsdal ", + "Sylvain Dumont ", + "Alun Davies ", + "Aidan Hoolachan ", + "Axel Eirola ", + "Freezy ", + "Daiz ", + "Julian Aubourg ", + "Keith Belovay ", + "Michael B. Klein ", + "Jordan Prudhomme ", + "Ilya Ovdin ", + "Andargor ", + "Paul Neave ", + "Brendan Kennedy ", + "Brychan Bennett-Odlum ", + "Edward Silverton ", + "Roman Malieiev ", + "Tomas Szabo ", + "Robert O'Rourke ", + "Guillermo Alfonso Varela Chouciño ", + "Christian Flintrup ", + "Manan Jadhav ", + "Leon Radley ", + "alza54 ", + "Jacob Smith ", + "Michael Nutt ", + "Brad Parham ", + "Taneli Vatanen ", + "Joris Dugué ", + "Chris Banks ", + "Ompal Singh ", + "Brodan ", + "Ankur Parihar ", + "Brahim Ait elhaj ", + "Mart Jansink ", + "Lachlan Newman ", + "Dennis Beatty ", + "Ingvar Stepanyan ", + "Don Denton " + ], + "scripts": { + "install": "node install/check.js", + "clean": "rm -rf src/build/ .nyc_output/ coverage/ test/fixtures/output.*", + "test": "npm run test-lint && npm run test-unit && npm run test-licensing && npm run test-types", + "test-lint": "semistandard && cpplint", + "test-unit": "nyc --reporter=lcov --reporter=text --check-coverage --branches=100 mocha", + "test-licensing": "license-checker --production --summary --onlyAllow=\"Apache-2.0;BSD;ISC;LGPL-3.0-or-later;MIT\"", + "test-leak": "./test/leak/leak.sh", + "test-types": "tsd", + "package-from-local-build": "node npm/from-local-build.js", + "package-release-notes": "node npm/release-notes.js", + "docs-build": "node docs/build.mjs", + "docs-serve": "cd docs && npm start", + "docs-publish": "cd docs && npm run build && npx firebase-tools deploy --project pixelplumbing --only hosting:pixelplumbing-sharp" + }, + "type": "commonjs", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "files": [ + "install", + "lib", + "src/*.{cc,h,gyp}" + ], + "repository": { + "type": "git", + "url": "git://github.com/lovell/sharp.git" + }, + "keywords": [ + "jpeg", + "png", + "webp", + "avif", + "tiff", + "gif", + "svg", + "jp2", + "dzi", + "image", + "resize", + "thumbnail", + "crop", + "embed", + "libvips", + "vips" + ], + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.0", + "semver": "^7.7.2" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.4", + "@img/sharp-darwin-x64": "0.34.4", + "@img/sharp-libvips-darwin-arm64": "1.2.3", + "@img/sharp-libvips-darwin-x64": "1.2.3", + "@img/sharp-libvips-linux-arm": "1.2.3", + "@img/sharp-libvips-linux-arm64": "1.2.3", + "@img/sharp-libvips-linux-ppc64": "1.2.3", + "@img/sharp-libvips-linux-s390x": "1.2.3", + "@img/sharp-libvips-linux-x64": "1.2.3", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", + "@img/sharp-libvips-linuxmusl-x64": "1.2.3", + "@img/sharp-linux-arm": "0.34.4", + "@img/sharp-linux-arm64": "0.34.4", + "@img/sharp-linux-ppc64": "0.34.4", + "@img/sharp-linux-s390x": "0.34.4", + "@img/sharp-linux-x64": "0.34.4", + "@img/sharp-linuxmusl-arm64": "0.34.4", + "@img/sharp-linuxmusl-x64": "0.34.4", + "@img/sharp-wasm32": "0.34.4", + "@img/sharp-win32-arm64": "0.34.4", + "@img/sharp-win32-ia32": "0.34.4", + "@img/sharp-win32-x64": "0.34.4" + }, + "devDependencies": { + "@emnapi/runtime": "^1.5.0", + "@img/sharp-libvips-dev": "1.2.3", + "@img/sharp-libvips-dev-wasm32": "1.2.3", + "@img/sharp-libvips-win32-arm64": "1.2.3", + "@img/sharp-libvips-win32-ia32": "1.2.3", + "@img/sharp-libvips-win32-x64": "1.2.3", + "@types/node": "*", + "cc": "^3.0.1", + "emnapi": "^1.5.0", + "exif-reader": "^2.0.2", + "extract-zip": "^2.0.1", + "icc": "^3.0.0", + "jsdoc-to-markdown": "^9.1.2", + "license-checker": "^25.0.1", + "mocha": "^11.7.2", + "node-addon-api": "^8.5.0", + "node-gyp": "^11.4.2", + "nyc": "^17.1.0", + "semistandard": "^17.0.0", + "tar-fs": "^3.1.1", + "tsd": "^0.33.0" + }, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "config": { + "libvips": ">=8.17.2" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "semistandard": { + "env": [ + "mocha" + ] + }, + "cc": { + "linelength": "120", + "filter": [ + "build/include" + ] + }, + "nyc": { + "include": [ + "lib" + ] + }, + "tsd": { + "directory": "test/types/" + } +} diff --git a/node_modules/sharp/src/binding.gyp b/node_modules/sharp/src/binding.gyp new file mode 100644 index 0000000..c4ec70c --- /dev/null +++ b/node_modules/sharp/src/binding.gyp @@ -0,0 +1,298 @@ +# Copyright 2013 Lovell Fuller and others. +# SPDX-License-Identifier: Apache-2.0 + +{ + 'variables': { + 'vips_version': ' +#include +#include +#include +#include +#include +#include // NOLINT(build/c++11) + +#include +#include + +#include "common.h" + +using vips::VImage; + +namespace sharp { + + // Convenience methods to access the attributes of a Napi::Object + bool HasAttr(Napi::Object obj, std::string attr) { + return obj.Has(attr); + } + std::string AttrAsStr(Napi::Object obj, std::string attr) { + return obj.Get(attr).As(); + } + std::string AttrAsStr(Napi::Object obj, unsigned int const attr) { + return obj.Get(attr).As(); + } + uint32_t AttrAsUint32(Napi::Object obj, std::string attr) { + return obj.Get(attr).As().Uint32Value(); + } + int32_t AttrAsInt32(Napi::Object obj, std::string attr) { + return obj.Get(attr).As().Int32Value(); + } + int32_t AttrAsInt32(Napi::Object obj, unsigned int const attr) { + return obj.Get(attr).As().Int32Value(); + } + int64_t AttrAsInt64(Napi::Object obj, std::string attr) { + return obj.Get(attr).As().Int64Value(); + } + double AttrAsDouble(Napi::Object obj, std::string attr) { + return obj.Get(attr).As().DoubleValue(); + } + double AttrAsDouble(Napi::Object obj, unsigned int const attr) { + return obj.Get(attr).As().DoubleValue(); + } + bool AttrAsBool(Napi::Object obj, std::string attr) { + return obj.Get(attr).As().Value(); + } + std::vector AttrAsVectorOfDouble(Napi::Object obj, std::string attr) { + Napi::Array napiArray = obj.Get(attr).As(); + std::vector vectorOfDouble(napiArray.Length()); + for (unsigned int i = 0; i < napiArray.Length(); i++) { + vectorOfDouble[i] = AttrAsDouble(napiArray, i); + } + return vectorOfDouble; + } + std::vector AttrAsInt32Vector(Napi::Object obj, std::string attr) { + Napi::Array array = obj.Get(attr).As(); + std::vector vector(array.Length()); + for (unsigned int i = 0; i < array.Length(); i++) { + vector[i] = AttrAsInt32(array, i); + } + return vector; + } + + // Create an InputDescriptor instance from a Napi::Object describing an input image + InputDescriptor* CreateInputDescriptor(Napi::Object input) { + InputDescriptor *descriptor = new InputDescriptor; + if (HasAttr(input, "file")) { + descriptor->file = AttrAsStr(input, "file"); + } else if (HasAttr(input, "buffer")) { + Napi::Buffer buffer = input.Get("buffer").As>(); + descriptor->bufferLength = buffer.Length(); + descriptor->buffer = buffer.Data(); + descriptor->isBuffer = true; + } + descriptor->failOn = AttrAsEnum(input, "failOn", VIPS_TYPE_FAIL_ON); + // Density for vector-based input + if (HasAttr(input, "density")) { + descriptor->density = AttrAsDouble(input, "density"); + } + // Should we ignore any embedded ICC profile + if (HasAttr(input, "ignoreIcc")) { + descriptor->ignoreIcc = AttrAsBool(input, "ignoreIcc"); + } + // Raw pixel input + if (HasAttr(input, "rawChannels")) { + descriptor->rawDepth = AttrAsEnum(input, "rawDepth", VIPS_TYPE_BAND_FORMAT); + descriptor->rawChannels = AttrAsUint32(input, "rawChannels"); + descriptor->rawWidth = AttrAsUint32(input, "rawWidth"); + descriptor->rawHeight = AttrAsUint32(input, "rawHeight"); + descriptor->rawPremultiplied = AttrAsBool(input, "rawPremultiplied"); + descriptor->rawPageHeight = AttrAsUint32(input, "rawPageHeight"); + } + // Multi-page input (GIF, TIFF, PDF) + if (HasAttr(input, "pages")) { + descriptor->pages = AttrAsInt32(input, "pages"); + } + if (HasAttr(input, "page")) { + descriptor->page = AttrAsUint32(input, "page"); + } + // SVG + if (HasAttr(input, "svgStylesheet")) { + descriptor->svgStylesheet = AttrAsStr(input, "svgStylesheet"); + } + if (HasAttr(input, "svgHighBitdepth")) { + descriptor->svgHighBitdepth = AttrAsBool(input, "svgHighBitdepth"); + } + // Multi-level input (OpenSlide) + if (HasAttr(input, "openSlideLevel")) { + descriptor->openSlideLevel = AttrAsUint32(input, "openSlideLevel"); + } + // subIFD (OME-TIFF) + if (HasAttr(input, "subifd")) { + descriptor->tiffSubifd = AttrAsInt32(input, "tiffSubifd"); + } + // // PDF background color + if (HasAttr(input, "pdfBackground")) { + descriptor->pdfBackground = AttrAsVectorOfDouble(input, "pdfBackground"); + } + // Use JPEG 2000 oneshot mode? + if (HasAttr(input, "jp2Oneshot")) { + descriptor->jp2Oneshot = AttrAsBool(input, "jp2Oneshot"); + } + // Create new image + if (HasAttr(input, "createChannels")) { + descriptor->createChannels = AttrAsUint32(input, "createChannels"); + descriptor->createWidth = AttrAsUint32(input, "createWidth"); + descriptor->createHeight = AttrAsUint32(input, "createHeight"); + descriptor->createPageHeight = AttrAsUint32(input, "createPageHeight"); + if (HasAttr(input, "createNoiseType")) { + descriptor->createNoiseType = AttrAsStr(input, "createNoiseType"); + descriptor->createNoiseMean = AttrAsDouble(input, "createNoiseMean"); + descriptor->createNoiseSigma = AttrAsDouble(input, "createNoiseSigma"); + } else { + descriptor->createBackground = AttrAsVectorOfDouble(input, "createBackground"); + } + } + // Create new image with text + if (HasAttr(input, "textValue")) { + descriptor->textValue = AttrAsStr(input, "textValue"); + if (HasAttr(input, "textFont")) { + descriptor->textFont = AttrAsStr(input, "textFont"); + } + if (HasAttr(input, "textFontfile")) { + descriptor->textFontfile = AttrAsStr(input, "textFontfile"); + } + if (HasAttr(input, "textWidth")) { + descriptor->textWidth = AttrAsUint32(input, "textWidth"); + } + if (HasAttr(input, "textHeight")) { + descriptor->textHeight = AttrAsUint32(input, "textHeight"); + } + if (HasAttr(input, "textAlign")) { + descriptor->textAlign = AttrAsEnum(input, "textAlign", VIPS_TYPE_ALIGN); + } + if (HasAttr(input, "textJustify")) { + descriptor->textJustify = AttrAsBool(input, "textJustify"); + } + if (HasAttr(input, "textDpi")) { + descriptor->textDpi = AttrAsUint32(input, "textDpi"); + } + if (HasAttr(input, "textRgba")) { + descriptor->textRgba = AttrAsBool(input, "textRgba"); + } + if (HasAttr(input, "textSpacing")) { + descriptor->textSpacing = AttrAsUint32(input, "textSpacing"); + } + if (HasAttr(input, "textWrap")) { + descriptor->textWrap = AttrAsEnum(input, "textWrap", VIPS_TYPE_TEXT_WRAP); + } + } + // Join images together + if (HasAttr(input, "joinAnimated")) { + descriptor->joinAnimated = AttrAsBool(input, "joinAnimated"); + } + if (HasAttr(input, "joinAcross")) { + descriptor->joinAcross = AttrAsUint32(input, "joinAcross"); + } + if (HasAttr(input, "joinShim")) { + descriptor->joinShim = AttrAsUint32(input, "joinShim"); + } + if (HasAttr(input, "joinBackground")) { + descriptor->joinBackground = AttrAsVectorOfDouble(input, "joinBackground"); + } + if (HasAttr(input, "joinHalign")) { + descriptor->joinHalign = AttrAsEnum(input, "joinHalign", VIPS_TYPE_ALIGN); + } + if (HasAttr(input, "joinValign")) { + descriptor->joinValign = AttrAsEnum(input, "joinValign", VIPS_TYPE_ALIGN); + } + // Limit input images to a given number of pixels, where pixels = width * height + descriptor->limitInputPixels = static_cast(AttrAsInt64(input, "limitInputPixels")); + if (HasAttr(input, "access")) { + descriptor->access = AttrAsBool(input, "sequentialRead") ? VIPS_ACCESS_SEQUENTIAL : VIPS_ACCESS_RANDOM; + } + // Remove safety features and allow unlimited input + descriptor->unlimited = AttrAsBool(input, "unlimited"); + // Use the EXIF orientation to auto orient the image + descriptor->autoOrient = AttrAsBool(input, "autoOrient"); + return descriptor; + } + + // How many tasks are in the queue? + std::atomic counterQueue{0}; + + // How many tasks are being processed? + std::atomic counterProcess{0}; + + // Filename extension checkers + static bool EndsWith(std::string const &str, std::string const &end) { + return str.length() >= end.length() && 0 == str.compare(str.length() - end.length(), end.length(), end); + } + bool IsJpeg(std::string const &str) { + return EndsWith(str, ".jpg") || EndsWith(str, ".jpeg") || EndsWith(str, ".JPG") || EndsWith(str, ".JPEG"); + } + bool IsPng(std::string const &str) { + return EndsWith(str, ".png") || EndsWith(str, ".PNG"); + } + bool IsWebp(std::string const &str) { + return EndsWith(str, ".webp") || EndsWith(str, ".WEBP"); + } + bool IsGif(std::string const &str) { + return EndsWith(str, ".gif") || EndsWith(str, ".GIF"); + } + bool IsJp2(std::string const &str) { + return EndsWith(str, ".jp2") || EndsWith(str, ".jpx") || EndsWith(str, ".j2k") || EndsWith(str, ".j2c") + || EndsWith(str, ".JP2") || EndsWith(str, ".JPX") || EndsWith(str, ".J2K") || EndsWith(str, ".J2C"); + } + bool IsTiff(std::string const &str) { + return EndsWith(str, ".tif") || EndsWith(str, ".tiff") || EndsWith(str, ".TIF") || EndsWith(str, ".TIFF"); + } + bool IsHeic(std::string const &str) { + return EndsWith(str, ".heic") || EndsWith(str, ".HEIC"); + } + bool IsHeif(std::string const &str) { + return EndsWith(str, ".heif") || EndsWith(str, ".HEIF") || IsHeic(str) || IsAvif(str); + } + bool IsAvif(std::string const &str) { + return EndsWith(str, ".avif") || EndsWith(str, ".AVIF"); + } + bool IsJxl(std::string const &str) { + return EndsWith(str, ".jxl") || EndsWith(str, ".JXL"); + } + bool IsDz(std::string const &str) { + return EndsWith(str, ".dzi") || EndsWith(str, ".DZI"); + } + bool IsDzZip(std::string const &str) { + return EndsWith(str, ".zip") || EndsWith(str, ".ZIP") || EndsWith(str, ".szi") || EndsWith(str, ".SZI"); + } + bool IsV(std::string const &str) { + return EndsWith(str, ".v") || EndsWith(str, ".V") || EndsWith(str, ".vips") || EndsWith(str, ".VIPS"); + } + + /* + Trim space from end of string. + */ + std::string TrimEnd(std::string const &str) { + return str.substr(0, str.find_last_not_of(" \n\r\f") + 1); + } + + /* + Provide a string identifier for the given image type. + */ + std::string ImageTypeId(ImageType const imageType) { + std::string id; + switch (imageType) { + case ImageType::JPEG: id = "jpeg"; break; + case ImageType::PNG: id = "png"; break; + case ImageType::WEBP: id = "webp"; break; + case ImageType::TIFF: id = "tiff"; break; + case ImageType::GIF: id = "gif"; break; + case ImageType::JP2: id = "jp2"; break; + case ImageType::SVG: id = "svg"; break; + case ImageType::HEIF: id = "heif"; break; + case ImageType::PDF: id = "pdf"; break; + case ImageType::MAGICK: id = "magick"; break; + case ImageType::OPENSLIDE: id = "openslide"; break; + case ImageType::PPM: id = "ppm"; break; + case ImageType::FITS: id = "fits"; break; + case ImageType::EXR: id = "exr"; break; + case ImageType::JXL: id = "jxl"; break; + case ImageType::RAD: id = "rad"; break; + case ImageType::DCRAW: id = "dcraw"; break; + case ImageType::VIPS: id = "vips"; break; + case ImageType::RAW: id = "raw"; break; + case ImageType::UNKNOWN: id = "unknown"; break; + case ImageType::MISSING: id = "missing"; break; + } + return id; + } + + /** + * Regenerate this table with something like: + * + * $ vips -l foreign | grep -i load | awk '{ print $2, $1; }' + * + * Plus a bit of editing. + */ + std::map loaderToType = { + { "VipsForeignLoadJpegFile", ImageType::JPEG }, + { "VipsForeignLoadJpegBuffer", ImageType::JPEG }, + { "VipsForeignLoadPngFile", ImageType::PNG }, + { "VipsForeignLoadPngBuffer", ImageType::PNG }, + { "VipsForeignLoadWebpFile", ImageType::WEBP }, + { "VipsForeignLoadWebpBuffer", ImageType::WEBP }, + { "VipsForeignLoadTiffFile", ImageType::TIFF }, + { "VipsForeignLoadTiffBuffer", ImageType::TIFF }, + { "VipsForeignLoadGifFile", ImageType::GIF }, + { "VipsForeignLoadGifBuffer", ImageType::GIF }, + { "VipsForeignLoadNsgifFile", ImageType::GIF }, + { "VipsForeignLoadNsgifBuffer", ImageType::GIF }, + { "VipsForeignLoadJp2kBuffer", ImageType::JP2 }, + { "VipsForeignLoadJp2kFile", ImageType::JP2 }, + { "VipsForeignLoadSvgFile", ImageType::SVG }, + { "VipsForeignLoadSvgBuffer", ImageType::SVG }, + { "VipsForeignLoadHeifFile", ImageType::HEIF }, + { "VipsForeignLoadHeifBuffer", ImageType::HEIF }, + { "VipsForeignLoadPdfFile", ImageType::PDF }, + { "VipsForeignLoadPdfBuffer", ImageType::PDF }, + { "VipsForeignLoadMagickFile", ImageType::MAGICK }, + { "VipsForeignLoadMagickBuffer", ImageType::MAGICK }, + { "VipsForeignLoadMagick7File", ImageType::MAGICK }, + { "VipsForeignLoadMagick7Buffer", ImageType::MAGICK }, + { "VipsForeignLoadOpenslideFile", ImageType::OPENSLIDE }, + { "VipsForeignLoadPpmFile", ImageType::PPM }, + { "VipsForeignLoadFitsFile", ImageType::FITS }, + { "VipsForeignLoadOpenexr", ImageType::EXR }, + { "VipsForeignLoadJxlFile", ImageType::JXL }, + { "VipsForeignLoadJxlBuffer", ImageType::JXL }, + { "VipsForeignLoadRadFile", ImageType::RAD }, + { "VipsForeignLoadRadBuffer", ImageType::RAD }, + { "VipsForeignLoadDcRawFile", ImageType::DCRAW }, + { "VipsForeignLoadDcRawBuffer", ImageType::DCRAW }, + { "VipsForeignLoadVips", ImageType::VIPS }, + { "VipsForeignLoadVipsFile", ImageType::VIPS }, + { "VipsForeignLoadRaw", ImageType::RAW } + }; + + /* + Determine image format of a buffer. + */ + ImageType DetermineImageType(void *buffer, size_t const length) { + ImageType imageType = ImageType::UNKNOWN; + char const *load = vips_foreign_find_load_buffer(buffer, length); + if (load != nullptr) { + auto it = loaderToType.find(load); + if (it != loaderToType.end()) { + imageType = it->second; + } + } + return imageType; + } + + /* + Determine image format, reads the first few bytes of the file + */ + ImageType DetermineImageType(char const *file) { + ImageType imageType = ImageType::UNKNOWN; + char const *load = vips_foreign_find_load(file); + if (load != nullptr) { + auto it = loaderToType.find(load); + if (it != loaderToType.end()) { + imageType = it->second; + } + } else { + if (EndsWith(vips::VError().what(), " does not exist\n")) { + imageType = ImageType::MISSING; + } + } + return imageType; + } + + /* + Does this image type support multiple pages? + */ + bool ImageTypeSupportsPage(ImageType imageType) { + return + imageType == ImageType::WEBP || + imageType == ImageType::MAGICK || + imageType == ImageType::GIF || + imageType == ImageType::JP2 || + imageType == ImageType::TIFF || + imageType == ImageType::HEIF || + imageType == ImageType::PDF; + } + + /* + Does this image type support removal of safety limits? + */ + bool ImageTypeSupportsUnlimited(ImageType imageType) { + return + imageType == ImageType::JPEG || + imageType == ImageType::PNG || + imageType == ImageType::SVG || + imageType == ImageType::TIFF || + imageType == ImageType::HEIF; + } + + /* + Format-specific options builder + */ + vips::VOption* GetOptionsForImageType(ImageType imageType, InputDescriptor *descriptor) { + vips::VOption *option = VImage::option() + ->set("access", descriptor->access) + ->set("fail_on", descriptor->failOn); + if (descriptor->unlimited && ImageTypeSupportsUnlimited(imageType)) { + option->set("unlimited", true); + } + if (ImageTypeSupportsPage(imageType)) { + option->set("n", descriptor->pages); + option->set("page", descriptor->page); + } + switch (imageType) { + case ImageType::SVG: + option->set("dpi", descriptor->density) + ->set("stylesheet", descriptor->svgStylesheet.data()) + ->set("high_bitdepth", descriptor->svgHighBitdepth); + break; + case ImageType::TIFF: + option->set("subifd", descriptor->tiffSubifd); + break; + case ImageType::PDF: + option->set("dpi", descriptor->density) + ->set("background", descriptor->pdfBackground); + break; + case ImageType::OPENSLIDE: + option->set("level", descriptor->openSlideLevel); + break; + case ImageType::JP2: + option->set("oneshot", descriptor->jp2Oneshot); + break; + case ImageType::MAGICK: + option->set("density", std::to_string(descriptor->density).data()); + break; + default: + break; + } + return option; + } + + /* + Open an image from the given InputDescriptor (filesystem, compressed buffer, raw pixel data) + */ + std::tuple OpenInput(InputDescriptor *descriptor) { + VImage image; + ImageType imageType; + if (descriptor->isBuffer) { + if (descriptor->rawChannels > 0) { + // Raw, uncompressed pixel data + bool const is8bit = vips_band_format_is8bit(descriptor->rawDepth); + image = VImage::new_from_memory(descriptor->buffer, descriptor->bufferLength, + descriptor->rawWidth, descriptor->rawHeight, descriptor->rawChannels, descriptor->rawDepth); + if (descriptor->rawChannels < 3) { + image.get_image()->Type = is8bit ? VIPS_INTERPRETATION_B_W : VIPS_INTERPRETATION_GREY16; + } else { + image.get_image()->Type = is8bit ? VIPS_INTERPRETATION_sRGB : VIPS_INTERPRETATION_RGB16; + } + if (descriptor->rawPageHeight > 0) { + image.set(VIPS_META_PAGE_HEIGHT, descriptor->rawPageHeight); + image.set(VIPS_META_N_PAGES, static_cast(descriptor->rawHeight / descriptor->rawPageHeight)); + } + if (descriptor->rawPremultiplied) { + image = image.unpremultiply(); + } + imageType = ImageType::RAW; + } else { + // Compressed data + imageType = DetermineImageType(descriptor->buffer, descriptor->bufferLength); + if (imageType != ImageType::UNKNOWN) { + try { + vips::VOption *option = GetOptionsForImageType(imageType, descriptor); + image = VImage::new_from_buffer(descriptor->buffer, descriptor->bufferLength, nullptr, option); + if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) { + image = SetDensity(image, descriptor->density); + } + } catch (vips::VError const &err) { + throw vips::VError(std::string("Input buffer has corrupt header: ") + err.what()); + } + } else { + throw vips::VError("Input buffer contains unsupported image format"); + } + } + } else { + int const channels = descriptor->createChannels; + if (channels > 0) { + // Create new image + if (descriptor->createNoiseType == "gaussian") { + std::vector bands = {}; + bands.reserve(channels); + for (int _band = 0; _band < channels; _band++) { + bands.push_back(VImage::gaussnoise(descriptor->createWidth, descriptor->createHeight, VImage::option() + ->set("mean", descriptor->createNoiseMean) + ->set("sigma", descriptor->createNoiseSigma))); + } + image = VImage::bandjoin(bands).copy(VImage::option()->set("interpretation", + channels < 3 ? VIPS_INTERPRETATION_B_W: VIPS_INTERPRETATION_sRGB)); + } else { + std::vector background = { + descriptor->createBackground[0], + descriptor->createBackground[1], + descriptor->createBackground[2] + }; + if (channels == 4) { + background.push_back(descriptor->createBackground[3]); + } + image = VImage::new_matrix(descriptor->createWidth, descriptor->createHeight) + .copy(VImage::option()->set("interpretation", + channels < 3 ? VIPS_INTERPRETATION_B_W : VIPS_INTERPRETATION_sRGB)) + .new_from_image(background); + } + if (descriptor->createPageHeight > 0) { + image.set(VIPS_META_PAGE_HEIGHT, descriptor->createPageHeight); + image.set(VIPS_META_N_PAGES, static_cast(descriptor->createHeight / descriptor->createPageHeight)); + } + image = image.cast(VIPS_FORMAT_UCHAR); + imageType = ImageType::RAW; + } else if (descriptor->textValue.length() > 0) { + // Create a new image with text + vips::VOption *textOptions = VImage::option() + ->set("align", descriptor->textAlign) + ->set("justify", descriptor->textJustify) + ->set("rgba", descriptor->textRgba) + ->set("spacing", descriptor->textSpacing) + ->set("wrap", descriptor->textWrap) + ->set("autofit_dpi", &descriptor->textAutofitDpi); + if (descriptor->textWidth > 0) { + textOptions->set("width", descriptor->textWidth); + } + // Ignore dpi if height is set + if (descriptor->textWidth > 0 && descriptor->textHeight > 0) { + textOptions->set("height", descriptor->textHeight); + } else if (descriptor->textDpi > 0) { + textOptions->set("dpi", descriptor->textDpi); + } + if (descriptor->textFont.length() > 0) { + textOptions->set("font", const_cast(descriptor->textFont.data())); + } + if (descriptor->textFontfile.length() > 0) { + textOptions->set("fontfile", const_cast(descriptor->textFontfile.data())); + } + image = VImage::text(const_cast(descriptor->textValue.data()), textOptions); + if (!descriptor->textRgba) { + image = image.copy(VImage::option()->set("interpretation", VIPS_INTERPRETATION_B_W)); + } + imageType = ImageType::RAW; + } else { + // From filesystem + imageType = DetermineImageType(descriptor->file.data()); + if (imageType == ImageType::MISSING) { + if (descriptor->file.find("file.substr(0, 8) + "...')?"); + } + throw vips::VError("Input file is missing: " + descriptor->file); + } + if (imageType != ImageType::UNKNOWN) { + try { + vips::VOption *option = GetOptionsForImageType(imageType, descriptor); + image = VImage::new_from_file(descriptor->file.data(), option); + if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) { + image = SetDensity(image, descriptor->density); + } + } catch (vips::VError const &err) { + throw vips::VError(std::string("Input file has corrupt header: ") + err.what()); + } + } else { + throw vips::VError("Input file contains unsupported image format"); + } + } + } + + // Limit input images to a given number of pixels, where pixels = width * height + if (descriptor->limitInputPixels > 0 && + static_cast(image.width()) * image.height() > descriptor->limitInputPixels) { + throw vips::VError("Input image exceeds pixel limit"); + } + return std::make_tuple(image, imageType); + } + + /* + Does this image have an embedded profile? + */ + bool HasProfile(VImage image) { + return image.get_typeof(VIPS_META_ICC_NAME) == VIPS_TYPE_BLOB; + } + + /* + Get copy of embedded profile. + */ + std::pair GetProfile(VImage image) { + std::pair icc(nullptr, 0); + if (HasProfile(image)) { + size_t length; + const void *data = image.get_blob(VIPS_META_ICC_NAME, &length); + icc.first = static_cast(g_malloc(length)); + icc.second = length; + memcpy(icc.first, data, length); + } + return icc; + } + + /* + Set embedded profile. + */ + VImage SetProfile(VImage image, std::pair icc) { + if (icc.first != nullptr) { + image = image.copy(); + image.set(VIPS_META_ICC_NAME, reinterpret_cast(vips_area_free_cb), icc.first, icc.second); + } + return image; + } + + static void* RemoveExifCallback(VipsImage *image, char const *field, GValue *value, void *data) { + std::vector *fieldNames = static_cast *>(data); + std::string fieldName(field); + if (fieldName.substr(0, 8) == ("exif-ifd")) { + fieldNames->push_back(fieldName); + } + return nullptr; + } + + /* + Remove all EXIF-related image fields. + */ + VImage RemoveExif(VImage image) { + std::vector fieldNames; + vips_image_map(image.get_image(), static_cast(RemoveExifCallback), &fieldNames); + for (const auto& f : fieldNames) { + image.remove(f.data()); + } + return image; + } + + /* + Get EXIF Orientation of image, if any. + */ + int ExifOrientation(VImage image) { + int orientation = 0; + if (image.get_typeof(VIPS_META_ORIENTATION) != 0) { + orientation = image.get_int(VIPS_META_ORIENTATION); + } + return orientation; + } + + /* + Set EXIF Orientation of image. + */ + VImage SetExifOrientation(VImage image, int const orientation) { + VImage copy = image.copy(); + copy.set(VIPS_META_ORIENTATION, orientation); + return copy; + } + + /* + Remove EXIF Orientation from image. + */ + VImage RemoveExifOrientation(VImage image) { + VImage copy = image.copy(); + copy.remove(VIPS_META_ORIENTATION); + copy.remove("exif-ifd0-Orientation"); + return copy; + } + + /* + Set animation properties if necessary. + */ + VImage SetAnimationProperties(VImage image, int nPages, int pageHeight, std::vector delay, int loop) { + bool hasDelay = !delay.empty(); + VImage copy = image.copy(); + + // Only set page-height if we have more than one page, or this could + // accidentally turn into an animated image later. + if (nPages > 1) copy.set(VIPS_META_PAGE_HEIGHT, pageHeight); + if (hasDelay) { + if (delay.size() == 1) { + // We have just one delay, repeat that value for all frames. + delay.insert(delay.end(), nPages - 1, delay[0]); + } + copy.set("delay", delay); + } + if (nPages == 1 && !hasDelay && loop == -1) { + loop = 1; + } + if (loop != -1) copy.set("loop", loop); + + return copy; + } + + /* + Remove animation properties from image. + */ + VImage RemoveAnimationProperties(VImage image) { + VImage copy = image.copy(); + copy.remove(VIPS_META_PAGE_HEIGHT); + copy.remove("delay"); + copy.remove("loop"); + return copy; + } + + /* + Remove GIF palette from image. + */ + VImage RemoveGifPalette(VImage image) { + VImage copy = image.copy(); + copy.remove("gif-palette"); + return copy; + } + + /* + Does this image have a non-default density? + */ + bool HasDensity(VImage image) { + return image.xres() > 1.0; + } + + /* + Get pixels/mm resolution as pixels/inch density. + */ + int GetDensity(VImage image) { + return static_cast(round(image.xres() * 25.4)); + } + + /* + Set pixels/mm resolution based on a pixels/inch density. + */ + VImage SetDensity(VImage image, const double density) { + const double pixelsPerMm = density / 25.4; + VImage copy = image.copy(); + copy.get_image()->Xres = pixelsPerMm; + copy.get_image()->Yres = pixelsPerMm; + return copy; + } + + /* + Multi-page images can have a page height. Fetch it, and sanity check it. + If page-height is not set, it defaults to the image height + */ + int GetPageHeight(VImage image) { + return vips_image_get_page_height(image.get_image()); + } + + /* + Check the proposed format supports the current dimensions. + */ + void AssertImageTypeDimensions(VImage image, ImageType const imageType) { + const int height = image.get_typeof(VIPS_META_PAGE_HEIGHT) == G_TYPE_INT + ? image.get_int(VIPS_META_PAGE_HEIGHT) + : image.height(); + if (imageType == ImageType::JPEG) { + if (image.width() > 65535 || height > 65535) { + throw vips::VError("Processed image is too large for the JPEG format"); + } + } else if (imageType == ImageType::WEBP) { + if (image.width() > 16383 || height > 16383) { + throw vips::VError("Processed image is too large for the WebP format"); + } + } else if (imageType == ImageType::GIF) { + if (image.width() > 65535 || height > 65535) { + throw vips::VError("Processed image is too large for the GIF format"); + } + } else if (imageType == ImageType::HEIF) { + if (image.width() > 16384 || height > 16384) { + throw vips::VError("Processed image is too large for the HEIF format"); + } + } + } + + /* + Called when a Buffer undergoes GC, required to support mixed runtime libraries in Windows + */ + std::function FreeCallback = [](void*, char* data) { + g_free(data); + }; + + /* + Temporary buffer of warnings + */ + std::queue vipsWarnings; + std::mutex vipsWarningsMutex; + + /* + Called with warnings from the glib-registered "VIPS" domain + */ + void VipsWarningCallback(char const* log_domain, GLogLevelFlags log_level, char const* message, void* ignore) { + std::lock_guard lock(vipsWarningsMutex); + vipsWarnings.emplace(message); + } + + /* + Pop the oldest warning message from the queue + */ + std::string VipsWarningPop() { + std::string warning; + std::lock_guard lock(vipsWarningsMutex); + if (!vipsWarnings.empty()) { + warning = vipsWarnings.front(); + vipsWarnings.pop(); + } + return warning; + } + + /* + Attach an event listener for progress updates, used to detect timeout + */ + void SetTimeout(VImage image, int const seconds) { + if (seconds > 0) { + VipsImage *im = image.get_image(); + if (im->progress_signal == NULL) { + int *timeout = VIPS_NEW(im, int); + *timeout = seconds; + g_signal_connect(im, "eval", G_CALLBACK(VipsProgressCallBack), timeout); + vips_image_set_progress(im, true); + } + } + } + + /* + Event listener for progress updates, used to detect timeout + */ + void VipsProgressCallBack(VipsImage *im, VipsProgress *progress, int *timeout) { + if (*timeout > 0 && progress->run >= *timeout) { + vips_image_set_kill(im, true); + vips_error("timeout", "%d%% complete", progress->percent); + *timeout = 0; + } + } + + /* + Calculate the (left, top) coordinates of the output image + within the input image, applying the given gravity during an embed. + + @Azurebyte: We are basically swapping the inWidth and outWidth, inHeight and outHeight from the CalculateCrop function. + */ + std::tuple CalculateEmbedPosition(int const inWidth, int const inHeight, + int const outWidth, int const outHeight, int const gravity) { + + int left = 0; + int top = 0; + switch (gravity) { + case 1: + // North + left = (outWidth - inWidth) / 2; + break; + case 2: + // East + left = outWidth - inWidth; + top = (outHeight - inHeight) / 2; + break; + case 3: + // South + left = (outWidth - inWidth) / 2; + top = outHeight - inHeight; + break; + case 4: + // West + top = (outHeight - inHeight) / 2; + break; + case 5: + // Northeast + left = outWidth - inWidth; + break; + case 6: + // Southeast + left = outWidth - inWidth; + top = outHeight - inHeight; + break; + case 7: + // Southwest + top = outHeight - inHeight; + break; + case 8: + // Northwest + // Which is the default is 0,0 so we do not assign anything here. + break; + default: + // Centre + left = (outWidth - inWidth) / 2; + top = (outHeight - inHeight) / 2; + } + return std::make_tuple(left, top); + } + + /* + Calculate the (left, top) coordinates of the output image + within the input image, applying the given gravity during a crop. + */ + std::tuple CalculateCrop(int const inWidth, int const inHeight, + int const outWidth, int const outHeight, int const gravity) { + + int left = 0; + int top = 0; + switch (gravity) { + case 1: + // North + left = (inWidth - outWidth + 1) / 2; + break; + case 2: + // East + left = inWidth - outWidth; + top = (inHeight - outHeight + 1) / 2; + break; + case 3: + // South + left = (inWidth - outWidth + 1) / 2; + top = inHeight - outHeight; + break; + case 4: + // West + top = (inHeight - outHeight + 1) / 2; + break; + case 5: + // Northeast + left = inWidth - outWidth; + break; + case 6: + // Southeast + left = inWidth - outWidth; + top = inHeight - outHeight; + break; + case 7: + // Southwest + top = inHeight - outHeight; + break; + case 8: + // Northwest + break; + default: + // Centre + left = (inWidth - outWidth + 1) / 2; + top = (inHeight - outHeight + 1) / 2; + } + return std::make_tuple(left, top); + } + + /* + Calculate the (left, top) coordinates of the output image + within the input image, applying the given x and y offsets. + */ + std::tuple CalculateCrop(int const inWidth, int const inHeight, + int const outWidth, int const outHeight, int const x, int const y) { + + // default values + int left = 0; + int top = 0; + + // assign only if valid + if (x < (inWidth - outWidth)) { + left = x; + } else if (x >= (inWidth - outWidth)) { + left = inWidth - outWidth; + } + + if (y < (inHeight - outHeight)) { + top = y; + } else if (y >= (inHeight - outHeight)) { + top = inHeight - outHeight; + } + + return std::make_tuple(left, top); + } + + /* + Are pixel values in this image 16-bit integer? + */ + bool Is16Bit(VipsInterpretation const interpretation) { + return interpretation == VIPS_INTERPRETATION_RGB16 || interpretation == VIPS_INTERPRETATION_GREY16; + } + + /* + Convert RGBA value to another colourspace + */ + std::vector GetRgbaAsColourspace(std::vector const rgba, + VipsInterpretation const interpretation, bool premultiply) { + int const bands = static_cast(rgba.size()); + if (bands < 3) { + return rgba; + } + VImage pixel = VImage::new_matrix(1, 1); + pixel.set("bands", bands); + pixel = pixel + .new_from_image(rgba) + .colourspace(interpretation, VImage::option()->set("source_space", VIPS_INTERPRETATION_sRGB)); + if (premultiply) { + pixel = pixel.premultiply(); + } + return pixel(0, 0); + } + + /* + Apply the alpha channel to a given colour + */ + std::tuple> ApplyAlpha(VImage image, std::vector colour, bool premultiply) { + // Scale up 8-bit values to match 16-bit input image + double const multiplier = sharp::Is16Bit(image.interpretation()) ? 256.0 : 1.0; + // Create alphaColour colour + std::vector alphaColour; + if (image.bands() > 2) { + alphaColour = { + multiplier * colour[0], + multiplier * colour[1], + multiplier * colour[2] + }; + } else { + // Convert sRGB to greyscale + alphaColour = { multiplier * ( + 0.2126 * colour[0] + + 0.7152 * colour[1] + + 0.0722 * colour[2]) + }; + } + // Add alpha channel(s) to alphaColour colour + if (colour[3] < 255.0 || image.has_alpha()) { + int extraBands = image.bands() > 4 ? image.bands() - 3 : 1; + alphaColour.insert(alphaColour.end(), extraBands, colour[3] * multiplier); + } + // Ensure alphaColour colour uses correct colourspace + alphaColour = sharp::GetRgbaAsColourspace(alphaColour, image.interpretation(), premultiply); + // Add non-transparent alpha channel, if required + if (colour[3] < 255.0 && !image.has_alpha()) { + image = image.bandjoin_const({ 255 * multiplier }); + } + return std::make_tuple(image, alphaColour); + } + + /* + Removes alpha channels, if any. + */ + VImage RemoveAlpha(VImage image) { + while (image.bands() > 1 && image.has_alpha()) { + image = image.extract_band(0, VImage::option()->set("n", image.bands() - 1)); + } + return image; + } + + /* + Ensures alpha channel, if missing. + */ + VImage EnsureAlpha(VImage image, double const value) { + if (!image.has_alpha()) { + image = image.bandjoin_const({ value * vips_interpretation_max_alpha(image.interpretation()) }); + } + return image; + } + + std::pair ResolveShrink(int width, int height, int targetWidth, int targetHeight, + Canvas canvas, bool withoutEnlargement, bool withoutReduction) { + double hshrink = 1.0; + double vshrink = 1.0; + + if (targetWidth > 0 && targetHeight > 0) { + // Fixed width and height + hshrink = static_cast(width) / targetWidth; + vshrink = static_cast(height) / targetHeight; + + switch (canvas) { + case Canvas::CROP: + case Canvas::MIN: + if (hshrink < vshrink) { + vshrink = hshrink; + } else { + hshrink = vshrink; + } + break; + case Canvas::EMBED: + case Canvas::MAX: + if (hshrink > vshrink) { + vshrink = hshrink; + } else { + hshrink = vshrink; + } + break; + case Canvas::IGNORE_ASPECT: + break; + } + } else if (targetWidth > 0) { + // Fixed width + hshrink = static_cast(width) / targetWidth; + + if (canvas != Canvas::IGNORE_ASPECT) { + // Auto height + vshrink = hshrink; + } + } else if (targetHeight > 0) { + // Fixed height + vshrink = static_cast(height) / targetHeight; + + if (canvas != Canvas::IGNORE_ASPECT) { + // Auto width + hshrink = vshrink; + } + } + + // We should not reduce or enlarge the output image, if + // withoutReduction or withoutEnlargement is specified. + if (withoutReduction) { + // Equivalent of VIPS_SIZE_UP + hshrink = std::min(1.0, hshrink); + vshrink = std::min(1.0, vshrink); + } else if (withoutEnlargement) { + // Equivalent of VIPS_SIZE_DOWN + hshrink = std::max(1.0, hshrink); + vshrink = std::max(1.0, vshrink); + } + + // We don't want to shrink so much that we send an axis to 0 + hshrink = std::min(hshrink, static_cast(width)); + vshrink = std::min(vshrink, static_cast(height)); + + return std::make_pair(hshrink, vshrink); + } + + /* + Ensure decoding remains sequential. + */ + VImage StaySequential(VImage image, bool condition) { + if (vips_image_is_sequential(image.get_image()) && condition) { + image = image.copy_memory().copy(); + image.remove(VIPS_META_SEQUENTIAL); + } + return image; + } +} // namespace sharp diff --git a/node_modules/sharp/src/common.h b/node_modules/sharp/src/common.h new file mode 100644 index 0000000..2bba5e1 --- /dev/null +++ b/node_modules/sharp/src/common.h @@ -0,0 +1,399 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +#ifndef SRC_COMMON_H_ +#define SRC_COMMON_H_ + +#include +#include +#include +#include + +#include +#include + +// Verify platform and compiler compatibility + +#if (VIPS_MAJOR_VERSION < 8) || \ + (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 17) || \ + (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 17 && VIPS_MICRO_VERSION < 2) +#error "libvips version 8.17.2+ is required - please see https://sharp.pixelplumbing.com/install" +#endif + +#if defined(__has_include) +#if !__has_include() +#error "C++17 compiler required - please see https://sharp.pixelplumbing.com/install" +#endif +#endif + +using vips::VImage; + +namespace sharp { + + struct InputDescriptor { // NOLINT(runtime/indentation_namespace) + std::string name; + std::string file; + bool autoOrient; + char *buffer; + VipsFailOn failOn; + uint64_t limitInputPixels; + bool unlimited; + VipsAccess access; + size_t bufferLength; + bool isBuffer; + double density; + bool ignoreIcc; + VipsBandFormat rawDepth; + int rawChannels; + int rawWidth; + int rawHeight; + bool rawPremultiplied; + int rawPageHeight; + int pages; + int page; + int createChannels; + int createWidth; + int createHeight; + int createPageHeight; + std::vector createBackground; + std::string createNoiseType; + double createNoiseMean; + double createNoiseSigma; + std::string textValue; + std::string textFont; + std::string textFontfile; + int textWidth; + int textHeight; + VipsAlign textAlign; + bool textJustify; + int textDpi; + bool textRgba; + int textSpacing; + VipsTextWrap textWrap; + int textAutofitDpi; + bool joinAnimated; + int joinAcross; + int joinShim; + std::vector joinBackground; + VipsAlign joinHalign; + VipsAlign joinValign; + std::string svgStylesheet; + bool svgHighBitdepth; + int tiffSubifd; + int openSlideLevel; + std::vector pdfBackground; + bool jp2Oneshot; + + InputDescriptor(): + autoOrient(false), + buffer(nullptr), + failOn(VIPS_FAIL_ON_WARNING), + limitInputPixels(0x3FFF * 0x3FFF), + unlimited(false), + access(VIPS_ACCESS_SEQUENTIAL), + bufferLength(0), + isBuffer(false), + density(72.0), + ignoreIcc(false), + rawDepth(VIPS_FORMAT_UCHAR), + rawChannels(0), + rawWidth(0), + rawHeight(0), + rawPremultiplied(false), + rawPageHeight(0), + pages(1), + page(0), + createChannels(0), + createWidth(0), + createHeight(0), + createPageHeight(0), + createBackground{ 0.0, 0.0, 0.0, 255.0 }, + createNoiseMean(0.0), + createNoiseSigma(0.0), + textWidth(0), + textHeight(0), + textAlign(VIPS_ALIGN_LOW), + textJustify(false), + textDpi(72), + textRgba(false), + textSpacing(0), + textWrap(VIPS_TEXT_WRAP_WORD), + textAutofitDpi(0), + joinAnimated(false), + joinAcross(1), + joinShim(0), + joinBackground{ 0.0, 0.0, 0.0, 255.0 }, + joinHalign(VIPS_ALIGN_LOW), + joinValign(VIPS_ALIGN_LOW), + svgHighBitdepth(false), + tiffSubifd(-1), + openSlideLevel(0), + pdfBackground{ 255.0, 255.0, 255.0, 255.0 }, + jp2Oneshot(false) {} + }; + + // Convenience methods to access the attributes of a Napi::Object + bool HasAttr(Napi::Object obj, std::string attr); + std::string AttrAsStr(Napi::Object obj, std::string attr); + std::string AttrAsStr(Napi::Object obj, unsigned int const attr); + uint32_t AttrAsUint32(Napi::Object obj, std::string attr); + int32_t AttrAsInt32(Napi::Object obj, std::string attr); + int32_t AttrAsInt32(Napi::Object obj, unsigned int const attr); + double AttrAsDouble(Napi::Object obj, std::string attr); + double AttrAsDouble(Napi::Object obj, unsigned int const attr); + bool AttrAsBool(Napi::Object obj, std::string attr); + std::vector AttrAsVectorOfDouble(Napi::Object obj, std::string attr); + std::vector AttrAsInt32Vector(Napi::Object obj, std::string attr); + template T AttrAsEnum(Napi::Object obj, std::string attr, GType type) { + return static_cast( + vips_enum_from_nick(nullptr, type, AttrAsStr(obj, attr).data())); + } + + // Create an InputDescriptor instance from a Napi::Object describing an input image + InputDescriptor* CreateInputDescriptor(Napi::Object input); + + enum class ImageType { + JPEG, + PNG, + WEBP, + JP2, + TIFF, + GIF, + SVG, + HEIF, + PDF, + MAGICK, + OPENSLIDE, + PPM, + FITS, + EXR, + JXL, + RAD, + DCRAW, + VIPS, + RAW, + UNKNOWN, + MISSING + }; + + enum class Canvas { + CROP, + EMBED, + MAX, + MIN, + IGNORE_ASPECT + }; + + // How many tasks are in the queue? + extern std::atomic counterQueue; + + // How many tasks are being processed? + extern std::atomic counterProcess; + + // Filename extension checkers + bool IsJpeg(std::string const &str); + bool IsPng(std::string const &str); + bool IsWebp(std::string const &str); + bool IsJp2(std::string const &str); + bool IsGif(std::string const &str); + bool IsTiff(std::string const &str); + bool IsHeic(std::string const &str); + bool IsHeif(std::string const &str); + bool IsAvif(std::string const &str); + bool IsJxl(std::string const &str); + bool IsDz(std::string const &str); + bool IsDzZip(std::string const &str); + bool IsV(std::string const &str); + + /* + Trim space from end of string. + */ + std::string TrimEnd(std::string const &str); + + /* + Provide a string identifier for the given image type. + */ + std::string ImageTypeId(ImageType const imageType); + + /* + Determine image format of a buffer. + */ + ImageType DetermineImageType(void *buffer, size_t const length); + + /* + Determine image format of a file. + */ + ImageType DetermineImageType(char const *file); + + /* + Format-specific options builder + */ + vips::VOption* GetOptionsForImageType(ImageType imageType, InputDescriptor *descriptor); + + /* + Open an image from the given InputDescriptor (filesystem, compressed buffer, raw pixel data) + */ + std::tuple OpenInput(InputDescriptor *descriptor); + + /* + Does this image have an embedded profile? + */ + bool HasProfile(VImage image); + + /* + Get copy of embedded profile. + */ + std::pair GetProfile(VImage image); + + /* + Set embedded profile. + */ + VImage SetProfile(VImage image, std::pair icc); + + /* + Remove all EXIF-related image fields. + */ + VImage RemoveExif(VImage image); + + /* + Get EXIF Orientation of image, if any. + */ + int ExifOrientation(VImage image); + + /* + Set EXIF Orientation of image. + */ + VImage SetExifOrientation(VImage image, int const orientation); + + /* + Remove EXIF Orientation from image. + */ + VImage RemoveExifOrientation(VImage image); + + /* + Set animation properties if necessary. + */ + VImage SetAnimationProperties(VImage image, int nPages, int pageHeight, std::vector delay, int loop); + + /* + Remove animation properties from image. + */ + VImage RemoveAnimationProperties(VImage image); + + /* + Remove GIF palette from image. + */ + VImage RemoveGifPalette(VImage image); + + /* + Does this image have a non-default density? + */ + bool HasDensity(VImage image); + + /* + Get pixels/mm resolution as pixels/inch density. + */ + int GetDensity(VImage image); + + /* + Set pixels/mm resolution based on a pixels/inch density. + */ + VImage SetDensity(VImage image, const double density); + + /* + Multi-page images can have a page height. Fetch it, and sanity check it. + If page-height is not set, it defaults to the image height + */ + int GetPageHeight(VImage image); + + /* + Check the proposed format supports the current dimensions. + */ + void AssertImageTypeDimensions(VImage image, ImageType const imageType); + + /* + Called when a Buffer undergoes GC, required to support mixed runtime libraries in Windows + */ + extern std::function FreeCallback; + + /* + Called with warnings from the glib-registered "VIPS" domain + */ + void VipsWarningCallback(char const* log_domain, GLogLevelFlags log_level, char const* message, void* ignore); + + /* + Pop the oldest warning message from the queue + */ + std::string VipsWarningPop(); + + /* + Attach an event listener for progress updates, used to detect timeout + */ + void SetTimeout(VImage image, int const timeoutSeconds); + + /* + Event listener for progress updates, used to detect timeout + */ + void VipsProgressCallBack(VipsImage *image, VipsProgress *progress, int *timeoutSeconds); + + /* + Calculate the (left, top) coordinates of the output image + within the input image, applying the given gravity during an embed. + */ + std::tuple CalculateEmbedPosition(int const inWidth, int const inHeight, + int const outWidth, int const outHeight, int const gravity); + + /* + Calculate the (left, top) coordinates of the output image + within the input image, applying the given gravity. + */ + std::tuple CalculateCrop(int const inWidth, int const inHeight, + int const outWidth, int const outHeight, int const gravity); + + /* + Calculate the (left, top) coordinates of the output image + within the input image, applying the given x and y offsets of the output image. + */ + std::tuple CalculateCrop(int const inWidth, int const inHeight, + int const outWidth, int const outHeight, int const x, int const y); + + /* + Are pixel values in this image 16-bit integer? + */ + bool Is16Bit(VipsInterpretation const interpretation); + + /* + Convert RGBA value to another colourspace + */ + std::vector GetRgbaAsColourspace(std::vector const rgba, + VipsInterpretation const interpretation, bool premultiply); + + /* + Apply the alpha channel to a given colour + */ + std::tuple> ApplyAlpha(VImage image, std::vector colour, bool premultiply); + + /* + Removes alpha channels, if any. + */ + VImage RemoveAlpha(VImage image); + + /* + Ensures alpha channel, if missing. + */ + VImage EnsureAlpha(VImage image, double const value); + + /* + Calculate the horizontal and vertical shrink factors, taking the canvas mode into account. + */ + std::pair ResolveShrink(int width, int height, int targetWidth, int targetHeight, + Canvas canvas, bool withoutEnlargement, bool withoutReduction); + + /* + Ensure decoding remains sequential. + */ + VImage StaySequential(VImage image, bool condition = true); + +} // namespace sharp + +#endif // SRC_COMMON_H_ diff --git a/node_modules/sharp/src/metadata.cc b/node_modules/sharp/src/metadata.cc new file mode 100644 index 0000000..788b712 --- /dev/null +++ b/node_modules/sharp/src/metadata.cc @@ -0,0 +1,342 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include + +#include +#include + +#include "common.h" +#include "metadata.h" + +static void* readPNGComment(VipsImage *image, const char *field, GValue *value, void *p); + +class MetadataWorker : public Napi::AsyncWorker { + public: + MetadataWorker(Napi::Function callback, MetadataBaton *baton, Napi::Function debuglog) : + Napi::AsyncWorker(callback), baton(baton), debuglog(Napi::Persistent(debuglog)) {} + ~MetadataWorker() {} + + void Execute() { + // Decrement queued task counter + sharp::counterQueue--; + + vips::VImage image; + sharp::ImageType imageType = sharp::ImageType::UNKNOWN; + try { + std::tie(image, imageType) = OpenInput(baton->input); + } catch (vips::VError const &err) { + (baton->err).append(err.what()); + } + if (imageType != sharp::ImageType::UNKNOWN) { + // Image type + baton->format = sharp::ImageTypeId(imageType); + // VipsImage attributes + baton->width = image.width(); + baton->height = image.height(); + baton->space = vips_enum_nick(VIPS_TYPE_INTERPRETATION, image.interpretation()); + baton->channels = image.bands(); + baton->depth = vips_enum_nick(VIPS_TYPE_BAND_FORMAT, image.format()); + if (sharp::HasDensity(image)) { + baton->density = sharp::GetDensity(image); + } + if (image.get_typeof("jpeg-chroma-subsample") == VIPS_TYPE_REF_STRING) { + baton->chromaSubsampling = image.get_string("jpeg-chroma-subsample"); + } + if (image.get_typeof("interlaced") == G_TYPE_INT) { + baton->isProgressive = image.get_int("interlaced") == 1; + } + if (image.get_typeof(VIPS_META_PALETTE) == G_TYPE_INT) { + baton->isPalette = image.get_int(VIPS_META_PALETTE); + } + if (image.get_typeof(VIPS_META_BITS_PER_SAMPLE) == G_TYPE_INT) { + baton->bitsPerSample = image.get_int(VIPS_META_BITS_PER_SAMPLE); + } + if (image.get_typeof(VIPS_META_N_PAGES) == G_TYPE_INT) { + baton->pages = image.get_int(VIPS_META_N_PAGES); + } + if (image.get_typeof(VIPS_META_PAGE_HEIGHT) == G_TYPE_INT) { + baton->pageHeight = image.get_int(VIPS_META_PAGE_HEIGHT); + } + if (image.get_typeof("loop") == G_TYPE_INT) { + baton->loop = image.get_int("loop"); + } + if (image.get_typeof("delay") == VIPS_TYPE_ARRAY_INT) { + baton->delay = image.get_array_int("delay"); + } + if (image.get_typeof("heif-primary") == G_TYPE_INT) { + baton->pagePrimary = image.get_int("heif-primary"); + } + if (image.get_typeof("heif-compression") == VIPS_TYPE_REF_STRING) { + baton->compression = image.get_string("heif-compression"); + } + if (image.get_typeof(VIPS_META_RESOLUTION_UNIT) == VIPS_TYPE_REF_STRING) { + baton->resolutionUnit = image.get_string(VIPS_META_RESOLUTION_UNIT); + } + if (image.get_typeof("magick-format") == VIPS_TYPE_REF_STRING) { + baton->formatMagick = image.get_string("magick-format"); + } + if (image.get_typeof("openslide.level-count") == VIPS_TYPE_REF_STRING) { + int const levels = std::stoi(image.get_string("openslide.level-count")); + for (int l = 0; l < levels; l++) { + std::string prefix = "openslide.level[" + std::to_string(l) + "]."; + int const width = std::stoi(image.get_string((prefix + "width").data())); + int const height = std::stoi(image.get_string((prefix + "height").data())); + baton->levels.push_back(std::pair(width, height)); + } + } + if (image.get_typeof(VIPS_META_N_SUBIFDS) == G_TYPE_INT) { + baton->subifds = image.get_int(VIPS_META_N_SUBIFDS); + } + baton->hasProfile = sharp::HasProfile(image); + if (image.get_typeof("background") == VIPS_TYPE_ARRAY_DOUBLE) { + baton->background = image.get_array_double("background"); + } + // Derived attributes + baton->hasAlpha = image.has_alpha(); + baton->orientation = sharp::ExifOrientation(image); + // EXIF + if (image.get_typeof(VIPS_META_EXIF_NAME) == VIPS_TYPE_BLOB) { + size_t exifLength; + void const *exif = image.get_blob(VIPS_META_EXIF_NAME, &exifLength); + baton->exif = static_cast(g_malloc(exifLength)); + memcpy(baton->exif, exif, exifLength); + baton->exifLength = exifLength; + } + // ICC profile + if (image.get_typeof(VIPS_META_ICC_NAME) == VIPS_TYPE_BLOB) { + size_t iccLength; + void const *icc = image.get_blob(VIPS_META_ICC_NAME, &iccLength); + baton->icc = static_cast(g_malloc(iccLength)); + memcpy(baton->icc, icc, iccLength); + baton->iccLength = iccLength; + } + // IPTC + if (image.get_typeof(VIPS_META_IPTC_NAME) == VIPS_TYPE_BLOB) { + size_t iptcLength; + void const *iptc = image.get_blob(VIPS_META_IPTC_NAME, &iptcLength); + baton->iptc = static_cast(g_malloc(iptcLength)); + memcpy(baton->iptc, iptc, iptcLength); + baton->iptcLength = iptcLength; + } + // XMP + if (image.get_typeof(VIPS_META_XMP_NAME) == VIPS_TYPE_BLOB) { + size_t xmpLength; + void const *xmp = image.get_blob(VIPS_META_XMP_NAME, &xmpLength); + baton->xmp = static_cast(g_malloc(xmpLength)); + memcpy(baton->xmp, xmp, xmpLength); + baton->xmpLength = xmpLength; + } + // TIFFTAG_PHOTOSHOP + if (image.get_typeof(VIPS_META_PHOTOSHOP_NAME) == VIPS_TYPE_BLOB) { + size_t tifftagPhotoshopLength; + void const *tifftagPhotoshop = image.get_blob(VIPS_META_PHOTOSHOP_NAME, &tifftagPhotoshopLength); + baton->tifftagPhotoshop = static_cast(g_malloc(tifftagPhotoshopLength)); + memcpy(baton->tifftagPhotoshop, tifftagPhotoshop, tifftagPhotoshopLength); + baton->tifftagPhotoshopLength = tifftagPhotoshopLength; + } + // PNG comments + vips_image_map(image.get_image(), readPNGComment, &baton->comments); + } + + // Clean up + vips_error_clear(); + vips_thread_shutdown(); + } + + void OnOK() { + Napi::Env env = Env(); + Napi::HandleScope scope(env); + + // Handle warnings + std::string warning = sharp::VipsWarningPop(); + while (!warning.empty()) { + debuglog.Call(Receiver().Value(), { Napi::String::New(env, warning) }); + warning = sharp::VipsWarningPop(); + } + + if (baton->err.empty()) { + Napi::Object info = Napi::Object::New(env); + info.Set("format", baton->format); + if (baton->input->bufferLength > 0) { + info.Set("size", baton->input->bufferLength); + } + info.Set("width", baton->width); + info.Set("height", baton->height); + info.Set("space", baton->space); + info.Set("channels", baton->channels); + info.Set("depth", baton->depth); + if (baton->density > 0) { + info.Set("density", baton->density); + } + if (!baton->chromaSubsampling.empty()) { + info.Set("chromaSubsampling", baton->chromaSubsampling); + } + info.Set("isProgressive", baton->isProgressive); + info.Set("isPalette", baton->isPalette); + if (baton->bitsPerSample > 0) { + info.Set("bitsPerSample", baton->bitsPerSample); + if (baton->isPalette) { + // Deprecated, remove with libvips 8.17.0 + info.Set("paletteBitDepth", baton->bitsPerSample); + } + } + if (baton->pages > 0) { + info.Set("pages", baton->pages); + } + if (baton->pageHeight > 0) { + info.Set("pageHeight", baton->pageHeight); + } + if (baton->loop >= 0) { + info.Set("loop", baton->loop); + } + if (!baton->delay.empty()) { + int i = 0; + Napi::Array delay = Napi::Array::New(env, static_cast(baton->delay.size())); + for (int const d : baton->delay) { + delay.Set(i++, d); + } + info.Set("delay", delay); + } + if (baton->pagePrimary > -1) { + info.Set("pagePrimary", baton->pagePrimary); + } + if (!baton->compression.empty()) { + info.Set("compression", baton->compression); + } + if (!baton->resolutionUnit.empty()) { + info.Set("resolutionUnit", baton->resolutionUnit == "in" ? "inch" : baton->resolutionUnit); + } + if (!baton->formatMagick.empty()) { + info.Set("formatMagick", baton->formatMagick); + } + if (!baton->levels.empty()) { + int i = 0; + Napi::Array levels = Napi::Array::New(env, static_cast(baton->levels.size())); + for (std::pair const &l : baton->levels) { + Napi::Object level = Napi::Object::New(env); + level.Set("width", l.first); + level.Set("height", l.second); + levels.Set(i++, level); + } + info.Set("levels", levels); + } + if (baton->subifds > 0) { + info.Set("subifds", baton->subifds); + } + if (!baton->background.empty()) { + Napi::Object background = Napi::Object::New(env); + if (baton->background.size() == 3) { + background.Set("r", baton->background[0]); + background.Set("g", baton->background[1]); + background.Set("b", baton->background[2]); + } else { + background.Set("gray", round(baton->background[0] * 100 / 255)); + } + info.Set("background", background); + } + info.Set("hasProfile", baton->hasProfile); + info.Set("hasAlpha", baton->hasAlpha); + if (baton->orientation > 0) { + info.Set("orientation", baton->orientation); + } + Napi::Object autoOrient = Napi::Object::New(env); + info.Set("autoOrient", autoOrient); + if (baton->orientation >= 5) { + autoOrient.Set("width", baton->height); + autoOrient.Set("height", baton->width); + } else { + autoOrient.Set("width", baton->width); + autoOrient.Set("height", baton->height); + } + if (baton->exifLength > 0) { + info.Set("exif", Napi::Buffer::NewOrCopy(env, baton->exif, baton->exifLength, sharp::FreeCallback)); + } + if (baton->iccLength > 0) { + info.Set("icc", Napi::Buffer::NewOrCopy(env, baton->icc, baton->iccLength, sharp::FreeCallback)); + } + if (baton->iptcLength > 0) { + info.Set("iptc", Napi::Buffer::NewOrCopy(env, baton->iptc, baton->iptcLength, sharp::FreeCallback)); + } + if (baton->xmpLength > 0) { + if (g_utf8_validate(static_cast(baton->xmp), baton->xmpLength, nullptr)) { + info.Set("xmpAsString", + Napi::String::New(env, static_cast(baton->xmp), baton->xmpLength)); + } + info.Set("xmp", Napi::Buffer::NewOrCopy(env, baton->xmp, baton->xmpLength, sharp::FreeCallback)); + } + if (baton->tifftagPhotoshopLength > 0) { + info.Set("tifftagPhotoshop", + Napi::Buffer::NewOrCopy(env, baton->tifftagPhotoshop, + baton->tifftagPhotoshopLength, sharp::FreeCallback)); + } + if (baton->comments.size() > 0) { + int i = 0; + Napi::Array comments = Napi::Array::New(env, baton->comments.size()); + for (auto &c : baton->comments) { + Napi::Object comment = Napi::Object::New(env); + comment.Set("keyword", c.first); + comment.Set("text", c.second); + comments.Set(i++, comment); + } + info.Set("comments", comments); + } + Callback().Call(Receiver().Value(), { env.Null(), info }); + } else { + Callback().Call(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() }); + } + + delete baton->input; + delete baton; + } + + private: + MetadataBaton* baton; + Napi::FunctionReference debuglog; +}; + +/* + metadata(options, callback) +*/ +Napi::Value metadata(const Napi::CallbackInfo& info) { + // V8 objects are converted to non-V8 types held in the baton struct + MetadataBaton *baton = new MetadataBaton; + Napi::Object options = info[size_t(0)].As(); + + // Input + baton->input = sharp::CreateInputDescriptor(options.Get("input").As()); + + // Function to notify of libvips warnings + Napi::Function debuglog = options.Get("debuglog").As(); + + // Join queue for worker thread + Napi::Function callback = info[size_t(1)].As(); + MetadataWorker *worker = new MetadataWorker(callback, baton, debuglog); + worker->Receiver().Set("options", options); + worker->Queue(); + + // Increment queued task counter + sharp::counterQueue++; + + return info.Env().Undefined(); +} + +const char *PNG_COMMENT_START = "png-comment-"; +const int PNG_COMMENT_START_LEN = strlen(PNG_COMMENT_START); + +static void* readPNGComment(VipsImage *image, const char *field, GValue *value, void *p) { + MetadataComments *comments = static_cast(p); + + if (vips_isprefix(PNG_COMMENT_START, field)) { + const char *keyword = strchr(field + PNG_COMMENT_START_LEN, '-'); + const char *str; + if (keyword != NULL && !vips_image_get_string(image, field, &str)) { + keyword++; // Skip the hyphen + comments->push_back(std::make_pair(keyword, str)); + } + } + + return NULL; +} diff --git a/node_modules/sharp/src/metadata.h b/node_modules/sharp/src/metadata.h new file mode 100644 index 0000000..f93dd51 --- /dev/null +++ b/node_modules/sharp/src/metadata.h @@ -0,0 +1,87 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +#ifndef SRC_METADATA_H_ +#define SRC_METADATA_H_ + +#include +#include + +#include "./common.h" + +typedef std::vector> MetadataComments; + +struct MetadataBaton { + // Input + sharp::InputDescriptor *input; + // Output + std::string format; + int width; + int height; + std::string space; + int channels; + std::string depth; + int density; + std::string chromaSubsampling; + bool isProgressive; + bool isPalette; + int bitsPerSample; + int pages; + int pageHeight; + int loop; + std::vector delay; + int pagePrimary; + std::string compression; + std::string resolutionUnit; + std::string formatMagick; + std::vector> levels; + int subifds; + std::vector background; + bool hasProfile; + bool hasAlpha; + int orientation; + char *exif; + size_t exifLength; + char *icc; + size_t iccLength; + char *iptc; + size_t iptcLength; + char *xmp; + size_t xmpLength; + char *tifftagPhotoshop; + size_t tifftagPhotoshopLength; + MetadataComments comments; + std::string err; + + MetadataBaton(): + input(nullptr), + width(0), + height(0), + channels(0), + density(0), + isProgressive(false), + isPalette(false), + bitsPerSample(0), + pages(0), + pageHeight(0), + loop(-1), + pagePrimary(-1), + subifds(0), + hasProfile(false), + hasAlpha(false), + orientation(0), + exif(nullptr), + exifLength(0), + icc(nullptr), + iccLength(0), + iptc(nullptr), + iptcLength(0), + xmp(nullptr), + xmpLength(0), + tifftagPhotoshop(nullptr), + tifftagPhotoshopLength(0) {} +}; + +Napi::Value metadata(const Napi::CallbackInfo& info); + +#endif // SRC_METADATA_H_ diff --git a/node_modules/sharp/src/operations.cc b/node_modules/sharp/src/operations.cc new file mode 100644 index 0000000..ba3a051 --- /dev/null +++ b/node_modules/sharp/src/operations.cc @@ -0,0 +1,497 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "operations.h" + +using vips::VImage; +using vips::VError; + +namespace sharp { + /* + * Tint an image using the provided RGB. + */ + VImage Tint(VImage image, std::vector const tint) { + std::vector const tintLab = (VImage::black(1, 1) + tint) + .colourspace(VIPS_INTERPRETATION_LAB, VImage::option()->set("source_space", VIPS_INTERPRETATION_sRGB)) + .getpoint(0, 0); + // LAB identity function + VImage identityLab = VImage::identity(VImage::option()->set("bands", 3)) + .colourspace(VIPS_INTERPRETATION_LAB, VImage::option()->set("source_space", VIPS_INTERPRETATION_sRGB)); + // Scale luminance range, 0.0 to 1.0 + VImage l = identityLab[0] / 100; + // Weighting functions + VImage weightL = 1.0 - 4.0 * ((l - 0.5) * (l - 0.5)); + VImage weightAB = (weightL * tintLab).extract_band(1, VImage::option()->set("n", 2)); + identityLab = identityLab[0].bandjoin(weightAB); + // Convert lookup table to sRGB + VImage lut = identityLab.colourspace(VIPS_INTERPRETATION_sRGB, + VImage::option()->set("source_space", VIPS_INTERPRETATION_LAB)); + // Original colourspace + VipsInterpretation typeBeforeTint = image.interpretation(); + if (typeBeforeTint == VIPS_INTERPRETATION_RGB) { + typeBeforeTint = VIPS_INTERPRETATION_sRGB; + } + // Apply lookup table + if (image.has_alpha()) { + VImage alpha = image[image.bands() - 1]; + image = RemoveAlpha(image) + .colourspace(VIPS_INTERPRETATION_B_W) + .maplut(lut) + .colourspace(typeBeforeTint) + .bandjoin(alpha); + } else { + image = image + .colourspace(VIPS_INTERPRETATION_B_W) + .maplut(lut) + .colourspace(typeBeforeTint); + } + return image; + } + + /* + * Stretch luminance to cover full dynamic range. + */ + VImage Normalise(VImage image, int const lower, int const upper) { + // Get original colourspace + VipsInterpretation typeBeforeNormalize = image.interpretation(); + if (typeBeforeNormalize == VIPS_INTERPRETATION_RGB) { + typeBeforeNormalize = VIPS_INTERPRETATION_sRGB; + } + // Convert to LAB colourspace + VImage lab = image.colourspace(VIPS_INTERPRETATION_LAB); + // Extract luminance + VImage luminance = lab[0]; + + // Find luminance range + int const min = lower == 0 ? luminance.min() : luminance.percent(lower); + int const max = upper == 100 ? luminance.max() : luminance.percent(upper); + + if (std::abs(max - min) > 1) { + // Extract chroma + VImage chroma = lab.extract_band(1, VImage::option()->set("n", 2)); + // Calculate multiplication factor and addition + double f = 100.0 / (max - min); + double a = -(min * f); + // Scale luminance, join to chroma, convert back to original colourspace + VImage normalized = luminance.linear(f, a).bandjoin(chroma).colourspace(typeBeforeNormalize); + // Attach original alpha channel, if any + if (image.has_alpha()) { + // Extract original alpha channel + VImage alpha = image[image.bands() - 1]; + // Join alpha channel to normalised image + return normalized.bandjoin(alpha); + } else { + return normalized; + } + } + return image; + } + + /* + * Contrast limiting adapative histogram equalization (CLAHE) + */ + VImage Clahe(VImage image, int const width, int const height, int const maxSlope) { + return image.hist_local(width, height, VImage::option()->set("max_slope", maxSlope)); + } + + /* + * Gamma encoding/decoding + */ + VImage Gamma(VImage image, double const exponent) { + if (image.has_alpha()) { + // Separate alpha channel + VImage alpha = image[image.bands() - 1]; + return RemoveAlpha(image).gamma(VImage::option()->set("exponent", exponent)).bandjoin(alpha); + } else { + return image.gamma(VImage::option()->set("exponent", exponent)); + } + } + + /* + * Flatten image to remove alpha channel + */ + VImage Flatten(VImage image, std::vector flattenBackground) { + double const multiplier = sharp::Is16Bit(image.interpretation()) ? 256.0 : 1.0; + std::vector background { + flattenBackground[0] * multiplier, + flattenBackground[1] * multiplier, + flattenBackground[2] * multiplier + }; + return image.flatten(VImage::option()->set("background", background)); + } + + /** + * Produce the "negative" of the image. + */ + VImage Negate(VImage image, bool const negateAlpha) { + if (image.has_alpha() && !negateAlpha) { + // Separate alpha channel + VImage alpha = image[image.bands() - 1]; + return RemoveAlpha(image).invert().bandjoin(alpha); + } else { + return image.invert(); + } + } + + /* + * Gaussian blur. Use sigma of -1.0 for fast blur. + */ + VImage Blur(VImage image, double const sigma, VipsPrecision precision, double const minAmpl) { + if (sigma == -1.0) { + // Fast, mild blur - averages neighbouring pixels + VImage blur = VImage::new_matrixv(3, 3, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0); + blur.set("scale", 9.0); + return image.conv(blur); + } else { + // Slower, accurate Gaussian blur + return StaySequential(image).gaussblur(sigma, VImage::option() + ->set("precision", precision) + ->set("min_ampl", minAmpl)); + } + } + + /* + * Convolution with a kernel. + */ + VImage Convolve(VImage image, int const width, int const height, + double const scale, double const offset, + std::vector const &kernel_v + ) { + VImage kernel = VImage::new_from_memory( + static_cast(const_cast(kernel_v.data())), + width * height * sizeof(double), + width, + height, + 1, + VIPS_FORMAT_DOUBLE); + kernel.set("scale", scale); + kernel.set("offset", offset); + + return image.conv(kernel); + } + + /* + * Recomb with a Matrix of the given bands/channel size. + * Eg. RGB will be a 3x3 matrix. + */ + VImage Recomb(VImage image, std::vector const& matrix) { + double* m = const_cast(matrix.data()); + image = image.colourspace(VIPS_INTERPRETATION_sRGB); + if (matrix.size() == 9) { + return image + .recomb(image.bands() == 3 + ? VImage::new_matrix(3, 3, m, 9) + : VImage::new_matrixv(4, 4, + m[0], m[1], m[2], 0.0, + m[3], m[4], m[5], 0.0, + m[6], m[7], m[8], 0.0, + 0.0, 0.0, 0.0, 1.0)); + } else { + return image.recomb(VImage::new_matrix(4, 4, m, 16)); + } + } + + VImage Modulate(VImage image, double const brightness, double const saturation, + int const hue, double const lightness) { + VipsInterpretation colourspaceBeforeModulate = image.interpretation(); + if (image.has_alpha()) { + // Separate alpha channel + VImage alpha = image[image.bands() - 1]; + return RemoveAlpha(image) + .colourspace(VIPS_INTERPRETATION_LCH) + .linear( + { brightness, saturation, 1}, + { lightness, 0.0, static_cast(hue) } + ) + .colourspace(colourspaceBeforeModulate) + .bandjoin(alpha); + } else { + return image + .colourspace(VIPS_INTERPRETATION_LCH) + .linear( + { brightness, saturation, 1 }, + { lightness, 0.0, static_cast(hue) } + ) + .colourspace(colourspaceBeforeModulate); + } + } + + /* + * Sharpen flat and jagged areas. Use sigma of -1.0 for fast sharpen. + */ + VImage Sharpen(VImage image, double const sigma, double const m1, double const m2, + double const x1, double const y2, double const y3) { + if (sigma == -1.0) { + // Fast, mild sharpen + VImage sharpen = VImage::new_matrixv(3, 3, + -1.0, -1.0, -1.0, + -1.0, 32.0, -1.0, + -1.0, -1.0, -1.0); + sharpen.set("scale", 24.0); + return image.conv(sharpen); + } else { + // Slow, accurate sharpen in LAB colour space, with control over flat vs jagged areas + VipsInterpretation colourspaceBeforeSharpen = image.interpretation(); + if (colourspaceBeforeSharpen == VIPS_INTERPRETATION_RGB) { + colourspaceBeforeSharpen = VIPS_INTERPRETATION_sRGB; + } + return image + .sharpen(VImage::option() + ->set("sigma", sigma) + ->set("m1", m1) + ->set("m2", m2) + ->set("x1", x1) + ->set("y2", y2) + ->set("y3", y3)) + .colourspace(colourspaceBeforeSharpen); + } + } + + VImage Threshold(VImage image, double const threshold, bool const thresholdGrayscale) { + if (!thresholdGrayscale) { + return image >= threshold; + } + return image.colourspace(VIPS_INTERPRETATION_B_W) >= threshold; + } + + /* + Perform boolean/bitwise operation on image color channels - results in one channel image + */ + VImage Bandbool(VImage image, VipsOperationBoolean const boolean) { + image = image.bandbool(boolean); + return image.copy(VImage::option()->set("interpretation", VIPS_INTERPRETATION_B_W)); + } + + /* + Perform bitwise boolean operation between images + */ + VImage Boolean(VImage image, VImage imageR, VipsOperationBoolean const boolean) { + return image.boolean(imageR, boolean); + } + + /* + Trim an image + */ + VImage Trim(VImage image, std::vector background, double threshold, bool const lineArt) { + if (image.width() < 3 && image.height() < 3) { + throw VError("Image to trim must be at least 3x3 pixels"); + } + if (background.size() == 0) { + // Top-left pixel provides the default background colour if none is given + background = image.extract_area(0, 0, 1, 1)(0, 0); + } else if (sharp::Is16Bit(image.interpretation())) { + for (size_t i = 0; i < background.size(); i++) { + background[i] *= 256.0; + } + threshold *= 256.0; + } + std::vector backgroundAlpha({ background.back() }); + if (image.has_alpha()) { + background.pop_back(); + } else { + background.resize(image.bands()); + } + int left, top, width, height; + left = image.find_trim(&top, &width, &height, VImage::option() + ->set("background", background) + ->set("line_art", lineArt) + ->set("threshold", threshold)); + if (image.has_alpha()) { + // Search alpha channel (A) + int leftA, topA, widthA, heightA; + VImage alpha = image[image.bands() - 1]; + leftA = alpha.find_trim(&topA, &widthA, &heightA, VImage::option() + ->set("background", backgroundAlpha) + ->set("line_art", lineArt) + ->set("threshold", threshold)); + if (widthA > 0 && heightA > 0) { + if (width > 0 && height > 0) { + // Combined bounding box (B) + int const leftB = std::min(left, leftA); + int const topB = std::min(top, topA); + int const widthB = std::max(left + width, leftA + widthA) - leftB; + int const heightB = std::max(top + height, topA + heightA) - topB; + return image.extract_area(leftB, topB, widthB, heightB); + } else { + // Use alpha only + return image.extract_area(leftA, topA, widthA, heightA); + } + } + } + if (width > 0 && height > 0) { + return image.extract_area(left, top, width, height); + } + return image; + } + + /* + * Calculate (a * in + b) + */ + VImage Linear(VImage image, std::vector const a, std::vector const b) { + size_t const bands = static_cast(image.bands()); + if (a.size() > bands) { + throw VError("Band expansion using linear is unsupported"); + } + bool const uchar = !Is16Bit(image.interpretation()); + if (image.has_alpha() && a.size() != bands && (a.size() == 1 || a.size() == bands - 1 || bands - 1 == 1)) { + // Separate alpha channel + VImage alpha = image[bands - 1]; + return RemoveAlpha(image).linear(a, b, VImage::option()->set("uchar", uchar)).bandjoin(alpha); + } else { + return image.linear(a, b, VImage::option()->set("uchar", uchar)); + } + } + + /* + * Unflatten + */ + VImage Unflatten(VImage image) { + if (image.has_alpha()) { + VImage alpha = image[image.bands() - 1]; + VImage noAlpha = RemoveAlpha(image); + return noAlpha.bandjoin(alpha & (noAlpha.colourspace(VIPS_INTERPRETATION_B_W) < 255)); + } else { + return image.bandjoin(image.colourspace(VIPS_INTERPRETATION_B_W) < 255); + } + } + + /* + * Ensure the image is in a given colourspace + */ + VImage EnsureColourspace(VImage image, VipsInterpretation colourspace) { + if (colourspace != VIPS_INTERPRETATION_LAST && image.interpretation() != colourspace) { + image = image.colourspace(colourspace, + VImage::option()->set("source_space", image.interpretation())); + } + return image; + } + + /* + * Split and crop each frame, reassemble, and update pageHeight. + */ + VImage CropMultiPage(VImage image, int left, int top, int width, int height, + int nPages, int *pageHeight) { + if (top == 0 && height == *pageHeight) { + // Fast path; no need to adjust the height of the multi-page image + return image.extract_area(left, 0, width, image.height()); + } else { + std::vector pages; + pages.reserve(nPages); + + // Split the image into cropped frames + image = StaySequential(image); + for (int i = 0; i < nPages; i++) { + pages.push_back( + image.extract_area(left, *pageHeight * i + top, width, height)); + } + + // Reassemble the frames into a tall, thin image + VImage assembled = VImage::arrayjoin(pages, + VImage::option()->set("across", 1)); + + // Update the page height + *pageHeight = height; + + return assembled; + } + } + + /* + * Split into frames, embed each frame, reassemble, and update pageHeight. + */ + VImage EmbedMultiPage(VImage image, int left, int top, int width, int height, + VipsExtend extendWith, std::vector background, int nPages, int *pageHeight) { + if (top == 0 && height == *pageHeight) { + // Fast path; no need to adjust the height of the multi-page image + return image.embed(left, 0, width, image.height(), VImage::option() + ->set("extend", extendWith) + ->set("background", background)); + } else if (left == 0 && width == image.width()) { + // Fast path; no need to adjust the width of the multi-page image + std::vector pages; + pages.reserve(nPages); + + // Rearrange the tall image into a vertical grid + image = image.grid(*pageHeight, nPages, 1); + + // Do the embed on the wide image + image = image.embed(0, top, image.width(), height, VImage::option() + ->set("extend", extendWith) + ->set("background", background)); + + // Split the wide image into frames + for (int i = 0; i < nPages; i++) { + pages.push_back( + image.extract_area(width * i, 0, width, height)); + } + + // Reassemble the frames into a tall, thin image + VImage assembled = VImage::arrayjoin(pages, + VImage::option()->set("across", 1)); + + // Update the page height + *pageHeight = height; + + return assembled; + } else { + std::vector pages; + pages.reserve(nPages); + + // Split the image into frames + for (int i = 0; i < nPages; i++) { + pages.push_back( + image.extract_area(0, *pageHeight * i, image.width(), *pageHeight)); + } + + // Embed each frame in the target size + for (int i = 0; i < nPages; i++) { + pages[i] = pages[i].embed(left, top, width, height, VImage::option() + ->set("extend", extendWith) + ->set("background", background)); + } + + // Reassemble the frames into a tall, thin image + VImage assembled = VImage::arrayjoin(pages, + VImage::option()->set("across", 1)); + + // Update the page height + *pageHeight = height; + + return assembled; + } + } + + /* + * Dilate an image + */ + VImage Dilate(VImage image, int const width) { + int const maskWidth = 2 * width + 1; + VImage mask = VImage::new_matrix(maskWidth, maskWidth); + return image.morph( + mask, + VIPS_OPERATION_MORPHOLOGY_DILATE).invert(); + } + + /* + * Erode an image + */ + VImage Erode(VImage image, int const width) { + int const maskWidth = 2 * width + 1; + VImage mask = VImage::new_matrix(maskWidth, maskWidth); + return image.morph( + mask, + VIPS_OPERATION_MORPHOLOGY_ERODE).invert(); + } + +} // namespace sharp diff --git a/node_modules/sharp/src/operations.h b/node_modules/sharp/src/operations.h new file mode 100644 index 0000000..22ff46f --- /dev/null +++ b/node_modules/sharp/src/operations.h @@ -0,0 +1,134 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +#ifndef SRC_OPERATIONS_H_ +#define SRC_OPERATIONS_H_ + +#include +#include +#include +#include +#include + +using vips::VImage; + +namespace sharp { + + /* + * Tint an image using the provided RGB. + */ + VImage Tint(VImage image, std::vector const tint); + + /* + * Stretch luminance to cover full dynamic range. + */ + VImage Normalise(VImage image, int const lower, int const upper); + + /* + * Contrast limiting adapative histogram equalization (CLAHE) + */ + VImage Clahe(VImage image, int const width, int const height, int const maxSlope); + + /* + * Gamma encoding/decoding + */ + VImage Gamma(VImage image, double const exponent); + + /* + * Flatten image to remove alpha channel + */ + VImage Flatten(VImage image, std::vector flattenBackground); + + /* + * Produce the "negative" of the image. + */ + VImage Negate(VImage image, bool const negateAlpha); + + /* + * Gaussian blur. Use sigma of -1.0 for fast blur. + */ + VImage Blur(VImage image, double const sigma, VipsPrecision precision, double const minAmpl); + + /* + * Convolution with a kernel. + */ + VImage Convolve(VImage image, int const width, int const height, + double const scale, double const offset, std::vector const &kernel_v); + + /* + * Sharpen flat and jagged areas. Use sigma of -1.0 for fast sharpen. + */ + VImage Sharpen(VImage image, double const sigma, double const m1, double const m2, + double const x1, double const y2, double const y3); + + /* + Threshold an image + */ + VImage Threshold(VImage image, double const threshold, bool const thresholdColor); + + /* + Perform boolean/bitwise operation on image color channels - results in one channel image + */ + VImage Bandbool(VImage image, VipsOperationBoolean const boolean); + + /* + Perform bitwise boolean operation between images + */ + VImage Boolean(VImage image, VImage imageR, VipsOperationBoolean const boolean); + + /* + Trim an image + */ + VImage Trim(VImage image, std::vector background, double threshold, bool const lineArt); + + /* + * Linear adjustment (a * in + b) + */ + VImage Linear(VImage image, std::vector const a, std::vector const b); + + /* + * Unflatten + */ + VImage Unflatten(VImage image); + + /* + * Recomb with a Matrix of the given bands/channel size. + * Eg. RGB will be a 3x3 matrix. + */ + VImage Recomb(VImage image, std::vector const &matrix); + + /* + * Modulate brightness, saturation, hue and lightness + */ + VImage Modulate(VImage image, double const brightness, double const saturation, + int const hue, double const lightness); + + /* + * Ensure the image is in a given colourspace + */ + VImage EnsureColourspace(VImage image, VipsInterpretation colourspace); + + /* + * Split and crop each frame, reassemble, and update pageHeight. + */ + VImage CropMultiPage(VImage image, int left, int top, int width, int height, + int nPages, int *pageHeight); + + /* + * Split into frames, embed each frame, reassemble, and update pageHeight. + */ + VImage EmbedMultiPage(VImage image, int left, int top, int width, int height, + VipsExtend extendWith, std::vector background, int nPages, int *pageHeight); + + /* + * Dilate an image + */ + VImage Dilate(VImage image, int const maskWidth); + + /* + * Erode an image + */ + VImage Erode(VImage image, int const maskWidth); +} // namespace sharp + +#endif // SRC_OPERATIONS_H_ diff --git a/node_modules/sharp/src/pipeline.cc b/node_modules/sharp/src/pipeline.cc new file mode 100644 index 0000000..e2dd118 --- /dev/null +++ b/node_modules/sharp/src/pipeline.cc @@ -0,0 +1,1813 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "common.h" +#include "operations.h" +#include "pipeline.h" + +class PipelineWorker : public Napi::AsyncWorker { + public: + PipelineWorker(Napi::Function callback, PipelineBaton *baton, + Napi::Function debuglog, Napi::Function queueListener) : + Napi::AsyncWorker(callback), + baton(baton), + debuglog(Napi::Persistent(debuglog)), + queueListener(Napi::Persistent(queueListener)) {} + ~PipelineWorker() {} + + // libuv worker + void Execute() { + // Decrement queued task counter + sharp::counterQueue--; + // Increment processing task counter + sharp::counterProcess++; + + try { + // Open input + vips::VImage image; + sharp::ImageType inputImageType; + if (baton->join.empty()) { + std::tie(image, inputImageType) = sharp::OpenInput(baton->input); + } else { + std::vector images; + bool hasAlpha = false; + for (auto &join : baton->join) { + std::tie(image, inputImageType) = sharp::OpenInput(join); + image = sharp::EnsureColourspace(image, baton->colourspacePipeline); + images.push_back(image); + hasAlpha |= image.has_alpha(); + } + if (hasAlpha) { + for (auto &image : images) { + if (!image.has_alpha()) { + image = sharp::EnsureAlpha(image, 1); + } + } + } else { + baton->input->joinBackground.pop_back(); + } + inputImageType = sharp::ImageType::PNG; + image = VImage::arrayjoin(images, VImage::option() + ->set("across", baton->input->joinAcross) + ->set("shim", baton->input->joinShim) + ->set("background", baton->input->joinBackground) + ->set("halign", baton->input->joinHalign) + ->set("valign", baton->input->joinValign)); + if (baton->input->joinAnimated) { + image = image.copy(); + image.set(VIPS_META_N_PAGES, static_cast(images.size())); + image.set(VIPS_META_PAGE_HEIGHT, static_cast(image.height() / images.size())); + } + } + VipsAccess access = baton->input->access; + image = sharp::EnsureColourspace(image, baton->colourspacePipeline); + + int nPages = baton->input->pages; + if (nPages == -1) { + // Resolve the number of pages if we need to render until the end of the document + nPages = image.get_typeof(VIPS_META_N_PAGES) != 0 + ? image.get_int(VIPS_META_N_PAGES) - baton->input->page + : 1; + } + + // Get pre-resize page height + int pageHeight = sharp::GetPageHeight(image); + + // Calculate angle of rotation + VipsAngle rotation = VIPS_ANGLE_D0; + VipsAngle autoRotation = VIPS_ANGLE_D0; + bool autoFlop = false; + + if (baton->input->autoOrient) { + // Rotate and flip image according to Exif orientation + std::tie(autoRotation, autoFlop) = CalculateExifRotationAndFlop(sharp::ExifOrientation(image)); + } + + rotation = CalculateAngleRotation(baton->angle); + + bool const shouldRotateBefore = baton->rotateBefore && + (rotation != VIPS_ANGLE_D0 || baton->flip || baton->flop || baton->rotationAngle != 0.0); + bool const shouldOrientBefore = (shouldRotateBefore || baton->orientBefore) && + (autoRotation != VIPS_ANGLE_D0 || autoFlop); + + if (shouldOrientBefore) { + image = sharp::StaySequential(image, autoRotation != VIPS_ANGLE_D0); + if (autoRotation != VIPS_ANGLE_D0) { + if (autoRotation != VIPS_ANGLE_D180) { + MultiPageUnsupported(nPages, "Rotate"); + } + image = image.rot(autoRotation); + autoRotation = VIPS_ANGLE_D0; + } + if (autoFlop) { + image = image.flip(VIPS_DIRECTION_HORIZONTAL); + autoFlop = false; + } + } + + if (shouldRotateBefore) { + image = sharp::StaySequential(image, rotation != VIPS_ANGLE_D0 || baton->flip || baton->rotationAngle != 0.0); + if (baton->flip) { + image = image.flip(VIPS_DIRECTION_VERTICAL); + baton->flip = false; + } + if (baton->flop) { + image = image.flip(VIPS_DIRECTION_HORIZONTAL); + baton->flop = false; + } + if (rotation != VIPS_ANGLE_D0) { + if (rotation != VIPS_ANGLE_D180) { + MultiPageUnsupported(nPages, "Rotate"); + } + image = image.rot(rotation); + rotation = VIPS_ANGLE_D0; + } + if (baton->rotationAngle != 0.0) { + MultiPageUnsupported(nPages, "Rotate"); + std::vector background; + std::tie(image, background) = sharp::ApplyAlpha(image, baton->rotationBackground, false); + image = image.rotate(baton->rotationAngle, VImage::option()->set("background", background)).copy_memory(); + baton->rotationAngle = 0.0; + } + } + + // Trim + if (baton->trimThreshold >= 0.0) { + MultiPageUnsupported(nPages, "Trim"); + image = sharp::StaySequential(image); + image = sharp::Trim(image, baton->trimBackground, baton->trimThreshold, baton->trimLineArt); + baton->trimOffsetLeft = image.xoffset(); + baton->trimOffsetTop = image.yoffset(); + } + + // Pre extraction + if (baton->topOffsetPre != -1) { + image = nPages > 1 + ? sharp::CropMultiPage(image, + baton->leftOffsetPre, baton->topOffsetPre, baton->widthPre, baton->heightPre, nPages, &pageHeight) + : image.extract_area(baton->leftOffsetPre, baton->topOffsetPre, baton->widthPre, baton->heightPre); + } + + // Get pre-resize image width and height + int inputWidth = image.width(); + int inputHeight = image.height(); + + // Is there just one page? Shrink to inputHeight instead + if (nPages == 1) { + pageHeight = inputHeight; + } + + // Scaling calculations + double hshrink; + double vshrink; + int targetResizeWidth = baton->width; + int targetResizeHeight = baton->height; + + // When auto-rotating by 90 or 270 degrees, swap the target width and + // height to ensure the behavior aligns with how it would have been if + // the rotation had taken place *before* resizing. + if (autoRotation == VIPS_ANGLE_D90 || autoRotation == VIPS_ANGLE_D270) { + std::swap(targetResizeWidth, targetResizeHeight); + } + + // Shrink to pageHeight, so we work for multi-page images + std::tie(hshrink, vshrink) = sharp::ResolveShrink( + inputWidth, pageHeight, targetResizeWidth, targetResizeHeight, + baton->canvas, baton->withoutEnlargement, baton->withoutReduction); + + // The jpeg preload shrink. + int jpegShrinkOnLoad = 1; + + // WebP, PDF, SVG scale + double scale = 1.0; + + // Try to reload input using shrink-on-load for JPEG, WebP, SVG and PDF, when: + // - the width or height parameters are specified; + // - gamma correction doesn't need to be applied; + // - trimming or pre-resize extract isn't required; + // - input colourspace is not specified; + bool const shouldPreShrink = (targetResizeWidth > 0 || targetResizeHeight > 0) && + baton->gamma == 0 && baton->topOffsetPre == -1 && baton->trimThreshold < 0.0 && + baton->colourspacePipeline == VIPS_INTERPRETATION_LAST && !(shouldOrientBefore || shouldRotateBefore); + + if (shouldPreShrink) { + // The common part of the shrink: the bit by which both axes must be shrunk + double shrink = std::min(hshrink, vshrink); + + if (inputImageType == sharp::ImageType::JPEG) { + // Leave at least a factor of two for the final resize step, when fastShrinkOnLoad: false + // for more consistent results and to avoid extra sharpness to the image + int factor = baton->fastShrinkOnLoad ? 1 : 2; + if (shrink >= 8 * factor) { + jpegShrinkOnLoad = 8; + } else if (shrink >= 4 * factor) { + jpegShrinkOnLoad = 4; + } else if (shrink >= 2 * factor) { + jpegShrinkOnLoad = 2; + } + // Lower shrink-on-load for known libjpeg rounding errors + if (jpegShrinkOnLoad > 1 && static_cast(shrink) == jpegShrinkOnLoad) { + jpegShrinkOnLoad /= 2; + } + } else if (inputImageType == sharp::ImageType::WEBP && baton->fastShrinkOnLoad && shrink > 1.0) { + // Avoid upscaling via webp + scale = 1.0 / shrink; + } else if (inputImageType == sharp::ImageType::SVG || + inputImageType == sharp::ImageType::PDF) { + scale = 1.0 / shrink; + } + } + + // Reload input using shrink-on-load, it'll be an integer shrink + // factor for jpegload*, a double scale factor for webpload*, + // pdfload* and svgload* + if (jpegShrinkOnLoad > 1) { + vips::VOption *option = GetOptionsForImageType(inputImageType, baton->input)->set("shrink", jpegShrinkOnLoad); + if (baton->input->buffer != nullptr) { + // Reload JPEG buffer + VipsBlob *blob = vips_blob_new(nullptr, baton->input->buffer, baton->input->bufferLength); + image = VImage::jpegload_buffer(blob, option); + vips_area_unref(reinterpret_cast(blob)); + } else { + // Reload JPEG file + image = VImage::jpegload(const_cast(baton->input->file.data()), option); + } + } else if (scale != 1.0) { + vips::VOption *option = GetOptionsForImageType(inputImageType, baton->input)->set("scale", scale); + if (inputImageType == sharp::ImageType::WEBP) { + if (baton->input->buffer != nullptr) { + // Reload WebP buffer + VipsBlob *blob = vips_blob_new(nullptr, baton->input->buffer, baton->input->bufferLength); + image = VImage::webpload_buffer(blob, option); + vips_area_unref(reinterpret_cast(blob)); + } else { + // Reload WebP file + image = VImage::webpload(const_cast(baton->input->file.data()), option); + } + } else if (inputImageType == sharp::ImageType::SVG) { + if (baton->input->buffer != nullptr) { + // Reload SVG buffer + VipsBlob *blob = vips_blob_new(nullptr, baton->input->buffer, baton->input->bufferLength); + image = VImage::svgload_buffer(blob, option); + vips_area_unref(reinterpret_cast(blob)); + } else { + // Reload SVG file + image = VImage::svgload(const_cast(baton->input->file.data()), option); + } + sharp::SetDensity(image, baton->input->density); + if (image.width() > 32767 || image.height() > 32767) { + throw vips::VError("Input SVG image will exceed 32767x32767 pixel limit when scaled"); + } + } else if (inputImageType == sharp::ImageType::PDF) { + if (baton->input->buffer != nullptr) { + // Reload PDF buffer + VipsBlob *blob = vips_blob_new(nullptr, baton->input->buffer, baton->input->bufferLength); + image = VImage::pdfload_buffer(blob, option); + vips_area_unref(reinterpret_cast(blob)); + } else { + // Reload PDF file + image = VImage::pdfload(const_cast(baton->input->file.data()), option); + } + sharp::SetDensity(image, baton->input->density); + } + } else { + if (inputImageType == sharp::ImageType::SVG && (image.width() > 32767 || image.height() > 32767)) { + throw vips::VError("Input SVG image exceeds 32767x32767 pixel limit"); + } + } + if (baton->input->autoOrient) { + image = sharp::RemoveExifOrientation(image); + } + + // Any pre-shrinking may already have been done + inputWidth = image.width(); + inputHeight = image.height(); + + // After pre-shrink, but before the main shrink stage + // Reuse the initial pageHeight if we didn't pre-shrink + if (shouldPreShrink) { + pageHeight = sharp::GetPageHeight(image); + } + + // Shrink to pageHeight, so we work for multi-page images + std::tie(hshrink, vshrink) = sharp::ResolveShrink( + inputWidth, pageHeight, targetResizeWidth, targetResizeHeight, + baton->canvas, baton->withoutEnlargement, baton->withoutReduction); + + int targetHeight = static_cast(std::rint(static_cast(pageHeight) / vshrink)); + int targetPageHeight = targetHeight; + + // In toilet-roll mode, we must adjust vshrink so that we exactly hit + // pageHeight or we'll have pixels straddling pixel boundaries + if (inputHeight > pageHeight) { + targetHeight *= nPages; + vshrink = static_cast(inputHeight) / targetHeight; + } + + // Ensure we're using a device-independent colour space + std::pair inputProfile(nullptr, 0); + if ((baton->keepMetadata & VIPS_FOREIGN_KEEP_ICC) && baton->withIccProfile.empty()) { + // Cache input profile for use with output + inputProfile = sharp::GetProfile(image); + baton->input->ignoreIcc = true; + } + char const *processingProfile = image.interpretation() == VIPS_INTERPRETATION_RGB16 ? "p3" : "srgb"; + if ( + sharp::HasProfile(image) && + image.interpretation() != VIPS_INTERPRETATION_LABS && + image.interpretation() != VIPS_INTERPRETATION_GREY16 && + baton->colourspacePipeline != VIPS_INTERPRETATION_CMYK && + !baton->input->ignoreIcc + ) { + // Convert to sRGB/P3 using embedded profile + try { + image = image.icc_transform(processingProfile, VImage::option() + ->set("embedded", true) + ->set("depth", sharp::Is16Bit(image.interpretation()) ? 16 : 8) + ->set("intent", VIPS_INTENT_PERCEPTUAL)); + } catch(...) { + sharp::VipsWarningCallback(nullptr, G_LOG_LEVEL_WARNING, "Invalid embedded profile", nullptr); + } + } else if ( + image.interpretation() == VIPS_INTERPRETATION_CMYK && + baton->colourspacePipeline != VIPS_INTERPRETATION_CMYK + ) { + image = image.icc_transform(processingProfile, VImage::option() + ->set("input_profile", "cmyk") + ->set("intent", VIPS_INTENT_PERCEPTUAL)); + } + + // Flatten image to remove alpha channel + if (baton->flatten && image.has_alpha()) { + image = sharp::Flatten(image, baton->flattenBackground); + } + + // Gamma encoding (darken) + if (baton->gamma >= 1 && baton->gamma <= 3) { + image = sharp::Gamma(image, 1.0 / baton->gamma); + } + + // Convert to greyscale (linear, therefore after gamma encoding, if any) + if (baton->greyscale) { + image = image.colourspace(VIPS_INTERPRETATION_B_W); + } + + bool const shouldResize = hshrink != 1.0 || vshrink != 1.0; + bool const shouldBlur = baton->blurSigma != 0.0; + bool const shouldConv = baton->convKernelWidth * baton->convKernelHeight > 0; + bool const shouldSharpen = baton->sharpenSigma != 0.0; + bool const shouldComposite = !baton->composite.empty(); + + if (shouldComposite && !image.has_alpha()) { + image = sharp::EnsureAlpha(image, 1); + } + + VipsBandFormat premultiplyFormat = image.format(); + bool const shouldPremultiplyAlpha = image.has_alpha() && + (shouldResize || shouldBlur || shouldConv || shouldSharpen); + + if (shouldPremultiplyAlpha) { + image = image.premultiply().cast(premultiplyFormat); + } + + // Resize + if (shouldResize) { + image = image.resize(1.0 / hshrink, VImage::option() + ->set("vscale", 1.0 / vshrink) + ->set("kernel", baton->kernel)); + } + + image = sharp::StaySequential(image, + autoRotation != VIPS_ANGLE_D0 || + baton->flip || + rotation != VIPS_ANGLE_D0); + // Auto-rotate post-extract + if (autoRotation != VIPS_ANGLE_D0) { + if (autoRotation != VIPS_ANGLE_D180) { + MultiPageUnsupported(nPages, "Rotate"); + } + image = image.rot(autoRotation); + } + // Mirror vertically (up-down) about the x-axis + if (baton->flip) { + image = image.flip(VIPS_DIRECTION_VERTICAL); + } + // Mirror horizontally (left-right) about the y-axis + if (baton->flop != autoFlop) { + image = image.flip(VIPS_DIRECTION_HORIZONTAL); + } + // Rotate post-extract 90-angle + if (rotation != VIPS_ANGLE_D0) { + if (rotation != VIPS_ANGLE_D180) { + MultiPageUnsupported(nPages, "Rotate"); + } + image = image.rot(rotation); + } + + // Join additional color channels to the image + if (!baton->joinChannelIn.empty()) { + VImage joinImage; + sharp::ImageType joinImageType = sharp::ImageType::UNKNOWN; + + for (unsigned int i = 0; i < baton->joinChannelIn.size(); i++) { + baton->joinChannelIn[i]->access = access; + std::tie(joinImage, joinImageType) = sharp::OpenInput(baton->joinChannelIn[i]); + joinImage = sharp::EnsureColourspace(joinImage, baton->colourspacePipeline); + image = image.bandjoin(joinImage); + } + image = image.copy(VImage::option()->set("interpretation", baton->colourspace)); + image = sharp::RemoveGifPalette(image); + } + + inputWidth = image.width(); + inputHeight = nPages > 1 ? targetPageHeight : image.height(); + + // Resolve dimensions + if (baton->width <= 0) { + baton->width = inputWidth; + } + if (baton->height <= 0) { + baton->height = inputHeight; + } + + // Crop/embed + if (inputWidth != baton->width || inputHeight != baton->height) { + if (baton->canvas == sharp::Canvas::EMBED) { + std::vector background; + std::tie(image, background) = sharp::ApplyAlpha(image, baton->resizeBackground, shouldPremultiplyAlpha); + + // Embed + int left; + int top; + std::tie(left, top) = sharp::CalculateEmbedPosition( + inputWidth, inputHeight, baton->width, baton->height, baton->position); + int width = std::max(inputWidth, baton->width); + int height = std::max(inputHeight, baton->height); + + image = nPages > 1 + ? sharp::EmbedMultiPage(image, + left, top, width, height, VIPS_EXTEND_BACKGROUND, background, nPages, &targetPageHeight) + : image.embed(left, top, width, height, VImage::option() + ->set("extend", VIPS_EXTEND_BACKGROUND) + ->set("background", background)); + } else if (baton->canvas == sharp::Canvas::CROP) { + if (baton->width > inputWidth) { + baton->width = inputWidth; + } + if (baton->height > inputHeight) { + baton->height = inputHeight; + } + + // Crop + if (baton->position < 9) { + // Gravity-based crop + int left; + int top; + + std::tie(left, top) = sharp::CalculateCrop( + inputWidth, inputHeight, baton->width, baton->height, baton->position); + int width = std::min(inputWidth, baton->width); + int height = std::min(inputHeight, baton->height); + + image = nPages > 1 + ? sharp::CropMultiPage(image, + left, top, width, height, nPages, &targetPageHeight) + : image.extract_area(left, top, width, height); + } else { + int attention_x; + int attention_y; + + // Attention-based or Entropy-based crop + MultiPageUnsupported(nPages, "Resize strategy"); + image = sharp::StaySequential(image); + image = image.smartcrop(baton->width, baton->height, VImage::option() + ->set("interesting", baton->position == 16 ? VIPS_INTERESTING_ENTROPY : VIPS_INTERESTING_ATTENTION) + ->set("premultiplied", shouldPremultiplyAlpha) + ->set("attention_x", &attention_x) + ->set("attention_y", &attention_y)); + baton->hasCropOffset = true; + baton->cropOffsetLeft = static_cast(image.xoffset()); + baton->cropOffsetTop = static_cast(image.yoffset()); + baton->hasAttentionCenter = true; + baton->attentionX = static_cast(attention_x * jpegShrinkOnLoad / scale); + baton->attentionY = static_cast(attention_y * jpegShrinkOnLoad / scale); + } + } + } + + // Rotate post-extract non-90 angle + if (!baton->rotateBefore && baton->rotationAngle != 0.0) { + MultiPageUnsupported(nPages, "Rotate"); + image = sharp::StaySequential(image); + std::vector background; + std::tie(image, background) = sharp::ApplyAlpha(image, baton->rotationBackground, shouldPremultiplyAlpha); + image = image.rotate(baton->rotationAngle, VImage::option()->set("background", background)); + } + + // Post extraction + if (baton->topOffsetPost != -1) { + if (nPages > 1) { + image = sharp::CropMultiPage(image, + baton->leftOffsetPost, baton->topOffsetPost, baton->widthPost, baton->heightPost, + nPages, &targetPageHeight); + + // heightPost is used in the info object, so update to reflect the number of pages + baton->heightPost *= nPages; + } else { + image = image.extract_area( + baton->leftOffsetPost, baton->topOffsetPost, baton->widthPost, baton->heightPost); + } + } + + // Affine transform + if (!baton->affineMatrix.empty()) { + MultiPageUnsupported(nPages, "Affine"); + image = sharp::StaySequential(image); + std::vector background; + std::tie(image, background) = sharp::ApplyAlpha(image, baton->affineBackground, shouldPremultiplyAlpha); + vips::VInterpolate interp = vips::VInterpolate::new_from_name( + const_cast(baton->affineInterpolator.data())); + image = image.affine(baton->affineMatrix, VImage::option()->set("background", background) + ->set("idx", baton->affineIdx) + ->set("idy", baton->affineIdy) + ->set("odx", baton->affineOdx) + ->set("ody", baton->affineOdy) + ->set("interpolate", interp)); + } + + // Extend edges + if (baton->extendTop > 0 || baton->extendBottom > 0 || baton->extendLeft > 0 || baton->extendRight > 0) { + // Embed + baton->width = image.width() + baton->extendLeft + baton->extendRight; + baton->height = (nPages > 1 ? targetPageHeight : image.height()) + baton->extendTop + baton->extendBottom; + + if (baton->extendWith == VIPS_EXTEND_BACKGROUND) { + std::vector background; + std::tie(image, background) = sharp::ApplyAlpha(image, baton->extendBackground, shouldPremultiplyAlpha); + + image = sharp::StaySequential(image, nPages > 1); + image = nPages > 1 + ? sharp::EmbedMultiPage(image, + baton->extendLeft, baton->extendTop, baton->width, baton->height, + baton->extendWith, background, nPages, &targetPageHeight) + : image.embed(baton->extendLeft, baton->extendTop, baton->width, baton->height, + VImage::option()->set("extend", baton->extendWith)->set("background", background)); + } else { + std::vector ignoredBackground(1); + image = sharp::StaySequential(image); + image = nPages > 1 + ? sharp::EmbedMultiPage(image, + baton->extendLeft, baton->extendTop, baton->width, baton->height, + baton->extendWith, ignoredBackground, nPages, &targetPageHeight) + : image.embed(baton->extendLeft, baton->extendTop, baton->width, baton->height, + VImage::option()->set("extend", baton->extendWith)); + } + } + // Median - must happen before blurring, due to the utility of blurring after thresholding + if (baton->medianSize > 0) { + image = image.median(baton->medianSize); + } + + // Threshold - must happen before blurring, due to the utility of blurring after thresholding + // Threshold - must happen before unflatten to enable non-white unflattening + if (baton->threshold != 0) { + image = sharp::Threshold(image, baton->threshold, baton->thresholdGrayscale); + } + + // Dilate - must happen before blurring, due to the utility of dilating after thresholding + if (baton->dilateWidth != 0) { + image = sharp::Dilate(image, baton->dilateWidth); + } + + // Erode - must happen before blurring, due to the utility of eroding after thresholding + if (baton->erodeWidth != 0) { + image = sharp::Erode(image, baton->erodeWidth); + } + + // Blur + if (shouldBlur) { + image = sharp::Blur(image, baton->blurSigma, baton->precision, baton->minAmpl); + } + + // Unflatten the image + if (baton->unflatten) { + image = sharp::Unflatten(image); + } + + // Convolve + if (shouldConv) { + image = sharp::Convolve(image, + baton->convKernelWidth, baton->convKernelHeight, + baton->convKernelScale, baton->convKernelOffset, + baton->convKernel); + } + + // Recomb + if (!baton->recombMatrix.empty()) { + image = sharp::Recomb(image, baton->recombMatrix); + } + + // Modulate + if (baton->brightness != 1.0 || baton->saturation != 1.0 || baton->hue != 0.0 || baton->lightness != 0.0) { + image = sharp::Modulate(image, baton->brightness, baton->saturation, baton->hue, baton->lightness); + } + + // Sharpen + if (shouldSharpen) { + image = sharp::Sharpen(image, baton->sharpenSigma, baton->sharpenM1, baton->sharpenM2, + baton->sharpenX1, baton->sharpenY2, baton->sharpenY3); + } + + // Reverse premultiplication after all transformations + if (shouldPremultiplyAlpha) { + image = image.unpremultiply().cast(premultiplyFormat); + } + baton->premultiplied = shouldPremultiplyAlpha; + + // Composite + if (shouldComposite) { + std::vector images = { image }; + std::vector modes, xs, ys; + for (Composite *composite : baton->composite) { + VImage compositeImage; + sharp::ImageType compositeImageType = sharp::ImageType::UNKNOWN; + composite->input->access = access; + std::tie(compositeImage, compositeImageType) = sharp::OpenInput(composite->input); + + if (composite->input->autoOrient) { + // Respect EXIF Orientation + VipsAngle compositeAutoRotation = VIPS_ANGLE_D0; + bool compositeAutoFlop = false; + std::tie(compositeAutoRotation, compositeAutoFlop) = + CalculateExifRotationAndFlop(sharp::ExifOrientation(compositeImage)); + + compositeImage = sharp::RemoveExifOrientation(compositeImage); + compositeImage = sharp::StaySequential(compositeImage, compositeAutoRotation != VIPS_ANGLE_D0); + + if (compositeAutoRotation != VIPS_ANGLE_D0) { + compositeImage = compositeImage.rot(compositeAutoRotation); + } + if (compositeAutoFlop) { + compositeImage = compositeImage.flip(VIPS_DIRECTION_HORIZONTAL); + } + } + + // Verify within current dimensions + if (compositeImage.width() > image.width() || compositeImage.height() > image.height()) { + throw vips::VError("Image to composite must have same dimensions or smaller"); + } + // Check if overlay is tiled + if (composite->tile) { + int across = 0; + int down = 0; + // Use gravity in overlay + if (compositeImage.width() <= image.width()) { + across = static_cast(ceil(static_cast(image.width()) / compositeImage.width())); + // Ensure odd number of tiles across when gravity is centre, north or south + if (composite->gravity == 0 || composite->gravity == 1 || composite->gravity == 3) { + across |= 1; + } + } + if (compositeImage.height() <= image.height()) { + down = static_cast(ceil(static_cast(image.height()) / compositeImage.height())); + // Ensure odd number of tiles down when gravity is centre, east or west + if (composite->gravity == 0 || composite->gravity == 2 || composite->gravity == 4) { + down |= 1; + } + } + if (across != 0 || down != 0) { + int left; + int top; + compositeImage = sharp::StaySequential(compositeImage).replicate(across, down); + if (composite->hasOffset) { + std::tie(left, top) = sharp::CalculateCrop( + compositeImage.width(), compositeImage.height(), image.width(), image.height(), + composite->left, composite->top); + } else { + std::tie(left, top) = sharp::CalculateCrop( + compositeImage.width(), compositeImage.height(), image.width(), image.height(), composite->gravity); + } + compositeImage = compositeImage.extract_area(left, top, image.width(), image.height()); + } + // gravity was used for extract_area, set it back to its default value of 0 + composite->gravity = 0; + } + // Ensure image to composite is with unpremultiplied alpha + compositeImage = sharp::EnsureAlpha(compositeImage, 1); + if (composite->premultiplied) compositeImage = compositeImage.unpremultiply(); + // Calculate position + int left; + int top; + if (composite->hasOffset) { + // Composite image at given offsets + if (composite->tile) { + std::tie(left, top) = sharp::CalculateCrop(image.width(), image.height(), + compositeImage.width(), compositeImage.height(), composite->left, composite->top); + } else { + left = composite->left; + top = composite->top; + } + } else { + // Composite image with given gravity + std::tie(left, top) = sharp::CalculateCrop(image.width(), image.height(), + compositeImage.width(), compositeImage.height(), composite->gravity); + } + images.push_back(compositeImage); + modes.push_back(composite->mode); + xs.push_back(left); + ys.push_back(top); + } + image = VImage::composite(images, modes, VImage::option() + ->set("compositing_space", baton->colourspacePipeline == VIPS_INTERPRETATION_LAST + ? VIPS_INTERPRETATION_sRGB + : baton->colourspacePipeline) + ->set("x", xs) + ->set("y", ys)); + image = sharp::RemoveGifPalette(image); + } + + // Gamma decoding (brighten) + if (baton->gammaOut >= 1 && baton->gammaOut <= 3) { + image = sharp::Gamma(image, baton->gammaOut); + } + + // Linear adjustment (a * in + b) + if (!baton->linearA.empty()) { + image = sharp::Linear(image, baton->linearA, baton->linearB); + } + + // Apply normalisation - stretch luminance to cover full dynamic range + if (baton->normalise) { + image = sharp::StaySequential(image); + image = sharp::Normalise(image, baton->normaliseLower, baton->normaliseUpper); + } + + // Apply contrast limiting adaptive histogram equalization (CLAHE) + if (baton->claheWidth != 0 && baton->claheHeight != 0) { + image = sharp::StaySequential(image); + image = sharp::Clahe(image, baton->claheWidth, baton->claheHeight, baton->claheMaxSlope); + } + + // Apply bitwise boolean operation between images + if (baton->boolean != nullptr) { + VImage booleanImage; + sharp::ImageType booleanImageType = sharp::ImageType::UNKNOWN; + baton->boolean->access = access; + std::tie(booleanImage, booleanImageType) = sharp::OpenInput(baton->boolean); + booleanImage = sharp::EnsureColourspace(booleanImage, baton->colourspacePipeline); + image = sharp::Boolean(image, booleanImage, baton->booleanOp); + image = sharp::RemoveGifPalette(image); + } + + // Apply per-channel Bandbool bitwise operations after all other operations + if (baton->bandBoolOp >= VIPS_OPERATION_BOOLEAN_AND && baton->bandBoolOp < VIPS_OPERATION_BOOLEAN_LAST) { + image = sharp::Bandbool(image, baton->bandBoolOp); + } + + // Tint the image + if (baton->tint[0] >= 0.0) { + image = sharp::Tint(image, baton->tint); + } + + // Remove alpha channel, if any + if (baton->removeAlpha) { + image = sharp::RemoveAlpha(image); + } + + // Ensure alpha channel, if missing + if (baton->ensureAlpha != -1) { + image = sharp::EnsureAlpha(image, baton->ensureAlpha); + } + + // Convert image to sRGB, if not already + if (sharp::Is16Bit(image.interpretation())) { + image = image.cast(VIPS_FORMAT_USHORT); + } + if (image.interpretation() != baton->colourspace) { + // Convert colourspace, pass the current known interpretation so libvips doesn't have to guess + image = image.colourspace(baton->colourspace, VImage::option()->set("source_space", image.interpretation())); + // Transform colours from embedded profile to output profile + if ((baton->keepMetadata & VIPS_FOREIGN_KEEP_ICC) && baton->colourspacePipeline != VIPS_INTERPRETATION_CMYK && + baton->withIccProfile.empty() && sharp::HasProfile(image)) { + image = image.icc_transform(processingProfile, VImage::option() + ->set("embedded", true) + ->set("depth", sharp::Is16Bit(image.interpretation()) ? 16 : 8) + ->set("intent", VIPS_INTENT_PERCEPTUAL)); + } + } + + // Extract channel + if (baton->extractChannel > -1) { + if (baton->extractChannel >= image.bands()) { + if (baton->extractChannel == 3 && image.has_alpha()) { + baton->extractChannel = image.bands() - 1; + } else { + (baton->err) + .append("Cannot extract channel ").append(std::to_string(baton->extractChannel)) + .append(" from image with channels 0-").append(std::to_string(image.bands() - 1)); + return Error(); + } + } + VipsInterpretation colourspace = sharp::Is16Bit(image.interpretation()) + ? VIPS_INTERPRETATION_GREY16 + : VIPS_INTERPRETATION_B_W; + image = image + .extract_band(baton->extractChannel) + .copy(VImage::option()->set("interpretation", colourspace)); + } + + // Apply output ICC profile + if (!baton->withIccProfile.empty()) { + try { + image = image.icc_transform(const_cast(baton->withIccProfile.data()), VImage::option() + ->set("input_profile", processingProfile) + ->set("embedded", true) + ->set("depth", sharp::Is16Bit(image.interpretation()) ? 16 : 8) + ->set("intent", VIPS_INTENT_PERCEPTUAL)); + } catch(...) { + sharp::VipsWarningCallback(nullptr, G_LOG_LEVEL_WARNING, "Invalid profile", nullptr); + } + } else if (baton->keepMetadata & VIPS_FOREIGN_KEEP_ICC) { + image = sharp::SetProfile(image, inputProfile); + } + + // Negate the colours in the image + if (baton->negate) { + image = sharp::Negate(image, baton->negateAlpha); + } + + // Override EXIF Orientation tag + if (baton->withMetadataOrientation != -1) { + image = sharp::SetExifOrientation(image, baton->withMetadataOrientation); + } + // Override pixel density + if (baton->withMetadataDensity > 0) { + image = sharp::SetDensity(image, baton->withMetadataDensity); + } + // EXIF key/value pairs + if (baton->keepMetadata & VIPS_FOREIGN_KEEP_EXIF) { + image = image.copy(); + if (!baton->withExifMerge) { + image = sharp::RemoveExif(image); + } + for (const auto& s : baton->withExif) { + image.set(s.first.data(), s.second.data()); + } + } + // XMP buffer + if ((baton->keepMetadata & VIPS_FOREIGN_KEEP_XMP) && !baton->withXmp.empty()) { + image = image.copy(); + image.set(VIPS_META_XMP_NAME, nullptr, + const_cast(static_cast(baton->withXmp.c_str())), baton->withXmp.size()); + } + // Number of channels used in output image + baton->channels = image.bands(); + baton->width = image.width(); + baton->height = image.height(); + + image = sharp::SetAnimationProperties( + image, nPages, targetPageHeight, baton->delay, baton->loop); + + if (image.get_typeof(VIPS_META_PAGE_HEIGHT) == G_TYPE_INT) { + baton->pageHeightOut = image.get_int(VIPS_META_PAGE_HEIGHT); + baton->pagesOut = image.get_int(VIPS_META_N_PAGES); + } + + // Output + sharp::SetTimeout(image, baton->timeoutSeconds); + if (baton->fileOut.empty()) { + // Buffer output + if (baton->formatOut == "jpeg" || (baton->formatOut == "input" && inputImageType == sharp::ImageType::JPEG)) { + // Write JPEG to buffer + sharp::AssertImageTypeDimensions(image, sharp::ImageType::JPEG); + VipsArea *area = reinterpret_cast(image.jpegsave_buffer(VImage::option() + ->set("keep", baton->keepMetadata) + ->set("Q", baton->jpegQuality) + ->set("interlace", baton->jpegProgressive) + ->set("subsample_mode", baton->jpegChromaSubsampling == "4:4:4" + ? VIPS_FOREIGN_SUBSAMPLE_OFF + : VIPS_FOREIGN_SUBSAMPLE_ON) + ->set("trellis_quant", baton->jpegTrellisQuantisation) + ->set("quant_table", baton->jpegQuantisationTable) + ->set("overshoot_deringing", baton->jpegOvershootDeringing) + ->set("optimize_scans", baton->jpegOptimiseScans) + ->set("optimize_coding", baton->jpegOptimiseCoding))); + baton->bufferOut = static_cast(area->data); + baton->bufferOutLength = area->length; + area->free_fn = nullptr; + vips_area_unref(area); + baton->formatOut = "jpeg"; + if (baton->colourspace == VIPS_INTERPRETATION_CMYK) { + baton->channels = std::min(baton->channels, 4); + } else { + baton->channels = std::min(baton->channels, 3); + } + } else if (baton->formatOut == "jp2" || (baton->formatOut == "input" + && inputImageType == sharp::ImageType::JP2)) { + // Write JP2 to Buffer + sharp::AssertImageTypeDimensions(image, sharp::ImageType::JP2); + VipsArea *area = reinterpret_cast(image.jp2ksave_buffer(VImage::option() + ->set("Q", baton->jp2Quality) + ->set("lossless", baton->jp2Lossless) + ->set("subsample_mode", baton->jp2ChromaSubsampling == "4:4:4" + ? VIPS_FOREIGN_SUBSAMPLE_OFF : VIPS_FOREIGN_SUBSAMPLE_ON) + ->set("tile_height", baton->jp2TileHeight) + ->set("tile_width", baton->jp2TileWidth))); + baton->bufferOut = static_cast(area->data); + baton->bufferOutLength = area->length; + area->free_fn = nullptr; + vips_area_unref(area); + baton->formatOut = "jp2"; + } else if (baton->formatOut == "png" || (baton->formatOut == "input" && + (inputImageType == sharp::ImageType::PNG || inputImageType == sharp::ImageType::SVG))) { + // Write PNG to buffer + sharp::AssertImageTypeDimensions(image, sharp::ImageType::PNG); + VipsArea *area = reinterpret_cast(image.pngsave_buffer(VImage::option() + ->set("keep", baton->keepMetadata) + ->set("interlace", baton->pngProgressive) + ->set("compression", baton->pngCompressionLevel) + ->set("filter", baton->pngAdaptiveFiltering ? VIPS_FOREIGN_PNG_FILTER_ALL : VIPS_FOREIGN_PNG_FILTER_NONE) + ->set("palette", baton->pngPalette) + ->set("Q", baton->pngQuality) + ->set("effort", baton->pngEffort) + ->set("bitdepth", sharp::Is16Bit(image.interpretation()) ? 16 : baton->pngBitdepth) + ->set("dither", baton->pngDither))); + baton->bufferOut = static_cast(area->data); + baton->bufferOutLength = area->length; + area->free_fn = nullptr; + vips_area_unref(area); + baton->formatOut = "png"; + } else if (baton->formatOut == "webp" || + (baton->formatOut == "input" && inputImageType == sharp::ImageType::WEBP)) { + // Write WEBP to buffer + sharp::AssertImageTypeDimensions(image, sharp::ImageType::WEBP); + VipsArea *area = reinterpret_cast(image.webpsave_buffer(VImage::option() + ->set("keep", baton->keepMetadata) + ->set("Q", baton->webpQuality) + ->set("lossless", baton->webpLossless) + ->set("near_lossless", baton->webpNearLossless) + ->set("smart_subsample", baton->webpSmartSubsample) + ->set("smart_deblock", baton->webpSmartDeblock) + ->set("preset", baton->webpPreset) + ->set("effort", baton->webpEffort) + ->set("min_size", baton->webpMinSize) + ->set("mixed", baton->webpMixed) + ->set("alpha_q", baton->webpAlphaQuality))); + baton->bufferOut = static_cast(area->data); + baton->bufferOutLength = area->length; + area->free_fn = nullptr; + vips_area_unref(area); + baton->formatOut = "webp"; + } else if (baton->formatOut == "gif" || + (baton->formatOut == "input" && inputImageType == sharp::ImageType::GIF)) { + // Write GIF to buffer + sharp::AssertImageTypeDimensions(image, sharp::ImageType::GIF); + VipsArea *area = reinterpret_cast(image.gifsave_buffer(VImage::option() + ->set("keep", baton->keepMetadata) + ->set("bitdepth", baton->gifBitdepth) + ->set("effort", baton->gifEffort) + ->set("reuse", baton->gifReuse) + ->set("interlace", baton->gifProgressive) + ->set("interframe_maxerror", baton->gifInterFrameMaxError) + ->set("interpalette_maxerror", baton->gifInterPaletteMaxError) + ->set("keep_duplicate_frames", baton->gifKeepDuplicateFrames) + ->set("dither", baton->gifDither))); + baton->bufferOut = static_cast(area->data); + baton->bufferOutLength = area->length; + area->free_fn = nullptr; + vips_area_unref(area); + baton->formatOut = "gif"; + } else if (baton->formatOut == "tiff" || + (baton->formatOut == "input" && inputImageType == sharp::ImageType::TIFF)) { + // Write TIFF to buffer + if (baton->tiffCompression == VIPS_FOREIGN_TIFF_COMPRESSION_JPEG) { + sharp::AssertImageTypeDimensions(image, sharp::ImageType::JPEG); + baton->channels = std::min(baton->channels, 3); + } + // Cast pixel values to float, if required + if (baton->tiffPredictor == VIPS_FOREIGN_TIFF_PREDICTOR_FLOAT) { + image = image.cast(VIPS_FORMAT_FLOAT); + } + VipsArea *area = reinterpret_cast(image.tiffsave_buffer(VImage::option() + ->set("keep", baton->keepMetadata) + ->set("Q", baton->tiffQuality) + ->set("bitdepth", baton->tiffBitdepth) + ->set("compression", baton->tiffCompression) + ->set("miniswhite", baton->tiffMiniswhite) + ->set("predictor", baton->tiffPredictor) + ->set("pyramid", baton->tiffPyramid) + ->set("tile", baton->tiffTile) + ->set("tile_height", baton->tiffTileHeight) + ->set("tile_width", baton->tiffTileWidth) + ->set("xres", baton->tiffXres) + ->set("yres", baton->tiffYres) + ->set("resunit", baton->tiffResolutionUnit))); + baton->bufferOut = static_cast(area->data); + baton->bufferOutLength = area->length; + area->free_fn = nullptr; + vips_area_unref(area); + baton->formatOut = "tiff"; + } else if (baton->formatOut == "heif" || + (baton->formatOut == "input" && inputImageType == sharp::ImageType::HEIF)) { + // Write HEIF to buffer + sharp::AssertImageTypeDimensions(image, sharp::ImageType::HEIF); + image = sharp::RemoveAnimationProperties(image); + VipsArea *area = reinterpret_cast(image.heifsave_buffer(VImage::option() + ->set("keep", baton->keepMetadata) + ->set("Q", baton->heifQuality) + ->set("compression", baton->heifCompression) + ->set("effort", baton->heifEffort) + ->set("bitdepth", baton->heifBitdepth) + ->set("subsample_mode", baton->heifChromaSubsampling == "4:4:4" + ? VIPS_FOREIGN_SUBSAMPLE_OFF : VIPS_FOREIGN_SUBSAMPLE_ON) + ->set("lossless", baton->heifLossless))); + baton->bufferOut = static_cast(area->data); + baton->bufferOutLength = area->length; + area->free_fn = nullptr; + vips_area_unref(area); + baton->formatOut = "heif"; + } else if (baton->formatOut == "dz") { + // Write DZ to buffer + baton->tileContainer = VIPS_FOREIGN_DZ_CONTAINER_ZIP; + if (!image.has_alpha()) { + baton->tileBackground.pop_back(); + } + image = sharp::StaySequential(image, baton->tileAngle != 0); + vips::VOption *options = BuildOptionsDZ(baton); + VipsArea *area = reinterpret_cast(image.dzsave_buffer(options)); + baton->bufferOut = static_cast(area->data); + baton->bufferOutLength = area->length; + area->free_fn = nullptr; + vips_area_unref(area); + baton->formatOut = "dz"; + } else if (baton->formatOut == "jxl" || + (baton->formatOut == "input" && inputImageType == sharp::ImageType::JXL)) { + // Write JXL to buffer + image = sharp::RemoveAnimationProperties(image); + VipsArea *area = reinterpret_cast(image.jxlsave_buffer(VImage::option() + ->set("keep", baton->keepMetadata) + ->set("distance", baton->jxlDistance) + ->set("tier", baton->jxlDecodingTier) + ->set("effort", baton->jxlEffort) + ->set("lossless", baton->jxlLossless))); + baton->bufferOut = static_cast(area->data); + baton->bufferOutLength = area->length; + area->free_fn = nullptr; + vips_area_unref(area); + baton->formatOut = "jxl"; + } else if (baton->formatOut == "raw" || + (baton->formatOut == "input" && inputImageType == sharp::ImageType::RAW)) { + // Write raw, uncompressed image data to buffer + if (baton->greyscale || image.interpretation() == VIPS_INTERPRETATION_B_W) { + // Extract first band for greyscale image + image = image[0]; + baton->channels = 1; + } + if (image.format() != baton->rawDepth) { + // Cast pixels to requested format + image = image.cast(baton->rawDepth); + } + // Get raw image data + baton->bufferOut = static_cast(image.write_to_memory(&baton->bufferOutLength)); + if (baton->bufferOut == nullptr) { + (baton->err).append("Could not allocate enough memory for raw output"); + return Error(); + } + baton->formatOut = "raw"; + } else { + // Unsupported output format + (baton->err).append("Unsupported output format "); + if (baton->formatOut == "input") { + (baton->err).append("when trying to match input format of "); + (baton->err).append(ImageTypeId(inputImageType)); + } else { + (baton->err).append(baton->formatOut); + } + return Error(); + } + } else { + // File output + bool const isJpeg = sharp::IsJpeg(baton->fileOut); + bool const isPng = sharp::IsPng(baton->fileOut); + bool const isWebp = sharp::IsWebp(baton->fileOut); + bool const isGif = sharp::IsGif(baton->fileOut); + bool const isTiff = sharp::IsTiff(baton->fileOut); + bool const isJp2 = sharp::IsJp2(baton->fileOut); + bool const isHeif = sharp::IsHeif(baton->fileOut); + bool const isJxl = sharp::IsJxl(baton->fileOut); + bool const isDz = sharp::IsDz(baton->fileOut); + bool const isDzZip = sharp::IsDzZip(baton->fileOut); + bool const isV = sharp::IsV(baton->fileOut); + bool const mightMatchInput = baton->formatOut == "input"; + bool const willMatchInput = mightMatchInput && + !(isJpeg || isPng || isWebp || isGif || isTiff || isJp2 || isHeif || isDz || isDzZip || isV); + + if (baton->formatOut == "jpeg" || (mightMatchInput && isJpeg) || + (willMatchInput && inputImageType == sharp::ImageType::JPEG)) { + // Write JPEG to file + sharp::AssertImageTypeDimensions(image, sharp::ImageType::JPEG); + image.jpegsave(const_cast(baton->fileOut.data()), VImage::option() + ->set("keep", baton->keepMetadata) + ->set("Q", baton->jpegQuality) + ->set("interlace", baton->jpegProgressive) + ->set("subsample_mode", baton->jpegChromaSubsampling == "4:4:4" + ? VIPS_FOREIGN_SUBSAMPLE_OFF + : VIPS_FOREIGN_SUBSAMPLE_ON) + ->set("trellis_quant", baton->jpegTrellisQuantisation) + ->set("quant_table", baton->jpegQuantisationTable) + ->set("overshoot_deringing", baton->jpegOvershootDeringing) + ->set("optimize_scans", baton->jpegOptimiseScans) + ->set("optimize_coding", baton->jpegOptimiseCoding)); + baton->formatOut = "jpeg"; + baton->channels = std::min(baton->channels, 3); + } else if (baton->formatOut == "jp2" || (mightMatchInput && isJp2) || + (willMatchInput && (inputImageType == sharp::ImageType::JP2))) { + // Write JP2 to file + sharp::AssertImageTypeDimensions(image, sharp::ImageType::JP2); + image.jp2ksave(const_cast(baton->fileOut.data()), VImage::option() + ->set("Q", baton->jp2Quality) + ->set("lossless", baton->jp2Lossless) + ->set("subsample_mode", baton->jp2ChromaSubsampling == "4:4:4" + ? VIPS_FOREIGN_SUBSAMPLE_OFF : VIPS_FOREIGN_SUBSAMPLE_ON) + ->set("tile_height", baton->jp2TileHeight) + ->set("tile_width", baton->jp2TileWidth)); + baton->formatOut = "jp2"; + } else if (baton->formatOut == "png" || (mightMatchInput && isPng) || (willMatchInput && + (inputImageType == sharp::ImageType::PNG || inputImageType == sharp::ImageType::SVG))) { + // Write PNG to file + sharp::AssertImageTypeDimensions(image, sharp::ImageType::PNG); + image.pngsave(const_cast(baton->fileOut.data()), VImage::option() + ->set("keep", baton->keepMetadata) + ->set("interlace", baton->pngProgressive) + ->set("compression", baton->pngCompressionLevel) + ->set("filter", baton->pngAdaptiveFiltering ? VIPS_FOREIGN_PNG_FILTER_ALL : VIPS_FOREIGN_PNG_FILTER_NONE) + ->set("palette", baton->pngPalette) + ->set("Q", baton->pngQuality) + ->set("bitdepth", sharp::Is16Bit(image.interpretation()) ? 16 : baton->pngBitdepth) + ->set("effort", baton->pngEffort) + ->set("dither", baton->pngDither)); + baton->formatOut = "png"; + } else if (baton->formatOut == "webp" || (mightMatchInput && isWebp) || + (willMatchInput && inputImageType == sharp::ImageType::WEBP)) { + // Write WEBP to file + sharp::AssertImageTypeDimensions(image, sharp::ImageType::WEBP); + image.webpsave(const_cast(baton->fileOut.data()), VImage::option() + ->set("keep", baton->keepMetadata) + ->set("Q", baton->webpQuality) + ->set("lossless", baton->webpLossless) + ->set("near_lossless", baton->webpNearLossless) + ->set("smart_subsample", baton->webpSmartSubsample) + ->set("smart_deblock", baton->webpSmartDeblock) + ->set("preset", baton->webpPreset) + ->set("effort", baton->webpEffort) + ->set("min_size", baton->webpMinSize) + ->set("mixed", baton->webpMixed) + ->set("alpha_q", baton->webpAlphaQuality)); + baton->formatOut = "webp"; + } else if (baton->formatOut == "gif" || (mightMatchInput && isGif) || + (willMatchInput && inputImageType == sharp::ImageType::GIF)) { + // Write GIF to file + sharp::AssertImageTypeDimensions(image, sharp::ImageType::GIF); + image.gifsave(const_cast(baton->fileOut.data()), VImage::option() + ->set("keep", baton->keepMetadata) + ->set("bitdepth", baton->gifBitdepth) + ->set("effort", baton->gifEffort) + ->set("reuse", baton->gifReuse) + ->set("interlace", baton->gifProgressive) + ->set("interframe_maxerror", baton->gifInterFrameMaxError) + ->set("interpalette_maxerror", baton->gifInterPaletteMaxError) + ->set("keep_duplicate_frames", baton->gifKeepDuplicateFrames) + ->set("dither", baton->gifDither)); + baton->formatOut = "gif"; + } else if (baton->formatOut == "tiff" || (mightMatchInput && isTiff) || + (willMatchInput && inputImageType == sharp::ImageType::TIFF)) { + // Write TIFF to file + if (baton->tiffCompression == VIPS_FOREIGN_TIFF_COMPRESSION_JPEG) { + sharp::AssertImageTypeDimensions(image, sharp::ImageType::JPEG); + baton->channels = std::min(baton->channels, 3); + } + // Cast pixel values to float, if required + if (baton->tiffPredictor == VIPS_FOREIGN_TIFF_PREDICTOR_FLOAT) { + image = image.cast(VIPS_FORMAT_FLOAT); + } + image.tiffsave(const_cast(baton->fileOut.data()), VImage::option() + ->set("keep", baton->keepMetadata) + ->set("Q", baton->tiffQuality) + ->set("bitdepth", baton->tiffBitdepth) + ->set("compression", baton->tiffCompression) + ->set("miniswhite", baton->tiffMiniswhite) + ->set("predictor", baton->tiffPredictor) + ->set("pyramid", baton->tiffPyramid) + ->set("tile", baton->tiffTile) + ->set("tile_height", baton->tiffTileHeight) + ->set("tile_width", baton->tiffTileWidth) + ->set("xres", baton->tiffXres) + ->set("yres", baton->tiffYres) + ->set("resunit", baton->tiffResolutionUnit)); + baton->formatOut = "tiff"; + } else if (baton->formatOut == "heif" || (mightMatchInput && isHeif) || + (willMatchInput && inputImageType == sharp::ImageType::HEIF)) { + // Write HEIF to file + sharp::AssertImageTypeDimensions(image, sharp::ImageType::HEIF); + image = sharp::RemoveAnimationProperties(image); + image.heifsave(const_cast(baton->fileOut.data()), VImage::option() + ->set("keep", baton->keepMetadata) + ->set("Q", baton->heifQuality) + ->set("compression", baton->heifCompression) + ->set("effort", baton->heifEffort) + ->set("bitdepth", baton->heifBitdepth) + ->set("subsample_mode", baton->heifChromaSubsampling == "4:4:4" + ? VIPS_FOREIGN_SUBSAMPLE_OFF : VIPS_FOREIGN_SUBSAMPLE_ON) + ->set("lossless", baton->heifLossless)); + baton->formatOut = "heif"; + } else if (baton->formatOut == "jxl" || (mightMatchInput && isJxl) || + (willMatchInput && inputImageType == sharp::ImageType::JXL)) { + // Write JXL to file + image = sharp::RemoveAnimationProperties(image); + image.jxlsave(const_cast(baton->fileOut.data()), VImage::option() + ->set("keep", baton->keepMetadata) + ->set("distance", baton->jxlDistance) + ->set("tier", baton->jxlDecodingTier) + ->set("effort", baton->jxlEffort) + ->set("lossless", baton->jxlLossless)); + baton->formatOut = "jxl"; + } else if (baton->formatOut == "dz" || isDz || isDzZip) { + // Write DZ to file + if (isDzZip) { + baton->tileContainer = VIPS_FOREIGN_DZ_CONTAINER_ZIP; + } + if (!image.has_alpha()) { + baton->tileBackground.pop_back(); + } + image = sharp::StaySequential(image, baton->tileAngle != 0); + vips::VOption *options = BuildOptionsDZ(baton); + image.dzsave(const_cast(baton->fileOut.data()), options); + baton->formatOut = "dz"; + } else if (baton->formatOut == "v" || (mightMatchInput && isV) || + (willMatchInput && inputImageType == sharp::ImageType::VIPS)) { + // Write V to file + image.vipssave(const_cast(baton->fileOut.data()), VImage::option() + ->set("keep", baton->keepMetadata)); + baton->formatOut = "v"; + } else { + // Unsupported output format + (baton->err).append("Unsupported output format " + baton->fileOut); + return Error(); + } + } + } catch (vips::VError const &err) { + char const *what = err.what(); + if (what && what[0]) { + (baton->err).append(what); + } else { + (baton->err).append("Unknown error"); + } + } + // Clean up libvips' per-request data and threads + vips_error_clear(); + vips_thread_shutdown(); + } + + void OnOK() { + Napi::Env env = Env(); + Napi::HandleScope scope(env); + + // Handle warnings + std::string warning = sharp::VipsWarningPop(); + while (!warning.empty()) { + debuglog.Call(Receiver().Value(), { Napi::String::New(env, warning) }); + warning = sharp::VipsWarningPop(); + } + + if (baton->err.empty()) { + int width = baton->width; + int height = baton->height; + if (baton->topOffsetPre != -1 && (baton->width == -1 || baton->height == -1)) { + width = baton->widthPre; + height = baton->heightPre; + } + if (baton->topOffsetPost != -1) { + width = baton->widthPost; + height = baton->heightPost; + } + // Info Object + Napi::Object info = Napi::Object::New(env); + info.Set("format", baton->formatOut); + info.Set("width", static_cast(width)); + info.Set("height", static_cast(height)); + info.Set("channels", static_cast(baton->channels)); + if (baton->formatOut == "raw") { + info.Set("depth", vips_enum_nick(VIPS_TYPE_BAND_FORMAT, baton->rawDepth)); + } + info.Set("premultiplied", baton->premultiplied); + if (baton->hasCropOffset) { + info.Set("cropOffsetLeft", static_cast(baton->cropOffsetLeft)); + info.Set("cropOffsetTop", static_cast(baton->cropOffsetTop)); + } + if (baton->hasAttentionCenter) { + info.Set("attentionX", static_cast(baton->attentionX)); + info.Set("attentionY", static_cast(baton->attentionY)); + } + if (baton->trimThreshold >= 0.0) { + info.Set("trimOffsetLeft", static_cast(baton->trimOffsetLeft)); + info.Set("trimOffsetTop", static_cast(baton->trimOffsetTop)); + } + if (baton->input->textAutofitDpi) { + info.Set("textAutofitDpi", static_cast(baton->input->textAutofitDpi)); + } + if (baton->pageHeightOut) { + info.Set("pageHeight", static_cast(baton->pageHeightOut)); + info.Set("pages", static_cast(baton->pagesOut)); + } + + if (baton->bufferOutLength > 0) { + // Add buffer size to info + info.Set("size", static_cast(baton->bufferOutLength)); + // Pass ownership of output data to Buffer instance + Napi::Buffer data = Napi::Buffer::NewOrCopy(env, static_cast(baton->bufferOut), + baton->bufferOutLength, sharp::FreeCallback); + Callback().Call(Receiver().Value(), { env.Null(), data, info }); + } else { + // Add file size to info + if (baton->formatOut != "dz" || sharp::IsDzZip(baton->fileOut)) { + try { + uint32_t const size = static_cast( + std::filesystem::file_size(std::filesystem::u8path(baton->fileOut))); + info.Set("size", size); + } catch (...) {} + } + Callback().Call(Receiver().Value(), { env.Null(), info }); + } + } else { + Callback().Call(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() }); + } + + // Delete baton + delete baton->input; + delete baton->boolean; + for (Composite *composite : baton->composite) { + delete composite->input; + delete composite; + } + for (sharp::InputDescriptor *input : baton->joinChannelIn) { + delete input; + } + for (sharp::InputDescriptor *input : baton->join) { + delete input; + } + delete baton; + + // Decrement processing task counter + sharp::counterProcess--; + Napi::Number queueLength = Napi::Number::New(env, static_cast(sharp::counterQueue)); + queueListener.Call(Receiver().Value(), { queueLength }); + } + + private: + PipelineBaton *baton; + Napi::FunctionReference debuglog; + Napi::FunctionReference queueListener; + + void MultiPageUnsupported(int const pages, std::string op) { + if (pages > 1) { + throw vips::VError(op + " is not supported for multi-page images"); + } + } + + /* + Calculate the angle of rotation and need-to-flip for the given Exif orientation + By default, returns zero, i.e. no rotation. + */ + std::tuple + CalculateExifRotationAndFlop(int const exifOrientation) { + VipsAngle rotate = VIPS_ANGLE_D0; + bool flop = false; + switch (exifOrientation) { + case 6: rotate = VIPS_ANGLE_D90; break; + case 3: rotate = VIPS_ANGLE_D180; break; + case 8: rotate = VIPS_ANGLE_D270; break; + case 2: flop = true; break; + case 7: flop = true; rotate = VIPS_ANGLE_D270; break; + case 4: flop = true; rotate = VIPS_ANGLE_D180; break; + case 5: flop = true; rotate = VIPS_ANGLE_D90; break; + } + return std::make_tuple(rotate, flop); + } + + /* + Calculate the rotation for the given angle. + Supports any positive or negative angle that is a multiple of 90. + */ + VipsAngle + CalculateAngleRotation(int angle) { + angle = angle % 360; + if (angle < 0) + angle = 360 + angle; + switch (angle) { + case 90: return VIPS_ANGLE_D90; + case 180: return VIPS_ANGLE_D180; + case 270: return VIPS_ANGLE_D270; + } + return VIPS_ANGLE_D0; + } + + /* + Assemble the suffix argument to dzsave, which is the format (by extname) + alongside comma-separated arguments to the corresponding `formatsave` vips + action. + */ + std::string + AssembleSuffixString(std::string extname, std::vector> options) { + std::string argument; + for (auto const &option : options) { + if (!argument.empty()) { + argument += ","; + } + argument += option.first + "=" + option.second; + } + return extname + "[" + argument + "]"; + } + + /* + Build VOption for dzsave + */ + vips::VOption* + BuildOptionsDZ(PipelineBaton *baton) { + // Forward format options through suffix + std::string suffix; + if (baton->tileFormat == "png") { + std::vector> options { + {"interlace", baton->pngProgressive ? "true" : "false"}, + {"compression", std::to_string(baton->pngCompressionLevel)}, + {"filter", baton->pngAdaptiveFiltering ? "all" : "none"} + }; + suffix = AssembleSuffixString(".png", options); + } else if (baton->tileFormat == "webp") { + std::vector> options { + {"Q", std::to_string(baton->webpQuality)}, + {"alpha_q", std::to_string(baton->webpAlphaQuality)}, + {"lossless", baton->webpLossless ? "true" : "false"}, + {"near_lossless", baton->webpNearLossless ? "true" : "false"}, + {"smart_subsample", baton->webpSmartSubsample ? "true" : "false"}, + {"smart_deblock", baton->webpSmartDeblock ? "true" : "false"}, + {"preset", vips_enum_nick(VIPS_TYPE_FOREIGN_WEBP_PRESET, baton->webpPreset)}, + {"min_size", baton->webpMinSize ? "true" : "false"}, + {"mixed", baton->webpMixed ? "true" : "false"}, + {"effort", std::to_string(baton->webpEffort)} + }; + suffix = AssembleSuffixString(".webp", options); + } else { + std::vector> options { + {"Q", std::to_string(baton->jpegQuality)}, + {"interlace", baton->jpegProgressive ? "true" : "false"}, + {"subsample_mode", baton->jpegChromaSubsampling == "4:4:4" ? "off" : "on"}, + {"trellis_quant", baton->jpegTrellisQuantisation ? "true" : "false"}, + {"quant_table", std::to_string(baton->jpegQuantisationTable)}, + {"overshoot_deringing", baton->jpegOvershootDeringing ? "true": "false"}, + {"optimize_scans", baton->jpegOptimiseScans ? "true": "false"}, + {"optimize_coding", baton->jpegOptimiseCoding ? "true": "false"} + }; + std::string extname = baton->tileLayout == VIPS_FOREIGN_DZ_LAYOUT_DZ ? ".jpeg" : ".jpg"; + suffix = AssembleSuffixString(extname, options); + } + vips::VOption *options = VImage::option() + ->set("keep", baton->keepMetadata) + ->set("tile_size", baton->tileSize) + ->set("overlap", baton->tileOverlap) + ->set("container", baton->tileContainer) + ->set("layout", baton->tileLayout) + ->set("suffix", const_cast(suffix.data())) + ->set("angle", CalculateAngleRotation(baton->tileAngle)) + ->set("background", baton->tileBackground) + ->set("centre", baton->tileCentre) + ->set("id", const_cast(baton->tileId.data())) + ->set("skip_blanks", baton->tileSkipBlanks); + if (baton->tileDepth < VIPS_FOREIGN_DZ_DEPTH_LAST) { + options->set("depth", baton->tileDepth); + } + if (!baton->tileBasename.empty()) { + options->set("basename", const_cast(baton->tileBasename.data())); + } + return options; + } + + /* + Clear all thread-local data. + */ + void Error() { + // Clean up libvips' per-request data and threads + vips_error_clear(); + vips_thread_shutdown(); + } +}; + +/* + pipeline(options, output, callback) +*/ +Napi::Value pipeline(const Napi::CallbackInfo& info) { + // V8 objects are converted to non-V8 types held in the baton struct + PipelineBaton *baton = new PipelineBaton; + Napi::Object options = info[size_t(0)].As(); + + // Input + baton->input = sharp::CreateInputDescriptor(options.Get("input").As()); + // Join images together + if (sharp::HasAttr(options, "join")) { + Napi::Array join = options.Get("join").As(); + for (unsigned int i = 0; i < join.Length(); i++) { + baton->join.push_back( + sharp::CreateInputDescriptor(join.Get(i).As())); + } + } + // Extract image options + baton->topOffsetPre = sharp::AttrAsInt32(options, "topOffsetPre"); + baton->leftOffsetPre = sharp::AttrAsInt32(options, "leftOffsetPre"); + baton->widthPre = sharp::AttrAsInt32(options, "widthPre"); + baton->heightPre = sharp::AttrAsInt32(options, "heightPre"); + baton->topOffsetPost = sharp::AttrAsInt32(options, "topOffsetPost"); + baton->leftOffsetPost = sharp::AttrAsInt32(options, "leftOffsetPost"); + baton->widthPost = sharp::AttrAsInt32(options, "widthPost"); + baton->heightPost = sharp::AttrAsInt32(options, "heightPost"); + // Output image dimensions + baton->width = sharp::AttrAsInt32(options, "width"); + baton->height = sharp::AttrAsInt32(options, "height"); + // Canvas option + std::string canvas = sharp::AttrAsStr(options, "canvas"); + if (canvas == "crop") { + baton->canvas = sharp::Canvas::CROP; + } else if (canvas == "embed") { + baton->canvas = sharp::Canvas::EMBED; + } else if (canvas == "max") { + baton->canvas = sharp::Canvas::MAX; + } else if (canvas == "min") { + baton->canvas = sharp::Canvas::MIN; + } else if (canvas == "ignore_aspect") { + baton->canvas = sharp::Canvas::IGNORE_ASPECT; + } + // Composite + Napi::Array compositeArray = options.Get("composite").As(); + for (unsigned int i = 0; i < compositeArray.Length(); i++) { + Napi::Object compositeObject = compositeArray.Get(i).As(); + Composite *composite = new Composite; + composite->input = sharp::CreateInputDescriptor(compositeObject.Get("input").As()); + composite->mode = sharp::AttrAsEnum(compositeObject, "blend", VIPS_TYPE_BLEND_MODE); + composite->gravity = sharp::AttrAsUint32(compositeObject, "gravity"); + composite->left = sharp::AttrAsInt32(compositeObject, "left"); + composite->top = sharp::AttrAsInt32(compositeObject, "top"); + composite->hasOffset = sharp::AttrAsBool(compositeObject, "hasOffset"); + composite->tile = sharp::AttrAsBool(compositeObject, "tile"); + composite->premultiplied = sharp::AttrAsBool(compositeObject, "premultiplied"); + baton->composite.push_back(composite); + } + // Resize options + baton->withoutEnlargement = sharp::AttrAsBool(options, "withoutEnlargement"); + baton->withoutReduction = sharp::AttrAsBool(options, "withoutReduction"); + baton->position = sharp::AttrAsInt32(options, "position"); + baton->resizeBackground = sharp::AttrAsVectorOfDouble(options, "resizeBackground"); + baton->kernel = sharp::AttrAsEnum(options, "kernel", VIPS_TYPE_KERNEL); + baton->fastShrinkOnLoad = sharp::AttrAsBool(options, "fastShrinkOnLoad"); + // Join Channel Options + if (options.Has("joinChannelIn")) { + Napi::Array joinChannelArray = options.Get("joinChannelIn").As(); + for (unsigned int i = 0; i < joinChannelArray.Length(); i++) { + baton->joinChannelIn.push_back( + sharp::CreateInputDescriptor(joinChannelArray.Get(i).As())); + } + } + // Operators + baton->flatten = sharp::AttrAsBool(options, "flatten"); + baton->flattenBackground = sharp::AttrAsVectorOfDouble(options, "flattenBackground"); + baton->unflatten = sharp::AttrAsBool(options, "unflatten"); + baton->negate = sharp::AttrAsBool(options, "negate"); + baton->negateAlpha = sharp::AttrAsBool(options, "negateAlpha"); + baton->blurSigma = sharp::AttrAsDouble(options, "blurSigma"); + baton->precision = sharp::AttrAsEnum(options, "precision", VIPS_TYPE_PRECISION); + baton->minAmpl = sharp::AttrAsDouble(options, "minAmpl"); + baton->brightness = sharp::AttrAsDouble(options, "brightness"); + baton->saturation = sharp::AttrAsDouble(options, "saturation"); + baton->hue = sharp::AttrAsInt32(options, "hue"); + baton->lightness = sharp::AttrAsDouble(options, "lightness"); + baton->medianSize = sharp::AttrAsUint32(options, "medianSize"); + baton->sharpenSigma = sharp::AttrAsDouble(options, "sharpenSigma"); + baton->sharpenM1 = sharp::AttrAsDouble(options, "sharpenM1"); + baton->sharpenM2 = sharp::AttrAsDouble(options, "sharpenM2"); + baton->sharpenX1 = sharp::AttrAsDouble(options, "sharpenX1"); + baton->sharpenY2 = sharp::AttrAsDouble(options, "sharpenY2"); + baton->sharpenY3 = sharp::AttrAsDouble(options, "sharpenY3"); + baton->threshold = sharp::AttrAsInt32(options, "threshold"); + baton->thresholdGrayscale = sharp::AttrAsBool(options, "thresholdGrayscale"); + baton->trimBackground = sharp::AttrAsVectorOfDouble(options, "trimBackground"); + baton->trimThreshold = sharp::AttrAsDouble(options, "trimThreshold"); + baton->trimLineArt = sharp::AttrAsBool(options, "trimLineArt"); + baton->gamma = sharp::AttrAsDouble(options, "gamma"); + baton->gammaOut = sharp::AttrAsDouble(options, "gammaOut"); + baton->linearA = sharp::AttrAsVectorOfDouble(options, "linearA"); + baton->linearB = sharp::AttrAsVectorOfDouble(options, "linearB"); + baton->dilateWidth = sharp::AttrAsUint32(options, "dilateWidth"); + baton->erodeWidth = sharp::AttrAsUint32(options, "erodeWidth"); + baton->greyscale = sharp::AttrAsBool(options, "greyscale"); + baton->normalise = sharp::AttrAsBool(options, "normalise"); + baton->normaliseLower = sharp::AttrAsUint32(options, "normaliseLower"); + baton->normaliseUpper = sharp::AttrAsUint32(options, "normaliseUpper"); + baton->tint = sharp::AttrAsVectorOfDouble(options, "tint"); + baton->claheWidth = sharp::AttrAsUint32(options, "claheWidth"); + baton->claheHeight = sharp::AttrAsUint32(options, "claheHeight"); + baton->claheMaxSlope = sharp::AttrAsUint32(options, "claheMaxSlope"); + baton->angle = sharp::AttrAsInt32(options, "angle"); + baton->rotationAngle = sharp::AttrAsDouble(options, "rotationAngle"); + baton->rotationBackground = sharp::AttrAsVectorOfDouble(options, "rotationBackground"); + baton->rotateBefore = sharp::AttrAsBool(options, "rotateBefore"); + baton->orientBefore = sharp::AttrAsBool(options, "orientBefore"); + baton->flip = sharp::AttrAsBool(options, "flip"); + baton->flop = sharp::AttrAsBool(options, "flop"); + baton->extendTop = sharp::AttrAsInt32(options, "extendTop"); + baton->extendBottom = sharp::AttrAsInt32(options, "extendBottom"); + baton->extendLeft = sharp::AttrAsInt32(options, "extendLeft"); + baton->extendRight = sharp::AttrAsInt32(options, "extendRight"); + baton->extendBackground = sharp::AttrAsVectorOfDouble(options, "extendBackground"); + baton->extendWith = sharp::AttrAsEnum(options, "extendWith", VIPS_TYPE_EXTEND); + baton->extractChannel = sharp::AttrAsInt32(options, "extractChannel"); + baton->affineMatrix = sharp::AttrAsVectorOfDouble(options, "affineMatrix"); + baton->affineBackground = sharp::AttrAsVectorOfDouble(options, "affineBackground"); + baton->affineIdx = sharp::AttrAsDouble(options, "affineIdx"); + baton->affineIdy = sharp::AttrAsDouble(options, "affineIdy"); + baton->affineOdx = sharp::AttrAsDouble(options, "affineOdx"); + baton->affineOdy = sharp::AttrAsDouble(options, "affineOdy"); + baton->affineInterpolator = sharp::AttrAsStr(options, "affineInterpolator"); + baton->removeAlpha = sharp::AttrAsBool(options, "removeAlpha"); + baton->ensureAlpha = sharp::AttrAsDouble(options, "ensureAlpha"); + if (options.Has("boolean")) { + baton->boolean = sharp::CreateInputDescriptor(options.Get("boolean").As()); + baton->booleanOp = sharp::AttrAsEnum(options, "booleanOp", VIPS_TYPE_OPERATION_BOOLEAN); + } + if (options.Has("bandBoolOp")) { + baton->bandBoolOp = sharp::AttrAsEnum(options, "bandBoolOp", VIPS_TYPE_OPERATION_BOOLEAN); + } + if (options.Has("convKernel")) { + Napi::Object kernel = options.Get("convKernel").As(); + baton->convKernelWidth = sharp::AttrAsUint32(kernel, "width"); + baton->convKernelHeight = sharp::AttrAsUint32(kernel, "height"); + baton->convKernelScale = sharp::AttrAsDouble(kernel, "scale"); + baton->convKernelOffset = sharp::AttrAsDouble(kernel, "offset"); + size_t const kernelSize = static_cast(baton->convKernelWidth * baton->convKernelHeight); + baton->convKernel.resize(kernelSize); + Napi::Array kdata = kernel.Get("kernel").As(); + for (unsigned int i = 0; i < kernelSize; i++) { + baton->convKernel[i] = sharp::AttrAsDouble(kdata, i); + } + } + if (options.Has("recombMatrix")) { + Napi::Array recombMatrix = options.Get("recombMatrix").As(); + unsigned int matrixElements = recombMatrix.Length(); + baton->recombMatrix.resize(matrixElements); + for (unsigned int i = 0; i < matrixElements; i++) { + baton->recombMatrix[i] = sharp::AttrAsDouble(recombMatrix, i); + } + } + baton->colourspacePipeline = sharp::AttrAsEnum( + options, "colourspacePipeline", VIPS_TYPE_INTERPRETATION); + if (baton->colourspacePipeline == VIPS_INTERPRETATION_ERROR) { + baton->colourspacePipeline = VIPS_INTERPRETATION_LAST; + } + baton->colourspace = sharp::AttrAsEnum(options, "colourspace", VIPS_TYPE_INTERPRETATION); + if (baton->colourspace == VIPS_INTERPRETATION_ERROR) { + baton->colourspace = VIPS_INTERPRETATION_sRGB; + } + // Output + baton->formatOut = sharp::AttrAsStr(options, "formatOut"); + baton->fileOut = sharp::AttrAsStr(options, "fileOut"); + baton->keepMetadata = sharp::AttrAsUint32(options, "keepMetadata"); + baton->withMetadataOrientation = sharp::AttrAsUint32(options, "withMetadataOrientation"); + baton->withMetadataDensity = sharp::AttrAsDouble(options, "withMetadataDensity"); + baton->withIccProfile = sharp::AttrAsStr(options, "withIccProfile"); + Napi::Object withExif = options.Get("withExif").As(); + Napi::Array withExifKeys = withExif.GetPropertyNames(); + for (unsigned int i = 0; i < withExifKeys.Length(); i++) { + std::string k = sharp::AttrAsStr(withExifKeys, i); + if (withExif.HasOwnProperty(k)) { + baton->withExif.insert(std::make_pair(k, sharp::AttrAsStr(withExif, k))); + } + } + baton->withExifMerge = sharp::AttrAsBool(options, "withExifMerge"); + baton->withXmp = sharp::AttrAsStr(options, "withXmp"); + baton->timeoutSeconds = sharp::AttrAsUint32(options, "timeoutSeconds"); + baton->loop = sharp::AttrAsUint32(options, "loop"); + baton->delay = sharp::AttrAsInt32Vector(options, "delay"); + // Format-specific + baton->jpegQuality = sharp::AttrAsUint32(options, "jpegQuality"); + baton->jpegProgressive = sharp::AttrAsBool(options, "jpegProgressive"); + baton->jpegChromaSubsampling = sharp::AttrAsStr(options, "jpegChromaSubsampling"); + baton->jpegTrellisQuantisation = sharp::AttrAsBool(options, "jpegTrellisQuantisation"); + baton->jpegQuantisationTable = sharp::AttrAsUint32(options, "jpegQuantisationTable"); + baton->jpegOvershootDeringing = sharp::AttrAsBool(options, "jpegOvershootDeringing"); + baton->jpegOptimiseScans = sharp::AttrAsBool(options, "jpegOptimiseScans"); + baton->jpegOptimiseCoding = sharp::AttrAsBool(options, "jpegOptimiseCoding"); + baton->pngProgressive = sharp::AttrAsBool(options, "pngProgressive"); + baton->pngCompressionLevel = sharp::AttrAsUint32(options, "pngCompressionLevel"); + baton->pngAdaptiveFiltering = sharp::AttrAsBool(options, "pngAdaptiveFiltering"); + baton->pngPalette = sharp::AttrAsBool(options, "pngPalette"); + baton->pngQuality = sharp::AttrAsUint32(options, "pngQuality"); + baton->pngEffort = sharp::AttrAsUint32(options, "pngEffort"); + baton->pngBitdepth = sharp::AttrAsUint32(options, "pngBitdepth"); + baton->pngDither = sharp::AttrAsDouble(options, "pngDither"); + baton->jp2Quality = sharp::AttrAsUint32(options, "jp2Quality"); + baton->jp2Lossless = sharp::AttrAsBool(options, "jp2Lossless"); + baton->jp2TileHeight = sharp::AttrAsUint32(options, "jp2TileHeight"); + baton->jp2TileWidth = sharp::AttrAsUint32(options, "jp2TileWidth"); + baton->jp2ChromaSubsampling = sharp::AttrAsStr(options, "jp2ChromaSubsampling"); + baton->webpQuality = sharp::AttrAsUint32(options, "webpQuality"); + baton->webpAlphaQuality = sharp::AttrAsUint32(options, "webpAlphaQuality"); + baton->webpLossless = sharp::AttrAsBool(options, "webpLossless"); + baton->webpNearLossless = sharp::AttrAsBool(options, "webpNearLossless"); + baton->webpSmartSubsample = sharp::AttrAsBool(options, "webpSmartSubsample"); + baton->webpSmartDeblock = sharp::AttrAsBool(options, "webpSmartDeblock"); + baton->webpPreset = sharp::AttrAsEnum(options, "webpPreset", VIPS_TYPE_FOREIGN_WEBP_PRESET); + baton->webpEffort = sharp::AttrAsUint32(options, "webpEffort"); + baton->webpMinSize = sharp::AttrAsBool(options, "webpMinSize"); + baton->webpMixed = sharp::AttrAsBool(options, "webpMixed"); + baton->gifBitdepth = sharp::AttrAsUint32(options, "gifBitdepth"); + baton->gifEffort = sharp::AttrAsUint32(options, "gifEffort"); + baton->gifDither = sharp::AttrAsDouble(options, "gifDither"); + baton->gifInterFrameMaxError = sharp::AttrAsDouble(options, "gifInterFrameMaxError"); + baton->gifInterPaletteMaxError = sharp::AttrAsDouble(options, "gifInterPaletteMaxError"); + baton->gifKeepDuplicateFrames = sharp::AttrAsBool(options, "gifKeepDuplicateFrames"); + baton->gifReuse = sharp::AttrAsBool(options, "gifReuse"); + baton->gifProgressive = sharp::AttrAsBool(options, "gifProgressive"); + baton->tiffQuality = sharp::AttrAsUint32(options, "tiffQuality"); + baton->tiffPyramid = sharp::AttrAsBool(options, "tiffPyramid"); + baton->tiffMiniswhite = sharp::AttrAsBool(options, "tiffMiniswhite"); + baton->tiffBitdepth = sharp::AttrAsUint32(options, "tiffBitdepth"); + baton->tiffTile = sharp::AttrAsBool(options, "tiffTile"); + baton->tiffTileWidth = sharp::AttrAsUint32(options, "tiffTileWidth"); + baton->tiffTileHeight = sharp::AttrAsUint32(options, "tiffTileHeight"); + baton->tiffXres = sharp::AttrAsDouble(options, "tiffXres"); + baton->tiffYres = sharp::AttrAsDouble(options, "tiffYres"); + if (baton->tiffXres == 1.0 && baton->tiffYres == 1.0 && baton->withMetadataDensity > 0) { + baton->tiffXres = baton->tiffYres = baton->withMetadataDensity / 25.4; + } + baton->tiffCompression = sharp::AttrAsEnum( + options, "tiffCompression", VIPS_TYPE_FOREIGN_TIFF_COMPRESSION); + baton->tiffPredictor = sharp::AttrAsEnum( + options, "tiffPredictor", VIPS_TYPE_FOREIGN_TIFF_PREDICTOR); + baton->tiffResolutionUnit = sharp::AttrAsEnum( + options, "tiffResolutionUnit", VIPS_TYPE_FOREIGN_TIFF_RESUNIT); + baton->heifQuality = sharp::AttrAsUint32(options, "heifQuality"); + baton->heifLossless = sharp::AttrAsBool(options, "heifLossless"); + baton->heifCompression = sharp::AttrAsEnum( + options, "heifCompression", VIPS_TYPE_FOREIGN_HEIF_COMPRESSION); + baton->heifEffort = sharp::AttrAsUint32(options, "heifEffort"); + baton->heifChromaSubsampling = sharp::AttrAsStr(options, "heifChromaSubsampling"); + baton->heifBitdepth = sharp::AttrAsUint32(options, "heifBitdepth"); + baton->jxlDistance = sharp::AttrAsDouble(options, "jxlDistance"); + baton->jxlDecodingTier = sharp::AttrAsUint32(options, "jxlDecodingTier"); + baton->jxlEffort = sharp::AttrAsUint32(options, "jxlEffort"); + baton->jxlLossless = sharp::AttrAsBool(options, "jxlLossless"); + baton->rawDepth = sharp::AttrAsEnum(options, "rawDepth", VIPS_TYPE_BAND_FORMAT); + baton->tileSize = sharp::AttrAsUint32(options, "tileSize"); + baton->tileOverlap = sharp::AttrAsUint32(options, "tileOverlap"); + baton->tileAngle = sharp::AttrAsInt32(options, "tileAngle"); + baton->tileBackground = sharp::AttrAsVectorOfDouble(options, "tileBackground"); + baton->tileSkipBlanks = sharp::AttrAsInt32(options, "tileSkipBlanks"); + baton->tileContainer = sharp::AttrAsEnum( + options, "tileContainer", VIPS_TYPE_FOREIGN_DZ_CONTAINER); + baton->tileLayout = sharp::AttrAsEnum(options, "tileLayout", VIPS_TYPE_FOREIGN_DZ_LAYOUT); + baton->tileFormat = sharp::AttrAsStr(options, "tileFormat"); + baton->tileDepth = sharp::AttrAsEnum(options, "tileDepth", VIPS_TYPE_FOREIGN_DZ_DEPTH); + baton->tileCentre = sharp::AttrAsBool(options, "tileCentre"); + baton->tileId = sharp::AttrAsStr(options, "tileId"); + baton->tileBasename = sharp::AttrAsStr(options, "tileBasename"); + + // Function to notify of libvips warnings + Napi::Function debuglog = options.Get("debuglog").As(); + + // Function to notify of queue length changes + Napi::Function queueListener = options.Get("queueListener").As(); + + // Join queue for worker thread + Napi::Function callback = info[size_t(1)].As(); + PipelineWorker *worker = new PipelineWorker(callback, baton, debuglog, queueListener); + worker->Receiver().Set("options", options); + worker->Queue(); + + // Increment queued task counter + Napi::Number queueLength = Napi::Number::New(info.Env(), static_cast(++sharp::counterQueue)); + queueListener.Call(info.This(), { queueLength }); + + return info.Env().Undefined(); +} diff --git a/node_modules/sharp/src/pipeline.h b/node_modules/sharp/src/pipeline.h new file mode 100644 index 0000000..8edfff5 --- /dev/null +++ b/node_modules/sharp/src/pipeline.h @@ -0,0 +1,402 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +#ifndef SRC_PIPELINE_H_ +#define SRC_PIPELINE_H_ + +#include +#include +#include +#include + +#include +#include + +#include "./common.h" + +Napi::Value pipeline(const Napi::CallbackInfo& info); + +struct Composite { + sharp::InputDescriptor *input; + VipsBlendMode mode; + int gravity; + int left; + int top; + bool hasOffset; + bool tile; + bool premultiplied; + + Composite(): + input(nullptr), + mode(VIPS_BLEND_MODE_OVER), + gravity(0), + left(0), + top(0), + hasOffset(false), + tile(false), + premultiplied(false) {} +}; + +struct PipelineBaton { + sharp::InputDescriptor *input; + std::vector join; + std::string formatOut; + std::string fileOut; + void *bufferOut; + size_t bufferOutLength; + int pageHeightOut; + int pagesOut; + std::vector composite; + std::vector joinChannelIn; + int topOffsetPre; + int leftOffsetPre; + int widthPre; + int heightPre; + int topOffsetPost; + int leftOffsetPost; + int widthPost; + int heightPost; + int width; + int height; + int channels; + VipsKernel kernel; + sharp::Canvas canvas; + int position; + std::vector resizeBackground; + bool hasCropOffset; + int cropOffsetLeft; + int cropOffsetTop; + bool hasAttentionCenter; + int attentionX; + int attentionY; + bool premultiplied; + bool tileCentre; + bool fastShrinkOnLoad; + std::vector tint; + bool flatten; + std::vector flattenBackground; + bool unflatten; + bool negate; + bool negateAlpha; + double blurSigma; + VipsPrecision precision; + double minAmpl; + double brightness; + double saturation; + int hue; + double lightness; + int medianSize; + double sharpenSigma; + double sharpenM1; + double sharpenM2; + double sharpenX1; + double sharpenY2; + double sharpenY3; + int threshold; + bool thresholdGrayscale; + std::vector trimBackground; + double trimThreshold; + bool trimLineArt; + int trimOffsetLeft; + int trimOffsetTop; + std::vector linearA; + std::vector linearB; + int dilateWidth; + int erodeWidth; + double gamma; + double gammaOut; + bool greyscale; + bool normalise; + int normaliseLower; + int normaliseUpper; + int claheWidth; + int claheHeight; + int claheMaxSlope; + int angle; + double rotationAngle; + std::vector rotationBackground; + bool rotateBefore; + bool orientBefore; + bool flip; + bool flop; + int extendTop; + int extendBottom; + int extendLeft; + int extendRight; + std::vector extendBackground; + VipsExtend extendWith; + bool withoutEnlargement; + bool withoutReduction; + std::vector affineMatrix; + std::vector affineBackground; + double affineIdx; + double affineIdy; + double affineOdx; + double affineOdy; + std::string affineInterpolator; + int jpegQuality; + bool jpegProgressive; + std::string jpegChromaSubsampling; + bool jpegTrellisQuantisation; + int jpegQuantisationTable; + bool jpegOvershootDeringing; + bool jpegOptimiseScans; + bool jpegOptimiseCoding; + bool pngProgressive; + int pngCompressionLevel; + bool pngAdaptiveFiltering; + bool pngPalette; + int pngQuality; + int pngEffort; + int pngBitdepth; + double pngDither; + int jp2Quality; + bool jp2Lossless; + int jp2TileHeight; + int jp2TileWidth; + std::string jp2ChromaSubsampling; + int webpQuality; + int webpAlphaQuality; + bool webpNearLossless; + bool webpLossless; + bool webpSmartSubsample; + bool webpSmartDeblock; + VipsForeignWebpPreset webpPreset; + int webpEffort; + bool webpMinSize; + bool webpMixed; + int gifBitdepth; + int gifEffort; + double gifDither; + double gifInterFrameMaxError; + double gifInterPaletteMaxError; + bool gifKeepDuplicateFrames; + bool gifReuse; + bool gifProgressive; + int tiffQuality; + VipsForeignTiffCompression tiffCompression; + VipsForeignTiffPredictor tiffPredictor; + bool tiffPyramid; + int tiffBitdepth; + bool tiffMiniswhite; + bool tiffTile; + int tiffTileHeight; + int tiffTileWidth; + double tiffXres; + double tiffYres; + VipsForeignTiffResunit tiffResolutionUnit; + int heifQuality; + VipsForeignHeifCompression heifCompression; + int heifEffort; + std::string heifChromaSubsampling; + bool heifLossless; + int heifBitdepth; + double jxlDistance; + int jxlDecodingTier; + int jxlEffort; + bool jxlLossless; + VipsBandFormat rawDepth; + std::string err; + int keepMetadata; + int withMetadataOrientation; + double withMetadataDensity; + std::string withIccProfile; + std::unordered_map withExif; + bool withExifMerge; + std::string withXmp; + int timeoutSeconds; + std::vector convKernel; + int convKernelWidth; + int convKernelHeight; + double convKernelScale; + double convKernelOffset; + sharp::InputDescriptor *boolean; + VipsOperationBoolean booleanOp; + VipsOperationBoolean bandBoolOp; + int extractChannel; + bool removeAlpha; + double ensureAlpha; + VipsInterpretation colourspacePipeline; + VipsInterpretation colourspace; + std::vector delay; + int loop; + int tileSize; + int tileOverlap; + VipsForeignDzContainer tileContainer; + VipsForeignDzLayout tileLayout; + std::string tileFormat; + int tileAngle; + std::vector tileBackground; + int tileSkipBlanks; + VipsForeignDzDepth tileDepth; + std::string tileId; + std::string tileBasename; + std::vector recombMatrix; + + PipelineBaton(): + input(nullptr), + bufferOutLength(0), + pageHeightOut(0), + pagesOut(0), + topOffsetPre(-1), + topOffsetPost(-1), + channels(0), + kernel(VIPS_KERNEL_LANCZOS3), + canvas(sharp::Canvas::CROP), + position(0), + resizeBackground{ 0.0, 0.0, 0.0, 255.0 }, + hasCropOffset(false), + cropOffsetLeft(0), + cropOffsetTop(0), + hasAttentionCenter(false), + attentionX(0), + attentionY(0), + premultiplied(false), + tint{ -1.0, 0.0, 0.0, 0.0 }, + flatten(false), + flattenBackground{ 0.0, 0.0, 0.0 }, + unflatten(false), + negate(false), + negateAlpha(true), + blurSigma(0.0), + brightness(1.0), + saturation(1.0), + hue(0), + lightness(0), + medianSize(0), + sharpenSigma(0.0), + sharpenM1(1.0), + sharpenM2(2.0), + sharpenX1(2.0), + sharpenY2(10.0), + sharpenY3(20.0), + threshold(0), + thresholdGrayscale(true), + trimBackground{}, + trimThreshold(-1.0), + trimLineArt(false), + trimOffsetLeft(0), + trimOffsetTop(0), + linearA{}, + linearB{}, + dilateWidth(0), + erodeWidth(0), + gamma(0.0), + greyscale(false), + normalise(false), + normaliseLower(1), + normaliseUpper(99), + claheWidth(0), + claheHeight(0), + claheMaxSlope(3), + angle(0), + rotationAngle(0.0), + rotationBackground{ 0.0, 0.0, 0.0, 255.0 }, + flip(false), + flop(false), + extendTop(0), + extendBottom(0), + extendLeft(0), + extendRight(0), + extendBackground{ 0.0, 0.0, 0.0, 255.0 }, + extendWith(VIPS_EXTEND_BACKGROUND), + withoutEnlargement(false), + withoutReduction(false), + affineMatrix{ 1.0, 0.0, 0.0, 1.0 }, + affineBackground{ 0.0, 0.0, 0.0, 255.0 }, + affineIdx(0), + affineIdy(0), + affineOdx(0), + affineOdy(0), + affineInterpolator("bicubic"), + jpegQuality(80), + jpegProgressive(false), + jpegChromaSubsampling("4:2:0"), + jpegTrellisQuantisation(false), + jpegQuantisationTable(0), + jpegOvershootDeringing(false), + jpegOptimiseScans(false), + jpegOptimiseCoding(true), + pngProgressive(false), + pngCompressionLevel(6), + pngAdaptiveFiltering(false), + pngPalette(false), + pngQuality(100), + pngEffort(7), + pngBitdepth(8), + pngDither(1.0), + jp2Quality(80), + jp2Lossless(false), + jp2TileHeight(512), + jp2TileWidth(512), + jp2ChromaSubsampling("4:4:4"), + webpQuality(80), + webpAlphaQuality(100), + webpNearLossless(false), + webpLossless(false), + webpSmartSubsample(false), + webpSmartDeblock(false), + webpPreset(VIPS_FOREIGN_WEBP_PRESET_DEFAULT), + webpEffort(4), + webpMinSize(false), + webpMixed(false), + gifBitdepth(8), + gifEffort(7), + gifDither(1.0), + gifInterFrameMaxError(0.0), + gifInterPaletteMaxError(3.0), + gifKeepDuplicateFrames(false), + gifReuse(true), + gifProgressive(false), + tiffQuality(80), + tiffCompression(VIPS_FOREIGN_TIFF_COMPRESSION_JPEG), + tiffPredictor(VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL), + tiffPyramid(false), + tiffBitdepth(8), + tiffMiniswhite(false), + tiffTile(false), + tiffTileHeight(256), + tiffTileWidth(256), + tiffXres(1.0), + tiffYres(1.0), + tiffResolutionUnit(VIPS_FOREIGN_TIFF_RESUNIT_INCH), + heifQuality(50), + heifCompression(VIPS_FOREIGN_HEIF_COMPRESSION_AV1), + heifEffort(4), + heifChromaSubsampling("4:4:4"), + heifLossless(false), + heifBitdepth(8), + jxlDistance(1.0), + jxlDecodingTier(0), + jxlEffort(7), + jxlLossless(false), + rawDepth(VIPS_FORMAT_UCHAR), + keepMetadata(0), + withMetadataOrientation(-1), + withMetadataDensity(0.0), + withExifMerge(true), + timeoutSeconds(0), + convKernelWidth(0), + convKernelHeight(0), + convKernelScale(0.0), + convKernelOffset(0.0), + boolean(nullptr), + booleanOp(VIPS_OPERATION_BOOLEAN_LAST), + bandBoolOp(VIPS_OPERATION_BOOLEAN_LAST), + extractChannel(-1), + removeAlpha(false), + ensureAlpha(-1.0), + colourspacePipeline(VIPS_INTERPRETATION_LAST), + colourspace(VIPS_INTERPRETATION_LAST), + loop(-1), + tileSize(256), + tileOverlap(0), + tileContainer(VIPS_FOREIGN_DZ_CONTAINER_FS), + tileLayout(VIPS_FOREIGN_DZ_LAYOUT_DZ), + tileAngle(0), + tileBackground{ 255.0, 255.0, 255.0, 255.0 }, + tileSkipBlanks(-1), + tileDepth(VIPS_FOREIGN_DZ_DEPTH_LAST) {} +}; + +#endif // SRC_PIPELINE_H_ diff --git a/node_modules/sharp/src/sharp.cc b/node_modules/sharp/src/sharp.cc new file mode 100644 index 0000000..ed54c50 --- /dev/null +++ b/node_modules/sharp/src/sharp.cc @@ -0,0 +1,41 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +#include // NOLINT(build/c++11) + +#include +#include + +#include "common.h" +#include "metadata.h" +#include "pipeline.h" +#include "utilities.h" +#include "stats.h" + +Napi::Object init(Napi::Env env, Napi::Object exports) { + static std::once_flag sharp_vips_init_once; + std::call_once(sharp_vips_init_once, []() { + vips_init("sharp"); + }); + + g_log_set_handler("VIPS", static_cast(G_LOG_LEVEL_WARNING), + static_cast(sharp::VipsWarningCallback), nullptr); + + // Methods available to JavaScript + exports.Set("metadata", Napi::Function::New(env, metadata)); + exports.Set("pipeline", Napi::Function::New(env, pipeline)); + exports.Set("cache", Napi::Function::New(env, cache)); + exports.Set("concurrency", Napi::Function::New(env, concurrency)); + exports.Set("counters", Napi::Function::New(env, counters)); + exports.Set("simd", Napi::Function::New(env, simd)); + exports.Set("libvipsVersion", Napi::Function::New(env, libvipsVersion)); + exports.Set("format", Napi::Function::New(env, format)); + exports.Set("block", Napi::Function::New(env, block)); + exports.Set("_maxColourDistance", Napi::Function::New(env, _maxColourDistance)); + exports.Set("_isUsingJemalloc", Napi::Function::New(env, _isUsingJemalloc)); + exports.Set("_isUsingX64V2", Napi::Function::New(env, _isUsingX64V2)); + exports.Set("stats", Napi::Function::New(env, stats)); + return exports; +} + +NODE_API_MODULE(sharp, init) diff --git a/node_modules/sharp/src/stats.cc b/node_modules/sharp/src/stats.cc new file mode 100644 index 0000000..bc9b243 --- /dev/null +++ b/node_modules/sharp/src/stats.cc @@ -0,0 +1,183 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include + +#include +#include + +#include "common.h" +#include "stats.h" + +class StatsWorker : public Napi::AsyncWorker { + public: + StatsWorker(Napi::Function callback, StatsBaton *baton, Napi::Function debuglog) : + Napi::AsyncWorker(callback), baton(baton), debuglog(Napi::Persistent(debuglog)) {} + ~StatsWorker() {} + + const int STAT_MIN_INDEX = 0; + const int STAT_MAX_INDEX = 1; + const int STAT_SUM_INDEX = 2; + const int STAT_SQ_SUM_INDEX = 3; + const int STAT_MEAN_INDEX = 4; + const int STAT_STDEV_INDEX = 5; + const int STAT_MINX_INDEX = 6; + const int STAT_MINY_INDEX = 7; + const int STAT_MAXX_INDEX = 8; + const int STAT_MAXY_INDEX = 9; + + void Execute() { + // Decrement queued task counter + sharp::counterQueue--; + + vips::VImage image; + sharp::ImageType imageType = sharp::ImageType::UNKNOWN; + try { + std::tie(image, imageType) = OpenInput(baton->input); + } catch (vips::VError const &err) { + (baton->err).append(err.what()); + } + if (imageType != sharp::ImageType::UNKNOWN) { + try { + vips::VImage stats = image.stats(); + int const bands = image.bands(); + for (int b = 1; b <= bands; b++) { + ChannelStats cStats( + static_cast(stats.getpoint(STAT_MIN_INDEX, b).front()), + static_cast(stats.getpoint(STAT_MAX_INDEX, b).front()), + stats.getpoint(STAT_SUM_INDEX, b).front(), + stats.getpoint(STAT_SQ_SUM_INDEX, b).front(), + stats.getpoint(STAT_MEAN_INDEX, b).front(), + stats.getpoint(STAT_STDEV_INDEX, b).front(), + static_cast(stats.getpoint(STAT_MINX_INDEX, b).front()), + static_cast(stats.getpoint(STAT_MINY_INDEX, b).front()), + static_cast(stats.getpoint(STAT_MAXX_INDEX, b).front()), + static_cast(stats.getpoint(STAT_MAXY_INDEX, b).front())); + baton->channelStats.push_back(cStats); + } + // Image is not opaque when alpha layer is present and contains a non-mamixa value + if (image.has_alpha()) { + double const minAlpha = static_cast(stats.getpoint(STAT_MIN_INDEX, bands).front()); + if (minAlpha != vips_interpretation_max_alpha(image.interpretation())) { + baton->isOpaque = false; + } + } + // Convert to greyscale + vips::VImage greyscale = image.colourspace(VIPS_INTERPRETATION_B_W)[0]; + // Estimate entropy via histogram of greyscale value frequency + baton->entropy = std::abs(greyscale.hist_find().hist_entropy()); + // Estimate sharpness via standard deviation of greyscale laplacian + if (image.width() > 1 || image.height() > 1) { + VImage laplacian = VImage::new_matrixv(3, 3, + 0.0, 1.0, 0.0, + 1.0, -4.0, 1.0, + 0.0, 1.0, 0.0); + laplacian.set("scale", 9.0); + baton->sharpness = greyscale.conv(laplacian).deviate(); + } + // Most dominant sRGB colour via 4096-bin 3D histogram + vips::VImage hist = sharp::RemoveAlpha(image) + .colourspace(VIPS_INTERPRETATION_sRGB) + .hist_find_ndim(VImage::option()->set("bins", 16)); + std::complex maxpos = hist.maxpos(); + int const dx = static_cast(std::real(maxpos)); + int const dy = static_cast(std::imag(maxpos)); + std::vector pel = hist(dx, dy); + int const dz = std::distance(pel.begin(), std::find(pel.begin(), pel.end(), hist.max())); + baton->dominantRed = dx * 16 + 8; + baton->dominantGreen = dy * 16 + 8; + baton->dominantBlue = dz * 16 + 8; + } catch (vips::VError const &err) { + (baton->err).append(err.what()); + } + } + + // Clean up + vips_error_clear(); + vips_thread_shutdown(); + } + + void OnOK() { + Napi::Env env = Env(); + Napi::HandleScope scope(env); + + // Handle warnings + std::string warning = sharp::VipsWarningPop(); + while (!warning.empty()) { + debuglog.Call(Receiver().Value(), { Napi::String::New(env, warning) }); + warning = sharp::VipsWarningPop(); + } + + if (baton->err.empty()) { + // Stats Object + Napi::Object info = Napi::Object::New(env); + Napi::Array channels = Napi::Array::New(env); + + std::vector::iterator it; + int i = 0; + for (it = baton->channelStats.begin(); it < baton->channelStats.end(); it++, i++) { + Napi::Object channelStat = Napi::Object::New(env); + channelStat.Set("min", it->min); + channelStat.Set("max", it->max); + channelStat.Set("sum", it->sum); + channelStat.Set("squaresSum", it->squaresSum); + channelStat.Set("mean", it->mean); + channelStat.Set("stdev", it->stdev); + channelStat.Set("minX", it->minX); + channelStat.Set("minY", it->minY); + channelStat.Set("maxX", it->maxX); + channelStat.Set("maxY", it->maxY); + channels.Set(i, channelStat); + } + + info.Set("channels", channels); + info.Set("isOpaque", baton->isOpaque); + info.Set("entropy", baton->entropy); + info.Set("sharpness", baton->sharpness); + Napi::Object dominant = Napi::Object::New(env); + dominant.Set("r", baton->dominantRed); + dominant.Set("g", baton->dominantGreen); + dominant.Set("b", baton->dominantBlue); + info.Set("dominant", dominant); + Callback().Call(Receiver().Value(), { env.Null(), info }); + } else { + Callback().Call(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() }); + } + + delete baton->input; + delete baton; + } + + private: + StatsBaton* baton; + Napi::FunctionReference debuglog; +}; + +/* + stats(options, callback) +*/ +Napi::Value stats(const Napi::CallbackInfo& info) { + // V8 objects are converted to non-V8 types held in the baton struct + StatsBaton *baton = new StatsBaton; + Napi::Object options = info[size_t(0)].As(); + + // Input + baton->input = sharp::CreateInputDescriptor(options.Get("input").As()); + baton->input->access = VIPS_ACCESS_RANDOM; + + // Function to notify of libvips warnings + Napi::Function debuglog = options.Get("debuglog").As(); + + // Join queue for worker thread + Napi::Function callback = info[size_t(1)].As(); + StatsWorker *worker = new StatsWorker(callback, baton, debuglog); + worker->Receiver().Set("options", options); + worker->Queue(); + + // Increment queued task counter + sharp::counterQueue++; + + return info.Env().Undefined(); +} diff --git a/node_modules/sharp/src/stats.h b/node_modules/sharp/src/stats.h new file mode 100644 index 0000000..c80e65f --- /dev/null +++ b/node_modules/sharp/src/stats.h @@ -0,0 +1,59 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +#ifndef SRC_STATS_H_ +#define SRC_STATS_H_ + +#include +#include + +#include "./common.h" + +struct ChannelStats { + // stats per channel + int min; + int max; + double sum; + double squaresSum; + double mean; + double stdev; + int minX; + int minY; + int maxX; + int maxY; + + ChannelStats(int minVal, int maxVal, double sumVal, double squaresSumVal, + double meanVal, double stdevVal, int minXVal, int minYVal, int maxXVal, int maxYVal): + min(minVal), max(maxVal), sum(sumVal), squaresSum(squaresSumVal), + mean(meanVal), stdev(stdevVal), minX(minXVal), minY(minYVal), maxX(maxXVal), maxY(maxYVal) {} +}; + +struct StatsBaton { + // Input + sharp::InputDescriptor *input; + + // Output + std::vector channelStats; + bool isOpaque; + double entropy; + double sharpness; + int dominantRed; + int dominantGreen; + int dominantBlue; + + std::string err; + + StatsBaton(): + input(nullptr), + isOpaque(true), + entropy(0.0), + sharpness(0.0), + dominantRed(0), + dominantGreen(0), + dominantBlue(0) + {} +}; + +Napi::Value stats(const Napi::CallbackInfo& info); + +#endif // SRC_STATS_H_ diff --git a/node_modules/sharp/src/utilities.cc b/node_modules/sharp/src/utilities.cc new file mode 100644 index 0000000..1f78cdd --- /dev/null +++ b/node_modules/sharp/src/utilities.cc @@ -0,0 +1,286 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include + +#include +#include +#include + +#include "common.h" +#include "operations.h" +#include "utilities.h" + +/* + Get and set cache limits +*/ +Napi::Value cache(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + + // Set memory limit + if (info[size_t(0)].IsNumber()) { + vips_cache_set_max_mem(info[size_t(0)].As().Int32Value() * 1048576); + } + // Set file limit + if (info[size_t(1)].IsNumber()) { + vips_cache_set_max_files(info[size_t(1)].As().Int32Value()); + } + // Set items limit + if (info[size_t(2)].IsNumber()) { + vips_cache_set_max(info[size_t(2)].As().Int32Value()); + } + + // Get memory stats + Napi::Object memory = Napi::Object::New(env); + memory.Set("current", round(vips_tracked_get_mem() / 1048576)); + memory.Set("high", round(vips_tracked_get_mem_highwater() / 1048576)); + memory.Set("max", round(vips_cache_get_max_mem() / 1048576)); + // Get file stats + Napi::Object files = Napi::Object::New(env); + files.Set("current", vips_tracked_get_files()); + files.Set("max", vips_cache_get_max_files()); + + // Get item stats + Napi::Object items = Napi::Object::New(env); + items.Set("current", vips_cache_get_size()); + items.Set("max", vips_cache_get_max()); + + Napi::Object cache = Napi::Object::New(env); + cache.Set("memory", memory); + cache.Set("files", files); + cache.Set("items", items); + return cache; +} + +/* + Get and set size of thread pool +*/ +Napi::Value concurrency(const Napi::CallbackInfo& info) { + // Set concurrency + if (info[size_t(0)].IsNumber()) { + vips_concurrency_set(info[size_t(0)].As().Int32Value()); + } + // Get concurrency + return Napi::Number::New(info.Env(), vips_concurrency_get()); +} + +/* + Get internal counters (queued tasks, processing tasks) +*/ +Napi::Value counters(const Napi::CallbackInfo& info) { + Napi::Object counters = Napi::Object::New(info.Env()); + counters.Set("queue", static_cast(sharp::counterQueue)); + counters.Set("process", static_cast(sharp::counterProcess)); + return counters; +} + +/* + Get and set use of SIMD vector unit instructions +*/ +Napi::Value simd(const Napi::CallbackInfo& info) { + // Set state + if (info[size_t(0)].IsBoolean()) { + vips_vector_set_enabled(info[size_t(0)].As().Value()); + } + // Get state + return Napi::Boolean::New(info.Env(), vips_vector_isenabled()); +} + +/* + Get libvips version +*/ +Napi::Value libvipsVersion(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::Object version = Napi::Object::New(env); + + char semver[9]; + std::snprintf(semver, sizeof(semver), "%d.%d.%d", vips_version(0), vips_version(1), vips_version(2)); + version.Set("semver", Napi::String::New(env, semver)); +#ifdef SHARP_USE_GLOBAL_LIBVIPS + version.Set("isGlobal", Napi::Boolean::New(env, true)); +#else + version.Set("isGlobal", Napi::Boolean::New(env, false)); +#endif +#ifdef __EMSCRIPTEN__ + version.Set("isWasm", Napi::Boolean::New(env, true)); +#else + version.Set("isWasm", Napi::Boolean::New(env, false)); +#endif + return version; +} + +/* + Get available input/output file/buffer/stream formats +*/ +Napi::Value format(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + Napi::Object format = Napi::Object::New(env); + for (std::string const f : { + "jpeg", "png", "webp", "tiff", "magick", "openslide", "dz", + "ppm", "fits", "gif", "svg", "heif", "pdf", "vips", "jp2k", "jxl", "rad", "dcraw" + }) { + // Input + const VipsObjectClass *oc = vips_class_find("VipsOperation", (f + "load").c_str()); + Napi::Boolean hasInputFile = Napi::Boolean::New(env, oc); + Napi::Boolean hasInputBuffer = + Napi::Boolean::New(env, vips_type_find("VipsOperation", (f + "load_buffer").c_str())); + Napi::Object input = Napi::Object::New(env); + input.Set("file", hasInputFile); + input.Set("buffer", hasInputBuffer); + input.Set("stream", hasInputBuffer); + if (hasInputFile) { + const VipsForeignClass *fc = VIPS_FOREIGN_CLASS(oc); + if (fc->suffs) { + Napi::Array fileSuffix = Napi::Array::New(env); + const char **suffix = fc->suffs; + for (int i = 0; *suffix; i++, suffix++) { + fileSuffix.Set(i, Napi::String::New(env, *suffix)); + } + input.Set("fileSuffix", fileSuffix); + } + } + // Output + Napi::Boolean hasOutputFile = + Napi::Boolean::New(env, vips_type_find("VipsOperation", (f + "save").c_str())); + Napi::Boolean hasOutputBuffer = + Napi::Boolean::New(env, vips_type_find("VipsOperation", (f + "save_buffer").c_str())); + Napi::Object output = Napi::Object::New(env); + output.Set("file", hasOutputFile); + output.Set("buffer", hasOutputBuffer); + output.Set("stream", hasOutputBuffer); + // Other attributes + Napi::Object container = Napi::Object::New(env); + container.Set("id", f); + container.Set("input", input); + container.Set("output", output); + // Add to set of formats + format.Set(f, container); + } + + // Raw, uncompressed data + Napi::Boolean supported = Napi::Boolean::New(env, true); + Napi::Boolean unsupported = Napi::Boolean::New(env, false); + Napi::Object rawInput = Napi::Object::New(env); + rawInput.Set("file", unsupported); + rawInput.Set("buffer", supported); + rawInput.Set("stream", supported); + Napi::Object rawOutput = Napi::Object::New(env); + rawOutput.Set("file", unsupported); + rawOutput.Set("buffer", supported); + rawOutput.Set("stream", supported); + Napi::Object raw = Napi::Object::New(env); + raw.Set("id", "raw"); + raw.Set("input", rawInput); + raw.Set("output", rawOutput); + format.Set("raw", raw); + + return format; +} + +/* + (Un)block libvips operations at runtime. +*/ +void block(const Napi::CallbackInfo& info) { + Napi::Array ops = info[size_t(0)].As(); + bool const state = info[size_t(1)].As().Value(); + for (unsigned int i = 0; i < ops.Length(); i++) { + vips_operation_block_set(ops.Get(i).As().Utf8Value().c_str(), state); + } +} + +/* + Synchronous, internal-only method used by some of the functional tests. + Calculates the maximum colour distance using the DE2000 algorithm + between two images of the same dimensions and number of channels. +*/ +Napi::Value _maxColourDistance(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + + // Open input files + VImage image1; + sharp::ImageType imageType1 = sharp::DetermineImageType(info[size_t(0)].As().Utf8Value().data()); + if (imageType1 != sharp::ImageType::UNKNOWN) { + try { + image1 = VImage::new_from_file(info[size_t(0)].As().Utf8Value().c_str()); + } catch (...) { + throw Napi::Error::New(env, "Input file 1 has corrupt header"); + } + } else { + throw Napi::Error::New(env, "Input file 1 is of an unsupported image format"); + } + VImage image2; + sharp::ImageType imageType2 = sharp::DetermineImageType(info[size_t(1)].As().Utf8Value().data()); + if (imageType2 != sharp::ImageType::UNKNOWN) { + try { + image2 = VImage::new_from_file(info[size_t(1)].As().Utf8Value().c_str()); + } catch (...) { + throw Napi::Error::New(env, "Input file 2 has corrupt header"); + } + } else { + throw Napi::Error::New(env, "Input file 2 is of an unsupported image format"); + } + // Ensure same number of channels + if (image1.bands() != image2.bands()) { + throw Napi::Error::New(env, "mismatchedBands"); + } + // Ensure same dimensions + if (image1.width() != image2.width() || image1.height() != image2.height()) { + throw Napi::Error::New(env, "mismatchedDimensions"); + } + + double maxColourDistance; + try { + // Premultiply and remove alpha + if (image1.has_alpha()) { + image1 = image1.premultiply().extract_band(1, VImage::option()->set("n", image1.bands() - 1)); + } + if (image2.has_alpha()) { + image2 = image2.premultiply().extract_band(1, VImage::option()->set("n", image2.bands() - 1)); + } + // Calculate colour distance + maxColourDistance = image1.dE00(image2).max(); + } catch (vips::VError const &err) { + throw Napi::Error::New(env, err.what()); + } + + // Clean up libvips' per-request data and threads + vips_error_clear(); + vips_thread_shutdown(); + + return Napi::Number::New(env, maxColourDistance); +} + +#if defined(__GNUC__) +// mallctl will be resolved by the runtime linker when jemalloc is being used +extern "C" { + int mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen) __attribute__((weak)); +} +Napi::Value _isUsingJemalloc(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + return Napi::Boolean::New(env, mallctl != nullptr); +} +#else +Napi::Value _isUsingJemalloc(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + return Napi::Boolean::New(env, false); +} +#endif + +#if defined(__GNUC__) && defined(__x86_64__) +// Are SSE 4.2 intrinsics available at runtime? +Napi::Value _isUsingX64V2(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + unsigned int eax, ebx, ecx, edx; + __asm__ __volatile__("cpuid" + : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) + : "a"(1)); + return Napi::Boolean::New(env, (ecx & 1U << 20) != 0); +} +#else +Napi::Value _isUsingX64V2(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + return Napi::Boolean::New(env, false); +} +#endif diff --git a/node_modules/sharp/src/utilities.h b/node_modules/sharp/src/utilities.h new file mode 100644 index 0000000..9272f95 --- /dev/null +++ b/node_modules/sharp/src/utilities.h @@ -0,0 +1,20 @@ +// Copyright 2013 Lovell Fuller and others. +// SPDX-License-Identifier: Apache-2.0 + +#ifndef SRC_UTILITIES_H_ +#define SRC_UTILITIES_H_ + +#include + +Napi::Value cache(const Napi::CallbackInfo& info); +Napi::Value concurrency(const Napi::CallbackInfo& info); +Napi::Value counters(const Napi::CallbackInfo& info); +Napi::Value simd(const Napi::CallbackInfo& info); +Napi::Value libvipsVersion(const Napi::CallbackInfo& info); +Napi::Value format(const Napi::CallbackInfo& info); +void block(const Napi::CallbackInfo& info); +Napi::Value _maxColourDistance(const Napi::CallbackInfo& info); +Napi::Value _isUsingJemalloc(const Napi::CallbackInfo& info); +Napi::Value _isUsingX64V2(const Napi::CallbackInfo& info); + +#endif // SRC_UTILITIES_H_ diff --git a/node_modules/source-map-support/LICENSE.md b/node_modules/source-map-support/LICENSE.md new file mode 100644 index 0000000..6247ca9 --- /dev/null +++ b/node_modules/source-map-support/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Evan Wallace + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/source-map-support/README.md b/node_modules/source-map-support/README.md new file mode 100644 index 0000000..40228b7 --- /dev/null +++ b/node_modules/source-map-support/README.md @@ -0,0 +1,284 @@ +# Source Map Support +[![Build Status](https://travis-ci.org/evanw/node-source-map-support.svg?branch=master)](https://travis-ci.org/evanw/node-source-map-support) + +This module provides source map support for stack traces in node via the [V8 stack trace API](https://github.com/v8/v8/wiki/Stack-Trace-API). It uses the [source-map](https://github.com/mozilla/source-map) module to replace the paths and line numbers of source-mapped files with their original paths and line numbers. The output mimics node's stack trace format with the goal of making every compile-to-JS language more of a first-class citizen. Source maps are completely general (not specific to any one language) so you can use source maps with multiple compile-to-JS languages in the same node process. + +## Installation and Usage + +#### Node support + +``` +$ npm install source-map-support +``` + +Source maps can be generated using libraries such as [source-map-index-generator](https://github.com/twolfson/source-map-index-generator). Once you have a valid source map, place a source mapping comment somewhere in the file (usually done automatically or with an option by your transpiler): + +``` +//# sourceMappingURL=path/to/source.map +``` + +If multiple sourceMappingURL comments exist in one file, the last sourceMappingURL comment will be +respected (e.g. if a file mentions the comment in code, or went through multiple transpilers). +The path should either be absolute or relative to the compiled file. + +From here you have two options. + +##### CLI Usage + +```bash +node -r source-map-support/register compiled.js +``` + +##### Programmatic Usage + +Put the following line at the top of the compiled file. + +```js +require('source-map-support').install(); +``` + +It is also possible to install the source map support directly by +requiring the `register` module which can be handy with ES6: + +```js +import 'source-map-support/register' + +// Instead of: +import sourceMapSupport from 'source-map-support' +sourceMapSupport.install() +``` +Note: if you're using babel-register, it includes source-map-support already. + +It is also very useful with Mocha: + +``` +$ mocha --require source-map-support/register tests/ +``` + +#### Browser support + +This library also works in Chrome. While the DevTools console already supports source maps, the V8 engine doesn't and `Error.prototype.stack` will be incorrect without this library. Everything will just work if you deploy your source files using [browserify](http://browserify.org/). Just make sure to pass the `--debug` flag to the browserify command so your source maps are included in the bundled code. + +This library also works if you use another build process or just include the source files directly. In this case, include the file `browser-source-map-support.js` in your page and call `sourceMapSupport.install()`. It contains the whole library already bundled for the browser using browserify. + +```html + + +``` + +This library also works if you use AMD (Asynchronous Module Definition), which is used in tools like [RequireJS](http://requirejs.org/). Just list `browser-source-map-support` as a dependency: + +```html + +``` + +## Options + +This module installs two things: a change to the `stack` property on `Error` objects and a handler for uncaught exceptions that mimics node's default exception handler (the handler can be seen in the demos below). You may want to disable the handler if you have your own uncaught exception handler. This can be done by passing an argument to the installer: + +```js +require('source-map-support').install({ + handleUncaughtExceptions: false +}); +``` + +This module loads source maps from the filesystem by default. You can provide alternate loading behavior through a callback as shown below. For example, [Meteor](https://github.com/meteor) keeps all source maps cached in memory to avoid disk access. + +```js +require('source-map-support').install({ + retrieveSourceMap: function(source) { + if (source === 'compiled.js') { + return { + url: 'original.js', + map: fs.readFileSync('compiled.js.map', 'utf8') + }; + } + return null; + } +}); +``` + +The module will by default assume a browser environment if XMLHttpRequest and window are defined. If either of these do not exist it will instead assume a node environment. +In some rare cases, e.g. when running a browser emulation and where both variables are also set, you can explictly specify the environment to be either 'browser' or 'node'. + +```js +require('source-map-support').install({ + environment: 'node' +}); +``` + +To support files with inline source maps, the `hookRequire` options can be specified, which will monitor all source files for inline source maps. + + +```js +require('source-map-support').install({ + hookRequire: true +}); +``` + +This monkey patches the `require` module loading chain, so is not enabled by default and is not recommended for any sort of production usage. + +## Demos + +#### Basic Demo + +original.js: + +```js +throw new Error('test'); // This is the original code +``` + +compiled.js: + +```js +require('source-map-support').install(); + +throw new Error('test'); // This is the compiled code +// The next line defines the sourceMapping. +//# sourceMappingURL=compiled.js.map +``` + +compiled.js.map: + +```json +{ + "version": 3, + "file": "compiled.js", + "sources": ["original.js"], + "names": [], + "mappings": ";;AAAA,MAAM,IAAI" +} +``` + +Run compiled.js using node (notice how the stack trace uses original.js instead of compiled.js): + +``` +$ node compiled.js + +original.js:1 +throw new Error('test'); // This is the original code + ^ +Error: test + at Object. (original.js:1:7) + at Module._compile (module.js:456:26) + at Object.Module._extensions..js (module.js:474:10) + at Module.load (module.js:356:32) + at Function.Module._load (module.js:312:12) + at Function.Module.runMain (module.js:497:10) + at startup (node.js:119:16) + at node.js:901:3 +``` + +#### TypeScript Demo + +demo.ts: + +```typescript +declare function require(name: string); +require('source-map-support').install(); +class Foo { + constructor() { this.bar(); } + bar() { throw new Error('this is a demo'); } +} +new Foo(); +``` + +Compile and run the file using the TypeScript compiler from the terminal: + +``` +$ npm install source-map-support typescript +$ node_modules/typescript/bin/tsc -sourcemap demo.ts +$ node demo.js + +demo.ts:5 + bar() { throw new Error('this is a demo'); } + ^ +Error: this is a demo + at Foo.bar (demo.ts:5:17) + at new Foo (demo.ts:4:24) + at Object. (demo.ts:7:1) + at Module._compile (module.js:456:26) + at Object.Module._extensions..js (module.js:474:10) + at Module.load (module.js:356:32) + at Function.Module._load (module.js:312:12) + at Function.Module.runMain (module.js:497:10) + at startup (node.js:119:16) + at node.js:901:3 +``` + +There is also the option to use `-r source-map-support/register` with typescript, without the need add the `require('source-map-support').install()` in the code base: + +``` +$ npm install source-map-support typescript +$ node_modules/typescript/bin/tsc -sourcemap demo.ts +$ node -r source-map-support/register demo.js + +demo.ts:5 + bar() { throw new Error('this is a demo'); } + ^ +Error: this is a demo + at Foo.bar (demo.ts:5:17) + at new Foo (demo.ts:4:24) + at Object. (demo.ts:7:1) + at Module._compile (module.js:456:26) + at Object.Module._extensions..js (module.js:474:10) + at Module.load (module.js:356:32) + at Function.Module._load (module.js:312:12) + at Function.Module.runMain (module.js:497:10) + at startup (node.js:119:16) + at node.js:901:3 +``` + +#### CoffeeScript Demo + +demo.coffee: + +```coffee +require('source-map-support').install() +foo = -> + bar = -> throw new Error 'this is a demo' + bar() +foo() +``` + +Compile and run the file using the CoffeeScript compiler from the terminal: + +```sh +$ npm install source-map-support coffeescript +$ node_modules/.bin/coffee --map --compile demo.coffee +$ node demo.js + +demo.coffee:3 + bar = -> throw new Error 'this is a demo' + ^ +Error: this is a demo + at bar (demo.coffee:3:22) + at foo (demo.coffee:4:3) + at Object. (demo.coffee:5:1) + at Object. (demo.coffee:1:1) + at Module._compile (module.js:456:26) + at Object.Module._extensions..js (module.js:474:10) + at Module.load (module.js:356:32) + at Function.Module._load (module.js:312:12) + at Function.Module.runMain (module.js:497:10) + at startup (node.js:119:16) +``` + +## Tests + +This repo contains both automated tests for node and manual tests for the browser. The automated tests can be run using mocha (type `mocha` in the root directory). To run the manual tests: + +* Build the tests using `build.js` +* Launch the HTTP server (`npm run serve-tests`) and visit + * http://127.0.0.1:1336/amd-test + * http://127.0.0.1:1336/browser-test + * http://127.0.0.1:1336/browserify-test - **Currently not working** due to a bug with browserify (see [pull request #66](https://github.com/evanw/node-source-map-support/pull/66) for details). +* For `header-test`, run `server.js` inside that directory and visit http://127.0.0.1:1337/ + +## License + +This code is available under the [MIT license](http://opensource.org/licenses/MIT). diff --git a/node_modules/source-map-support/browser-source-map-support.js b/node_modules/source-map-support/browser-source-map-support.js new file mode 100644 index 0000000..782da50 --- /dev/null +++ b/node_modules/source-map-support/browser-source-map-support.js @@ -0,0 +1,114 @@ +/* + * Support for source maps in V8 stack traces + * https://github.com/evanw/node-source-map-support + */ +/* + The buffer module from node.js, for the browser. + + @author Feross Aboukhadijeh + license MIT +*/ +(this.define||function(R,U){this.sourceMapSupport=U()})("browser-source-map-support",function(R){(function e(C,J,A){function p(f,c){if(!J[f]){if(!C[f]){var l="function"==typeof require&&require;if(!c&&l)return l(f,!0);if(t)return t(f,!0);throw Error("Cannot find module '"+f+"'");}l=J[f]={exports:{}};C[f][0].call(l.exports,function(q){var r=C[f][1][q];return p(r?r:q)},l,l.exports,e,C,J,A)}return J[f].exports}for(var t="function"==typeof require&&require,m=0;mm)return-1;if(58>m)return m-48+52;if(91>m)return m-65;if(123>m)return m-97+26}var t="undefined"!==typeof Uint8Array?Uint8Array:Array;e.toByteArray=function(m){function f(d){q[k++]=d}if(0>16);f((u&65280)>>8);f(u&255)}2===l?(u=p(m.charAt(c))<<2|p(m.charAt(c+1))>>4,f(u&255)):1===l&&(u=p(m.charAt(c))<<10|p(m.charAt(c+1))<<4|p(m.charAt(c+2))>>2,f(u>>8&255),f(u&255));return q};e.fromByteArray=function(m){var f=m.length%3,c="",l;var q=0;for(l=m.length-f;q> +18&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>12&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>6&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r&63);c+=r}switch(f){case 1:r=m[m.length-1];c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>2);c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r<<4&63);c+="==";break;case 2:r=(m[m.length-2]<<8)+ +m[m.length-1],c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>10),c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>4&63),c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r<<2&63),c+="="}return c}})("undefined"===typeof A?this.base64js={}:A)},{}],3:[function(C,J,A){},{}],4:[function(C,J,A){(function(e){var p=Object.prototype.toString,t="function"===typeof e.alloc&&"function"===typeof e.allocUnsafe&&"function"=== +typeof e.from;J.exports=function(m,f,c){if("number"===typeof m)throw new TypeError('"value" argument must not be a number');if("ArrayBuffer"===p.call(m).slice(8,-1)){f>>>=0;var l=m.byteLength-f;if(0>l)throw new RangeError("'offset' is out of bounds");if(void 0===c)c=l;else if(c>>>=0,c>l)throw new RangeError("'length' is out of bounds");return t?e.from(m.slice(f,f+c)):new e(new Uint8Array(m.slice(f,f+c)))}if("string"===typeof m){c=f;if("string"!==typeof c||""===c)c="utf8";if(!e.isEncoding(c))throw new TypeError('"encoding" must be a valid string encoding'); +return t?e.from(m,c):new e(m,c)}return t?e.from(m):new e(m)}}).call(this,C("buffer").Buffer)},{buffer:5}],5:[function(C,J,A){function e(a,b,h){if(!(this instanceof e))return new e(a,b,h);var w=typeof a;if("number"===w)var y=0>>0:0;else if("string"===w){if("base64"===b)for(a=(a.trim?a.trim():a.replace(/^\s+|\s+$/g,"")).replace(L,"");0!==a.length%4;)a+="=";y=e.byteLength(a,b)}else if("object"===w&&null!==a)"Buffer"===a.type&&z(a.data)&&(a=a.data),y=0<+a.length?Math.floor(+a.length):0;else throw new TypeError("must start with number, buffer, array or string"); +if(this.length>G)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+G.toString(16)+" bytes");if(e.TYPED_ARRAY_SUPPORT)var I=e._augment(new Uint8Array(y));else I=this,I.length=y,I._isBuffer=!0;if(e.TYPED_ARRAY_SUPPORT&&"number"===typeof a.byteLength)I._set(a);else{var K=a;if(z(K)||e.isBuffer(K)||K&&"object"===typeof K&&"number"===typeof K.length)if(e.isBuffer(a))for(b=0;ba)throw new RangeError("offset is not uint");if(a+b>h)throw new RangeError("Trying to access beyond buffer length");}function m(a,b,h,w,y,I){if(!e.isBuffer(a))throw new TypeError("buffer must be a Buffer instance");if(b>y||ba.length)throw new TypeError("index out of range"); +}function f(a,b,h,w){0>b&&(b=65535+b+1);for(var y=0,I=Math.min(a.length-h,2);y>>8*(w?y:1-y)}function c(a,b,h,w){0>b&&(b=4294967295+b+1);for(var y=0,I=Math.min(a.length-h,4);y>>8*(w?y:3-y)&255}function l(a,b,h,w,y,I){if(b>y||ba.length)throw new TypeError("index out of range");}function q(a,b,h,w,y){y||l(a,b,h,4,3.4028234663852886E38,-3.4028234663852886E38);v.write(a,b,h,w,23,4);return h+4}function r(a, +b,h,w,y){y||l(a,b,h,8,1.7976931348623157E308,-1.7976931348623157E308);v.write(a,b,h,w,52,8);return h+8}function k(a){for(var b=[],h=0;h=w)b.push(w);else{var y=h;55296<=w&&57343>=w&&h++;w=encodeURIComponent(a.slice(y,h+1)).substr(1).split("%");for(y=0;y=b.length||y>=a.length);y++)b[y+ +h]=a[y];return y}function g(a){try{return decodeURIComponent(a)}catch(b){return String.fromCharCode(65533)}}var n=C("base64-js"),v=C("ieee754"),z=C("is-array");A.Buffer=e;A.SlowBuffer=e;A.INSPECT_MAX_BYTES=50;e.poolSize=8192;var G=1073741823;e.TYPED_ARRAY_SUPPORT=function(){try{var a=new ArrayBuffer(0),b=new Uint8Array(a);b.foo=function(){return 42};return 42===b.foo()&&"function"===typeof b.subarray&&0===(new Uint8Array(1)).subarray(1,1).byteLength}catch(h){return!1}}();e.isBuffer=function(a){return!(null== +a||!a._isBuffer)};e.compare=function(a,b){if(!e.isBuffer(a)||!e.isBuffer(b))throw new TypeError("Arguments must be Buffers");for(var h=a.length,w=b.length,y=0,I=Math.min(h,w);y>>1;break;case "utf8":case "utf-8":h=k(a).length;break;case "base64":h=n.toByteArray(a).length; +break;default:h=a.length}return h};e.prototype.length=void 0;e.prototype.parent=void 0;e.prototype.toString=function(a,b,h){var w=!1;b>>>=0;h=void 0===h||Infinity===h?this.length:h>>>0;a||(a="utf8");0>b&&(b=0);h>this.length&&(h=this.length);if(h<=b)return"";for(;;)switch(a){case "hex":a=b;b=h;h=this.length;if(!a||0>a)a=0;if(!b||0>b||b>h)b=h;w="";for(h=a;hw?"0"+w.toString(16):w.toString(16),w=a+w;return w;case "utf8":case "utf-8":w=a="";for(h=Math.min(this.length,h);b= +this[b]?(a+=g(w)+String.fromCharCode(this[b]),w=""):w+="%"+this[b].toString(16);return a+g(w);case "ascii":return p(this,b,h);case "binary":return p(this,b,h);case "base64":return b=0===b&&h===this.length?n.fromByteArray(this):n.fromByteArray(this.slice(b,h)),b;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":b=this.slice(b,h);h="";for(a=0;ab&&(a+=" ... "));return""};e.prototype.compare=function(a){if(!e.isBuffer(a))throw new TypeError("Argument must be a Buffer");return e.compare(this,a)};e.prototype.get=function(a){console.log(".get() is deprecated. Access using array indexes instead."); +return this.readUInt8(a)};e.prototype.set=function(a,b){console.log(".set() is deprecated. Access using array indexes instead.");return this.writeUInt8(a,b)};e.prototype.write=function(a,b,h,w){if(isFinite(b))isFinite(h)||(w=h,h=void 0);else{var y=w;w=b;b=h;h=y}b=Number(b)||0;y=this.length-b;h?(h=Number(h),h>y&&(h=y)):h=y;w=String(w||"utf8").toLowerCase();switch(w){case "hex":b=Number(b)||0;w=this.length-b;h?(h=Number(h),h>w&&(h=w)):h=w;w=a.length;if(0!==w%2)throw Error("Invalid hex string");h>w/ +2&&(h=w/2);for(w=0;w>8;K%=256;y.push(K);y.push(w)}a=d(y,this,b,h,2);break;default:throw new TypeError("Unknown encoding: "+ +w);}return a};e.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};e.prototype.slice=function(a,b){var h=this.length;a=~~a;b=void 0===b?h:~~b;0>a?(a+=h,0>a&&(a=0)):a>h&&(a=h);0>b?(b+=h,0>b&&(b=0)):b>h&&(b=h);b>>=0;h||m(this,a,b,1,255,0);e.TYPED_ARRAY_SUPPORT||(a=Math.floor(a));this[b]=a;return b+1};e.prototype.writeUInt16LE=function(a, +b,h){a=+a;b>>>=0;h||m(this,a,b,2,65535,0);e.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8):f(this,a,b,!0);return b+2};e.prototype.writeUInt16BE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,2,65535,0);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>8,this[b+1]=a):f(this,a,b,!1);return b+2};e.prototype.writeUInt32LE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,4,4294967295,0);e.TYPED_ARRAY_SUPPORT?(this[b+3]=a>>>24,this[b+2]=a>>>16,this[b+1]=a>>>8,this[b]=a):c(this,a,b,!0);return b+4};e.prototype.writeUInt32BE=function(a, +b,h){a=+a;b>>>=0;h||m(this,a,b,4,4294967295,0);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>24,this[b+1]=a>>>16,this[b+2]=a>>>8,this[b+3]=a):c(this,a,b,!1);return b+4};e.prototype.writeInt8=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,1,127,-128);e.TYPED_ARRAY_SUPPORT||(a=Math.floor(a));0>a&&(a=255+a+1);this[b]=a;return b+1};e.prototype.writeInt16LE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,2,32767,-32768);e.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8):f(this,a,b,!0);return b+2};e.prototype.writeInt16BE=function(a, +b,h){a=+a;b>>>=0;h||m(this,a,b,2,32767,-32768);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>8,this[b+1]=a):f(this,a,b,!1);return b+2};e.prototype.writeInt32LE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,4,2147483647,-2147483648);e.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8,this[b+2]=a>>>16,this[b+3]=a>>>24):c(this,a,b,!0);return b+4};e.prototype.writeInt32BE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,4,2147483647,-2147483648);0>a&&(a=4294967295+a+1);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>24,this[b+1]=a>>>16,this[b+ +2]=a>>>8,this[b+3]=a):c(this,a,b,!1);return b+4};e.prototype.writeFloatLE=function(a,b,h){return q(this,a,b,!0,h)};e.prototype.writeFloatBE=function(a,b,h){return q(this,a,b,!1,h)};e.prototype.writeDoubleLE=function(a,b,h){return r(this,a,b,!0,h)};e.prototype.writeDoubleBE=function(a,b,h){return r(this,a,b,!1,h)};e.prototype.copy=function(a,b,h,w){h||(h=0);w||0===w||(w=this.length);b||(b=0);if(w!==h&&0!==a.length&&0!==this.length){if(wb||b>=a.length)throw new TypeError("targetStart out of bounds"); +if(0>h||h>=this.length)throw new TypeError("sourceStart out of bounds");if(0>w||w>this.length)throw new TypeError("sourceEnd out of bounds");w>this.length&&(w=this.length);a.length-bw||!e.TYPED_ARRAY_SUPPORT)for(var y=0;yb||b>=this.length)throw new TypeError("start out of bounds"); +if(0>h||h>this.length)throw new TypeError("end out of bounds");if("number"===typeof a)for(;b>1,r=-7;f=t?f-1:0;var k=t?-1:1,u=e[p+f];f+=k;t=u&(1<<-r)-1;u>>=-r;for(r+=c;0>=-r;for(r+=m;0>1,u=23===f?Math.pow(2,-24)-Math.pow(2,-77):0;c=m?0:c-1;var d=m?1:-1,g=0>p||0===p&&0>1/p?1:0;p=Math.abs(p);isNaN(p)||Infinity===p?(p=isNaN(p)?1:0,m=r):(m=Math.floor(Math.log(p)/Math.LN2),1>p*(l=Math.pow(2,-m))&&(m--,l*=2),p=1<=m+k?p+u/l:p+u*Math.pow(2,1-k),2<=p*l&&(m++,l/=2),m+k>=r?(p=0,m=r):1<=m+k?(p=(p*l-1)*Math.pow(2,f),m+=k):(p=p*Math.pow(2,k-1)*Math.pow(2,f),m=0));for(;8<=f;e[t+c]=p&255,c+= +d,p/=256,f-=8);m=m<z?[]:n.slice(v,z-v+1)}c=A.resolve(c).substr(1);l=A.resolve(l).substr(1); +for(var r=q(c.split("/")),k=q(l.split("/")),u=Math.min(r.length,k.length),d=u,g=0;gl&&(l=c.length+l);return c.substr(l,q)}}).call(this,C("g5I+bs"))},{"g5I+bs":9}],9:[function(C,J,A){function e(){}C=J.exports={};C.nextTick=function(){if("undefined"!==typeof window&&window.setImmediate)return function(t){return window.setImmediate(t)};if("undefined"!==typeof window&&window.postMessage&&window.addEventListener){var p=[];window.addEventListener("message",function(t){var m=t.source;m!==window&&null!== +m||"process-tick"!==t.data||(t.stopPropagation(),0p?(-p<<1)+1:p<<1;do p=m&31,m>>>=5,0=f)throw Error("Expected more digits in base 64 VLQ value.");var q=e.decode(p.charCodeAt(t++));if(-1===q)throw Error("Invalid base64 digit: "+p.charAt(t-1));var r=!!(q&32);q&=31;c+=q<>1;m.value=1===(c&1)?-p:p;m.rest=t}},{"./base64":12}],12:[function(C, +J,A){var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");A.encode=function(p){if(0<=p&&p=p?p-65:97<=p&&122>=p?p-97+26:48<=p&&57>=p?p-48+52:43==p?62:47==p?63:-1}},{}],13:[function(C,J,A){function e(p,t,m,f,c,l){var q=Math.floor((t-p)/2)+p,r=c(m,f[q],!0);return 0===r?q:0p?-1:p}A.GREATEST_LOWER_BOUND=1;A.LEAST_UPPER_BOUND=2;A.search=function(p,t,m,f){if(0===t.length)return-1;p=e(-1,t.length,p,t,m,f||A.GREATEST_LOWER_BOUND);if(0>p)return-1;for(;0<=p-1&&0===m(t[p],t[p-1],!0);)--p;return p}},{}],14:[function(C,J,A){function e(){this._array=[];this._sorted=!0;this._last={generatedLine:-1,generatedColumn:0}}var p=C("./util");e.prototype.unsortedForEach=function(t,m){this._array.forEach(t,m)};e.prototype.add=function(t){var m=this._last,f=m.generatedLine, +c=t.generatedLine,l=m.generatedColumn,q=t.generatedColumn;c>f||c==f&&q>=l||0>=p.compareByGeneratedPositionsInflated(m,t)?this._last=t:this._sorted=!1;this._array.push(t)};e.prototype.toArray=function(){this._sorted||(this._array.sort(p.compareByGeneratedPositionsInflated),this._sorted=!0);return this._array};A.MappingList=e},{"./util":19}],15:[function(C,J,A){function e(t,m,f){var c=t[m];t[m]=t[f];t[f]=c}function p(t,m,f,c){if(f=m(t[r],q)&&(l+=1,e(t,l,r));e(t,l+1,r);l+=1;p(t,m,f,l-1);p(t,m,l+1,c)}}A.quickSort=function(t,m){p(t,m,0,t.length-1)}},{}],16:[function(C,J,A){function e(k,u){var d=k;"string"===typeof k&&(d=f.parseSourceMapInput(k));return null!=d.sections?new m(d,u):new p(d,u)}function p(k,u){var d=k;"string"===typeof k&&(d=f.parseSourceMapInput(k));var g=f.getArg(d,"version"),n=f.getArg(d,"sources"),v=f.getArg(d,"names",[]),z=f.getArg(d,"sourceRoot",null),G=f.getArg(d,"sourcesContent",null),D=f.getArg(d, +"mappings");d=f.getArg(d,"file",null);if(g!=this._version)throw Error("Unsupported version: "+g);z&&(z=f.normalize(z));n=n.map(String).map(f.normalize).map(function(L){return z&&f.isAbsolute(z)&&f.isAbsolute(L)?f.relative(z,L):L});this._names=l.fromArray(v.map(String),!0);this._sources=l.fromArray(n,!0);this.sourceRoot=z;this.sourcesContent=G;this._mappings=D;this._sourceMapURL=u;this.file=d}function t(){this.generatedColumn=this.generatedLine=0;this.name=this.originalColumn=this.originalLine=this.source= +null}function m(k,u){var d=k;"string"===typeof k&&(d=f.parseSourceMapInput(k));var g=f.getArg(d,"version");d=f.getArg(d,"sections");if(g!=this._version)throw Error("Unsupported version: "+g);this._sources=new l;this._names=new l;var n={line:-1,column:0};this._sections=d.map(function(v){if(v.url)throw Error("Support for url field in sections not implemented.");var z=f.getArg(v,"offset"),G=f.getArg(z,"line"),D=f.getArg(z,"column");if(G=k[d])throw new TypeError("Line must be greater than or equal to 1, got "+ +k[d]);if(0>k[g])throw new TypeError("Column must be greater than or equal to 0, got "+k[g]);return c.search(k,u,n,v)};p.prototype.computeColumnSpans=function(){for(var k=0;k=this._sources.size()&&!this.sourcesContent.some(function(k){return null==k}):!1};p.prototype.sourceContentFor=function(k,u){if(!this.sourcesContent)return null;var d=k;null!=this.sourceRoot&&(d=f.relative(this.sourceRoot,d));if(this._sources.has(d))return this.sourcesContent[this._sources.indexOf(d)]; +var g=this.sources,n;for(n=0;n +g||95!==d.charCodeAt(g-1)||95!==d.charCodeAt(g-2)||111!==d.charCodeAt(g-3)||116!==d.charCodeAt(g-4)||111!==d.charCodeAt(g-5)||114!==d.charCodeAt(g-6)||112!==d.charCodeAt(g-7)||95!==d.charCodeAt(g-8)||95!==d.charCodeAt(g-9))return!1;for(g-=10;0<=g;g--)if(36!==d.charCodeAt(g))return!1;return!0}function r(d,g){return d===g?0:null===d?1:null===g?-1:d>g?1:-1}A.getArg=function(d,g,n){if(g in d)return d[g];if(3===arguments.length)return n;throw Error('"'+g+'" is a required argument.');};var k=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/, +u=/^data:.+,.+$/;A.urlParse=e;A.urlGenerate=p;A.normalize=t;A.join=m;A.isAbsolute=function(d){return"/"===d.charAt(0)||k.test(d)};A.relative=function(d,g){""===d&&(d=".");d=d.replace(/\/$/,"");for(var n=0;0!==g.indexOf(d+"/");){var v=d.lastIndexOf("/");if(0>v)return g;d=d.slice(0,v);if(d.match(/^([^\/]+:\/)?\/*$/))return g;++n}return Array(n+1).join("../")+g.substr(d.length+1)};C=!("__proto__"in Object.create(null));A.toSetString=C?f:c;A.fromSetString=C?f:l;A.compareByOriginalPositions=function(d, +g,n){var v=r(d.source,g.source);if(0!==v)return v;v=d.originalLine-g.originalLine;if(0!==v)return v;v=d.originalColumn-g.originalColumn;if(0!==v||n)return v;v=d.generatedColumn-g.generatedColumn;if(0!==v)return v;v=d.generatedLine-g.generatedLine;return 0!==v?v:r(d.name,g.name)};A.compareByGeneratedPositionsDeflated=function(d,g,n){var v=d.generatedLine-g.generatedLine;if(0!==v)return v;v=d.generatedColumn-g.generatedColumn;if(0!==v||n)return v;v=r(d.source,g.source);if(0!==v)return v;v=d.originalLine- +g.originalLine;if(0!==v)return v;v=d.originalColumn-g.originalColumn;return 0!==v?v:r(d.name,g.name)};A.compareByGeneratedPositionsInflated=function(d,g){var n=d.generatedLine-g.generatedLine;if(0!==n)return n;n=d.generatedColumn-g.generatedColumn;if(0!==n)return n;n=r(d.source,g.source);if(0!==n)return n;n=d.originalLine-g.originalLine;if(0!==n)return n;n=d.originalColumn-g.originalColumn;return 0!==n?n:r(d.name,g.name)};A.parseSourceMapInput=function(d){return JSON.parse(d.replace(/^\)]}'[^\n]*\n/, +""))};A.computeSourceURL=function(d,g,n){g=g||"";d&&("/"!==d[d.length-1]&&"/"!==g[0]&&(d+="/"),g=d+g);if(n){d=e(n);if(!d)throw Error("sourceMapURL could not be parsed");d.path&&(n=d.path.lastIndexOf("/"),0<=n&&(d.path=d.path.substring(0,n+1)));g=m(p(d),g)}return t(g)}},{}],20:[function(C,J,A){A.SourceMapGenerator=C("./lib/source-map-generator").SourceMapGenerator;A.SourceMapConsumer=C("./lib/source-map-consumer").SourceMapConsumer;A.SourceNode=C("./lib/source-node").SourceNode},{"./lib/source-map-consumer":16, +"./lib/source-map-generator":17,"./lib/source-node":18}],21:[function(C,J,A){(function(e){function p(){return"browser"===a?!0:"node"===a?!1:"undefined"!==typeof window&&"function"===typeof XMLHttpRequest&&!(window.require&&window.module&&window.process&&"renderer"===window.process.type)}function t(x){return function(B){for(var F=0;F";B=this.getLineNumber();null!=B&&(x+=":"+B,(B= +this.getColumnNumber())&&(x+=":"+B))}B="";var F=this.getFunctionName(),E=!0,H=this.isConstructor();if(this.isToplevel()||H)H?B+="new "+(F||""):F?B+=F:(B+=x,E=!1);else{H=this.getTypeName();"[object Object]"===H&&(H="null");var M=this.getMethodName();F?(H&&0!=F.indexOf(H)&&(B+=H+"."),B+=F,M&&F.indexOf("."+M)!=F.length-M.length-1&&(B+=" [as "+M+"]")):B+=H+"."+(M||"")}E&&(B+=" ("+x+")");return B}function q(x){var B={};Object.getOwnPropertyNames(Object.getPrototypeOf(x)).forEach(function(F){B[F]= +/^(?:is|get)/.test(F)?function(){return x[F].call(x)}:x[F]});B.toString=l;return B}function r(x,B){void 0===B&&(B={nextPosition:null,curPosition:null});if(x.isNative())return B.curPosition=null,x;var F=x.getFileName()||x.getScriptNameOrSourceURL();if(F){var E=x.getLineNumber(),H=x.getColumnNumber()-1,M=/^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/,S=M.test;var V="object"===typeof e&&null!==e?e.version:"";M=S.call(M,V)?0:62;1===E&&H>M&&!p()&&!x.isEval()&&(H-=M);var O= +f({source:F,line:E,column:H});B.curPosition=O;x=q(x);var T=x.getFunctionName;x.getFunctionName=function(){return null==B.nextPosition?T():B.nextPosition.name||T()};x.getFileName=function(){return O.source};x.getLineNumber=function(){return O.line};x.getColumnNumber=function(){return O.column+1};x.getScriptNameOrSourceURL=function(){return O.source};return x}var Q=x.isEval()&&x.getEvalOrigin();Q&&(Q=c(Q),x=q(x),x.getEvalOrigin=function(){return Q});return x}function k(x,B){L&&(b={},h={});for(var F= +(x.name||"Error")+": "+(x.message||""),E={nextPosition:null,curPosition:null},H=[],M=B.length-1;0<=M;M--)H.push("\n at "+r(B[M],E)),E.nextPosition=E.curPosition;E.curPosition=E.nextPosition=null;return F+H.reverse().join("")}function u(x){var B=/\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(x.stack);if(B){x=B[1];var F=+B[2];B=+B[3];var E=b[x];if(!E&&v&&v.existsSync(x))try{E=v.readFileSync(x,"utf8")}catch(H){E=""}if(E&&(E=E.split(/(?:\r\n|\r|\n)/)[F-1]))return x+":"+F+"\n"+E+"\n"+Array(B).join(" ")+ +"^"}return null}function d(){var x=e.emit;e.emit=function(B){if("uncaughtException"===B){var F=arguments[1]&&arguments[1].stack,E=0 C:/dir/file + '/'; // file:///root-dir/file -> /root-dir/file + }); + } + if (path in fileContentsCache) { + return fileContentsCache[path]; + } + + var contents = ''; + try { + if (!fs) { + // Use SJAX if we are in the browser + var xhr = new XMLHttpRequest(); + xhr.open('GET', path, /** async */ false); + xhr.send(null); + if (xhr.readyState === 4 && xhr.status === 200) { + contents = xhr.responseText; + } + } else if (fs.existsSync(path)) { + // Otherwise, use the filesystem + contents = fs.readFileSync(path, 'utf8'); + } + } catch (er) { + /* ignore any errors */ + } + + return fileContentsCache[path] = contents; +}); + +// Support URLs relative to a directory, but be careful about a protocol prefix +// in case we are in the browser (i.e. directories may start with "http://" or "file:///") +function supportRelativeURL(file, url) { + if (!file) return url; + var dir = path.dirname(file); + var match = /^\w+:\/\/[^\/]*/.exec(dir); + var protocol = match ? match[0] : ''; + var startPath = dir.slice(protocol.length); + if (protocol && /^\/\w\:/.test(startPath)) { + // handle file:///C:/ paths + protocol += '/'; + return protocol + path.resolve(dir.slice(protocol.length), url).replace(/\\/g, '/'); + } + return protocol + path.resolve(dir.slice(protocol.length), url); +} + +function retrieveSourceMapURL(source) { + var fileData; + + if (isInBrowser()) { + try { + var xhr = new XMLHttpRequest(); + xhr.open('GET', source, false); + xhr.send(null); + fileData = xhr.readyState === 4 ? xhr.responseText : null; + + // Support providing a sourceMappingURL via the SourceMap header + var sourceMapHeader = xhr.getResponseHeader("SourceMap") || + xhr.getResponseHeader("X-SourceMap"); + if (sourceMapHeader) { + return sourceMapHeader; + } + } catch (e) { + } + } + + // Get the URL of the source map + fileData = retrieveFile(source); + var re = /(?:\/\/[@#][\s]*sourceMappingURL=([^\s'"]+)[\s]*$)|(?:\/\*[@#][\s]*sourceMappingURL=([^\s*'"]+)[\s]*(?:\*\/)[\s]*$)/mg; + // Keep executing the search to find the *last* sourceMappingURL to avoid + // picking up sourceMappingURLs from comments, strings, etc. + var lastMatch, match; + while (match = re.exec(fileData)) lastMatch = match; + if (!lastMatch) return null; + return lastMatch[1]; +}; + +// Can be overridden by the retrieveSourceMap option to install. Takes a +// generated source filename; returns a {map, optional url} object, or null if +// there is no source map. The map field may be either a string or the parsed +// JSON object (ie, it must be a valid argument to the SourceMapConsumer +// constructor). +var retrieveSourceMap = handlerExec(retrieveMapHandlers); +retrieveMapHandlers.push(function(source) { + var sourceMappingURL = retrieveSourceMapURL(source); + if (!sourceMappingURL) return null; + + // Read the contents of the source map + var sourceMapData; + if (reSourceMap.test(sourceMappingURL)) { + // Support source map URL as a data url + var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1); + sourceMapData = bufferFrom(rawData, "base64").toString(); + sourceMappingURL = source; + } else { + // Support source map URLs relative to the source URL + sourceMappingURL = supportRelativeURL(source, sourceMappingURL); + sourceMapData = retrieveFile(sourceMappingURL); + } + + if (!sourceMapData) { + return null; + } + + return { + url: sourceMappingURL, + map: sourceMapData + }; +}); + +function mapSourcePosition(position) { + var sourceMap = sourceMapCache[position.source]; + if (!sourceMap) { + // Call the (overrideable) retrieveSourceMap function to get the source map. + var urlAndMap = retrieveSourceMap(position.source); + if (urlAndMap) { + sourceMap = sourceMapCache[position.source] = { + url: urlAndMap.url, + map: new SourceMapConsumer(urlAndMap.map) + }; + + // Load all sources stored inline with the source map into the file cache + // to pretend like they are already loaded. They may not exist on disk. + if (sourceMap.map.sourcesContent) { + sourceMap.map.sources.forEach(function(source, i) { + var contents = sourceMap.map.sourcesContent[i]; + if (contents) { + var url = supportRelativeURL(sourceMap.url, source); + fileContentsCache[url] = contents; + } + }); + } + } else { + sourceMap = sourceMapCache[position.source] = { + url: null, + map: null + }; + } + } + + // Resolve the source URL relative to the URL of the source map + if (sourceMap && sourceMap.map && typeof sourceMap.map.originalPositionFor === 'function') { + var originalPosition = sourceMap.map.originalPositionFor(position); + + // Only return the original position if a matching line was found. If no + // matching line is found then we return position instead, which will cause + // the stack trace to print the path and line for the compiled file. It is + // better to give a precise location in the compiled file than a vague + // location in the original file. + if (originalPosition.source !== null) { + originalPosition.source = supportRelativeURL( + sourceMap.url, originalPosition.source); + return originalPosition; + } + } + + return position; +} + +// Parses code generated by FormatEvalOrigin(), a function inside V8: +// https://code.google.com/p/v8/source/browse/trunk/src/messages.js +function mapEvalOrigin(origin) { + // Most eval() calls are in this format + var match = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(origin); + if (match) { + var position = mapSourcePosition({ + source: match[2], + line: +match[3], + column: match[4] - 1 + }); + return 'eval at ' + match[1] + ' (' + position.source + ':' + + position.line + ':' + (position.column + 1) + ')'; + } + + // Parse nested eval() calls using recursion + match = /^eval at ([^(]+) \((.+)\)$/.exec(origin); + if (match) { + return 'eval at ' + match[1] + ' (' + mapEvalOrigin(match[2]) + ')'; + } + + // Make sure we still return useful information if we didn't find anything + return origin; +} + +// This is copied almost verbatim from the V8 source code at +// https://code.google.com/p/v8/source/browse/trunk/src/messages.js. The +// implementation of wrapCallSite() used to just forward to the actual source +// code of CallSite.prototype.toString but unfortunately a new release of V8 +// did something to the prototype chain and broke the shim. The only fix I +// could find was copy/paste. +function CallSiteToString() { + var fileName; + var fileLocation = ""; + if (this.isNative()) { + fileLocation = "native"; + } else { + fileName = this.getScriptNameOrSourceURL(); + if (!fileName && this.isEval()) { + fileLocation = this.getEvalOrigin(); + fileLocation += ", "; // Expecting source position to follow. + } + + if (fileName) { + fileLocation += fileName; + } else { + // Source code does not originate from a file and is not native, but we + // can still get the source position inside the source string, e.g. in + // an eval string. + fileLocation += ""; + } + var lineNumber = this.getLineNumber(); + if (lineNumber != null) { + fileLocation += ":" + lineNumber; + var columnNumber = this.getColumnNumber(); + if (columnNumber) { + fileLocation += ":" + columnNumber; + } + } + } + + var line = ""; + var functionName = this.getFunctionName(); + var addSuffix = true; + var isConstructor = this.isConstructor(); + var isMethodCall = !(this.isToplevel() || isConstructor); + if (isMethodCall) { + var typeName = this.getTypeName(); + // Fixes shim to be backward compatable with Node v0 to v4 + if (typeName === "[object Object]") { + typeName = "null"; + } + var methodName = this.getMethodName(); + if (functionName) { + if (typeName && functionName.indexOf(typeName) != 0) { + line += typeName + "."; + } + line += functionName; + if (methodName && functionName.indexOf("." + methodName) != functionName.length - methodName.length - 1) { + line += " [as " + methodName + "]"; + } + } else { + line += typeName + "." + (methodName || ""); + } + } else if (isConstructor) { + line += "new " + (functionName || ""); + } else if (functionName) { + line += functionName; + } else { + line += fileLocation; + addSuffix = false; + } + if (addSuffix) { + line += " (" + fileLocation + ")"; + } + return line; +} + +function cloneCallSite(frame) { + var object = {}; + Object.getOwnPropertyNames(Object.getPrototypeOf(frame)).forEach(function(name) { + object[name] = /^(?:is|get)/.test(name) ? function() { return frame[name].call(frame); } : frame[name]; + }); + object.toString = CallSiteToString; + return object; +} + +function wrapCallSite(frame, state) { + // provides interface backward compatibility + if (state === undefined) { + state = { nextPosition: null, curPosition: null } + } + if(frame.isNative()) { + state.curPosition = null; + return frame; + } + + // Most call sites will return the source file from getFileName(), but code + // passed to eval() ending in "//# sourceURL=..." will return the source file + // from getScriptNameOrSourceURL() instead + var source = frame.getFileName() || frame.getScriptNameOrSourceURL(); + if (source) { + var line = frame.getLineNumber(); + var column = frame.getColumnNumber() - 1; + + // Fix position in Node where some (internal) code is prepended. + // See https://github.com/evanw/node-source-map-support/issues/36 + // Header removed in node at ^10.16 || >=11.11.0 + // v11 is not an LTS candidate, we can just test the one version with it. + // Test node versions for: 10.16-19, 10.20+, 12-19, 20-99, 100+, or 11.11 + var noHeader = /^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/; + var headerLength = noHeader.test(globalProcessVersion()) ? 0 : 62; + if (line === 1 && column > headerLength && !isInBrowser() && !frame.isEval()) { + column -= headerLength; + } + + var position = mapSourcePosition({ + source: source, + line: line, + column: column + }); + state.curPosition = position; + frame = cloneCallSite(frame); + var originalFunctionName = frame.getFunctionName; + frame.getFunctionName = function() { + if (state.nextPosition == null) { + return originalFunctionName(); + } + return state.nextPosition.name || originalFunctionName(); + }; + frame.getFileName = function() { return position.source; }; + frame.getLineNumber = function() { return position.line; }; + frame.getColumnNumber = function() { return position.column + 1; }; + frame.getScriptNameOrSourceURL = function() { return position.source; }; + return frame; + } + + // Code called using eval() needs special handling + var origin = frame.isEval() && frame.getEvalOrigin(); + if (origin) { + origin = mapEvalOrigin(origin); + frame = cloneCallSite(frame); + frame.getEvalOrigin = function() { return origin; }; + return frame; + } + + // If we get here then we were unable to change the source position + return frame; +} + +// This function is part of the V8 stack trace API, for more info see: +// https://v8.dev/docs/stack-trace-api +function prepareStackTrace(error, stack) { + if (emptyCacheBetweenOperations) { + fileContentsCache = {}; + sourceMapCache = {}; + } + + var name = error.name || 'Error'; + var message = error.message || ''; + var errorString = name + ": " + message; + + var state = { nextPosition: null, curPosition: null }; + var processedStack = []; + for (var i = stack.length - 1; i >= 0; i--) { + processedStack.push('\n at ' + wrapCallSite(stack[i], state)); + state.nextPosition = state.curPosition; + } + state.curPosition = state.nextPosition = null; + return errorString + processedStack.reverse().join(''); +} + +// Generate position and snippet of original source with pointer +function getErrorSource(error) { + var match = /\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(error.stack); + if (match) { + var source = match[1]; + var line = +match[2]; + var column = +match[3]; + + // Support the inline sourceContents inside the source map + var contents = fileContentsCache[source]; + + // Support files on disk + if (!contents && fs && fs.existsSync(source)) { + try { + contents = fs.readFileSync(source, 'utf8'); + } catch (er) { + contents = ''; + } + } + + // Format the line from the original source code like node does + if (contents) { + var code = contents.split(/(?:\r\n|\r|\n)/)[line - 1]; + if (code) { + return source + ':' + line + '\n' + code + '\n' + + new Array(column).join(' ') + '^'; + } + } + } + return null; +} + +function printErrorAndExit (error) { + var source = getErrorSource(error); + + // Ensure error is printed synchronously and not truncated + var stderr = globalProcessStderr(); + if (stderr && stderr._handle && stderr._handle.setBlocking) { + stderr._handle.setBlocking(true); + } + + if (source) { + console.error(); + console.error(source); + } + + console.error(error.stack); + globalProcessExit(1); +} + +function shimEmitUncaughtException () { + var origEmit = process.emit; + + process.emit = function (type) { + if (type === 'uncaughtException') { + var hasStack = (arguments[1] && arguments[1].stack); + var hasListeners = (this.listeners(type).length > 0); + + if (hasStack && !hasListeners) { + return printErrorAndExit(arguments[1]); + } + } + + return origEmit.apply(this, arguments); + }; +} + +var originalRetrieveFileHandlers = retrieveFileHandlers.slice(0); +var originalRetrieveMapHandlers = retrieveMapHandlers.slice(0); + +exports.wrapCallSite = wrapCallSite; +exports.getErrorSource = getErrorSource; +exports.mapSourcePosition = mapSourcePosition; +exports.retrieveSourceMap = retrieveSourceMap; + +exports.install = function(options) { + options = options || {}; + + if (options.environment) { + environment = options.environment; + if (["node", "browser", "auto"].indexOf(environment) === -1) { + throw new Error("environment " + environment + " was unknown. Available options are {auto, browser, node}") + } + } + + // Allow sources to be found by methods other than reading the files + // directly from disk. + if (options.retrieveFile) { + if (options.overrideRetrieveFile) { + retrieveFileHandlers.length = 0; + } + + retrieveFileHandlers.unshift(options.retrieveFile); + } + + // Allow source maps to be found by methods other than reading the files + // directly from disk. + if (options.retrieveSourceMap) { + if (options.overrideRetrieveSourceMap) { + retrieveMapHandlers.length = 0; + } + + retrieveMapHandlers.unshift(options.retrieveSourceMap); + } + + // Support runtime transpilers that include inline source maps + if (options.hookRequire && !isInBrowser()) { + // Use dynamicRequire to avoid including in browser bundles + var Module = dynamicRequire(module, 'module'); + var $compile = Module.prototype._compile; + + if (!$compile.__sourceMapSupport) { + Module.prototype._compile = function(content, filename) { + fileContentsCache[filename] = content; + sourceMapCache[filename] = undefined; + return $compile.call(this, content, filename); + }; + + Module.prototype._compile.__sourceMapSupport = true; + } + } + + // Configure options + if (!emptyCacheBetweenOperations) { + emptyCacheBetweenOperations = 'emptyCacheBetweenOperations' in options ? + options.emptyCacheBetweenOperations : false; + } + + // Install the error reformatter + if (!errorFormatterInstalled) { + errorFormatterInstalled = true; + Error.prepareStackTrace = prepareStackTrace; + } + + if (!uncaughtShimInstalled) { + var installHandler = 'handleUncaughtExceptions' in options ? + options.handleUncaughtExceptions : true; + + // Do not override 'uncaughtException' with our own handler in Node.js + // Worker threads. Workers pass the error to the main thread as an event, + // rather than printing something to stderr and exiting. + try { + // We need to use `dynamicRequire` because `require` on it's own will be optimized by WebPack/Browserify. + var worker_threads = dynamicRequire(module, 'worker_threads'); + if (worker_threads.isMainThread === false) { + installHandler = false; + } + } catch(e) {} + + // Provide the option to not install the uncaught exception handler. This is + // to support other uncaught exception handlers (in test frameworks, for + // example). If this handler is not installed and there are no other uncaught + // exception handlers, uncaught exceptions will be caught by node's built-in + // exception handler and the process will still be terminated. However, the + // generated JavaScript code will be shown above the stack trace instead of + // the original source code. + if (installHandler && hasGlobalProcessEventEmitter()) { + uncaughtShimInstalled = true; + shimEmitUncaughtException(); + } + } +}; + +exports.resetRetrieveHandlers = function() { + retrieveFileHandlers.length = 0; + retrieveMapHandlers.length = 0; + + retrieveFileHandlers = originalRetrieveFileHandlers.slice(0); + retrieveMapHandlers = originalRetrieveMapHandlers.slice(0); + + retrieveSourceMap = handlerExec(retrieveMapHandlers); + retrieveFile = handlerExec(retrieveFileHandlers); +} diff --git a/node_modules/source-map/CHANGELOG.md b/node_modules/source-map/CHANGELOG.md new file mode 100644 index 0000000..3a8c066 --- /dev/null +++ b/node_modules/source-map/CHANGELOG.md @@ -0,0 +1,301 @@ +# Change Log + +## 0.5.6 + +* Fix for regression when people were using numbers as names in source maps. See + #236. + +## 0.5.5 + +* Fix "regression" of unsupported, implementation behavior that half the world + happens to have come to depend on. See #235. + +* Fix regression involving function hoisting in SpiderMonkey. See #233. + +## 0.5.4 + +* Large performance improvements to source-map serialization. See #228 and #229. + +## 0.5.3 + +* Do not include unnecessary distribution files. See + commit ef7006f8d1647e0a83fdc60f04f5a7ca54886f86. + +## 0.5.2 + +* Include browser distributions of the library in package.json's `files`. See + issue #212. + +## 0.5.1 + +* Fix latent bugs in IndexedSourceMapConsumer.prototype._parseMappings. See + ff05274becc9e6e1295ed60f3ea090d31d843379. + +## 0.5.0 + +* Node 0.8 is no longer supported. + +* Use webpack instead of dryice for bundling. + +* Big speedups serializing source maps. See pull request #203. + +* Fix a bug with `SourceMapConsumer.prototype.sourceContentFor` and sources that + explicitly start with the source root. See issue #199. + +## 0.4.4 + +* Fix an issue where using a `SourceMapGenerator` after having created a + `SourceMapConsumer` from it via `SourceMapConsumer.fromSourceMap` failed. See + issue #191. + +* Fix an issue with where `SourceMapGenerator` would mistakenly consider + different mappings as duplicates of each other and avoid generating them. See + issue #192. + +## 0.4.3 + +* A very large number of performance improvements, particularly when parsing + source maps. Collectively about 75% of time shaved off of the source map + parsing benchmark! + +* Fix a bug in `SourceMapConsumer.prototype.allGeneratedPositionsFor` and fuzzy + searching in the presence of a column option. See issue #177. + +* Fix a bug with joining a source and its source root when the source is above + the root. See issue #182. + +* Add the `SourceMapConsumer.prototype.hasContentsOfAllSources` method to + determine when all sources' contents are inlined into the source map. See + issue #190. + +## 0.4.2 + +* Add an `.npmignore` file so that the benchmarks aren't pulled down by + dependent projects. Issue #169. + +* Add an optional `column` argument to + `SourceMapConsumer.prototype.allGeneratedPositionsFor` and better handle lines + with no mappings. Issues #172 and #173. + +## 0.4.1 + +* Fix accidentally defining a global variable. #170. + +## 0.4.0 + +* The default direction for fuzzy searching was changed back to its original + direction. See #164. + +* There is now a `bias` option you can supply to `SourceMapConsumer` to control + the fuzzy searching direction. See #167. + +* About an 8% speed up in parsing source maps. See #159. + +* Added a benchmark for parsing and generating source maps. + +## 0.3.0 + +* Change the default direction that searching for positions fuzzes when there is + not an exact match. See #154. + +* Support for environments using json2.js for JSON serialization. See #156. + +## 0.2.0 + +* Support for consuming "indexed" source maps which do not have any remote + sections. See pull request #127. This introduces a minor backwards + incompatibility if you are monkey patching `SourceMapConsumer.prototype` + methods. + +## 0.1.43 + +* Performance improvements for `SourceMapGenerator` and `SourceNode`. See issue + #148 for some discussion and issues #150, #151, and #152 for implementations. + +## 0.1.42 + +* Fix an issue where `SourceNode`s from different versions of the source-map + library couldn't be used in conjunction with each other. See issue #142. + +## 0.1.41 + +* Fix a bug with getting the source content of relative sources with a "./" + prefix. See issue #145 and [Bug 1090768](bugzil.la/1090768). + +* Add the `SourceMapConsumer.prototype.computeColumnSpans` method to compute the + column span of each mapping. + +* Add the `SourceMapConsumer.prototype.allGeneratedPositionsFor` method to find + all generated positions associated with a given original source and line. + +## 0.1.40 + +* Performance improvements for parsing source maps in SourceMapConsumer. + +## 0.1.39 + +* Fix a bug where setting a source's contents to null before any source content + had been set before threw a TypeError. See issue #131. + +## 0.1.38 + +* Fix a bug where finding relative paths from an empty path were creating + absolute paths. See issue #129. + +## 0.1.37 + +* Fix a bug where if the source root was an empty string, relative source paths + would turn into absolute source paths. Issue #124. + +## 0.1.36 + +* Allow the `names` mapping property to be an empty string. Issue #121. + +## 0.1.35 + +* A third optional parameter was added to `SourceNode.fromStringWithSourceMap` + to specify a path that relative sources in the second parameter should be + relative to. Issue #105. + +* If no file property is given to a `SourceMapGenerator`, then the resulting + source map will no longer have a `null` file property. The property will + simply not exist. Issue #104. + +* Fixed a bug where consecutive newlines were ignored in `SourceNode`s. + Issue #116. + +## 0.1.34 + +* Make `SourceNode` work with windows style ("\r\n") newlines. Issue #103. + +* Fix bug involving source contents and the + `SourceMapGenerator.prototype.applySourceMap`. Issue #100. + +## 0.1.33 + +* Fix some edge cases surrounding path joining and URL resolution. + +* Add a third parameter for relative path to + `SourceMapGenerator.prototype.applySourceMap`. + +* Fix issues with mappings and EOLs. + +## 0.1.32 + +* Fixed a bug where SourceMapConsumer couldn't handle negative relative columns + (issue 92). + +* Fixed test runner to actually report number of failed tests as its process + exit code. + +* Fixed a typo when reporting bad mappings (issue 87). + +## 0.1.31 + +* Delay parsing the mappings in SourceMapConsumer until queried for a source + location. + +* Support Sass source maps (which at the time of writing deviate from the spec + in small ways) in SourceMapConsumer. + +## 0.1.30 + +* Do not join source root with a source, when the source is a data URI. + +* Extend the test runner to allow running single specific test files at a time. + +* Performance improvements in `SourceNode.prototype.walk` and + `SourceMapConsumer.prototype.eachMapping`. + +* Source map browser builds will now work inside Workers. + +* Better error messages when attempting to add an invalid mapping to a + `SourceMapGenerator`. + +## 0.1.29 + +* Allow duplicate entries in the `names` and `sources` arrays of source maps + (usually from TypeScript) we are parsing. Fixes github issue 72. + +## 0.1.28 + +* Skip duplicate mappings when creating source maps from SourceNode; github + issue 75. + +## 0.1.27 + +* Don't throw an error when the `file` property is missing in SourceMapConsumer, + we don't use it anyway. + +## 0.1.26 + +* Fix SourceNode.fromStringWithSourceMap for empty maps. Fixes github issue 70. + +## 0.1.25 + +* Make compatible with browserify + +## 0.1.24 + +* Fix issue with absolute paths and `file://` URIs. See + https://bugzilla.mozilla.org/show_bug.cgi?id=885597 + +## 0.1.23 + +* Fix issue with absolute paths and sourcesContent, github issue 64. + +## 0.1.22 + +* Ignore duplicate mappings in SourceMapGenerator. Fixes github issue 21. + +## 0.1.21 + +* Fixed handling of sources that start with a slash so that they are relative to + the source root's host. + +## 0.1.20 + +* Fixed github issue #43: absolute URLs aren't joined with the source root + anymore. + +## 0.1.19 + +* Using Travis CI to run tests. + +## 0.1.18 + +* Fixed a bug in the handling of sourceRoot. + +## 0.1.17 + +* Added SourceNode.fromStringWithSourceMap. + +## 0.1.16 + +* Added missing documentation. + +* Fixed the generating of empty mappings in SourceNode. + +## 0.1.15 + +* Added SourceMapGenerator.applySourceMap. + +## 0.1.14 + +* The sourceRoot is now handled consistently. + +## 0.1.13 + +* Added SourceMapGenerator.fromSourceMap. + +## 0.1.12 + +* SourceNode now generates empty mappings too. + +## 0.1.11 + +* Added name support to SourceNode. + +## 0.1.10 + +* Added sourcesContent support to the customer and generator. diff --git a/node_modules/source-map/LICENSE b/node_modules/source-map/LICENSE new file mode 100644 index 0000000..ed1b7cf --- /dev/null +++ b/node_modules/source-map/LICENSE @@ -0,0 +1,28 @@ + +Copyright (c) 2009-2011, Mozilla Foundation and contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* 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. + +* Neither the names of the Mozilla Foundation nor the names of project + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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. diff --git a/node_modules/source-map/README.md b/node_modules/source-map/README.md new file mode 100644 index 0000000..fea4beb --- /dev/null +++ b/node_modules/source-map/README.md @@ -0,0 +1,742 @@ +# Source Map + +[![Build Status](https://travis-ci.org/mozilla/source-map.png?branch=master)](https://travis-ci.org/mozilla/source-map) + +[![NPM](https://nodei.co/npm/source-map.png?downloads=true&downloadRank=true)](https://www.npmjs.com/package/source-map) + +This is a library to generate and consume the source map format +[described here][format]. + +[format]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit + +## Use with Node + + $ npm install source-map + +## Use on the Web + + + +-------------------------------------------------------------------------------- + + + + + +## Table of Contents + +- [Examples](#examples) + - [Consuming a source map](#consuming-a-source-map) + - [Generating a source map](#generating-a-source-map) + - [With SourceNode (high level API)](#with-sourcenode-high-level-api) + - [With SourceMapGenerator (low level API)](#with-sourcemapgenerator-low-level-api) +- [API](#api) + - [SourceMapConsumer](#sourcemapconsumer) + - [new SourceMapConsumer(rawSourceMap)](#new-sourcemapconsumerrawsourcemap) + - [SourceMapConsumer.prototype.computeColumnSpans()](#sourcemapconsumerprototypecomputecolumnspans) + - [SourceMapConsumer.prototype.originalPositionFor(generatedPosition)](#sourcemapconsumerprototypeoriginalpositionforgeneratedposition) + - [SourceMapConsumer.prototype.generatedPositionFor(originalPosition)](#sourcemapconsumerprototypegeneratedpositionfororiginalposition) + - [SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)](#sourcemapconsumerprototypeallgeneratedpositionsfororiginalposition) + - [SourceMapConsumer.prototype.hasContentsOfAllSources()](#sourcemapconsumerprototypehascontentsofallsources) + - [SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])](#sourcemapconsumerprototypesourcecontentforsource-returnnullonmissing) + - [SourceMapConsumer.prototype.eachMapping(callback, context, order)](#sourcemapconsumerprototypeeachmappingcallback-context-order) + - [SourceMapGenerator](#sourcemapgenerator) + - [new SourceMapGenerator([startOfSourceMap])](#new-sourcemapgeneratorstartofsourcemap) + - [SourceMapGenerator.fromSourceMap(sourceMapConsumer)](#sourcemapgeneratorfromsourcemapsourcemapconsumer) + - [SourceMapGenerator.prototype.addMapping(mapping)](#sourcemapgeneratorprototypeaddmappingmapping) + - [SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)](#sourcemapgeneratorprototypesetsourcecontentsourcefile-sourcecontent) + - [SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])](#sourcemapgeneratorprototypeapplysourcemapsourcemapconsumer-sourcefile-sourcemappath) + - [SourceMapGenerator.prototype.toString()](#sourcemapgeneratorprototypetostring) + - [SourceNode](#sourcenode) + - [new SourceNode([line, column, source[, chunk[, name]]])](#new-sourcenodeline-column-source-chunk-name) + - [SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])](#sourcenodefromstringwithsourcemapcode-sourcemapconsumer-relativepath) + - [SourceNode.prototype.add(chunk)](#sourcenodeprototypeaddchunk) + - [SourceNode.prototype.prepend(chunk)](#sourcenodeprototypeprependchunk) + - [SourceNode.prototype.setSourceContent(sourceFile, sourceContent)](#sourcenodeprototypesetsourcecontentsourcefile-sourcecontent) + - [SourceNode.prototype.walk(fn)](#sourcenodeprototypewalkfn) + - [SourceNode.prototype.walkSourceContents(fn)](#sourcenodeprototypewalksourcecontentsfn) + - [SourceNode.prototype.join(sep)](#sourcenodeprototypejoinsep) + - [SourceNode.prototype.replaceRight(pattern, replacement)](#sourcenodeprototypereplacerightpattern-replacement) + - [SourceNode.prototype.toString()](#sourcenodeprototypetostring) + - [SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])](#sourcenodeprototypetostringwithsourcemapstartofsourcemap) + + + +## Examples + +### Consuming a source map + +```js +var rawSourceMap = { + version: 3, + file: 'min.js', + names: ['bar', 'baz', 'n'], + sources: ['one.js', 'two.js'], + sourceRoot: 'http://example.com/www/js/', + mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA' +}; + +var smc = new SourceMapConsumer(rawSourceMap); + +console.log(smc.sources); +// [ 'http://example.com/www/js/one.js', +// 'http://example.com/www/js/two.js' ] + +console.log(smc.originalPositionFor({ + line: 2, + column: 28 +})); +// { source: 'http://example.com/www/js/two.js', +// line: 2, +// column: 10, +// name: 'n' } + +console.log(smc.generatedPositionFor({ + source: 'http://example.com/www/js/two.js', + line: 2, + column: 10 +})); +// { line: 2, column: 28 } + +smc.eachMapping(function (m) { + // ... +}); +``` + +### Generating a source map + +In depth guide: +[**Compiling to JavaScript, and Debugging with Source Maps**](https://hacks.mozilla.org/2013/05/compiling-to-javascript-and-debugging-with-source-maps/) + +#### With SourceNode (high level API) + +```js +function compile(ast) { + switch (ast.type) { + case 'BinaryExpression': + return new SourceNode( + ast.location.line, + ast.location.column, + ast.location.source, + [compile(ast.left), " + ", compile(ast.right)] + ); + case 'Literal': + return new SourceNode( + ast.location.line, + ast.location.column, + ast.location.source, + String(ast.value) + ); + // ... + default: + throw new Error("Bad AST"); + } +} + +var ast = parse("40 + 2", "add.js"); +console.log(compile(ast).toStringWithSourceMap({ + file: 'add.js' +})); +// { code: '40 + 2', +// map: [object SourceMapGenerator] } +``` + +#### With SourceMapGenerator (low level API) + +```js +var map = new SourceMapGenerator({ + file: "source-mapped.js" +}); + +map.addMapping({ + generated: { + line: 10, + column: 35 + }, + source: "foo.js", + original: { + line: 33, + column: 2 + }, + name: "christopher" +}); + +console.log(map.toString()); +// '{"version":3,"file":"source-mapped.js","sources":["foo.js"],"names":["christopher"],"mappings":";;;;;;;;;mCAgCEA"}' +``` + +## API + +Get a reference to the module: + +```js +// Node.js +var sourceMap = require('source-map'); + +// Browser builds +var sourceMap = window.sourceMap; + +// Inside Firefox +const sourceMap = require("devtools/toolkit/sourcemap/source-map.js"); +``` + +### SourceMapConsumer + +A SourceMapConsumer instance represents a parsed source map which we can query +for information about the original file positions by giving it a file position +in the generated source. + +#### new SourceMapConsumer(rawSourceMap) + +The only parameter is the raw source map (either as a string which can be +`JSON.parse`'d, or an object). According to the spec, source maps have the +following attributes: + +* `version`: Which version of the source map spec this map is following. + +* `sources`: An array of URLs to the original source files. + +* `names`: An array of identifiers which can be referenced by individual + mappings. + +* `sourceRoot`: Optional. The URL root from which all sources are relative. + +* `sourcesContent`: Optional. An array of contents of the original source files. + +* `mappings`: A string of base64 VLQs which contain the actual mappings. + +* `file`: Optional. The generated filename this source map is associated with. + +```js +var consumer = new sourceMap.SourceMapConsumer(rawSourceMapJsonData); +``` + +#### SourceMapConsumer.prototype.computeColumnSpans() + +Compute the last column for each generated mapping. The last column is +inclusive. + +```js +// Before: +consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }) +// [ { line: 2, +// column: 1 }, +// { line: 2, +// column: 10 }, +// { line: 2, +// column: 20 } ] + +consumer.computeColumnSpans(); + +// After: +consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }) +// [ { line: 2, +// column: 1, +// lastColumn: 9 }, +// { line: 2, +// column: 10, +// lastColumn: 19 }, +// { line: 2, +// column: 20, +// lastColumn: Infinity } ] + +``` + +#### SourceMapConsumer.prototype.originalPositionFor(generatedPosition) + +Returns the original source, line, and column information for the generated +source's line and column positions provided. The only argument is an object with +the following properties: + +* `line`: The line number in the generated source. Line numbers in + this library are 1-based (note that the underlying source map + specification uses 0-based line numbers -- this library handles the + translation). + +* `column`: The column number in the generated source. Column numbers + in this library are 0-based. + +* `bias`: Either `SourceMapConsumer.GREATEST_LOWER_BOUND` or + `SourceMapConsumer.LEAST_UPPER_BOUND`. Specifies whether to return the closest + element that is smaller than or greater than the one we are searching for, + respectively, if the exact element cannot be found. Defaults to + `SourceMapConsumer.GREATEST_LOWER_BOUND`. + +and an object is returned with the following properties: + +* `source`: The original source file, or null if this information is not + available. + +* `line`: The line number in the original source, or null if this information is + not available. The line number is 1-based. + +* `column`: The column number in the original source, or null if this + information is not available. The column number is 0-based. + +* `name`: The original identifier, or null if this information is not available. + +```js +consumer.originalPositionFor({ line: 2, column: 10 }) +// { source: 'foo.coffee', +// line: 2, +// column: 2, +// name: null } + +consumer.originalPositionFor({ line: 99999999999999999, column: 999999999999999 }) +// { source: null, +// line: null, +// column: null, +// name: null } +``` + +#### SourceMapConsumer.prototype.generatedPositionFor(originalPosition) + +Returns the generated line and column information for the original source, +line, and column positions provided. The only argument is an object with +the following properties: + +* `source`: The filename of the original source. + +* `line`: The line number in the original source. The line number is + 1-based. + +* `column`: The column number in the original source. The column + number is 0-based. + +and an object is returned with the following properties: + +* `line`: The line number in the generated source, or null. The line + number is 1-based. + +* `column`: The column number in the generated source, or null. The + column number is 0-based. + +```js +consumer.generatedPositionFor({ source: "example.js", line: 2, column: 10 }) +// { line: 1, +// column: 56 } +``` + +#### SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition) + +Returns all generated line and column information for the original source, line, +and column provided. If no column is provided, returns all mappings +corresponding to a either the line we are searching for or the next closest line +that has any mappings. Otherwise, returns all mappings corresponding to the +given line and either the column we are searching for or the next closest column +that has any offsets. + +The only argument is an object with the following properties: + +* `source`: The filename of the original source. + +* `line`: The line number in the original source. The line number is + 1-based. + +* `column`: Optional. The column number in the original source. The + column number is 0-based. + +and an array of objects is returned, each with the following properties: + +* `line`: The line number in the generated source, or null. The line + number is 1-based. + +* `column`: The column number in the generated source, or null. The + column number is 0-based. + +```js +consumer.allGeneratedpositionsfor({ line: 2, source: "foo.coffee" }) +// [ { line: 2, +// column: 1 }, +// { line: 2, +// column: 10 }, +// { line: 2, +// column: 20 } ] +``` + +#### SourceMapConsumer.prototype.hasContentsOfAllSources() + +Return true if we have the embedded source content for every source listed in +the source map, false otherwise. + +In other words, if this method returns `true`, then +`consumer.sourceContentFor(s)` will succeed for every source `s` in +`consumer.sources`. + +```js +// ... +if (consumer.hasContentsOfAllSources()) { + consumerReadyCallback(consumer); +} else { + fetchSources(consumer, consumerReadyCallback); +} +// ... +``` + +#### SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing]) + +Returns the original source content for the source provided. The only +argument is the URL of the original source file. + +If the source content for the given source is not found, then an error is +thrown. Optionally, pass `true` as the second param to have `null` returned +instead. + +```js +consumer.sources +// [ "my-cool-lib.clj" ] + +consumer.sourceContentFor("my-cool-lib.clj") +// "..." + +consumer.sourceContentFor("this is not in the source map"); +// Error: "this is not in the source map" is not in the source map + +consumer.sourceContentFor("this is not in the source map", true); +// null +``` + +#### SourceMapConsumer.prototype.eachMapping(callback, context, order) + +Iterate over each mapping between an original source/line/column and a +generated line/column in this source map. + +* `callback`: The function that is called with each mapping. Mappings have the + form `{ source, generatedLine, generatedColumn, originalLine, originalColumn, + name }` + +* `context`: Optional. If specified, this object will be the value of `this` + every time that `callback` is called. + +* `order`: Either `SourceMapConsumer.GENERATED_ORDER` or + `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to iterate over + the mappings sorted by the generated file's line/column order or the + original's source/line/column order, respectively. Defaults to + `SourceMapConsumer.GENERATED_ORDER`. + +```js +consumer.eachMapping(function (m) { console.log(m); }) +// ... +// { source: 'illmatic.js', +// generatedLine: 1, +// generatedColumn: 0, +// originalLine: 1, +// originalColumn: 0, +// name: null } +// { source: 'illmatic.js', +// generatedLine: 2, +// generatedColumn: 0, +// originalLine: 2, +// originalColumn: 0, +// name: null } +// ... +``` +### SourceMapGenerator + +An instance of the SourceMapGenerator represents a source map which is being +built incrementally. + +#### new SourceMapGenerator([startOfSourceMap]) + +You may pass an object with the following properties: + +* `file`: The filename of the generated source that this source map is + associated with. + +* `sourceRoot`: A root for all relative URLs in this source map. + +* `skipValidation`: Optional. When `true`, disables validation of mappings as + they are added. This can improve performance but should be used with + discretion, as a last resort. Even then, one should avoid using this flag when + running tests, if possible. + +```js +var generator = new sourceMap.SourceMapGenerator({ + file: "my-generated-javascript-file.js", + sourceRoot: "http://example.com/app/js/" +}); +``` + +#### SourceMapGenerator.fromSourceMap(sourceMapConsumer) + +Creates a new `SourceMapGenerator` from an existing `SourceMapConsumer` instance. + +* `sourceMapConsumer` The SourceMap. + +```js +var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer); +``` + +#### SourceMapGenerator.prototype.addMapping(mapping) + +Add a single mapping from original source line and column to the generated +source's line and column for this source map being created. The mapping object +should have the following properties: + +* `generated`: An object with the generated line and column positions. + +* `original`: An object with the original line and column positions. + +* `source`: The original source file (relative to the sourceRoot). + +* `name`: An optional original token name for this mapping. + +```js +generator.addMapping({ + source: "module-one.scm", + original: { line: 128, column: 0 }, + generated: { line: 3, column: 456 } +}) +``` + +#### SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent) + +Set the source content for an original source file. + +* `sourceFile` the URL of the original source file. + +* `sourceContent` the content of the source file. + +```js +generator.setSourceContent("module-one.scm", + fs.readFileSync("path/to/module-one.scm")) +``` + +#### SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]]) + +Applies a SourceMap for a source file to the SourceMap. +Each mapping to the supplied source file is rewritten using the +supplied SourceMap. Note: The resolution for the resulting mappings +is the minimum of this map and the supplied map. + +* `sourceMapConsumer`: The SourceMap to be applied. + +* `sourceFile`: Optional. The filename of the source file. + If omitted, sourceMapConsumer.file will be used, if it exists. + Otherwise an error will be thrown. + +* `sourceMapPath`: Optional. The dirname of the path to the SourceMap + to be applied. If relative, it is relative to the SourceMap. + + This parameter is needed when the two SourceMaps aren't in the same + directory, and the SourceMap to be applied contains relative source + paths. If so, those relative source paths need to be rewritten + relative to the SourceMap. + + If omitted, it is assumed that both SourceMaps are in the same directory, + thus not needing any rewriting. (Supplying `'.'` has the same effect.) + +#### SourceMapGenerator.prototype.toString() + +Renders the source map being generated to a string. + +```js +generator.toString() +// '{"version":3,"sources":["module-one.scm"],"names":[],"mappings":"...snip...","file":"my-generated-javascript-file.js","sourceRoot":"http://example.com/app/js/"}' +``` + +### SourceNode + +SourceNodes provide a way to abstract over interpolating and/or concatenating +snippets of generated JavaScript source code, while maintaining the line and +column information associated between those snippets and the original source +code. This is useful as the final intermediate representation a compiler might +use before outputting the generated JS and source map. + +#### new SourceNode([line, column, source[, chunk[, name]]]) + +* `line`: The original line number associated with this source node, or null if + it isn't associated with an original line. The line number is 1-based. + +* `column`: The original column number associated with this source node, or null + if it isn't associated with an original column. The column number + is 0-based. + +* `source`: The original source's filename; null if no filename is provided. + +* `chunk`: Optional. Is immediately passed to `SourceNode.prototype.add`, see + below. + +* `name`: Optional. The original identifier. + +```js +var node = new SourceNode(1, 2, "a.cpp", [ + new SourceNode(3, 4, "b.cpp", "extern int status;\n"), + new SourceNode(5, 6, "c.cpp", "std::string* make_string(size_t n);\n"), + new SourceNode(7, 8, "d.cpp", "int main(int argc, char** argv) {}\n"), +]); +``` + +#### SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath]) + +Creates a SourceNode from generated code and a SourceMapConsumer. + +* `code`: The generated code + +* `sourceMapConsumer` The SourceMap for the generated code + +* `relativePath` The optional path that relative sources in `sourceMapConsumer` + should be relative to. + +```js +var consumer = new SourceMapConsumer(fs.readFileSync("path/to/my-file.js.map", "utf8")); +var node = SourceNode.fromStringWithSourceMap(fs.readFileSync("path/to/my-file.js"), + consumer); +``` + +#### SourceNode.prototype.add(chunk) + +Add a chunk of generated JS to this source node. + +* `chunk`: A string snippet of generated JS code, another instance of + `SourceNode`, or an array where each member is one of those things. + +```js +node.add(" + "); +node.add(otherNode); +node.add([leftHandOperandNode, " + ", rightHandOperandNode]); +``` + +#### SourceNode.prototype.prepend(chunk) + +Prepend a chunk of generated JS to this source node. + +* `chunk`: A string snippet of generated JS code, another instance of + `SourceNode`, or an array where each member is one of those things. + +```js +node.prepend("/** Build Id: f783haef86324gf **/\n\n"); +``` + +#### SourceNode.prototype.setSourceContent(sourceFile, sourceContent) + +Set the source content for a source file. This will be added to the +`SourceMap` in the `sourcesContent` field. + +* `sourceFile`: The filename of the source file + +* `sourceContent`: The content of the source file + +```js +node.setSourceContent("module-one.scm", + fs.readFileSync("path/to/module-one.scm")) +``` + +#### SourceNode.prototype.walk(fn) + +Walk over the tree of JS snippets in this node and its children. The walking +function is called once for each snippet of JS and is passed that snippet and +the its original associated source's line/column location. + +* `fn`: The traversal function. + +```js +var node = new SourceNode(1, 2, "a.js", [ + new SourceNode(3, 4, "b.js", "uno"), + "dos", + [ + "tres", + new SourceNode(5, 6, "c.js", "quatro") + ] +]); + +node.walk(function (code, loc) { console.log("WALK:", code, loc); }) +// WALK: uno { source: 'b.js', line: 3, column: 4, name: null } +// WALK: dos { source: 'a.js', line: 1, column: 2, name: null } +// WALK: tres { source: 'a.js', line: 1, column: 2, name: null } +// WALK: quatro { source: 'c.js', line: 5, column: 6, name: null } +``` + +#### SourceNode.prototype.walkSourceContents(fn) + +Walk over the tree of SourceNodes. The walking function is called for each +source file content and is passed the filename and source content. + +* `fn`: The traversal function. + +```js +var a = new SourceNode(1, 2, "a.js", "generated from a"); +a.setSourceContent("a.js", "original a"); +var b = new SourceNode(1, 2, "b.js", "generated from b"); +b.setSourceContent("b.js", "original b"); +var c = new SourceNode(1, 2, "c.js", "generated from c"); +c.setSourceContent("c.js", "original c"); + +var node = new SourceNode(null, null, null, [a, b, c]); +node.walkSourceContents(function (source, contents) { console.log("WALK:", source, ":", contents); }) +// WALK: a.js : original a +// WALK: b.js : original b +// WALK: c.js : original c +``` + +#### SourceNode.prototype.join(sep) + +Like `Array.prototype.join` except for SourceNodes. Inserts the separator +between each of this source node's children. + +* `sep`: The separator. + +```js +var lhs = new SourceNode(1, 2, "a.rs", "my_copy"); +var operand = new SourceNode(3, 4, "a.rs", "="); +var rhs = new SourceNode(5, 6, "a.rs", "orig.clone()"); + +var node = new SourceNode(null, null, null, [ lhs, operand, rhs ]); +var joinedNode = node.join(" "); +``` + +#### SourceNode.prototype.replaceRight(pattern, replacement) + +Call `String.prototype.replace` on the very right-most source snippet. Useful +for trimming white space from the end of a source node, etc. + +* `pattern`: The pattern to replace. + +* `replacement`: The thing to replace the pattern with. + +```js +// Trim trailing white space. +node.replaceRight(/\s*$/, ""); +``` + +#### SourceNode.prototype.toString() + +Return the string representation of this source node. Walks over the tree and +concatenates all the various snippets together to one string. + +```js +var node = new SourceNode(1, 2, "a.js", [ + new SourceNode(3, 4, "b.js", "uno"), + "dos", + [ + "tres", + new SourceNode(5, 6, "c.js", "quatro") + ] +]); + +node.toString() +// 'unodostresquatro' +``` + +#### SourceNode.prototype.toStringWithSourceMap([startOfSourceMap]) + +Returns the string representation of this tree of source nodes, plus a +SourceMapGenerator which contains all the mappings between the generated and +original sources. + +The arguments are the same as those to `new SourceMapGenerator`. + +```js +var node = new SourceNode(1, 2, "a.js", [ + new SourceNode(3, 4, "b.js", "uno"), + "dos", + [ + "tres", + new SourceNode(5, 6, "c.js", "quatro") + ] +]); + +node.toStringWithSourceMap({ file: "my-output-file.js" }) +// { code: 'unodostresquatro', +// map: [object SourceMapGenerator] } +``` diff --git a/node_modules/source-map/dist/source-map.debug.js b/node_modules/source-map/dist/source-map.debug.js new file mode 100644 index 0000000..aad0620 --- /dev/null +++ b/node_modules/source-map/dist/source-map.debug.js @@ -0,0 +1,3234 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["sourceMap"] = factory(); + else + root["sourceMap"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; +/******/ +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.loaded = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + + /* + * Copyright 2009-2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE.txt or: + * http://opensource.org/licenses/BSD-3-Clause + */ + exports.SourceMapGenerator = __webpack_require__(1).SourceMapGenerator; + exports.SourceMapConsumer = __webpack_require__(7).SourceMapConsumer; + exports.SourceNode = __webpack_require__(10).SourceNode; + + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var base64VLQ = __webpack_require__(2); + var util = __webpack_require__(4); + var ArraySet = __webpack_require__(5).ArraySet; + var MappingList = __webpack_require__(6).MappingList; + + /** + * An instance of the SourceMapGenerator represents a source map which is + * being built incrementally. You may pass an object with the following + * properties: + * + * - file: The filename of the generated source. + * - sourceRoot: A root for all relative URLs in this source map. + */ + function SourceMapGenerator(aArgs) { + if (!aArgs) { + aArgs = {}; + } + this._file = util.getArg(aArgs, 'file', null); + this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); + this._skipValidation = util.getArg(aArgs, 'skipValidation', false); + this._sources = new ArraySet(); + this._names = new ArraySet(); + this._mappings = new MappingList(); + this._sourcesContents = null; + } + + SourceMapGenerator.prototype._version = 3; + + /** + * Creates a new SourceMapGenerator based on a SourceMapConsumer + * + * @param aSourceMapConsumer The SourceMap. + */ + SourceMapGenerator.fromSourceMap = + function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { + var sourceRoot = aSourceMapConsumer.sourceRoot; + var generator = new SourceMapGenerator({ + file: aSourceMapConsumer.file, + sourceRoot: sourceRoot + }); + aSourceMapConsumer.eachMapping(function (mapping) { + var newMapping = { + generated: { + line: mapping.generatedLine, + column: mapping.generatedColumn + } + }; + + if (mapping.source != null) { + newMapping.source = mapping.source; + if (sourceRoot != null) { + newMapping.source = util.relative(sourceRoot, newMapping.source); + } + + newMapping.original = { + line: mapping.originalLine, + column: mapping.originalColumn + }; + + if (mapping.name != null) { + newMapping.name = mapping.name; + } + } + + generator.addMapping(newMapping); + }); + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var sourceRelative = sourceFile; + if (sourceRoot !== null) { + sourceRelative = util.relative(sourceRoot, sourceFile); + } + + if (!generator._sources.has(sourceRelative)) { + generator._sources.add(sourceRelative); + } + + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + generator.setSourceContent(sourceFile, content); + } + }); + return generator; + }; + + /** + * Add a single mapping from original source line and column to the generated + * source's line and column for this source map being created. The mapping + * object should have the following properties: + * + * - generated: An object with the generated line and column positions. + * - original: An object with the original line and column positions. + * - source: The original source file (relative to the sourceRoot). + * - name: An optional original token name for this mapping. + */ + SourceMapGenerator.prototype.addMapping = + function SourceMapGenerator_addMapping(aArgs) { + var generated = util.getArg(aArgs, 'generated'); + var original = util.getArg(aArgs, 'original', null); + var source = util.getArg(aArgs, 'source', null); + var name = util.getArg(aArgs, 'name', null); + + if (!this._skipValidation) { + this._validateMapping(generated, original, source, name); + } + + if (source != null) { + source = String(source); + if (!this._sources.has(source)) { + this._sources.add(source); + } + } + + if (name != null) { + name = String(name); + if (!this._names.has(name)) { + this._names.add(name); + } + } + + this._mappings.add({ + generatedLine: generated.line, + generatedColumn: generated.column, + originalLine: original != null && original.line, + originalColumn: original != null && original.column, + source: source, + name: name + }); + }; + + /** + * Set the source content for a source file. + */ + SourceMapGenerator.prototype.setSourceContent = + function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { + var source = aSourceFile; + if (this._sourceRoot != null) { + source = util.relative(this._sourceRoot, source); + } + + if (aSourceContent != null) { + // Add the source content to the _sourcesContents map. + // Create a new _sourcesContents map if the property is null. + if (!this._sourcesContents) { + this._sourcesContents = Object.create(null); + } + this._sourcesContents[util.toSetString(source)] = aSourceContent; + } else if (this._sourcesContents) { + // Remove the source file from the _sourcesContents map. + // If the _sourcesContents map is empty, set the property to null. + delete this._sourcesContents[util.toSetString(source)]; + if (Object.keys(this._sourcesContents).length === 0) { + this._sourcesContents = null; + } + } + }; + + /** + * Applies the mappings of a sub-source-map for a specific source file to the + * source map being generated. Each mapping to the supplied source file is + * rewritten using the supplied source map. Note: The resolution for the + * resulting mappings is the minimium of this map and the supplied map. + * + * @param aSourceMapConsumer The source map to be applied. + * @param aSourceFile Optional. The filename of the source file. + * If omitted, SourceMapConsumer's file property will be used. + * @param aSourceMapPath Optional. The dirname of the path to the source map + * to be applied. If relative, it is relative to the SourceMapConsumer. + * This parameter is needed when the two source maps aren't in the same + * directory, and the source map to be applied contains relative source + * paths. If so, those relative source paths need to be rewritten + * relative to the SourceMapGenerator. + */ + SourceMapGenerator.prototype.applySourceMap = + function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { + var sourceFile = aSourceFile; + // If aSourceFile is omitted, we will use the file property of the SourceMap + if (aSourceFile == null) { + if (aSourceMapConsumer.file == null) { + throw new Error( + 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + + 'or the source map\'s "file" property. Both were omitted.' + ); + } + sourceFile = aSourceMapConsumer.file; + } + var sourceRoot = this._sourceRoot; + // Make "sourceFile" relative if an absolute Url is passed. + if (sourceRoot != null) { + sourceFile = util.relative(sourceRoot, sourceFile); + } + // Applying the SourceMap can add and remove items from the sources and + // the names array. + var newSources = new ArraySet(); + var newNames = new ArraySet(); + + // Find mappings for the "sourceFile" + this._mappings.unsortedForEach(function (mapping) { + if (mapping.source === sourceFile && mapping.originalLine != null) { + // Check if it can be mapped by the source map, then update the mapping. + var original = aSourceMapConsumer.originalPositionFor({ + line: mapping.originalLine, + column: mapping.originalColumn + }); + if (original.source != null) { + // Copy mapping + mapping.source = original.source; + if (aSourceMapPath != null) { + mapping.source = util.join(aSourceMapPath, mapping.source) + } + if (sourceRoot != null) { + mapping.source = util.relative(sourceRoot, mapping.source); + } + mapping.originalLine = original.line; + mapping.originalColumn = original.column; + if (original.name != null) { + mapping.name = original.name; + } + } + } + + var source = mapping.source; + if (source != null && !newSources.has(source)) { + newSources.add(source); + } + + var name = mapping.name; + if (name != null && !newNames.has(name)) { + newNames.add(name); + } + + }, this); + this._sources = newSources; + this._names = newNames; + + // Copy sourcesContents of applied map. + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aSourceMapPath != null) { + sourceFile = util.join(aSourceMapPath, sourceFile); + } + if (sourceRoot != null) { + sourceFile = util.relative(sourceRoot, sourceFile); + } + this.setSourceContent(sourceFile, content); + } + }, this); + }; + + /** + * A mapping can have one of the three levels of data: + * + * 1. Just the generated position. + * 2. The Generated position, original position, and original source. + * 3. Generated and original position, original source, as well as a name + * token. + * + * To maintain consistency, we validate that any new mapping being added falls + * in to one of these categories. + */ + SourceMapGenerator.prototype._validateMapping = + function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, + aName) { + // When aOriginal is truthy but has empty values for .line and .column, + // it is most likely a programmer error. In this case we throw a very + // specific error message to try to guide them the right way. + // For example: https://github.com/Polymer/polymer-bundler/pull/519 + if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') { + throw new Error( + 'original.line and original.column are not numbers -- you probably meant to omit ' + + 'the original mapping entirely and only map the generated position. If so, pass ' + + 'null for the original mapping instead of an object with empty or null values.' + ); + } + + if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aGenerated.line > 0 && aGenerated.column >= 0 + && !aOriginal && !aSource && !aName) { + // Case 1. + return; + } + else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aOriginal && 'line' in aOriginal && 'column' in aOriginal + && aGenerated.line > 0 && aGenerated.column >= 0 + && aOriginal.line > 0 && aOriginal.column >= 0 + && aSource) { + // Cases 2 and 3. + return; + } + else { + throw new Error('Invalid mapping: ' + JSON.stringify({ + generated: aGenerated, + source: aSource, + original: aOriginal, + name: aName + })); + } + }; + + /** + * Serialize the accumulated mappings in to the stream of base 64 VLQs + * specified by the source map format. + */ + SourceMapGenerator.prototype._serializeMappings = + function SourceMapGenerator_serializeMappings() { + var previousGeneratedColumn = 0; + var previousGeneratedLine = 1; + var previousOriginalColumn = 0; + var previousOriginalLine = 0; + var previousName = 0; + var previousSource = 0; + var result = ''; + var next; + var mapping; + var nameIdx; + var sourceIdx; + + var mappings = this._mappings.toArray(); + for (var i = 0, len = mappings.length; i < len; i++) { + mapping = mappings[i]; + next = '' + + if (mapping.generatedLine !== previousGeneratedLine) { + previousGeneratedColumn = 0; + while (mapping.generatedLine !== previousGeneratedLine) { + next += ';'; + previousGeneratedLine++; + } + } + else { + if (i > 0) { + if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) { + continue; + } + next += ','; + } + } + + next += base64VLQ.encode(mapping.generatedColumn + - previousGeneratedColumn); + previousGeneratedColumn = mapping.generatedColumn; + + if (mapping.source != null) { + sourceIdx = this._sources.indexOf(mapping.source); + next += base64VLQ.encode(sourceIdx - previousSource); + previousSource = sourceIdx; + + // lines are stored 0-based in SourceMap spec version 3 + next += base64VLQ.encode(mapping.originalLine - 1 + - previousOriginalLine); + previousOriginalLine = mapping.originalLine - 1; + + next += base64VLQ.encode(mapping.originalColumn + - previousOriginalColumn); + previousOriginalColumn = mapping.originalColumn; + + if (mapping.name != null) { + nameIdx = this._names.indexOf(mapping.name); + next += base64VLQ.encode(nameIdx - previousName); + previousName = nameIdx; + } + } + + result += next; + } + + return result; + }; + + SourceMapGenerator.prototype._generateSourcesContent = + function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { + return aSources.map(function (source) { + if (!this._sourcesContents) { + return null; + } + if (aSourceRoot != null) { + source = util.relative(aSourceRoot, source); + } + var key = util.toSetString(source); + return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) + ? this._sourcesContents[key] + : null; + }, this); + }; + + /** + * Externalize the source map. + */ + SourceMapGenerator.prototype.toJSON = + function SourceMapGenerator_toJSON() { + var map = { + version: this._version, + sources: this._sources.toArray(), + names: this._names.toArray(), + mappings: this._serializeMappings() + }; + if (this._file != null) { + map.file = this._file; + } + if (this._sourceRoot != null) { + map.sourceRoot = this._sourceRoot; + } + if (this._sourcesContents) { + map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); + } + + return map; + }; + + /** + * Render the source map being generated to a string. + */ + SourceMapGenerator.prototype.toString = + function SourceMapGenerator_toString() { + return JSON.stringify(this.toJSON()); + }; + + exports.SourceMapGenerator = SourceMapGenerator; + + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + * + * Based on the Base 64 VLQ implementation in Closure Compiler: + * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java + * + * Copyright 2011 The Closure Compiler Authors. All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + */ + + var base64 = __webpack_require__(3); + + // A single base 64 digit can contain 6 bits of data. For the base 64 variable + // length quantities we use in the source map spec, the first bit is the sign, + // the next four bits are the actual value, and the 6th bit is the + // continuation bit. The continuation bit tells us whether there are more + // digits in this value following this digit. + // + // Continuation + // | Sign + // | | + // V V + // 101011 + + var VLQ_BASE_SHIFT = 5; + + // binary: 100000 + var VLQ_BASE = 1 << VLQ_BASE_SHIFT; + + // binary: 011111 + var VLQ_BASE_MASK = VLQ_BASE - 1; + + // binary: 100000 + var VLQ_CONTINUATION_BIT = VLQ_BASE; + + /** + * Converts from a two-complement value to a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) + * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) + */ + function toVLQSigned(aValue) { + return aValue < 0 + ? ((-aValue) << 1) + 1 + : (aValue << 1) + 0; + } + + /** + * Converts to a two-complement value from a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 + * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 + */ + function fromVLQSigned(aValue) { + var isNegative = (aValue & 1) === 1; + var shifted = aValue >> 1; + return isNegative + ? -shifted + : shifted; + } + + /** + * Returns the base 64 VLQ encoded value. + */ + exports.encode = function base64VLQ_encode(aValue) { + var encoded = ""; + var digit; + + var vlq = toVLQSigned(aValue); + + do { + digit = vlq & VLQ_BASE_MASK; + vlq >>>= VLQ_BASE_SHIFT; + if (vlq > 0) { + // There are still more digits in this value, so we must make sure the + // continuation bit is marked. + digit |= VLQ_CONTINUATION_BIT; + } + encoded += base64.encode(digit); + } while (vlq > 0); + + return encoded; + }; + + /** + * Decodes the next base 64 VLQ value from the given string and returns the + * value and the rest of the string via the out parameter. + */ + exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { + var strLen = aStr.length; + var result = 0; + var shift = 0; + var continuation, digit; + + do { + if (aIndex >= strLen) { + throw new Error("Expected more digits in base 64 VLQ value."); + } + + digit = base64.decode(aStr.charCodeAt(aIndex++)); + if (digit === -1) { + throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); + } + + continuation = !!(digit & VLQ_CONTINUATION_BIT); + digit &= VLQ_BASE_MASK; + result = result + (digit << shift); + shift += VLQ_BASE_SHIFT; + } while (continuation); + + aOutParam.value = fromVLQSigned(result); + aOutParam.rest = aIndex; + }; + + +/***/ }), +/* 3 */ +/***/ (function(module, exports) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); + + /** + * Encode an integer in the range of 0 to 63 to a single base 64 digit. + */ + exports.encode = function (number) { + if (0 <= number && number < intToCharMap.length) { + return intToCharMap[number]; + } + throw new TypeError("Must be between 0 and 63: " + number); + }; + + /** + * Decode a single base 64 character code digit to an integer. Returns -1 on + * failure. + */ + exports.decode = function (charCode) { + var bigA = 65; // 'A' + var bigZ = 90; // 'Z' + + var littleA = 97; // 'a' + var littleZ = 122; // 'z' + + var zero = 48; // '0' + var nine = 57; // '9' + + var plus = 43; // '+' + var slash = 47; // '/' + + var littleOffset = 26; + var numberOffset = 52; + + // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ + if (bigA <= charCode && charCode <= bigZ) { + return (charCode - bigA); + } + + // 26 - 51: abcdefghijklmnopqrstuvwxyz + if (littleA <= charCode && charCode <= littleZ) { + return (charCode - littleA + littleOffset); + } + + // 52 - 61: 0123456789 + if (zero <= charCode && charCode <= nine) { + return (charCode - zero + numberOffset); + } + + // 62: + + if (charCode == plus) { + return 62; + } + + // 63: / + if (charCode == slash) { + return 63; + } + + // Invalid base64 digit. + return -1; + }; + + +/***/ }), +/* 4 */ +/***/ (function(module, exports) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + /** + * This is a helper function for getting values from parameter/options + * objects. + * + * @param args The object we are extracting values from + * @param name The name of the property we are getting. + * @param defaultValue An optional value to return if the property is missing + * from the object. If this is not specified and the property is missing, an + * error will be thrown. + */ + function getArg(aArgs, aName, aDefaultValue) { + if (aName in aArgs) { + return aArgs[aName]; + } else if (arguments.length === 3) { + return aDefaultValue; + } else { + throw new Error('"' + aName + '" is a required argument.'); + } + } + exports.getArg = getArg; + + var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/; + var dataUrlRegexp = /^data:.+\,.+$/; + + function urlParse(aUrl) { + var match = aUrl.match(urlRegexp); + if (!match) { + return null; + } + return { + scheme: match[1], + auth: match[2], + host: match[3], + port: match[4], + path: match[5] + }; + } + exports.urlParse = urlParse; + + function urlGenerate(aParsedUrl) { + var url = ''; + if (aParsedUrl.scheme) { + url += aParsedUrl.scheme + ':'; + } + url += '//'; + if (aParsedUrl.auth) { + url += aParsedUrl.auth + '@'; + } + if (aParsedUrl.host) { + url += aParsedUrl.host; + } + if (aParsedUrl.port) { + url += ":" + aParsedUrl.port + } + if (aParsedUrl.path) { + url += aParsedUrl.path; + } + return url; + } + exports.urlGenerate = urlGenerate; + + /** + * Normalizes a path, or the path portion of a URL: + * + * - Replaces consecutive slashes with one slash. + * - Removes unnecessary '.' parts. + * - Removes unnecessary '/..' parts. + * + * Based on code in the Node.js 'path' core module. + * + * @param aPath The path or url to normalize. + */ + function normalize(aPath) { + var path = aPath; + var url = urlParse(aPath); + if (url) { + if (!url.path) { + return aPath; + } + path = url.path; + } + var isAbsolute = exports.isAbsolute(path); + + var parts = path.split(/\/+/); + for (var part, up = 0, i = parts.length - 1; i >= 0; i--) { + part = parts[i]; + if (part === '.') { + parts.splice(i, 1); + } else if (part === '..') { + up++; + } else if (up > 0) { + if (part === '') { + // The first part is blank if the path is absolute. Trying to go + // above the root is a no-op. Therefore we can remove all '..' parts + // directly after the root. + parts.splice(i + 1, up); + up = 0; + } else { + parts.splice(i, 2); + up--; + } + } + } + path = parts.join('/'); + + if (path === '') { + path = isAbsolute ? '/' : '.'; + } + + if (url) { + url.path = path; + return urlGenerate(url); + } + return path; + } + exports.normalize = normalize; + + /** + * Joins two paths/URLs. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be joined with the root. + * + * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a + * scheme-relative URL: Then the scheme of aRoot, if any, is prepended + * first. + * - Otherwise aPath is a path. If aRoot is a URL, then its path portion + * is updated with the result and aRoot is returned. Otherwise the result + * is returned. + * - If aPath is absolute, the result is aPath. + * - Otherwise the two paths are joined with a slash. + * - Joining for example 'http://' and 'www.example.com' is also supported. + */ + function join(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + if (aPath === "") { + aPath = "."; + } + var aPathUrl = urlParse(aPath); + var aRootUrl = urlParse(aRoot); + if (aRootUrl) { + aRoot = aRootUrl.path || '/'; + } + + // `join(foo, '//www.example.org')` + if (aPathUrl && !aPathUrl.scheme) { + if (aRootUrl) { + aPathUrl.scheme = aRootUrl.scheme; + } + return urlGenerate(aPathUrl); + } + + if (aPathUrl || aPath.match(dataUrlRegexp)) { + return aPath; + } + + // `join('http://', 'www.example.com')` + if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { + aRootUrl.host = aPath; + return urlGenerate(aRootUrl); + } + + var joined = aPath.charAt(0) === '/' + ? aPath + : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); + + if (aRootUrl) { + aRootUrl.path = joined; + return urlGenerate(aRootUrl); + } + return joined; + } + exports.join = join; + + exports.isAbsolute = function (aPath) { + return aPath.charAt(0) === '/' || urlRegexp.test(aPath); + }; + + /** + * Make a path relative to a URL or another path. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be made relative to aRoot. + */ + function relative(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + + aRoot = aRoot.replace(/\/$/, ''); + + // It is possible for the path to be above the root. In this case, simply + // checking whether the root is a prefix of the path won't work. Instead, we + // need to remove components from the root one by one, until either we find + // a prefix that fits, or we run out of components to remove. + var level = 0; + while (aPath.indexOf(aRoot + '/') !== 0) { + var index = aRoot.lastIndexOf("/"); + if (index < 0) { + return aPath; + } + + // If the only part of the root that is left is the scheme (i.e. http://, + // file:///, etc.), one or more slashes (/), or simply nothing at all, we + // have exhausted all components, so the path is not relative to the root. + aRoot = aRoot.slice(0, index); + if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { + return aPath; + } + + ++level; + } + + // Make sure we add a "../" for each component we removed from the root. + return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); + } + exports.relative = relative; + + var supportsNullProto = (function () { + var obj = Object.create(null); + return !('__proto__' in obj); + }()); + + function identity (s) { + return s; + } + + /** + * Because behavior goes wacky when you set `__proto__` on objects, we + * have to prefix all the strings in our set with an arbitrary character. + * + * See https://github.com/mozilla/source-map/pull/31 and + * https://github.com/mozilla/source-map/issues/30 + * + * @param String aStr + */ + function toSetString(aStr) { + if (isProtoString(aStr)) { + return '$' + aStr; + } + + return aStr; + } + exports.toSetString = supportsNullProto ? identity : toSetString; + + function fromSetString(aStr) { + if (isProtoString(aStr)) { + return aStr.slice(1); + } + + return aStr; + } + exports.fromSetString = supportsNullProto ? identity : fromSetString; + + function isProtoString(s) { + if (!s) { + return false; + } + + var length = s.length; + + if (length < 9 /* "__proto__".length */) { + return false; + } + + if (s.charCodeAt(length - 1) !== 95 /* '_' */ || + s.charCodeAt(length - 2) !== 95 /* '_' */ || + s.charCodeAt(length - 3) !== 111 /* 'o' */ || + s.charCodeAt(length - 4) !== 116 /* 't' */ || + s.charCodeAt(length - 5) !== 111 /* 'o' */ || + s.charCodeAt(length - 6) !== 114 /* 'r' */ || + s.charCodeAt(length - 7) !== 112 /* 'p' */ || + s.charCodeAt(length - 8) !== 95 /* '_' */ || + s.charCodeAt(length - 9) !== 95 /* '_' */) { + return false; + } + + for (var i = length - 10; i >= 0; i--) { + if (s.charCodeAt(i) !== 36 /* '$' */) { + return false; + } + } + + return true; + } + + /** + * Comparator between two mappings where the original positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same original source/line/column, but different generated + * line and column the same. Useful when searching for a mapping with a + * stubbed out mapping. + */ + function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { + var cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0 || onlyCompareOriginal) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + return strcmp(mappingA.name, mappingB.name); + } + exports.compareByOriginalPositions = compareByOriginalPositions; + + /** + * Comparator between two mappings with deflated source and name indices where + * the generated positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same generated line and column, but different + * source/name/original line and column the same. Useful when searching for a + * mapping with a stubbed out mapping. + */ + function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0 || onlyCompareGenerated) { + return cmp; + } + + cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return strcmp(mappingA.name, mappingB.name); + } + exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; + + function strcmp(aStr1, aStr2) { + if (aStr1 === aStr2) { + return 0; + } + + if (aStr1 === null) { + return 1; // aStr2 !== null + } + + if (aStr2 === null) { + return -1; // aStr1 !== null + } + + if (aStr1 > aStr2) { + return 1; + } + + return -1; + } + + /** + * Comparator between two mappings with inflated source and name strings where + * the generated positions are compared. + */ + function compareByGeneratedPositionsInflated(mappingA, mappingB) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return strcmp(mappingA.name, mappingB.name); + } + exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; + + /** + * Strip any JSON XSSI avoidance prefix from the string (as documented + * in the source maps specification), and then parse the string as + * JSON. + */ + function parseSourceMapInput(str) { + return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, '')); + } + exports.parseSourceMapInput = parseSourceMapInput; + + /** + * Compute the URL of a source given the the source root, the source's + * URL, and the source map's URL. + */ + function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) { + sourceURL = sourceURL || ''; + + if (sourceRoot) { + // This follows what Chrome does. + if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') { + sourceRoot += '/'; + } + // The spec says: + // Line 4: An optional source root, useful for relocating source + // files on a server or removing repeated values in the + // “sources” entry. This value is prepended to the individual + // entries in the “source” field. + sourceURL = sourceRoot + sourceURL; + } + + // Historically, SourceMapConsumer did not take the sourceMapURL as + // a parameter. This mode is still somewhat supported, which is why + // this code block is conditional. However, it's preferable to pass + // the source map URL to SourceMapConsumer, so that this function + // can implement the source URL resolution algorithm as outlined in + // the spec. This block is basically the equivalent of: + // new URL(sourceURL, sourceMapURL).toString() + // ... except it avoids using URL, which wasn't available in the + // older releases of node still supported by this library. + // + // The spec says: + // If the sources are not absolute URLs after prepending of the + // “sourceRoot”, the sources are resolved relative to the + // SourceMap (like resolving script src in a html document). + if (sourceMapURL) { + var parsed = urlParse(sourceMapURL); + if (!parsed) { + throw new Error("sourceMapURL could not be parsed"); + } + if (parsed.path) { + // Strip the last path component, but keep the "/". + var index = parsed.path.lastIndexOf('/'); + if (index >= 0) { + parsed.path = parsed.path.substring(0, index + 1); + } + } + sourceURL = join(urlGenerate(parsed), sourceURL); + } + + return normalize(sourceURL); + } + exports.computeSourceURL = computeSourceURL; + + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var util = __webpack_require__(4); + var has = Object.prototype.hasOwnProperty; + var hasNativeMap = typeof Map !== "undefined"; + + /** + * A data structure which is a combination of an array and a set. Adding a new + * member is O(1), testing for membership is O(1), and finding the index of an + * element is O(1). Removing elements from the set is not supported. Only + * strings are supported for membership. + */ + function ArraySet() { + this._array = []; + this._set = hasNativeMap ? new Map() : Object.create(null); + } + + /** + * Static method for creating ArraySet instances from an existing array. + */ + ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { + var set = new ArraySet(); + for (var i = 0, len = aArray.length; i < len; i++) { + set.add(aArray[i], aAllowDuplicates); + } + return set; + }; + + /** + * Return how many unique items are in this ArraySet. If duplicates have been + * added, than those do not count towards the size. + * + * @returns Number + */ + ArraySet.prototype.size = function ArraySet_size() { + return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length; + }; + + /** + * Add the given string to this set. + * + * @param String aStr + */ + ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { + var sStr = hasNativeMap ? aStr : util.toSetString(aStr); + var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr); + var idx = this._array.length; + if (!isDuplicate || aAllowDuplicates) { + this._array.push(aStr); + } + if (!isDuplicate) { + if (hasNativeMap) { + this._set.set(aStr, idx); + } else { + this._set[sStr] = idx; + } + } + }; + + /** + * Is the given string a member of this set? + * + * @param String aStr + */ + ArraySet.prototype.has = function ArraySet_has(aStr) { + if (hasNativeMap) { + return this._set.has(aStr); + } else { + var sStr = util.toSetString(aStr); + return has.call(this._set, sStr); + } + }; + + /** + * What is the index of the given string in the array? + * + * @param String aStr + */ + ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) { + if (hasNativeMap) { + var idx = this._set.get(aStr); + if (idx >= 0) { + return idx; + } + } else { + var sStr = util.toSetString(aStr); + if (has.call(this._set, sStr)) { + return this._set[sStr]; + } + } + + throw new Error('"' + aStr + '" is not in the set.'); + }; + + /** + * What is the element at the given index? + * + * @param Number aIdx + */ + ArraySet.prototype.at = function ArraySet_at(aIdx) { + if (aIdx >= 0 && aIdx < this._array.length) { + return this._array[aIdx]; + } + throw new Error('No element indexed by ' + aIdx); + }; + + /** + * Returns the array representation of this set (which has the proper indices + * indicated by indexOf). Note that this is a copy of the internal array used + * for storing the members so that no one can mess with internal state. + */ + ArraySet.prototype.toArray = function ArraySet_toArray() { + return this._array.slice(); + }; + + exports.ArraySet = ArraySet; + + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2014 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var util = __webpack_require__(4); + + /** + * Determine whether mappingB is after mappingA with respect to generated + * position. + */ + function generatedPositionAfter(mappingA, mappingB) { + // Optimized for most common case + var lineA = mappingA.generatedLine; + var lineB = mappingB.generatedLine; + var columnA = mappingA.generatedColumn; + var columnB = mappingB.generatedColumn; + return lineB > lineA || lineB == lineA && columnB >= columnA || + util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0; + } + + /** + * A data structure to provide a sorted view of accumulated mappings in a + * performance conscious manner. It trades a neglibable overhead in general + * case for a large speedup in case of mappings being added in order. + */ + function MappingList() { + this._array = []; + this._sorted = true; + // Serves as infimum + this._last = {generatedLine: -1, generatedColumn: 0}; + } + + /** + * Iterate through internal items. This method takes the same arguments that + * `Array.prototype.forEach` takes. + * + * NOTE: The order of the mappings is NOT guaranteed. + */ + MappingList.prototype.unsortedForEach = + function MappingList_forEach(aCallback, aThisArg) { + this._array.forEach(aCallback, aThisArg); + }; + + /** + * Add the given source mapping. + * + * @param Object aMapping + */ + MappingList.prototype.add = function MappingList_add(aMapping) { + if (generatedPositionAfter(this._last, aMapping)) { + this._last = aMapping; + this._array.push(aMapping); + } else { + this._sorted = false; + this._array.push(aMapping); + } + }; + + /** + * Returns the flat, sorted array of mappings. The mappings are sorted by + * generated position. + * + * WARNING: This method returns internal data without copying, for + * performance. The return value must NOT be mutated, and should be treated as + * an immutable borrow. If you want to take ownership, you must make your own + * copy. + */ + MappingList.prototype.toArray = function MappingList_toArray() { + if (!this._sorted) { + this._array.sort(util.compareByGeneratedPositionsInflated); + this._sorted = true; + } + return this._array; + }; + + exports.MappingList = MappingList; + + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var util = __webpack_require__(4); + var binarySearch = __webpack_require__(8); + var ArraySet = __webpack_require__(5).ArraySet; + var base64VLQ = __webpack_require__(2); + var quickSort = __webpack_require__(9).quickSort; + + function SourceMapConsumer(aSourceMap, aSourceMapURL) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = util.parseSourceMapInput(aSourceMap); + } + + return sourceMap.sections != null + ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL) + : new BasicSourceMapConsumer(sourceMap, aSourceMapURL); + } + + SourceMapConsumer.fromSourceMap = function(aSourceMap, aSourceMapURL) { + return BasicSourceMapConsumer.fromSourceMap(aSourceMap, aSourceMapURL); + } + + /** + * The version of the source mapping spec that we are consuming. + */ + SourceMapConsumer.prototype._version = 3; + + // `__generatedMappings` and `__originalMappings` are arrays that hold the + // parsed mapping coordinates from the source map's "mappings" attribute. They + // are lazily instantiated, accessed via the `_generatedMappings` and + // `_originalMappings` getters respectively, and we only parse the mappings + // and create these arrays once queried for a source location. We jump through + // these hoops because there can be many thousands of mappings, and parsing + // them is expensive, so we only want to do it if we must. + // + // Each object in the arrays is of the form: + // + // { + // generatedLine: The line number in the generated code, + // generatedColumn: The column number in the generated code, + // source: The path to the original source file that generated this + // chunk of code, + // originalLine: The line number in the original source that + // corresponds to this chunk of generated code, + // originalColumn: The column number in the original source that + // corresponds to this chunk of generated code, + // name: The name of the original symbol which generated this chunk of + // code. + // } + // + // All properties except for `generatedLine` and `generatedColumn` can be + // `null`. + // + // `_generatedMappings` is ordered by the generated positions. + // + // `_originalMappings` is ordered by the original positions. + + SourceMapConsumer.prototype.__generatedMappings = null; + Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', { + configurable: true, + enumerable: true, + get: function () { + if (!this.__generatedMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__generatedMappings; + } + }); + + SourceMapConsumer.prototype.__originalMappings = null; + Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { + configurable: true, + enumerable: true, + get: function () { + if (!this.__originalMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__originalMappings; + } + }); + + SourceMapConsumer.prototype._charIsMappingSeparator = + function SourceMapConsumer_charIsMappingSeparator(aStr, index) { + var c = aStr.charAt(index); + return c === ";" || c === ","; + }; + + /** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ + SourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + throw new Error("Subclasses must implement _parseMappings"); + }; + + SourceMapConsumer.GENERATED_ORDER = 1; + SourceMapConsumer.ORIGINAL_ORDER = 2; + + SourceMapConsumer.GREATEST_LOWER_BOUND = 1; + SourceMapConsumer.LEAST_UPPER_BOUND = 2; + + /** + * Iterate over each mapping between an original source/line/column and a + * generated line/column in this source map. + * + * @param Function aCallback + * The function that is called with each mapping. + * @param Object aContext + * Optional. If specified, this object will be the value of `this` every + * time that `aCallback` is called. + * @param aOrder + * Either `SourceMapConsumer.GENERATED_ORDER` or + * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to + * iterate over the mappings sorted by the generated file's line/column + * order or the original's source/line/column order, respectively. Defaults to + * `SourceMapConsumer.GENERATED_ORDER`. + */ + SourceMapConsumer.prototype.eachMapping = + function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { + var context = aContext || null; + var order = aOrder || SourceMapConsumer.GENERATED_ORDER; + + var mappings; + switch (order) { + case SourceMapConsumer.GENERATED_ORDER: + mappings = this._generatedMappings; + break; + case SourceMapConsumer.ORIGINAL_ORDER: + mappings = this._originalMappings; + break; + default: + throw new Error("Unknown order of iteration."); + } + + var sourceRoot = this.sourceRoot; + mappings.map(function (mapping) { + var source = mapping.source === null ? null : this._sources.at(mapping.source); + source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL); + return { + source: source, + generatedLine: mapping.generatedLine, + generatedColumn: mapping.generatedColumn, + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: mapping.name === null ? null : this._names.at(mapping.name) + }; + }, this).forEach(aCallback, context); + }; + + /** + * Returns all generated line and column information for the original source, + * line, and column provided. If no column is provided, returns all mappings + * corresponding to a either the line we are searching for or the next + * closest line that has any mappings. Otherwise, returns all mappings + * corresponding to the given line and either the column we are searching for + * or the next closest column that has any offsets. + * + * The only argument is an object with the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. The line number is 1-based. + * - column: Optional. the column number in the original source. + * The column number is 0-based. + * + * and an array of objects is returned, each with the following properties: + * + * - line: The line number in the generated source, or null. The + * line number is 1-based. + * - column: The column number in the generated source, or null. + * The column number is 0-based. + */ + SourceMapConsumer.prototype.allGeneratedPositionsFor = + function SourceMapConsumer_allGeneratedPositionsFor(aArgs) { + var line = util.getArg(aArgs, 'line'); + + // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping + // returns the index of the closest mapping less than the needle. By + // setting needle.originalColumn to 0, we thus find the last mapping for + // the given line, provided such a mapping exists. + var needle = { + source: util.getArg(aArgs, 'source'), + originalLine: line, + originalColumn: util.getArg(aArgs, 'column', 0) + }; + + needle.source = this._findSourceIndex(needle.source); + if (needle.source < 0) { + return []; + } + + var mappings = []; + + var index = this._findMapping(needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + binarySearch.LEAST_UPPER_BOUND); + if (index >= 0) { + var mapping = this._originalMappings[index]; + + if (aArgs.column === undefined) { + var originalLine = mapping.originalLine; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we found. Since + // mappings are sorted, this is guaranteed to find all mappings for + // the line we found. + while (mapping && mapping.originalLine === originalLine) { + mappings.push({ + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } + } else { + var originalColumn = mapping.originalColumn; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we were searching for. + // Since mappings are sorted, this is guaranteed to find all mappings for + // the line we are searching for. + while (mapping && + mapping.originalLine === line && + mapping.originalColumn == originalColumn) { + mappings.push({ + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } + } + } + + return mappings; + }; + + exports.SourceMapConsumer = SourceMapConsumer; + + /** + * A BasicSourceMapConsumer instance represents a parsed source map which we can + * query for information about the original file positions by giving it a file + * position in the generated source. + * + * The first parameter is the raw source map (either as a JSON string, or + * already parsed to an object). According to the spec, source maps have the + * following attributes: + * + * - version: Which version of the source map spec this map is following. + * - sources: An array of URLs to the original source files. + * - names: An array of identifiers which can be referrenced by individual mappings. + * - sourceRoot: Optional. The URL root from which all sources are relative. + * - sourcesContent: Optional. An array of contents of the original source files. + * - mappings: A string of base64 VLQs which contain the actual mappings. + * - file: Optional. The generated file this source map is associated with. + * + * Here is an example source map, taken from the source map spec[0]: + * + * { + * version : 3, + * file: "out.js", + * sourceRoot : "", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AA,AB;;ABCDE;" + * } + * + * The second parameter, if given, is a string whose value is the URL + * at which the source map was found. This URL is used to compute the + * sources array. + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# + */ + function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = util.parseSourceMapInput(aSourceMap); + } + + var version = util.getArg(sourceMap, 'version'); + var sources = util.getArg(sourceMap, 'sources'); + // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which + // requires the array) to play nice here. + var names = util.getArg(sourceMap, 'names', []); + var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); + var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); + var mappings = util.getArg(sourceMap, 'mappings'); + var file = util.getArg(sourceMap, 'file', null); + + // Once again, Sass deviates from the spec and supplies the version as a + // string rather than a number, so we use loose equality checking here. + if (version != this._version) { + throw new Error('Unsupported version: ' + version); + } + + if (sourceRoot) { + sourceRoot = util.normalize(sourceRoot); + } + + sources = sources + .map(String) + // Some source maps produce relative source paths like "./foo.js" instead of + // "foo.js". Normalize these first so that future comparisons will succeed. + // See bugzil.la/1090768. + .map(util.normalize) + // Always ensure that absolute sources are internally stored relative to + // the source root, if the source root is absolute. Not doing this would + // be particularly problematic when the source root is a prefix of the + // source (valid, but why??). See github issue #199 and bugzil.la/1188982. + .map(function (source) { + return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) + ? util.relative(sourceRoot, source) + : source; + }); + + // Pass `true` below to allow duplicate names and sources. While source maps + // are intended to be compressed and deduplicated, the TypeScript compiler + // sometimes generates source maps with duplicates in them. See Github issue + // #72 and bugzil.la/889492. + this._names = ArraySet.fromArray(names.map(String), true); + this._sources = ArraySet.fromArray(sources, true); + + this._absoluteSources = this._sources.toArray().map(function (s) { + return util.computeSourceURL(sourceRoot, s, aSourceMapURL); + }); + + this.sourceRoot = sourceRoot; + this.sourcesContent = sourcesContent; + this._mappings = mappings; + this._sourceMapURL = aSourceMapURL; + this.file = file; + } + + BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); + BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer; + + /** + * Utility function to find the index of a source. Returns -1 if not + * found. + */ + BasicSourceMapConsumer.prototype._findSourceIndex = function(aSource) { + var relativeSource = aSource; + if (this.sourceRoot != null) { + relativeSource = util.relative(this.sourceRoot, relativeSource); + } + + if (this._sources.has(relativeSource)) { + return this._sources.indexOf(relativeSource); + } + + // Maybe aSource is an absolute URL as returned by |sources|. In + // this case we can't simply undo the transform. + var i; + for (i = 0; i < this._absoluteSources.length; ++i) { + if (this._absoluteSources[i] == aSource) { + return i; + } + } + + return -1; + }; + + /** + * Create a BasicSourceMapConsumer from a SourceMapGenerator. + * + * @param SourceMapGenerator aSourceMap + * The source map that will be consumed. + * @param String aSourceMapURL + * The URL at which the source map can be found (optional) + * @returns BasicSourceMapConsumer + */ + BasicSourceMapConsumer.fromSourceMap = + function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) { + var smc = Object.create(BasicSourceMapConsumer.prototype); + + var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); + var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); + smc.sourceRoot = aSourceMap._sourceRoot; + smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), + smc.sourceRoot); + smc.file = aSourceMap._file; + smc._sourceMapURL = aSourceMapURL; + smc._absoluteSources = smc._sources.toArray().map(function (s) { + return util.computeSourceURL(smc.sourceRoot, s, aSourceMapURL); + }); + + // Because we are modifying the entries (by converting string sources and + // names to indices into the sources and names ArraySets), we have to make + // a copy of the entry or else bad things happen. Shared mutable state + // strikes again! See github issue #191. + + var generatedMappings = aSourceMap._mappings.toArray().slice(); + var destGeneratedMappings = smc.__generatedMappings = []; + var destOriginalMappings = smc.__originalMappings = []; + + for (var i = 0, length = generatedMappings.length; i < length; i++) { + var srcMapping = generatedMappings[i]; + var destMapping = new Mapping; + destMapping.generatedLine = srcMapping.generatedLine; + destMapping.generatedColumn = srcMapping.generatedColumn; + + if (srcMapping.source) { + destMapping.source = sources.indexOf(srcMapping.source); + destMapping.originalLine = srcMapping.originalLine; + destMapping.originalColumn = srcMapping.originalColumn; + + if (srcMapping.name) { + destMapping.name = names.indexOf(srcMapping.name); + } + + destOriginalMappings.push(destMapping); + } + + destGeneratedMappings.push(destMapping); + } + + quickSort(smc.__originalMappings, util.compareByOriginalPositions); + + return smc; + }; + + /** + * The version of the source mapping spec that we are consuming. + */ + BasicSourceMapConsumer.prototype._version = 3; + + /** + * The list of original sources. + */ + Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', { + get: function () { + return this._absoluteSources.slice(); + } + }); + + /** + * Provide the JIT with a nice shape / hidden class. + */ + function Mapping() { + this.generatedLine = 0; + this.generatedColumn = 0; + this.source = null; + this.originalLine = null; + this.originalColumn = null; + this.name = null; + } + + /** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ + BasicSourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + var generatedLine = 1; + var previousGeneratedColumn = 0; + var previousOriginalLine = 0; + var previousOriginalColumn = 0; + var previousSource = 0; + var previousName = 0; + var length = aStr.length; + var index = 0; + var cachedSegments = {}; + var temp = {}; + var originalMappings = []; + var generatedMappings = []; + var mapping, str, segment, end, value; + + while (index < length) { + if (aStr.charAt(index) === ';') { + generatedLine++; + index++; + previousGeneratedColumn = 0; + } + else if (aStr.charAt(index) === ',') { + index++; + } + else { + mapping = new Mapping(); + mapping.generatedLine = generatedLine; + + // Because each offset is encoded relative to the previous one, + // many segments often have the same encoding. We can exploit this + // fact by caching the parsed variable length fields of each segment, + // allowing us to avoid a second parse if we encounter the same + // segment again. + for (end = index; end < length; end++) { + if (this._charIsMappingSeparator(aStr, end)) { + break; + } + } + str = aStr.slice(index, end); + + segment = cachedSegments[str]; + if (segment) { + index += str.length; + } else { + segment = []; + while (index < end) { + base64VLQ.decode(aStr, index, temp); + value = temp.value; + index = temp.rest; + segment.push(value); + } + + if (segment.length === 2) { + throw new Error('Found a source, but no line and column'); + } + + if (segment.length === 3) { + throw new Error('Found a source and line, but no column'); + } + + cachedSegments[str] = segment; + } + + // Generated column. + mapping.generatedColumn = previousGeneratedColumn + segment[0]; + previousGeneratedColumn = mapping.generatedColumn; + + if (segment.length > 1) { + // Original source. + mapping.source = previousSource + segment[1]; + previousSource += segment[1]; + + // Original line. + mapping.originalLine = previousOriginalLine + segment[2]; + previousOriginalLine = mapping.originalLine; + // Lines are stored 0-based + mapping.originalLine += 1; + + // Original column. + mapping.originalColumn = previousOriginalColumn + segment[3]; + previousOriginalColumn = mapping.originalColumn; + + if (segment.length > 4) { + // Original name. + mapping.name = previousName + segment[4]; + previousName += segment[4]; + } + } + + generatedMappings.push(mapping); + if (typeof mapping.originalLine === 'number') { + originalMappings.push(mapping); + } + } + } + + quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated); + this.__generatedMappings = generatedMappings; + + quickSort(originalMappings, util.compareByOriginalPositions); + this.__originalMappings = originalMappings; + }; + + /** + * Find the mapping that best matches the hypothetical "needle" mapping that + * we are searching for in the given "haystack" of mappings. + */ + BasicSourceMapConsumer.prototype._findMapping = + function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, + aColumnName, aComparator, aBias) { + // To return the position we are searching for, we must first find the + // mapping for the given position and then return the opposite position it + // points to. Because the mappings are sorted, we can use binary search to + // find the best mapping. + + if (aNeedle[aLineName] <= 0) { + throw new TypeError('Line must be greater than or equal to 1, got ' + + aNeedle[aLineName]); + } + if (aNeedle[aColumnName] < 0) { + throw new TypeError('Column must be greater than or equal to 0, got ' + + aNeedle[aColumnName]); + } + + return binarySearch.search(aNeedle, aMappings, aComparator, aBias); + }; + + /** + * Compute the last column for each generated mapping. The last column is + * inclusive. + */ + BasicSourceMapConsumer.prototype.computeColumnSpans = + function SourceMapConsumer_computeColumnSpans() { + for (var index = 0; index < this._generatedMappings.length; ++index) { + var mapping = this._generatedMappings[index]; + + // Mappings do not contain a field for the last generated columnt. We + // can come up with an optimistic estimate, however, by assuming that + // mappings are contiguous (i.e. given two consecutive mappings, the + // first mapping ends where the second one starts). + if (index + 1 < this._generatedMappings.length) { + var nextMapping = this._generatedMappings[index + 1]; + + if (mapping.generatedLine === nextMapping.generatedLine) { + mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1; + continue; + } + } + + // The last mapping for each line spans the entire line. + mapping.lastGeneratedColumn = Infinity; + } + }; + + /** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. The line number + * is 1-based. + * - column: The column number in the generated source. The column + * number is 0-based. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. The + * line number is 1-based. + * - column: The column number in the original source, or null. The + * column number is 0-based. + * - name: The original identifier, or null. + */ + BasicSourceMapConsumer.prototype.originalPositionFor = + function SourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; + + var index = this._findMapping( + needle, + this._generatedMappings, + "generatedLine", + "generatedColumn", + util.compareByGeneratedPositionsDeflated, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._generatedMappings[index]; + + if (mapping.generatedLine === needle.generatedLine) { + var source = util.getArg(mapping, 'source', null); + if (source !== null) { + source = this._sources.at(source); + source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL); + } + var name = util.getArg(mapping, 'name', null); + if (name !== null) { + name = this._names.at(name); + } + return { + source: source, + line: util.getArg(mapping, 'originalLine', null), + column: util.getArg(mapping, 'originalColumn', null), + name: name + }; + } + } + + return { + source: null, + line: null, + column: null, + name: null + }; + }; + + /** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ + BasicSourceMapConsumer.prototype.hasContentsOfAllSources = + function BasicSourceMapConsumer_hasContentsOfAllSources() { + if (!this.sourcesContent) { + return false; + } + return this.sourcesContent.length >= this._sources.size() && + !this.sourcesContent.some(function (sc) { return sc == null; }); + }; + + /** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ + BasicSourceMapConsumer.prototype.sourceContentFor = + function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + if (!this.sourcesContent) { + return null; + } + + var index = this._findSourceIndex(aSource); + if (index >= 0) { + return this.sourcesContent[index]; + } + + var relativeSource = aSource; + if (this.sourceRoot != null) { + relativeSource = util.relative(this.sourceRoot, relativeSource); + } + + var url; + if (this.sourceRoot != null + && (url = util.urlParse(this.sourceRoot))) { + // XXX: file:// URIs and absolute paths lead to unexpected behavior for + // many users. We can help them out when they expect file:// URIs to + // behave like it would if they were running a local HTTP server. See + // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. + var fileUriAbsPath = relativeSource.replace(/^file:\/\//, ""); + if (url.scheme == "file" + && this._sources.has(fileUriAbsPath)) { + return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] + } + + if ((!url.path || url.path == "/") + && this._sources.has("/" + relativeSource)) { + return this.sourcesContent[this._sources.indexOf("/" + relativeSource)]; + } + } + + // This function is used recursively from + // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we + // don't want to throw if we can't find the source - we just want to + // return null, so we provide a flag to exit gracefully. + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + relativeSource + '" is not in the SourceMap.'); + } + }; + + /** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. The line number + * is 1-based. + * - column: The column number in the original source. The column + * number is 0-based. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. The + * line number is 1-based. + * - column: The column number in the generated source, or null. + * The column number is 0-based. + */ + BasicSourceMapConsumer.prototype.generatedPositionFor = + function SourceMapConsumer_generatedPositionFor(aArgs) { + var source = util.getArg(aArgs, 'source'); + source = this._findSourceIndex(source); + if (source < 0) { + return { + line: null, + column: null, + lastColumn: null + }; + } + + var needle = { + source: source, + originalLine: util.getArg(aArgs, 'line'), + originalColumn: util.getArg(aArgs, 'column') + }; + + var index = this._findMapping( + needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._originalMappings[index]; + + if (mapping.source === needle.source) { + return { + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }; + } + } + + return { + line: null, + column: null, + lastColumn: null + }; + }; + + exports.BasicSourceMapConsumer = BasicSourceMapConsumer; + + /** + * An IndexedSourceMapConsumer instance represents a parsed source map which + * we can query for information. It differs from BasicSourceMapConsumer in + * that it takes "indexed" source maps (i.e. ones with a "sections" field) as + * input. + * + * The first parameter is a raw source map (either as a JSON string, or already + * parsed to an object). According to the spec for indexed source maps, they + * have the following attributes: + * + * - version: Which version of the source map spec this map is following. + * - file: Optional. The generated file this source map is associated with. + * - sections: A list of section definitions. + * + * Each value under the "sections" field has two fields: + * - offset: The offset into the original specified at which this section + * begins to apply, defined as an object with a "line" and "column" + * field. + * - map: A source map definition. This source map could also be indexed, + * but doesn't have to be. + * + * Instead of the "map" field, it's also possible to have a "url" field + * specifying a URL to retrieve a source map from, but that's currently + * unsupported. + * + * Here's an example source map, taken from the source map spec[0], but + * modified to omit a section which uses the "url" field. + * + * { + * version : 3, + * file: "app.js", + * sections: [{ + * offset: {line:100, column:10}, + * map: { + * version : 3, + * file: "section.js", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AAAA,E;;ABCDE;" + * } + * }], + * } + * + * The second parameter, if given, is a string whose value is the URL + * at which the source map was found. This URL is used to compute the + * sources array. + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt + */ + function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = util.parseSourceMapInput(aSourceMap); + } + + var version = util.getArg(sourceMap, 'version'); + var sections = util.getArg(sourceMap, 'sections'); + + if (version != this._version) { + throw new Error('Unsupported version: ' + version); + } + + this._sources = new ArraySet(); + this._names = new ArraySet(); + + var lastOffset = { + line: -1, + column: 0 + }; + this._sections = sections.map(function (s) { + if (s.url) { + // The url field will require support for asynchronicity. + // See https://github.com/mozilla/source-map/issues/16 + throw new Error('Support for url field in sections not implemented.'); + } + var offset = util.getArg(s, 'offset'); + var offsetLine = util.getArg(offset, 'line'); + var offsetColumn = util.getArg(offset, 'column'); + + if (offsetLine < lastOffset.line || + (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { + throw new Error('Section offsets must be ordered and non-overlapping.'); + } + lastOffset = offset; + + return { + generatedOffset: { + // The offset fields are 0-based, but we use 1-based indices when + // encoding/decoding from VLQ. + generatedLine: offsetLine + 1, + generatedColumn: offsetColumn + 1 + }, + consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL) + } + }); + } + + IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); + IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer; + + /** + * The version of the source mapping spec that we are consuming. + */ + IndexedSourceMapConsumer.prototype._version = 3; + + /** + * The list of original sources. + */ + Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', { + get: function () { + var sources = []; + for (var i = 0; i < this._sections.length; i++) { + for (var j = 0; j < this._sections[i].consumer.sources.length; j++) { + sources.push(this._sections[i].consumer.sources[j]); + } + } + return sources; + } + }); + + /** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. The line number + * is 1-based. + * - column: The column number in the generated source. The column + * number is 0-based. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. The + * line number is 1-based. + * - column: The column number in the original source, or null. The + * column number is 0-based. + * - name: The original identifier, or null. + */ + IndexedSourceMapConsumer.prototype.originalPositionFor = + function IndexedSourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; + + // Find the section containing the generated position we're trying to map + // to an original position. + var sectionIndex = binarySearch.search(needle, this._sections, + function(needle, section) { + var cmp = needle.generatedLine - section.generatedOffset.generatedLine; + if (cmp) { + return cmp; + } + + return (needle.generatedColumn - + section.generatedOffset.generatedColumn); + }); + var section = this._sections[sectionIndex]; + + if (!section) { + return { + source: null, + line: null, + column: null, + name: null + }; + } + + return section.consumer.originalPositionFor({ + line: needle.generatedLine - + (section.generatedOffset.generatedLine - 1), + column: needle.generatedColumn - + (section.generatedOffset.generatedLine === needle.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + bias: aArgs.bias + }); + }; + + /** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ + IndexedSourceMapConsumer.prototype.hasContentsOfAllSources = + function IndexedSourceMapConsumer_hasContentsOfAllSources() { + return this._sections.every(function (s) { + return s.consumer.hasContentsOfAllSources(); + }); + }; + + /** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ + IndexedSourceMapConsumer.prototype.sourceContentFor = + function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + + var content = section.consumer.sourceContentFor(aSource, true); + if (content) { + return content; + } + } + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + aSource + '" is not in the SourceMap.'); + } + }; + + /** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. The line number + * is 1-based. + * - column: The column number in the original source. The column + * number is 0-based. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. The + * line number is 1-based. + * - column: The column number in the generated source, or null. + * The column number is 0-based. + */ + IndexedSourceMapConsumer.prototype.generatedPositionFor = + function IndexedSourceMapConsumer_generatedPositionFor(aArgs) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + + // Only consider this section if the requested source is in the list of + // sources of the consumer. + if (section.consumer._findSourceIndex(util.getArg(aArgs, 'source')) === -1) { + continue; + } + var generatedPosition = section.consumer.generatedPositionFor(aArgs); + if (generatedPosition) { + var ret = { + line: generatedPosition.line + + (section.generatedOffset.generatedLine - 1), + column: generatedPosition.column + + (section.generatedOffset.generatedLine === generatedPosition.line + ? section.generatedOffset.generatedColumn - 1 + : 0) + }; + return ret; + } + } + + return { + line: null, + column: null + }; + }; + + /** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ + IndexedSourceMapConsumer.prototype._parseMappings = + function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) { + this.__generatedMappings = []; + this.__originalMappings = []; + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + var sectionMappings = section.consumer._generatedMappings; + for (var j = 0; j < sectionMappings.length; j++) { + var mapping = sectionMappings[j]; + + var source = section.consumer._sources.at(mapping.source); + source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL); + this._sources.add(source); + source = this._sources.indexOf(source); + + var name = null; + if (mapping.name) { + name = section.consumer._names.at(mapping.name); + this._names.add(name); + name = this._names.indexOf(name); + } + + // The mappings coming from the consumer for the section have + // generated positions relative to the start of the section, so we + // need to offset them to be relative to the start of the concatenated + // generated file. + var adjustedMapping = { + source: source, + generatedLine: mapping.generatedLine + + (section.generatedOffset.generatedLine - 1), + generatedColumn: mapping.generatedColumn + + (section.generatedOffset.generatedLine === mapping.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: name + }; + + this.__generatedMappings.push(adjustedMapping); + if (typeof adjustedMapping.originalLine === 'number') { + this.__originalMappings.push(adjustedMapping); + } + } + } + + quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated); + quickSort(this.__originalMappings, util.compareByOriginalPositions); + }; + + exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; + + +/***/ }), +/* 8 */ +/***/ (function(module, exports) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + exports.GREATEST_LOWER_BOUND = 1; + exports.LEAST_UPPER_BOUND = 2; + + /** + * Recursive implementation of binary search. + * + * @param aLow Indices here and lower do not contain the needle. + * @param aHigh Indices here and higher do not contain the needle. + * @param aNeedle The element being searched for. + * @param aHaystack The non-empty array being searched. + * @param aCompare Function which takes two elements and returns -1, 0, or 1. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + */ + function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { + // This function terminates when one of the following is true: + // + // 1. We find the exact element we are looking for. + // + // 2. We did not find the exact element, but we can return the index of + // the next-closest element. + // + // 3. We did not find the exact element, and there is no next-closest + // element than the one we are searching for, so we return -1. + var mid = Math.floor((aHigh - aLow) / 2) + aLow; + var cmp = aCompare(aNeedle, aHaystack[mid], true); + if (cmp === 0) { + // Found the element we are looking for. + return mid; + } + else if (cmp > 0) { + // Our needle is greater than aHaystack[mid]. + if (aHigh - mid > 1) { + // The element is in the upper half. + return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias); + } + + // The exact needle element was not found in this haystack. Determine if + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return aHigh < aHaystack.length ? aHigh : -1; + } else { + return mid; + } + } + else { + // Our needle is less than aHaystack[mid]. + if (mid - aLow > 1) { + // The element is in the lower half. + return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias); + } + + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return mid; + } else { + return aLow < 0 ? -1 : aLow; + } + } + } + + /** + * This is an implementation of binary search which will always try and return + * the index of the closest element if there is no exact hit. This is because + * mappings between original and generated line/col pairs are single points, + * and there is an implicit region between each of them, so a miss just means + * that you aren't on the very start of a region. + * + * @param aNeedle The element you are looking for. + * @param aHaystack The array that is being searched. + * @param aCompare A function which takes the needle and an element in the + * array and returns -1, 0, or 1 depending on whether the needle is less + * than, equal to, or greater than the element, respectively. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. + */ + exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { + if (aHaystack.length === 0) { + return -1; + } + + var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, + aCompare, aBias || exports.GREATEST_LOWER_BOUND); + if (index < 0) { + return -1; + } + + // We have found either the exact element, or the next-closest element than + // the one we are searching for. However, there may be more than one such + // element. Make sure we always return the smallest of these. + while (index - 1 >= 0) { + if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { + break; + } + --index; + } + + return index; + }; + + +/***/ }), +/* 9 */ +/***/ (function(module, exports) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + // It turns out that some (most?) JavaScript engines don't self-host + // `Array.prototype.sort`. This makes sense because C++ will likely remain + // faster than JS when doing raw CPU-intensive sorting. However, when using a + // custom comparator function, calling back and forth between the VM's C++ and + // JIT'd JS is rather slow *and* loses JIT type information, resulting in + // worse generated code for the comparator function than would be optimal. In + // fact, when sorting with a comparator, these costs outweigh the benefits of + // sorting in C++. By using our own JS-implemented Quick Sort (below), we get + // a ~3500ms mean speed-up in `bench/bench.html`. + + /** + * Swap the elements indexed by `x` and `y` in the array `ary`. + * + * @param {Array} ary + * The array. + * @param {Number} x + * The index of the first item. + * @param {Number} y + * The index of the second item. + */ + function swap(ary, x, y) { + var temp = ary[x]; + ary[x] = ary[y]; + ary[y] = temp; + } + + /** + * Returns a random integer within the range `low .. high` inclusive. + * + * @param {Number} low + * The lower bound on the range. + * @param {Number} high + * The upper bound on the range. + */ + function randomIntInRange(low, high) { + return Math.round(low + (Math.random() * (high - low))); + } + + /** + * The Quick Sort algorithm. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + * @param {Number} p + * Start index of the array + * @param {Number} r + * End index of the array + */ + function doQuickSort(ary, comparator, p, r) { + // If our lower bound is less than our upper bound, we (1) partition the + // array into two pieces and (2) recurse on each half. If it is not, this is + // the empty array and our base case. + + if (p < r) { + // (1) Partitioning. + // + // The partitioning chooses a pivot between `p` and `r` and moves all + // elements that are less than or equal to the pivot to the before it, and + // all the elements that are greater than it after it. The effect is that + // once partition is done, the pivot is in the exact place it will be when + // the array is put in sorted order, and it will not need to be moved + // again. This runs in O(n) time. + + // Always choose a random pivot so that an input array which is reverse + // sorted does not cause O(n^2) running time. + var pivotIndex = randomIntInRange(p, r); + var i = p - 1; + + swap(ary, pivotIndex, r); + var pivot = ary[r]; + + // Immediately after `j` is incremented in this loop, the following hold + // true: + // + // * Every element in `ary[p .. i]` is less than or equal to the pivot. + // + // * Every element in `ary[i+1 .. j-1]` is greater than the pivot. + for (var j = p; j < r; j++) { + if (comparator(ary[j], pivot) <= 0) { + i += 1; + swap(ary, i, j); + } + } + + swap(ary, i + 1, j); + var q = i + 1; + + // (2) Recurse on each half. + + doQuickSort(ary, comparator, p, q - 1); + doQuickSort(ary, comparator, q + 1, r); + } + } + + /** + * Sort the given array in-place with the given comparator function. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + */ + exports.quickSort = function (ary, comparator) { + doQuickSort(ary, comparator, 0, ary.length - 1); + }; + + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var SourceMapGenerator = __webpack_require__(1).SourceMapGenerator; + var util = __webpack_require__(4); + + // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other + // operating systems these days (capturing the result). + var REGEX_NEWLINE = /(\r?\n)/; + + // Newline character code for charCodeAt() comparisons + var NEWLINE_CODE = 10; + + // Private symbol for identifying `SourceNode`s when multiple versions of + // the source-map library are loaded. This MUST NOT CHANGE across + // versions! + var isSourceNode = "$$$isSourceNode$$$"; + + /** + * SourceNodes provide a way to abstract over interpolating/concatenating + * snippets of generated JavaScript source code while maintaining the line and + * column information associated with the original source code. + * + * @param aLine The original line number. + * @param aColumn The original column number. + * @param aSource The original source's filename. + * @param aChunks Optional. An array of strings which are snippets of + * generated JS, or other SourceNodes. + * @param aName The original identifier. + */ + function SourceNode(aLine, aColumn, aSource, aChunks, aName) { + this.children = []; + this.sourceContents = {}; + this.line = aLine == null ? null : aLine; + this.column = aColumn == null ? null : aColumn; + this.source = aSource == null ? null : aSource; + this.name = aName == null ? null : aName; + this[isSourceNode] = true; + if (aChunks != null) this.add(aChunks); + } + + /** + * Creates a SourceNode from generated code and a SourceMapConsumer. + * + * @param aGeneratedCode The generated code + * @param aSourceMapConsumer The SourceMap for the generated code + * @param aRelativePath Optional. The path that relative sources in the + * SourceMapConsumer should be relative to. + */ + SourceNode.fromStringWithSourceMap = + function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) { + // The SourceNode we want to fill with the generated code + // and the SourceMap + var node = new SourceNode(); + + // All even indices of this array are one line of the generated code, + // while all odd indices are the newlines between two adjacent lines + // (since `REGEX_NEWLINE` captures its match). + // Processed fragments are accessed by calling `shiftNextLine`. + var remainingLines = aGeneratedCode.split(REGEX_NEWLINE); + var remainingLinesIndex = 0; + var shiftNextLine = function() { + var lineContents = getNextLine(); + // The last line of a file might not have a newline. + var newLine = getNextLine() || ""; + return lineContents + newLine; + + function getNextLine() { + return remainingLinesIndex < remainingLines.length ? + remainingLines[remainingLinesIndex++] : undefined; + } + }; + + // We need to remember the position of "remainingLines" + var lastGeneratedLine = 1, lastGeneratedColumn = 0; + + // The generate SourceNodes we need a code range. + // To extract it current and last mapping is used. + // Here we store the last mapping. + var lastMapping = null; + + aSourceMapConsumer.eachMapping(function (mapping) { + if (lastMapping !== null) { + // We add the code from "lastMapping" to "mapping": + // First check if there is a new line in between. + if (lastGeneratedLine < mapping.generatedLine) { + // Associate first line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + lastGeneratedLine++; + lastGeneratedColumn = 0; + // The remaining code is added without mapping + } else { + // There is no new line in between. + // Associate the code between "lastGeneratedColumn" and + // "mapping.generatedColumn" with "lastMapping" + var nextLine = remainingLines[remainingLinesIndex] || ''; + var code = nextLine.substr(0, mapping.generatedColumn - + lastGeneratedColumn); + remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn - + lastGeneratedColumn); + lastGeneratedColumn = mapping.generatedColumn; + addMappingWithCode(lastMapping, code); + // No more remaining code, continue + lastMapping = mapping; + return; + } + } + // We add the generated code until the first mapping + // to the SourceNode without any mapping. + // Each line is added as separate string. + while (lastGeneratedLine < mapping.generatedLine) { + node.add(shiftNextLine()); + lastGeneratedLine++; + } + if (lastGeneratedColumn < mapping.generatedColumn) { + var nextLine = remainingLines[remainingLinesIndex] || ''; + node.add(nextLine.substr(0, mapping.generatedColumn)); + remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn); + lastGeneratedColumn = mapping.generatedColumn; + } + lastMapping = mapping; + }, this); + // We have processed all mappings. + if (remainingLinesIndex < remainingLines.length) { + if (lastMapping) { + // Associate the remaining code in the current line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + } + // and add the remaining lines without any mapping + node.add(remainingLines.splice(remainingLinesIndex).join("")); + } + + // Copy sourcesContent into SourceNode + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aRelativePath != null) { + sourceFile = util.join(aRelativePath, sourceFile); + } + node.setSourceContent(sourceFile, content); + } + }); + + return node; + + function addMappingWithCode(mapping, code) { + if (mapping === null || mapping.source === undefined) { + node.add(code); + } else { + var source = aRelativePath + ? util.join(aRelativePath, mapping.source) + : mapping.source; + node.add(new SourceNode(mapping.originalLine, + mapping.originalColumn, + source, + code, + mapping.name)); + } + } + }; + + /** + * Add a chunk of generated JS to this source node. + * + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. + */ + SourceNode.prototype.add = function SourceNode_add(aChunk) { + if (Array.isArray(aChunk)) { + aChunk.forEach(function (chunk) { + this.add(chunk); + }, this); + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + if (aChunk) { + this.children.push(aChunk); + } + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; + }; + + /** + * Add a chunk of generated JS to the beginning of this source node. + * + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. + */ + SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { + if (Array.isArray(aChunk)) { + for (var i = aChunk.length-1; i >= 0; i--) { + this.prepend(aChunk[i]); + } + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + this.children.unshift(aChunk); + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; + }; + + /** + * Walk over the tree of JS snippets in this node and its children. The + * walking function is called once for each snippet of JS and is passed that + * snippet and the its original associated source's line/column location. + * + * @param aFn The traversal function. + */ + SourceNode.prototype.walk = function SourceNode_walk(aFn) { + var chunk; + for (var i = 0, len = this.children.length; i < len; i++) { + chunk = this.children[i]; + if (chunk[isSourceNode]) { + chunk.walk(aFn); + } + else { + if (chunk !== '') { + aFn(chunk, { source: this.source, + line: this.line, + column: this.column, + name: this.name }); + } + } + } + }; + + /** + * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between + * each of `this.children`. + * + * @param aSep The separator. + */ + SourceNode.prototype.join = function SourceNode_join(aSep) { + var newChildren; + var i; + var len = this.children.length; + if (len > 0) { + newChildren = []; + for (i = 0; i < len-1; i++) { + newChildren.push(this.children[i]); + newChildren.push(aSep); + } + newChildren.push(this.children[i]); + this.children = newChildren; + } + return this; + }; + + /** + * Call String.prototype.replace on the very right-most source snippet. Useful + * for trimming whitespace from the end of a source node, etc. + * + * @param aPattern The pattern to replace. + * @param aReplacement The thing to replace the pattern with. + */ + SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { + var lastChild = this.children[this.children.length - 1]; + if (lastChild[isSourceNode]) { + lastChild.replaceRight(aPattern, aReplacement); + } + else if (typeof lastChild === 'string') { + this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); + } + else { + this.children.push(''.replace(aPattern, aReplacement)); + } + return this; + }; + + /** + * Set the source content for a source file. This will be added to the SourceMapGenerator + * in the sourcesContent field. + * + * @param aSourceFile The filename of the source file + * @param aSourceContent The content of the source file + */ + SourceNode.prototype.setSourceContent = + function SourceNode_setSourceContent(aSourceFile, aSourceContent) { + this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; + }; + + /** + * Walk over the tree of SourceNodes. The walking function is called for each + * source file content and is passed the filename and source content. + * + * @param aFn The traversal function. + */ + SourceNode.prototype.walkSourceContents = + function SourceNode_walkSourceContents(aFn) { + for (var i = 0, len = this.children.length; i < len; i++) { + if (this.children[i][isSourceNode]) { + this.children[i].walkSourceContents(aFn); + } + } + + var sources = Object.keys(this.sourceContents); + for (var i = 0, len = sources.length; i < len; i++) { + aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); + } + }; + + /** + * Return the string representation of this source node. Walks over the tree + * and concatenates all the various snippets together to one string. + */ + SourceNode.prototype.toString = function SourceNode_toString() { + var str = ""; + this.walk(function (chunk) { + str += chunk; + }); + return str; + }; + + /** + * Returns the string representation of this source node along with a source + * map. + */ + SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { + var generated = { + code: "", + line: 1, + column: 0 + }; + var map = new SourceMapGenerator(aArgs); + var sourceMappingActive = false; + var lastOriginalSource = null; + var lastOriginalLine = null; + var lastOriginalColumn = null; + var lastOriginalName = null; + this.walk(function (chunk, original) { + generated.code += chunk; + if (original.source !== null + && original.line !== null + && original.column !== null) { + if(lastOriginalSource !== original.source + || lastOriginalLine !== original.line + || lastOriginalColumn !== original.column + || lastOriginalName !== original.name) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + lastOriginalSource = original.source; + lastOriginalLine = original.line; + lastOriginalColumn = original.column; + lastOriginalName = original.name; + sourceMappingActive = true; + } else if (sourceMappingActive) { + map.addMapping({ + generated: { + line: generated.line, + column: generated.column + } + }); + lastOriginalSource = null; + sourceMappingActive = false; + } + for (var idx = 0, length = chunk.length; idx < length; idx++) { + if (chunk.charCodeAt(idx) === NEWLINE_CODE) { + generated.line++; + generated.column = 0; + // Mappings end at eol + if (idx + 1 === length) { + lastOriginalSource = null; + sourceMappingActive = false; + } else if (sourceMappingActive) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + } else { + generated.column++; + } + } + }); + this.walkSourceContents(function (sourceFile, sourceContent) { + map.setSourceContent(sourceFile, sourceContent); + }); + + return { code: generated.code, map: map }; + }; + + exports.SourceNode = SourceNode; + + +/***/ }) +/******/ ]) +}); +; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovLy93ZWJwYWNrL2Jvb3RzdHJhcCAxNjI0YzcyOTliODg3ZjdiZGY2NCIsIndlYnBhY2s6Ly8vLi9zb3VyY2UtbWFwLmpzIiwid2VicGFjazovLy8uL2xpYi9zb3VyY2UtbWFwLWdlbmVyYXRvci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LXZscS5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmFzZTY0LmpzIiwid2VicGFjazovLy8uL2xpYi91dGlsLmpzIiwid2VicGFjazovLy8uL2xpYi9hcnJheS1zZXQuanMiLCJ3ZWJwYWNrOi8vLy4vbGliL21hcHBpbmctbGlzdC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvc291cmNlLW1hcC1jb25zdW1lci5qcyIsIndlYnBhY2s6Ly8vLi9saWIvYmluYXJ5LXNlYXJjaC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvcXVpY2stc29ydC5qcyIsIndlYnBhY2s6Ly8vLi9saWIvc291cmNlLW5vZGUuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNELE87QUNWQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx1QkFBZTtBQUNmO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNQQSxpQkFBZ0Isb0JBQW9CO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLE1BQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJDQUEwQyxTQUFTO0FBQ25EO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EscUJBQW9CO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7OztBQ3hhQSxpQkFBZ0Isb0JBQW9CO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0REFBMkQ7QUFDM0QscUJBQW9CO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7O0FBRUg7QUFDQTtBQUNBOzs7Ozs7O0FDM0lBLGlCQUFnQixvQkFBb0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFnQjtBQUNoQixpQkFBZ0I7O0FBRWhCLG9CQUFtQjtBQUNuQixxQkFBb0I7O0FBRXBCLGlCQUFnQjtBQUNoQixpQkFBZ0I7O0FBRWhCLGlCQUFnQjtBQUNoQixrQkFBaUI7O0FBRWpCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7Ozs7O0FDbEVBLGlCQUFnQixvQkFBb0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLCtDQUE4QyxRQUFRO0FBQ3REO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw0QkFBMkIsUUFBUTtBQUNuQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGNBQWE7QUFDYjs7QUFFQTtBQUNBLGVBQWM7QUFDZDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUFzQztBQUN0QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7Ozs7O0FDdmVBLGlCQUFnQixvQkFBb0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUFzQyxTQUFTO0FBQy9DO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7Ozs7QUN4SEEsaUJBQWdCLG9CQUFvQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFnQjtBQUNoQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7Ozs7Ozs7QUM5RUEsaUJBQWdCLG9CQUFvQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0Esb0JBQW1CO0FBQ25COztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVc7O0FBRVg7QUFDQTtBQUNBLFFBQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBVzs7QUFFWDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTJCLE1BQU07QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWEsa0NBQWtDO0FBQy9DO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHVEQUFzRCxZQUFZO0FBQ2xFO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esb0NBQW1DO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBeUIsY0FBYztBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFVBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXVCLHdDQUF3QztBQUMvRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUErQyxtQkFBbUIsRUFBRTtBQUNwRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBaUIsb0JBQW9CO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBNkIsTUFBTTtBQUNuQztBQUNBLFFBQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTztBQUNQO0FBQ0E7QUFDQSxJQUFHO0FBQ0g7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBbUIsMkJBQTJCO0FBQzlDLHNCQUFxQiwrQ0FBK0M7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsUUFBTztBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW1CLDJCQUEyQjtBQUM5Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFtQiwyQkFBMkI7QUFDOUM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW1CLDJCQUEyQjtBQUM5QztBQUNBO0FBQ0Esc0JBQXFCLDRCQUE0QjtBQUNqRDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7Ozs7OztBQ3huQ0EsaUJBQWdCLG9CQUFvQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7Ozs7Ozs7QUM5R0EsaUJBQWdCLG9CQUFvQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFXLE1BQU07QUFDakI7QUFDQSxZQUFXLE9BQU87QUFDbEI7QUFDQSxZQUFXLE9BQU87QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxPQUFPO0FBQ2xCO0FBQ0EsWUFBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxNQUFNO0FBQ2pCO0FBQ0EsWUFBVyxTQUFTO0FBQ3BCO0FBQ0EsWUFBVyxPQUFPO0FBQ2xCO0FBQ0EsWUFBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBbUIsT0FBTztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsWUFBVyxNQUFNO0FBQ2pCO0FBQ0EsWUFBVyxTQUFTO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNqSEEsaUJBQWdCLG9CQUFvQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSzs7QUFFTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWlDLFFBQVE7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOENBQTZDLFNBQVM7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQW9CO0FBQ3BCO0FBQ0E7QUFDQSx1Q0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWUsV0FBVztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQStDLFNBQVM7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQ0FBeUMsU0FBUztBQUNsRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQSxZQUFXO0FBQ1g7QUFDQSxVQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsNkNBQTRDLGNBQWM7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQSxjQUFhO0FBQ2I7QUFDQSxZQUFXO0FBQ1g7QUFDQSxRQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsSUFBRztBQUNIO0FBQ0E7QUFDQSxJQUFHOztBQUVILFdBQVU7QUFDVjs7QUFFQSIsImZpbGUiOiJzb3VyY2UtbWFwLmRlYnVnLmpzIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuXHRlbHNlIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZClcblx0XHRkZWZpbmUoW10sIGZhY3RvcnkpO1xuXHRlbHNlIGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jylcblx0XHRleHBvcnRzW1wic291cmNlTWFwXCJdID0gZmFjdG9yeSgpO1xuXHRlbHNlXG5cdFx0cm9vdFtcInNvdXJjZU1hcFwiXSA9IGZhY3RvcnkoKTtcbn0pKHRoaXMsIGZ1bmN0aW9uKCkge1xucmV0dXJuIFxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyB3ZWJwYWNrL3VuaXZlcnNhbE1vZHVsZURlZmluaXRpb24iLCIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSlcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcblxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0ZXhwb3J0czoge30sXG4gXHRcdFx0aWQ6IG1vZHVsZUlkLFxuIFx0XHRcdGxvYWRlZDogZmFsc2VcbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubG9hZGVkID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXygwKTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyB3ZWJwYWNrL2Jvb3RzdHJhcCAxNjI0YzcyOTliODg3ZjdiZGY2NCIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwOS0yMDExIE1vemlsbGEgRm91bmRhdGlvbiBhbmQgY29udHJpYnV0b3JzXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTmV3IEJTRCBsaWNlbnNlLiBTZWUgTElDRU5TRS50eHQgb3I6XG4gKiBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvQlNELTMtQ2xhdXNlXG4gKi9cbmV4cG9ydHMuU291cmNlTWFwR2VuZXJhdG9yID0gcmVxdWlyZSgnLi9saWIvc291cmNlLW1hcC1nZW5lcmF0b3InKS5Tb3VyY2VNYXBHZW5lcmF0b3I7XG5leHBvcnRzLlNvdXJjZU1hcENvbnN1bWVyID0gcmVxdWlyZSgnLi9saWIvc291cmNlLW1hcC1jb25zdW1lcicpLlNvdXJjZU1hcENvbnN1bWVyO1xuZXhwb3J0cy5Tb3VyY2VOb2RlID0gcmVxdWlyZSgnLi9saWIvc291cmNlLW5vZGUnKS5Tb3VyY2VOb2RlO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9zb3VyY2UtbWFwLmpzXG4vLyBtb2R1bGUgaWQgPSAwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qIC0qLSBNb2RlOiBqczsganMtaW5kZW50LWxldmVsOiAyOyAtKi0gKi9cbi8qXG4gKiBDb3B5cmlnaHQgMjAxMSBNb3ppbGxhIEZvdW5kYXRpb24gYW5kIGNvbnRyaWJ1dG9yc1xuICogTGljZW5zZWQgdW5kZXIgdGhlIE5ldyBCU0QgbGljZW5zZS4gU2VlIExJQ0VOU0Ugb3I6XG4gKiBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvQlNELTMtQ2xhdXNlXG4gKi9cblxudmFyIGJhc2U2NFZMUSA9IHJlcXVpcmUoJy4vYmFzZTY0LXZscScpO1xudmFyIHV0aWwgPSByZXF1aXJlKCcuL3V0aWwnKTtcbnZhciBBcnJheVNldCA9IHJlcXVpcmUoJy4vYXJyYXktc2V0JykuQXJyYXlTZXQ7XG52YXIgTWFwcGluZ0xpc3QgPSByZXF1aXJlKCcuL21hcHBpbmctbGlzdCcpLk1hcHBpbmdMaXN0O1xuXG4vKipcbiAqIEFuIGluc3RhbmNlIG9mIHRoZSBTb3VyY2VNYXBHZW5lcmF0b3IgcmVwcmVzZW50cyBhIHNvdXJjZSBtYXAgd2hpY2ggaXNcbiAqIGJlaW5nIGJ1aWx0IGluY3JlbWVudGFsbHkuIFlvdSBtYXkgcGFzcyBhbiBvYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nXG4gKiBwcm9wZXJ0aWVzOlxuICpcbiAqICAgLSBmaWxlOiBUaGUgZmlsZW5hbWUgb2YgdGhlIGdlbmVyYXRlZCBzb3VyY2UuXG4gKiAgIC0gc291cmNlUm9vdDogQSByb290IGZvciBhbGwgcmVsYXRpdmUgVVJMcyBpbiB0aGlzIHNvdXJjZSBtYXAuXG4gKi9cbmZ1bmN0aW9uIFNvdXJjZU1hcEdlbmVyYXRvcihhQXJncykge1xuICBpZiAoIWFBcmdzKSB7XG4gICAgYUFyZ3MgPSB7fTtcbiAgfVxuICB0aGlzLl9maWxlID0gdXRpbC5nZXRBcmcoYUFyZ3MsICdmaWxlJywgbnVsbCk7XG4gIHRoaXMuX3NvdXJjZVJvb3QgPSB1dGlsLmdldEFyZyhhQXJncywgJ3NvdXJjZVJvb3QnLCBudWxsKTtcbiAgdGhpcy5fc2tpcFZhbGlkYXRpb24gPSB1dGlsLmdldEFyZyhhQXJncywgJ3NraXBWYWxpZGF0aW9uJywgZmFsc2UpO1xuICB0aGlzLl9zb3VyY2VzID0gbmV3IEFycmF5U2V0KCk7XG4gIHRoaXMuX25hbWVzID0gbmV3IEFycmF5U2V0KCk7XG4gIHRoaXMuX21hcHBpbmdzID0gbmV3IE1hcHBpbmdMaXN0KCk7XG4gIHRoaXMuX3NvdXJjZXNDb250ZW50cyA9IG51bGw7XG59XG5cblNvdXJjZU1hcEdlbmVyYXRvci5wcm90b3R5cGUuX3ZlcnNpb24gPSAzO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgU291cmNlTWFwR2VuZXJhdG9yIGJhc2VkIG9uIGEgU291cmNlTWFwQ29uc3VtZXJcbiAqXG4gKiBAcGFyYW0gYVNvdXJjZU1hcENvbnN1bWVyIFRoZSBTb3VyY2VNYXAuXG4gKi9cblNvdXJjZU1hcEdlbmVyYXRvci5mcm9tU291cmNlTWFwID1cbiAgZnVuY3Rpb24gU291cmNlTWFwR2VuZXJhdG9yX2Zyb21Tb3VyY2VNYXAoYVNvdXJjZU1hcENvbnN1bWVyKSB7XG4gICAgdmFyIHNvdXJjZVJvb3QgPSBhU291cmNlTWFwQ29uc3VtZXIuc291cmNlUm9vdDtcbiAgICB2YXIgZ2VuZXJhdG9yID0gbmV3IFNvdXJjZU1hcEdlbmVyYXRvcih7XG4gICAgICBmaWxlOiBhU291cmNlTWFwQ29uc3VtZXIuZmlsZSxcbiAgICAgIHNvdXJjZVJvb3Q6IHNvdXJjZVJvb3RcbiAgICB9KTtcbiAgICBhU291cmNlTWFwQ29uc3VtZXIuZWFjaE1hcHBpbmcoZnVuY3Rpb24gKG1hcHBpbmcpIHtcbiAgICAgIHZhciBuZXdNYXBwaW5nID0ge1xuICAgICAgICBnZW5lcmF0ZWQ6IHtcbiAgICAgICAgICBsaW5lOiBtYXBwaW5nLmdlbmVyYXRlZExpbmUsXG4gICAgICAgICAgY29sdW1uOiBtYXBwaW5nLmdlbmVyYXRlZENvbHVtblxuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBpZiAobWFwcGluZy5zb3VyY2UgIT0gbnVsbCkge1xuICAgICAgICBuZXdNYXBwaW5nLnNvdXJjZSA9IG1hcHBpbmcuc291cmNlO1xuICAgICAgICBpZiAoc291cmNlUm9vdCAhPSBudWxsKSB7XG4gICAgICAgICAgbmV3TWFwcGluZy5zb3VyY2UgPSB1dGlsLnJlbGF0aXZlKHNvdXJjZVJvb3QsIG5ld01hcHBpbmcuc291cmNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5ld01hcHBpbmcub3JpZ2luYWwgPSB7XG4gICAgICAgICAgbGluZTogbWFwcGluZy5vcmlnaW5hbExpbmUsXG4gICAgICAgICAgY29sdW1uOiBtYXBwaW5nLm9yaWdpbmFsQ29sdW1uXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKG1hcHBpbmcubmFtZSAhPSBudWxsKSB7XG4gICAgICAgICAgbmV3TWFwcGluZy5uYW1lID0gbWFwcGluZy5uYW1lO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGdlbmVyYXRvci5hZGRNYXBwaW5nKG5ld01hcHBpbmcpO1xuICAgIH0pO1xuICAgIGFTb3VyY2VNYXBDb25zdW1lci5zb3VyY2VzLmZvckVhY2goZnVuY3Rpb24gKHNvdXJjZUZpbGUpIHtcbiAgICAgIHZhciBzb3VyY2VSZWxhdGl2ZSA9IHNvdXJjZUZpbGU7XG4gICAgICBpZiAoc291cmNlUm9vdCAhPT0gbnVsbCkge1xuICAgICAgICBzb3VyY2VSZWxhdGl2ZSA9IHV0aWwucmVsYXRpdmUoc291cmNlUm9vdCwgc291cmNlRmlsZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghZ2VuZXJhdG9yLl9zb3VyY2VzLmhhcyhzb3VyY2VSZWxhdGl2ZSkpIHtcbiAgICAgICAgZ2VuZXJhdG9yLl9zb3VyY2VzLmFkZChzb3VyY2VSZWxhdGl2ZSk7XG4gICAgICB9XG5cbiAgICAgIHZhciBjb250ZW50ID0gYVNvdXJjZU1hcENvbnN1bWVyLnNvdXJjZUNvbnRlbnRGb3Ioc291cmNlRmlsZSk7XG4gICAgICBpZiAoY29udGVudCAhPSBudWxsKSB7XG4gICAgICAgIGdlbmVyYXRvci5zZXRTb3VyY2VDb250ZW50KHNvdXJjZUZpbGUsIGNvbnRlbnQpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBnZW5lcmF0b3I7XG4gIH07XG5cbi8qKlxuICogQWRkIGEgc2luZ2xlIG1hcHBpbmcgZnJvbSBvcmlnaW5hbCBzb3VyY2UgbGluZSBhbmQgY29sdW1uIHRvIHRoZSBnZW5lcmF0ZWRcbiAqIHNvdXJjZSdzIGxpbmUgYW5kIGNvbHVtbiBmb3IgdGhpcyBzb3VyY2UgbWFwIGJlaW5nIGNyZWF0ZWQuIFRoZSBtYXBwaW5nXG4gKiBvYmplY3Qgc2hvdWxkIGhhdmUgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICpcbiAqICAgLSBnZW5lcmF0ZWQ6IEFuIG9iamVjdCB3aXRoIHRoZSBnZW5lcmF0ZWQgbGluZSBhbmQgY29sdW1uIHBvc2l0aW9ucy5cbiAqICAgLSBvcmlnaW5hbDogQW4gb2JqZWN0IHdpdGggdGhlIG9yaWdpbmFsIGxpbmUgYW5kIGNvbHVtbiBwb3NpdGlvbnMuXG4gKiAgIC0gc291cmNlOiBUaGUgb3JpZ2luYWwgc291cmNlIGZpbGUgKHJlbGF0aXZlIHRvIHRoZSBzb3VyY2VSb290KS5cbiAqICAgLSBuYW1lOiBBbiBvcHRpb25hbCBvcmlnaW5hbCB0b2tlbiBuYW1lIGZvciB0aGlzIG1hcHBpbmcuXG4gKi9cblNvdXJjZU1hcEdlbmVyYXRvci5wcm90b3R5cGUuYWRkTWFwcGluZyA9XG4gIGZ1bmN0aW9uIFNvdXJjZU1hcEdlbmVyYXRvcl9hZGRNYXBwaW5nKGFBcmdzKSB7XG4gICAgdmFyIGdlbmVyYXRlZCA9IHV0aWwuZ2V0QXJnKGFBcmdzLCAnZ2VuZXJhdGVkJyk7XG4gICAgdmFyIG9yaWdpbmFsID0gdXRpbC5nZXRBcmcoYUFyZ3MsICdvcmlnaW5hbCcsIG51bGwpO1xuICAgIHZhciBzb3VyY2UgPSB1dGlsLmdldEFyZyhhQXJncywgJ3NvdXJjZScsIG51bGwpO1xuICAgIHZhciBuYW1lID0gdXRpbC5nZXRBcmcoYUFyZ3MsICduYW1lJywgbnVsbCk7XG5cbiAgICBpZiAoIXRoaXMuX3NraXBWYWxpZGF0aW9uKSB7XG4gICAgICB0aGlzLl92YWxpZGF0ZU1hcHBpbmcoZ2VuZXJhdGVkLCBvcmlnaW5hbCwgc291cmNlLCBuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAoc291cmNlICE9IG51bGwpIHtcbiAgICAgIHNvdXJjZSA9IFN0cmluZyhzb3VyY2UpO1xuICAgICAgaWYgKCF0aGlzLl9zb3VyY2VzLmhhcyhzb3VyY2UpKSB7XG4gICAgICAgIHRoaXMuX3NvdXJjZXMuYWRkKHNvdXJjZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG5hbWUgIT0gbnVsbCkge1xuICAgICAgbmFtZSA9IFN0cmluZyhuYW1lKTtcbiAgICAgIGlmICghdGhpcy5fbmFtZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgIHRoaXMuX25hbWVzLmFkZChuYW1lKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9tYXBwaW5ncy5hZGQoe1xuICAgICAgZ2VuZXJhdGVkTGluZTogZ2VuZXJhdGVkLmxpbmUsXG4gICAgICBnZW5lcmF0ZWRDb2x1bW46IGdlbmVyYXRlZC5jb2x1bW4sXG4gICAgICBvcmlnaW5hbExpbmU6IG9yaWdpbmFsICE9IG51bGwgJiYgb3JpZ2luYWwubGluZSxcbiAgICAgIG9yaWdpbmFsQ29sdW1uOiBvcmlnaW5hbCAhPSBudWxsICYmIG9yaWdpbmFsLmNvbHVtbixcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgbmFtZTogbmFtZVxuICAgIH0pO1xuICB9O1xuXG4vKipcbiAqIFNldCB0aGUgc291cmNlIGNvbnRlbnQgZm9yIGEgc291cmNlIGZpbGUuXG4gKi9cblNvdXJjZU1hcEdlbmVyYXRvci5wcm90b3R5cGUuc2V0U291cmNlQ29udGVudCA9XG4gIGZ1bmN0aW9uIFNvdXJjZU1hcEdlbmVyYXRvcl9zZXRTb3VyY2VDb250ZW50KGFTb3VyY2VGaWxlLCBhU291cmNlQ29udGVudCkge1xuICAgIHZhciBzb3VyY2UgPSBhU291cmNlRmlsZTtcbiAgICBpZiAodGhpcy5fc291cmNlUm9vdCAhPSBudWxsKSB7XG4gICAgICBzb3VyY2UgPSB1dGlsLnJlbGF0aXZlKHRoaXMuX3NvdXJjZVJvb3QsIHNvdXJjZSk7XG4gICAgfVxuXG4gICAgaWYgKGFTb3VyY2VDb250ZW50ICE9IG51bGwpIHtcbiAgICAgIC8vIEFkZCB0aGUgc291cmNlIGNvbnRlbnQgdG8gdGhlIF9zb3VyY2VzQ29udGVudHMgbWFwLlxuICAgICAgLy8gQ3JlYXRlIGEgbmV3IF9zb3VyY2VzQ29udGVudHMgbWFwIGlmIHRoZSBwcm9wZXJ0eSBpcyBudWxsLlxuICAgICAgaWYgKCF0aGlzLl9zb3VyY2VzQ29udGVudHMpIHtcbiAgICAgICAgdGhpcy5fc291cmNlc0NvbnRlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3NvdXJjZXNDb250ZW50c1t1dGlsLnRvU2V0U3RyaW5nKHNvdXJjZSldID0gYVNvdXJjZUNvbnRlbnQ7XG4gICAgfSBlbHNlIGlmICh0aGlzLl9zb3VyY2VzQ29udGVudHMpIHtcbiAgICAgIC8vIFJlbW92ZSB0aGUgc291cmNlIGZpbGUgZnJvbSB0aGUgX3NvdXJjZXNDb250ZW50cyBtYXAuXG4gICAgICAvLyBJZiB0aGUgX3NvdXJjZXNDb250ZW50cyBtYXAgaXMgZW1wdHksIHNldCB0aGUgcHJvcGVydHkgdG8gbnVsbC5cbiAgICAgIGRlbGV0ZSB0aGlzLl9zb3VyY2VzQ29udGVudHNbdXRpbC50b1NldFN0cmluZyhzb3VyY2UpXTtcbiAgICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLl9zb3VyY2VzQ29udGVudHMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLl9zb3VyY2VzQ29udGVudHMgPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuLyoqXG4gKiBBcHBsaWVzIHRoZSBtYXBwaW5ncyBvZiBhIHN1Yi1zb3VyY2UtbWFwIGZvciBhIHNwZWNpZmljIHNvdXJjZSBmaWxlIHRvIHRoZVxuICogc291cmNlIG1hcCBiZWluZyBnZW5lcmF0ZWQuIEVhY2ggbWFwcGluZyB0byB0aGUgc3VwcGxpZWQgc291cmNlIGZpbGUgaXNcbiAqIHJld3JpdHRlbiB1c2luZyB0aGUgc3VwcGxpZWQgc291cmNlIG1hcC4gTm90ZTogVGhlIHJlc29sdXRpb24gZm9yIHRoZVxuICogcmVzdWx0aW5nIG1hcHBpbmdzIGlzIHRoZSBtaW5pbWl1bSBvZiB0aGlzIG1hcCBhbmQgdGhlIHN1cHBsaWVkIG1hcC5cbiAqXG4gKiBAcGFyYW0gYVNvdXJjZU1hcENvbnN1bWVyIFRoZSBzb3VyY2UgbWFwIHRvIGJlIGFwcGxpZWQuXG4gKiBAcGFyYW0gYVNvdXJjZUZpbGUgT3B0aW9uYWwuIFRoZSBmaWxlbmFtZSBvZiB0aGUgc291cmNlIGZpbGUuXG4gKiAgICAgICAgSWYgb21pdHRlZCwgU291cmNlTWFwQ29uc3VtZXIncyBmaWxlIHByb3BlcnR5IHdpbGwgYmUgdXNlZC5cbiAqIEBwYXJhbSBhU291cmNlTWFwUGF0aCBPcHRpb25hbC4gVGhlIGRpcm5hbWUgb2YgdGhlIHBhdGggdG8gdGhlIHNvdXJjZSBtYXBcbiAqICAgICAgICB0byBiZSBhcHBsaWVkLiBJZiByZWxhdGl2ZSwgaXQgaXMgcmVsYXRpdmUgdG8gdGhlIFNvdXJjZU1hcENvbnN1bWVyLlxuICogICAgICAgIFRoaXMgcGFyYW1ldGVyIGlzIG5lZWRlZCB3aGVuIHRoZSB0d28gc291cmNlIG1hcHMgYXJlbid0IGluIHRoZSBzYW1lXG4gKiAgICAgICAgZGlyZWN0b3J5LCBhbmQgdGhlIHNvdXJjZSBtYXAgdG8gYmUgYXBwbGllZCBjb250YWlucyByZWxhdGl2ZSBzb3VyY2VcbiAqICAgICAgICBwYXRocy4gSWYgc28sIHRob3NlIHJlbGF0aXZlIHNvdXJjZSBwYXRocyBuZWVkIHRvIGJlIHJld3JpdHRlblxuICogICAgICAgIHJlbGF0aXZlIHRvIHRoZSBTb3VyY2VNYXBHZW5lcmF0b3IuXG4gKi9cblNvdXJjZU1hcEdlbmVyYXRvci5wcm90b3R5cGUuYXBwbHlTb3VyY2VNYXAgPVxuICBmdW5jdGlvbiBTb3VyY2VNYXBHZW5lcmF0b3JfYXBwbHlTb3VyY2VNYXAoYVNvdXJjZU1hcENvbnN1bWVyLCBhU291cmNlRmlsZSwgYVNvdXJjZU1hcFBhdGgpIHtcbiAgICB2YXIgc291cmNlRmlsZSA9IGFTb3VyY2VGaWxlO1xuICAgIC8vIElmIGFTb3VyY2VGaWxlIGlzIG9taXR0ZWQsIHdlIHdpbGwgdXNlIHRoZSBmaWxlIHByb3BlcnR5IG9mIHRoZSBTb3VyY2VNYXBcbiAgICBpZiAoYVNvdXJjZUZpbGUgPT0gbnVsbCkge1xuICAgICAgaWYgKGFTb3VyY2VNYXBDb25zdW1lci5maWxlID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdTb3VyY2VNYXBHZW5lcmF0b3IucHJvdG90eXBlLmFwcGx5U291cmNlTWFwIHJlcXVpcmVzIGVpdGhlciBhbiBleHBsaWNpdCBzb3VyY2UgZmlsZSwgJyArXG4gICAgICAgICAgJ29yIHRoZSBzb3VyY2UgbWFwXFwncyBcImZpbGVcIiBwcm9wZXJ0eS4gQm90aCB3ZXJlIG9taXR0ZWQuJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgICAgc291cmNlRmlsZSA9IGFTb3VyY2VNYXBDb25zdW1lci5maWxlO1xuICAgIH1cbiAgICB2YXIgc291cmNlUm9vdCA9IHRoaXMuX3NvdXJjZVJvb3Q7XG4gICAgLy8gTWFrZSBcInNvdXJjZUZpbGVcIiByZWxhdGl2ZSBpZiBhbiBhYnNvbHV0ZSBVcmwgaXMgcGFzc2VkLlxuICAgIGlmIChzb3VyY2VSb290ICE9IG51bGwpIHtcbiAgICAgIHNvdXJjZUZpbGUgPSB1dGlsLnJlbGF0aXZlKHNvdXJjZVJvb3QsIHNvdXJjZUZpbGUpO1xuICAgIH1cbiAgICAvLyBBcHBseWluZyB0aGUgU291cmNlTWFwIGNhbiBhZGQgYW5kIHJlbW92ZSBpdGVtcyBmcm9tIHRoZSBzb3VyY2VzIGFuZFxuICAgIC8vIHRoZSBuYW1lcyBhcnJheS5cbiAgICB2YXIgbmV3U291cmNlcyA9IG5ldyBBcnJheVNldCgpO1xuICAgIHZhciBuZXdOYW1lcyA9IG5ldyBBcnJheVNldCgpO1xuXG4gICAgLy8gRmluZCBtYXBwaW5ncyBmb3IgdGhlIFwic291cmNlRmlsZVwiXG4gICAgdGhpcy5fbWFwcGluZ3MudW5zb3J0ZWRGb3JFYWNoKGZ1bmN0aW9uIChtYXBwaW5nKSB7XG4gICAgICBpZiAobWFwcGluZy5zb3VyY2UgPT09IHNvdXJjZUZpbGUgJiYgbWFwcGluZy5vcmlnaW5hbExpbmUgIT0gbnVsbCkge1xuICAgICAgICAvLyBDaGVjayBpZiBpdCBjYW4gYmUgbWFwcGVkIGJ5IHRoZSBzb3VyY2UgbWFwLCB0aGVuIHVwZGF0ZSB0aGUgbWFwcGluZy5cbiAgICAgICAgdmFyIG9yaWdpbmFsID0gYVNvdXJjZU1hcENvbnN1bWVyLm9yaWdpbmFsUG9zaXRpb25Gb3Ioe1xuICAgICAgICAgIGxpbmU6IG1hcHBpbmcub3JpZ2luYWxMaW5lLFxuICAgICAgICAgIGNvbHVtbjogbWFwcGluZy5vcmlnaW5hbENvbHVtblxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKG9yaWdpbmFsLnNvdXJjZSAhPSBudWxsKSB7XG4gICAgICAgICAgLy8gQ29weSBtYXBwaW5nXG4gICAgICAgICAgbWFwcGluZy5zb3VyY2UgPSBvcmlnaW5hbC5zb3VyY2U7XG4gICAgICAgICAgaWYgKGFTb3VyY2VNYXBQYXRoICE9IG51bGwpIHtcbiAgICAgICAgICAgIG1hcHBpbmcuc291cmNlID0gdXRpbC5qb2luKGFTb3VyY2VNYXBQYXRoLCBtYXBwaW5nLnNvdXJjZSlcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHNvdXJjZVJvb3QgIT0gbnVsbCkge1xuICAgICAgICAgICAgbWFwcGluZy5zb3VyY2UgPSB1dGlsLnJlbGF0aXZlKHNvdXJjZVJvb3QsIG1hcHBpbmcuc291cmNlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbWFwcGluZy5vcmlnaW5hbExpbmUgPSBvcmlnaW5hbC5saW5lO1xuICAgICAgICAgIG1hcHBpbmcub3JpZ2luYWxDb2x1bW4gPSBvcmlnaW5hbC5jb2x1bW47XG4gICAgICAgICAgaWYgKG9yaWdpbmFsLm5hbWUgIT0gbnVsbCkge1xuICAgICAgICAgICAgbWFwcGluZy5uYW1lID0gb3JpZ2luYWwubmFtZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdmFyIHNvdXJjZSA9IG1hcHBpbmcuc291cmNlO1xuICAgICAgaWYgKHNvdXJjZSAhPSBudWxsICYmICFuZXdTb3VyY2VzLmhhcyhzb3VyY2UpKSB7XG4gICAgICAgIG5ld1NvdXJjZXMuYWRkKHNvdXJjZSk7XG4gICAgICB9XG5cbiAgICAgIHZhciBuYW1lID0gbWFwcGluZy5uYW1lO1xuICAgICAgaWYgKG5hbWUgIT0gbnVsbCAmJiAhbmV3TmFtZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgIG5ld05hbWVzLmFkZChuYW1lKTtcbiAgICAgIH1cblxuICAgIH0sIHRoaXMpO1xuICAgIHRoaXMuX3NvdXJjZXMgPSBuZXdTb3VyY2VzO1xuICAgIHRoaXMuX25hbWVzID0gbmV3TmFtZXM7XG5cbiAgICAvLyBDb3B5IHNvdXJjZXNDb250ZW50cyBvZiBhcHBsaWVkIG1hcC5cbiAgICBhU291cmNlTWFwQ29uc3VtZXIuc291cmNlcy5mb3JFYWNoKGZ1bmN0aW9uIChzb3VyY2VGaWxlKSB7XG4gICAgICB2YXIgY29udGVudCA9IGFTb3VyY2VNYXBDb25zdW1lci5zb3VyY2VDb250ZW50Rm9yKHNvdXJjZUZpbGUpO1xuICAgICAgaWYgKGNvbnRlbnQgIT0gbnVsbCkge1xuICAgICAgICBpZiAoYVNvdXJjZU1hcFBhdGggIT0gbnVsbCkge1xuICAgICAgICAgIHNvdXJjZUZpbGUgPSB1dGlsLmpvaW4oYVNvdXJjZU1hcFBhdGgsIHNvdXJjZUZpbGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzb3VyY2VSb290ICE9IG51bGwpIHtcbiAgICAgICAgICBzb3VyY2VGaWxlID0gdXRpbC5yZWxhdGl2ZShzb3VyY2VSb290LCBzb3VyY2VGaWxlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFNvdXJjZUNvbnRlbnQoc291cmNlRmlsZSwgY29udGVudCk7XG4gICAgICB9XG4gICAgfSwgdGhpcyk7XG4gIH07XG5cbi8qKlxuICogQSBtYXBwaW5nIGNhbiBoYXZlIG9uZSBvZiB0aGUgdGhyZWUgbGV2ZWxzIG9mIGRhdGE6XG4gKlxuICogICAxLiBKdXN0IHRoZSBnZW5lcmF0ZWQgcG9zaXRpb24uXG4gKiAgIDIuIFRoZSBHZW5lcmF0ZWQgcG9zaXRpb24sIG9yaWdpbmFsIHBvc2l0aW9uLCBhbmQgb3JpZ2luYWwgc291cmNlLlxuICogICAzLiBHZW5lcmF0ZWQgYW5kIG9yaWdpbmFsIHBvc2l0aW9uLCBvcmlnaW5hbCBzb3VyY2UsIGFzIHdlbGwgYXMgYSBuYW1lXG4gKiAgICAgIHRva2VuLlxuICpcbiAqIFRvIG1haW50YWluIGNvbnNpc3RlbmN5LCB3ZSB2YWxpZGF0ZSB0aGF0IGFueSBuZXcgbWFwcGluZyBiZWluZyBhZGRlZCBmYWxsc1xuICogaW4gdG8gb25lIG9mIHRoZXNlIGNhdGVnb3JpZXMuXG4gKi9cblNvdXJjZU1hcEdlbmVyYXRvci5wcm90b3R5cGUuX3ZhbGlkYXRlTWFwcGluZyA9XG4gIGZ1bmN0aW9uIFNvdXJjZU1hcEdlbmVyYXRvcl92YWxpZGF0ZU1hcHBpbmcoYUdlbmVyYXRlZCwgYU9yaWdpbmFsLCBhU291cmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFOYW1lKSB7XG4gICAgLy8gV2hlbiBhT3JpZ2luYWwgaXMgdHJ1dGh5IGJ1dCBoYXMgZW1wdHkgdmFsdWVzIGZvciAubGluZSBhbmQgLmNvbHVtbixcbiAgICAvLyBpdCBpcyBtb3N0IGxpa2VseSBhIHByb2dyYW1tZXIgZXJyb3IuIEluIHRoaXMgY2FzZSB3ZSB0aHJvdyBhIHZlcnlcbiAgICAvLyBzcGVjaWZpYyBlcnJvciBtZXNzYWdlIHRvIHRyeSB0byBndWlkZSB0aGVtIHRoZSByaWdodCB3YXkuXG4gICAgLy8gRm9yIGV4YW1wbGU6IGh0dHBzOi8vZ2l0aHViLmNvbS9Qb2x5bWVyL3BvbHltZXItYnVuZGxlci9wdWxsLzUxOVxuICAgIGlmIChhT3JpZ2luYWwgJiYgdHlwZW9mIGFPcmlnaW5hbC5saW5lICE9PSAnbnVtYmVyJyAmJiB0eXBlb2YgYU9yaWdpbmFsLmNvbHVtbiAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgJ29yaWdpbmFsLmxpbmUgYW5kIG9yaWdpbmFsLmNvbHVtbiBhcmUgbm90IG51bWJlcnMgLS0geW91IHByb2JhYmx5IG1lYW50IHRvIG9taXQgJyArXG4gICAgICAgICAgICAndGhlIG9yaWdpbmFsIG1hcHBpbmcgZW50aXJlbHkgYW5kIG9ubHkgbWFwIHRoZSBnZW5lcmF0ZWQgcG9zaXRpb24uIElmIHNvLCBwYXNzICcgK1xuICAgICAgICAgICAgJ251bGwgZm9yIHRoZSBvcmlnaW5hbCBtYXBwaW5nIGluc3RlYWQgb2YgYW4gb2JqZWN0IHdpdGggZW1wdHkgb3IgbnVsbCB2YWx1ZXMuJ1xuICAgICAgICApO1xuICAgIH1cblxuICAgIGlmIChhR2VuZXJhdGVkICYmICdsaW5lJyBpbiBhR2VuZXJhdGVkICYmICdjb2x1bW4nIGluIGFHZW5lcmF0ZWRcbiAgICAgICAgJiYgYUdlbmVyYXRlZC5saW5lID4gMCAmJiBhR2VuZXJhdGVkLmNvbHVtbiA+PSAwXG4gICAgICAgICYmICFhT3JpZ2luYWwgJiYgIWFTb3VyY2UgJiYgIWFOYW1lKSB7XG4gICAgICAvLyBDYXNlIDEuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGVsc2UgaWYgKGFHZW5lcmF0ZWQgJiYgJ2xpbmUnIGluIGFHZW5lcmF0ZWQgJiYgJ2NvbHVtbicgaW4gYUdlbmVyYXRlZFxuICAgICAgICAgICAgICYmIGFPcmlnaW5hbCAmJiAnbGluZScgaW4gYU9yaWdpbmFsICYmICdjb2x1bW4nIGluIGFPcmlnaW5hbFxuICAgICAgICAgICAgICYmIGFHZW5lcmF0ZWQubGluZSA+IDAgJiYgYUdlbmVyYXRlZC5jb2x1bW4gPj0gMFxuICAgICAgICAgICAgICYmIGFPcmlnaW5hbC5saW5lID4gMCAmJiBhT3JpZ2luYWwuY29sdW1uID49IDBcbiAgICAgICAgICAgICAmJiBhU291cmNlKSB7XG4gICAgICAvLyBDYXNlcyAyIGFuZCAzLlxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBtYXBwaW5nOiAnICsgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICBnZW5lcmF0ZWQ6IGFHZW5lcmF0ZWQsXG4gICAgICAgIHNvdXJjZTogYVNvdXJjZSxcbiAgICAgICAgb3JpZ2luYWw6IGFPcmlnaW5hbCxcbiAgICAgICAgbmFtZTogYU5hbWVcbiAgICAgIH0pKTtcbiAgICB9XG4gIH07XG5cbi8qKlxuICogU2VyaWFsaXplIHRoZSBhY2N1bXVsYXRlZCBtYXBwaW5ncyBpbiB0byB0aGUgc3RyZWFtIG9mIGJhc2UgNjQgVkxRc1xuICogc3BlY2lmaWVkIGJ5IHRoZSBzb3VyY2UgbWFwIGZvcm1hdC5cbiAqL1xuU291cmNlTWFwR2VuZXJhdG9yLnByb3RvdHlwZS5fc2VyaWFsaXplTWFwcGluZ3MgPVxuICBmdW5jdGlvbiBTb3VyY2VNYXBHZW5lcmF0b3Jfc2VyaWFsaXplTWFwcGluZ3MoKSB7XG4gICAgdmFyIHByZXZpb3VzR2VuZXJhdGVkQ29sdW1uID0gMDtcbiAgICB2YXIgcHJldmlvdXNHZW5lcmF0ZWRMaW5lID0gMTtcbiAgICB2YXIgcHJldmlvdXNPcmlnaW5hbENvbHVtbiA9IDA7XG4gICAgdmFyIHByZXZpb3VzT3JpZ2luYWxMaW5lID0gMDtcbiAgICB2YXIgcHJldmlvdXNOYW1lID0gMDtcbiAgICB2YXIgcHJldmlvdXNTb3VyY2UgPSAwO1xuICAgIHZhciByZXN1bHQgPSAnJztcbiAgICB2YXIgbmV4dDtcbiAgICB2YXIgbWFwcGluZztcbiAgICB2YXIgbmFtZUlkeDtcbiAgICB2YXIgc291cmNlSWR4O1xuXG4gICAgdmFyIG1hcHBpbmdzID0gdGhpcy5fbWFwcGluZ3MudG9BcnJheSgpO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBtYXBwaW5ncy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgbWFwcGluZyA9IG1hcHBpbmdzW2ldO1xuICAgICAgbmV4dCA9ICcnXG5cbiAgICAgIGlmIChtYXBwaW5nLmdlbmVyYXRlZExpbmUgIT09IHByZXZpb3VzR2VuZXJhdGVkTGluZSkge1xuICAgICAgICBwcmV2aW91c0dlbmVyYXRlZENvbHVtbiA9IDA7XG4gICAgICAgIHdoaWxlIChtYXBwaW5nLmdlbmVyYXRlZExpbmUgIT09IHByZXZpb3VzR2VuZXJhdGVkTGluZSkge1xuICAgICAgICAgIG5leHQgKz0gJzsnO1xuICAgICAgICAgIHByZXZpb3VzR2VuZXJhdGVkTGluZSsrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgaWYgKCF1dGlsLmNvbXBhcmVCeUdlbmVyYXRlZFBvc2l0aW9uc0luZmxhdGVkKG1hcHBpbmcsIG1hcHBpbmdzW2kgLSAxXSkpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBuZXh0ICs9ICcsJztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBuZXh0ICs9IGJhc2U2NFZMUS5lbmNvZGUobWFwcGluZy5nZW5lcmF0ZWRDb2x1bW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gcHJldmlvdXNHZW5lcmF0ZWRDb2x1bW4pO1xuICAgICAgcHJldmlvdXNHZW5lcmF0ZWRDb2x1bW4gPSBtYXBwaW5nLmdlbmVyYXRlZENvbHVtbjtcblxuICAgICAgaWYgKG1hcHBpbmcuc291cmNlICE9IG51bGwpIHtcbiAgICAgICAgc291cmNlSWR4ID0gdGhpcy5fc291cmNlcy5pbmRleE9mKG1hcHBpbmcuc291cmNlKTtcbiAgICAgICAgbmV4dCArPSBiYXNlNjRWTFEuZW5jb2RlKHNvdXJjZUlkeCAtIHByZXZpb3VzU291cmNlKTtcbiAgICAgICAgcHJldmlvdXNTb3VyY2UgPSBzb3VyY2VJZHg7XG5cbiAgICAgICAgLy8gbGluZXMgYXJlIHN0b3JlZCAwLWJhc2VkIGluIFNvdXJjZU1hcCBzcGVjIHZlcnNpb24gM1xuICAgICAgICBuZXh0ICs9IGJhc2U2NFZMUS5lbmNvZGUobWFwcGluZy5vcmlnaW5hbExpbmUgLSAxXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gcHJldmlvdXNPcmlnaW5hbExpbmUpO1xuICAgICAgICBwcmV2aW91c09yaWdpbmFsTGluZSA9IG1hcHBpbmcub3JpZ2luYWxMaW5lIC0gMTtcblxuICAgICAgICBuZXh0ICs9IGJhc2U2NFZMUS5lbmNvZGUobWFwcGluZy5vcmlnaW5hbENvbHVtblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIHByZXZpb3VzT3JpZ2luYWxDb2x1bW4pO1xuICAgICAgICBwcmV2aW91c09yaWdpbmFsQ29sdW1uID0gbWFwcGluZy5vcmlnaW5hbENvbHVtbjtcblxuICAgICAgICBpZiAobWFwcGluZy5uYW1lICE9IG51bGwpIHtcbiAgICAgICAgICBuYW1lSWR4ID0gdGhpcy5fbmFtZXMuaW5kZXhPZihtYXBwaW5nLm5hbWUpO1xuICAgICAgICAgIG5leHQgKz0gYmFzZTY0VkxRLmVuY29kZShuYW1lSWR4IC0gcHJldmlvdXNOYW1lKTtcbiAgICAgICAgICBwcmV2aW91c05hbWUgPSBuYW1lSWR4O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJlc3VsdCArPSBuZXh0O1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG5cblNvdXJjZU1hcEdlbmVyYXRvci5wcm90b3R5cGUuX2dlbmVyYXRlU291cmNlc0NvbnRlbnQgPVxuICBmdW5jdGlvbiBTb3VyY2VNYXBHZW5lcmF0b3JfZ2VuZXJhdGVTb3VyY2VzQ29udGVudChhU291cmNlcywgYVNvdXJjZVJvb3QpIHtcbiAgICByZXR1cm4gYVNvdXJjZXMubWFwKGZ1bmN0aW9uIChzb3VyY2UpIHtcbiAgICAgIGlmICghdGhpcy5fc291cmNlc0NvbnRlbnRzKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgaWYgKGFTb3VyY2VSb290ICE9IG51bGwpIHtcbiAgICAgICAgc291cmNlID0gdXRpbC5yZWxhdGl2ZShhU291cmNlUm9vdCwgc291cmNlKTtcbiAgICAgIH1cbiAgICAgIHZhciBrZXkgPSB1dGlsLnRvU2V0U3RyaW5nKHNvdXJjZSk7XG4gICAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuX3NvdXJjZXNDb250ZW50cywga2V5KVxuICAgICAgICA/IHRoaXMuX3NvdXJjZXNDb250ZW50c1trZXldXG4gICAgICAgIDogbnVsbDtcbiAgICB9LCB0aGlzKTtcbiAgfTtcblxuLyoqXG4gKiBFeHRlcm5hbGl6ZSB0aGUgc291cmNlIG1hcC5cbiAqL1xuU291cmNlTWFwR2VuZXJhdG9yLnByb3RvdHlwZS50b0pTT04gPVxuICBmdW5jdGlvbiBTb3VyY2VNYXBHZW5lcmF0b3JfdG9KU09OKCkge1xuICAgIHZhciBtYXAgPSB7XG4gICAgICB2ZXJzaW9uOiB0aGlzLl92ZXJzaW9uLFxuICAgICAgc291cmNlczogdGhpcy5fc291cmNlcy50b0FycmF5KCksXG4gICAgICBuYW1lczogdGhpcy5fbmFtZXMudG9BcnJheSgpLFxuICAgICAgbWFwcGluZ3M6IHRoaXMuX3NlcmlhbGl6ZU1hcHBpbmdzKClcbiAgICB9O1xuICAgIGlmICh0aGlzLl9maWxlICE9IG51bGwpIHtcbiAgICAgIG1hcC5maWxlID0gdGhpcy5fZmlsZTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX3NvdXJjZVJvb3QgIT0gbnVsbCkge1xuICAgICAgbWFwLnNvdXJjZVJvb3QgPSB0aGlzLl9zb3VyY2VSb290O1xuICAgIH1cbiAgICBpZiAodGhpcy5fc291cmNlc0NvbnRlbnRzKSB7XG4gICAgICBtYXAuc291cmNlc0NvbnRlbnQgPSB0aGlzLl9nZW5lcmF0ZVNvdXJjZXNDb250ZW50KG1hcC5zb3VyY2VzLCBtYXAuc291cmNlUm9vdCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1hcDtcbiAgfTtcblxuLyoqXG4gKiBSZW5kZXIgdGhlIHNvdXJjZSBtYXAgYmVpbmcgZ2VuZXJhdGVkIHRvIGEgc3RyaW5nLlxuICovXG5Tb3VyY2VNYXBHZW5lcmF0b3IucHJvdG90eXBlLnRvU3RyaW5nID1cbiAgZnVuY3Rpb24gU291cmNlTWFwR2VuZXJhdG9yX3RvU3RyaW5nKCkge1xuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh0aGlzLnRvSlNPTigpKTtcbiAgfTtcblxuZXhwb3J0cy5Tb3VyY2VNYXBHZW5lcmF0b3IgPSBTb3VyY2VNYXBHZW5lcmF0b3I7XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL2xpYi9zb3VyY2UtbWFwLWdlbmVyYXRvci5qc1xuLy8gbW9kdWxlIGlkID0gMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKiAtKi0gTW9kZToganM7IGpzLWluZGVudC1sZXZlbDogMjsgLSotICovXG4vKlxuICogQ29weXJpZ2h0IDIwMTEgTW96aWxsYSBGb3VuZGF0aW9uIGFuZCBjb250cmlidXRvcnNcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBOZXcgQlNEIGxpY2Vuc2UuIFNlZSBMSUNFTlNFIG9yOlxuICogaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL0JTRC0zLUNsYXVzZVxuICpcbiAqIEJhc2VkIG9uIHRoZSBCYXNlIDY0IFZMUSBpbXBsZW1lbnRhdGlvbiBpbiBDbG9zdXJlIENvbXBpbGVyOlxuICogaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jbG9zdXJlLWNvbXBpbGVyL3NvdXJjZS9icm93c2UvdHJ1bmsvc3JjL2NvbS9nb29nbGUvZGVidWdnaW5nL3NvdXJjZW1hcC9CYXNlNjRWTFEuamF2YVxuICpcbiAqIENvcHlyaWdodCAyMDExIFRoZSBDbG9zdXJlIENvbXBpbGVyIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmVcbiAqIG1ldDpcbiAqXG4gKiAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodFxuICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICogICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZVxuICogICAgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmdcbiAqICAgIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZFxuICogICAgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuICogICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0c1xuICogICAgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkXG4gKiAgICBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SU1xuICogXCJBUyBJU1wiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVFxuICogTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SXG4gKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVFxuICogT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsXG4gKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UXG4gKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSxcbiAqIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWVxuICogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFXG4gKiBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLlxuICovXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCcuL2Jhc2U2NCcpO1xuXG4vLyBBIHNpbmdsZSBiYXNlIDY0IGRpZ2l0IGNhbiBjb250YWluIDYgYml0cyBvZiBkYXRhLiBGb3IgdGhlIGJhc2UgNjQgdmFyaWFibGVcbi8vIGxlbmd0aCBxdWFudGl0aWVzIHdlIHVzZSBpbiB0aGUgc291cmNlIG1hcCBzcGVjLCB0aGUgZmlyc3QgYml0IGlzIHRoZSBzaWduLFxuLy8gdGhlIG5leHQgZm91ciBiaXRzIGFyZSB0aGUgYWN0dWFsIHZhbHVlLCBhbmQgdGhlIDZ0aCBiaXQgaXMgdGhlXG4vLyBjb250aW51YXRpb24gYml0LiBUaGUgY29udGludWF0aW9uIGJpdCB0ZWxscyB1cyB3aGV0aGVyIHRoZXJlIGFyZSBtb3JlXG4vLyBkaWdpdHMgaW4gdGhpcyB2YWx1ZSBmb2xsb3dpbmcgdGhpcyBkaWdpdC5cbi8vXG4vLyAgIENvbnRpbnVhdGlvblxuLy8gICB8ICAgIFNpZ25cbi8vICAgfCAgICB8XG4vLyAgIFYgICAgVlxuLy8gICAxMDEwMTFcblxudmFyIFZMUV9CQVNFX1NISUZUID0gNTtcblxuLy8gYmluYXJ5OiAxMDAwMDBcbnZhciBWTFFfQkFTRSA9IDEgPDwgVkxRX0JBU0VfU0hJRlQ7XG5cbi8vIGJpbmFyeTogMDExMTExXG52YXIgVkxRX0JBU0VfTUFTSyA9IFZMUV9CQVNFIC0gMTtcblxuLy8gYmluYXJ5OiAxMDAwMDBcbnZhciBWTFFfQ09OVElOVUFUSU9OX0JJVCA9IFZMUV9CQVNFO1xuXG4vKipcbiAqIENvbnZlcnRzIGZyb20gYSB0d28tY29tcGxlbWVudCB2YWx1ZSB0byBhIHZhbHVlIHdoZXJlIHRoZSBzaWduIGJpdCBpc1xuICogcGxhY2VkIGluIHRoZSBsZWFzdCBzaWduaWZpY2FudCBiaXQuICBGb3IgZXhhbXBsZSwgYXMgZGVjaW1hbHM6XG4gKiAgIDEgYmVjb21lcyAyICgxMCBiaW5hcnkpLCAtMSBiZWNvbWVzIDMgKDExIGJpbmFyeSlcbiAqICAgMiBiZWNvbWVzIDQgKDEwMCBiaW5hcnkpLCAtMiBiZWNvbWVzIDUgKDEwMSBiaW5hcnkpXG4gKi9cbmZ1bmN0aW9uIHRvVkxRU2lnbmVkKGFWYWx1ZSkge1xuICByZXR1cm4gYVZhbHVlIDwgMFxuICAgID8gKCgtYVZhbHVlKSA8PCAxKSArIDFcbiAgICA6IChhVmFsdWUgPDwgMSkgKyAwO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRvIGEgdHdvLWNvbXBsZW1lbnQgdmFsdWUgZnJvbSBhIHZhbHVlIHdoZXJlIHRoZSBzaWduIGJpdCBpc1xuICogcGxhY2VkIGluIHRoZSBsZWFzdCBzaWduaWZpY2FudCBiaXQuICBGb3IgZXhhbXBsZSwgYXMgZGVjaW1hbHM6XG4gKiAgIDIgKDEwIGJpbmFyeSkgYmVjb21lcyAxLCAzICgxMSBiaW5hcnkpIGJlY29tZXMgLTFcbiAqICAgNCAoMTAwIGJpbmFyeSkgYmVjb21lcyAyLCA1ICgxMDEgYmluYXJ5KSBiZWNvbWVzIC0yXG4gKi9cbmZ1bmN0aW9uIGZyb21WTFFTaWduZWQoYVZhbHVlKSB7XG4gIHZhciBpc05lZ2F0aXZlID0gKGFWYWx1ZSAmIDEpID09PSAxO1xuICB2YXIgc2hpZnRlZCA9IGFWYWx1ZSA+PiAxO1xuICByZXR1cm4gaXNOZWdhdGl2ZVxuICAgID8gLXNoaWZ0ZWRcbiAgICA6IHNoaWZ0ZWQ7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgYmFzZSA2NCBWTFEgZW5jb2RlZCB2YWx1ZS5cbiAqL1xuZXhwb3J0cy5lbmNvZGUgPSBmdW5jdGlvbiBiYXNlNjRWTFFfZW5jb2RlKGFWYWx1ZSkge1xuICB2YXIgZW5jb2RlZCA9IFwiXCI7XG4gIHZhciBkaWdpdDtcblxuICB2YXIgdmxxID0gdG9WTFFTaWduZWQoYVZhbHVlKTtcblxuICBkbyB7XG4gICAgZGlnaXQgPSB2bHEgJiBWTFFfQkFTRV9NQVNLO1xuICAgIHZscSA+Pj49IFZMUV9CQVNFX1NISUZUO1xuICAgIGlmICh2bHEgPiAwKSB7XG4gICAgICAvLyBUaGVyZSBhcmUgc3RpbGwgbW9yZSBkaWdpdHMgaW4gdGhpcyB2YWx1ZSwgc28gd2UgbXVzdCBtYWtlIHN1cmUgdGhlXG4gICAgICAvLyBjb250aW51YXRpb24gYml0IGlzIG1hcmtlZC5cbiAgICAgIGRpZ2l0IHw9IFZMUV9DT05USU5VQVRJT05fQklUO1xuICAgIH1cbiAgICBlbmNvZGVkICs9IGJhc2U2NC5lbmNvZGUoZGlnaXQpO1xuICB9IHdoaWxlICh2bHEgPiAwKTtcblxuICByZXR1cm4gZW5jb2RlZDtcbn07XG5cbi8qKlxuICogRGVjb2RlcyB0aGUgbmV4dCBiYXNlIDY0IFZMUSB2YWx1ZSBmcm9tIHRoZSBnaXZlbiBzdHJpbmcgYW5kIHJldHVybnMgdGhlXG4gKiB2YWx1ZSBhbmQgdGhlIHJlc3Qgb2YgdGhlIHN0cmluZyB2aWEgdGhlIG91dCBwYXJhbWV0ZXIuXG4gKi9cbmV4cG9ydHMuZGVjb2RlID0gZnVuY3Rpb24gYmFzZTY0VkxRX2RlY29kZShhU3RyLCBhSW5kZXgsIGFPdXRQYXJhbSkge1xuICB2YXIgc3RyTGVuID0gYVN0ci5sZW5ndGg7XG4gIHZhciByZXN1bHQgPSAwO1xuICB2YXIgc2hpZnQgPSAwO1xuICB2YXIgY29udGludWF0aW9uLCBkaWdpdDtcblxuICBkbyB7XG4gICAgaWYgKGFJbmRleCA+PSBzdHJMZW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGVkIG1vcmUgZGlnaXRzIGluIGJhc2UgNjQgVkxRIHZhbHVlLlwiKTtcbiAgICB9XG5cbiAgICBkaWdpdCA9IGJhc2U2NC5kZWNvZGUoYVN0ci5jaGFyQ29kZUF0KGFJbmRleCsrKSk7XG4gICAgaWYgKGRpZ2l0ID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBiYXNlNjQgZGlnaXQ6IFwiICsgYVN0ci5jaGFyQXQoYUluZGV4IC0gMSkpO1xuICAgIH1cblxuICAgIGNvbnRpbnVhdGlvbiA9ICEhKGRpZ2l0ICYgVkxRX0NPTlRJTlVBVElPTl9CSVQpO1xuICAgIGRpZ2l0ICY9IFZMUV9CQVNFX01BU0s7XG4gICAgcmVzdWx0ID0gcmVzdWx0ICsgKGRpZ2l0IDw8IHNoaWZ0KTtcbiAgICBzaGlmdCArPSBWTFFfQkFTRV9TSElGVDtcbiAgfSB3aGlsZSAoY29udGludWF0aW9uKTtcblxuICBhT3V0UGFyYW0udmFsdWUgPSBmcm9tVkxRU2lnbmVkKHJlc3VsdCk7XG4gIGFPdXRQYXJhbS5yZXN0ID0gYUluZGV4O1xufTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbGliL2Jhc2U2NC12bHEuanNcbi8vIG1vZHVsZSBpZCA9IDJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLyogLSotIE1vZGU6IGpzOyBqcy1pbmRlbnQtbGV2ZWw6IDI7IC0qLSAqL1xuLypcbiAqIENvcHlyaWdodCAyMDExIE1vemlsbGEgRm91bmRhdGlvbiBhbmQgY29udHJpYnV0b3JzXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTmV3IEJTRCBsaWNlbnNlLiBTZWUgTElDRU5TRSBvcjpcbiAqIGh0dHA6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9CU0QtMy1DbGF1c2VcbiAqL1xuXG52YXIgaW50VG9DaGFyTWFwID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nLnNwbGl0KCcnKTtcblxuLyoqXG4gKiBFbmNvZGUgYW4gaW50ZWdlciBpbiB0aGUgcmFuZ2Ugb2YgMCB0byA2MyB0byBhIHNpbmdsZSBiYXNlIDY0IGRpZ2l0LlxuICovXG5leHBvcnRzLmVuY29kZSA9IGZ1bmN0aW9uIChudW1iZXIpIHtcbiAgaWYgKDAgPD0gbnVtYmVyICYmIG51bWJlciA8IGludFRvQ2hhck1hcC5sZW5ndGgpIHtcbiAgICByZXR1cm4gaW50VG9DaGFyTWFwW251bWJlcl07XG4gIH1cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk11c3QgYmUgYmV0d2VlbiAwIGFuZCA2MzogXCIgKyBudW1iZXIpO1xufTtcblxuLyoqXG4gKiBEZWNvZGUgYSBzaW5nbGUgYmFzZSA2NCBjaGFyYWN0ZXIgY29kZSBkaWdpdCB0byBhbiBpbnRlZ2VyLiBSZXR1cm5zIC0xIG9uXG4gKiBmYWlsdXJlLlxuICovXG5leHBvcnRzLmRlY29kZSA9IGZ1bmN0aW9uIChjaGFyQ29kZSkge1xuICB2YXIgYmlnQSA9IDY1OyAgICAgLy8gJ0EnXG4gIHZhciBiaWdaID0gOTA7ICAgICAvLyAnWidcblxuICB2YXIgbGl0dGxlQSA9IDk3OyAgLy8gJ2EnXG4gIHZhciBsaXR0bGVaID0gMTIyOyAvLyAneidcblxuICB2YXIgemVybyA9IDQ4OyAgICAgLy8gJzAnXG4gIHZhciBuaW5lID0gNTc7ICAgICAvLyAnOSdcblxuICB2YXIgcGx1cyA9IDQzOyAgICAgLy8gJysnXG4gIHZhciBzbGFzaCA9IDQ3OyAgICAvLyAnLydcblxuICB2YXIgbGl0dGxlT2Zmc2V0ID0gMjY7XG4gIHZhciBudW1iZXJPZmZzZXQgPSA1MjtcblxuICAvLyAwIC0gMjU6IEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaXG4gIGlmIChiaWdBIDw9IGNoYXJDb2RlICYmIGNoYXJDb2RlIDw9IGJpZ1opIHtcbiAgICByZXR1cm4gKGNoYXJDb2RlIC0gYmlnQSk7XG4gIH1cblxuICAvLyAyNiAtIDUxOiBhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5elxuICBpZiAobGl0dGxlQSA8PSBjaGFyQ29kZSAmJiBjaGFyQ29kZSA8PSBsaXR0bGVaKSB7XG4gICAgcmV0dXJuIChjaGFyQ29kZSAtIGxpdHRsZUEgKyBsaXR0bGVPZmZzZXQpO1xuICB9XG5cbiAgLy8gNTIgLSA2MTogMDEyMzQ1Njc4OVxuICBpZiAoemVybyA8PSBjaGFyQ29kZSAmJiBjaGFyQ29kZSA8PSBuaW5lKSB7XG4gICAgcmV0dXJuIChjaGFyQ29kZSAtIHplcm8gKyBudW1iZXJPZmZzZXQpO1xuICB9XG5cbiAgLy8gNjI6ICtcbiAgaWYgKGNoYXJDb2RlID09IHBsdXMpIHtcbiAgICByZXR1cm4gNjI7XG4gIH1cblxuICAvLyA2MzogL1xuICBpZiAoY2hhckNvZGUgPT0gc2xhc2gpIHtcbiAgICByZXR1cm4gNjM7XG4gIH1cblxuICAvLyBJbnZhbGlkIGJhc2U2NCBkaWdpdC5cbiAgcmV0dXJuIC0xO1xufTtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbGliL2Jhc2U2NC5qc1xuLy8gbW9kdWxlIGlkID0gM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKiAtKi0gTW9kZToganM7IGpzLWluZGVudC1sZXZlbDogMjsgLSotICovXG4vKlxuICogQ29weXJpZ2h0IDIwMTEgTW96aWxsYSBGb3VuZGF0aW9uIGFuZCBjb250cmlidXRvcnNcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBOZXcgQlNEIGxpY2Vuc2UuIFNlZSBMSUNFTlNFIG9yOlxuICogaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL0JTRC0zLUNsYXVzZVxuICovXG5cbi8qKlxuICogVGhpcyBpcyBhIGhlbHBlciBmdW5jdGlvbiBmb3IgZ2V0dGluZyB2YWx1ZXMgZnJvbSBwYXJhbWV0ZXIvb3B0aW9uc1xuICogb2JqZWN0cy5cbiAqXG4gKiBAcGFyYW0gYXJncyBUaGUgb2JqZWN0IHdlIGFyZSBleHRyYWN0aW5nIHZhbHVlcyBmcm9tXG4gKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgd2UgYXJlIGdldHRpbmcuXG4gKiBAcGFyYW0gZGVmYXVsdFZhbHVlIEFuIG9wdGlvbmFsIHZhbHVlIHRvIHJldHVybiBpZiB0aGUgcHJvcGVydHkgaXMgbWlzc2luZ1xuICogZnJvbSB0aGUgb2JqZWN0LiBJZiB0aGlzIGlzIG5vdCBzcGVjaWZpZWQgYW5kIHRoZSBwcm9wZXJ0eSBpcyBtaXNzaW5nLCBhblxuICogZXJyb3Igd2lsbCBiZSB0aHJvd24uXG4gKi9cbmZ1bmN0aW9uIGdldEFyZyhhQXJncywgYU5hbWUsIGFEZWZhdWx0VmFsdWUpIHtcbiAgaWYgKGFOYW1lIGluIGFBcmdzKSB7XG4gICAgcmV0dXJuIGFBcmdzW2FOYW1lXTtcbiAgfSBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgcmV0dXJuIGFEZWZhdWx0VmFsdWU7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdcIicgKyBhTmFtZSArICdcIiBpcyBhIHJlcXVpcmVkIGFyZ3VtZW50LicpO1xuICB9XG59XG5leHBvcnRzLmdldEFyZyA9IGdldEFyZztcblxudmFyIHVybFJlZ2V4cCA9IC9eKD86KFtcXHcrXFwtLl0rKTopP1xcL1xcLyg/OihcXHcrOlxcdyspQCk/KFtcXHcuLV0qKSg/OjooXFxkKykpPyguKikkLztcbnZhciBkYXRhVXJsUmVnZXhwID0gL15kYXRhOi4rXFwsLiskLztcblxuZnVuY3Rpb24gdXJsUGFyc2UoYVVybCkge1xuICB2YXIgbWF0Y2ggPSBhVXJsLm1hdGNoKHVybFJlZ2V4cCk7XG4gIGlmICghbWF0Y2gpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICByZXR1cm4ge1xuICAgIHNjaGVtZTogbWF0Y2hbMV0sXG4gICAgYXV0aDogbWF0Y2hbMl0sXG4gICAgaG9zdDogbWF0Y2hbM10sXG4gICAgcG9ydDogbWF0Y2hbNF0sXG4gICAgcGF0aDogbWF0Y2hbNV1cbiAgfTtcbn1cbmV4cG9ydHMudXJsUGFyc2UgPSB1cmxQYXJzZTtcblxuZnVuY3Rpb24gdXJsR2VuZXJhdGUoYVBhcnNlZFVybCkge1xuICB2YXIgdXJsID0gJyc7XG4gIGlmIChhUGFyc2VkVXJsLnNjaGVtZSkge1xuICAgIHVybCArPSBhUGFyc2VkVXJsLnNjaGVtZSArICc6JztcbiAgfVxuICB1cmwgKz0gJy8vJztcbiAgaWYgKGFQYXJzZWRVcmwuYXV0aCkge1xuICAgIHVybCArPSBhUGFyc2VkVXJsLmF1dGggKyAnQCc7XG4gIH1cbiAgaWYgKGFQYXJzZWRVcmwuaG9zdCkge1xuICAgIHVybCArPSBhUGFyc2VkVXJsLmhvc3Q7XG4gIH1cbiAgaWYgKGFQYXJzZWRVcmwucG9ydCkge1xuICAgIHVybCArPSBcIjpcIiArIGFQYXJzZWRVcmwucG9ydFxuICB9XG4gIGlmIChhUGFyc2VkVXJsLnBhdGgpIHtcbiAgICB1cmwgKz0gYVBhcnNlZFVybC5wYXRoO1xuICB9XG4gIHJldHVybiB1cmw7XG59XG5leHBvcnRzLnVybEdlbmVyYXRlID0gdXJsR2VuZXJhdGU7XG5cbi8qKlxuICogTm9ybWFsaXplcyBhIHBhdGgsIG9yIHRoZSBwYXRoIHBvcnRpb24gb2YgYSBVUkw6XG4gKlxuICogLSBSZXBsYWNlcyBjb25zZWN1dGl2ZSBzbGFzaGVzIHdpdGggb25lIHNsYXNoLlxuICogLSBSZW1vdmVzIHVubmVjZXNzYXJ5ICcuJyBwYXJ0cy5cbiAqIC0gUmVtb3ZlcyB1bm5lY2Vzc2FyeSAnPGRpcj4vLi4nIHBhcnRzLlxuICpcbiAqIEJhc2VkIG9uIGNvZGUgaW4gdGhlIE5vZGUuanMgJ3BhdGgnIGNvcmUgbW9kdWxlLlxuICpcbiAqIEBwYXJhbSBhUGF0aCBUaGUgcGF0aCBvciB1cmwgdG8gbm9ybWFsaXplLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemUoYVBhdGgpIHtcbiAgdmFyIHBhdGggPSBhUGF0aDtcbiAgdmFyIHVybCA9IHVybFBhcnNlKGFQYXRoKTtcbiAgaWYgKHVybCkge1xuICAgIGlmICghdXJsLnBhdGgpIHtcbiAgICAgIHJldHVybiBhUGF0aDtcbiAgICB9XG4gICAgcGF0aCA9IHVybC5wYXRoO1xuICB9XG4gIHZhciBpc0Fic29sdXRlID0gZXhwb3J0cy5pc0Fic29sdXRlKHBhdGgpO1xuXG4gIHZhciBwYXJ0cyA9IHBhdGguc3BsaXQoL1xcLysvKTtcbiAgZm9yICh2YXIgcGFydCwgdXAgPSAwLCBpID0gcGFydHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBwYXJ0ID0gcGFydHNbaV07XG4gICAgaWYgKHBhcnQgPT09ICcuJykge1xuICAgICAgcGFydHMuc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSBpZiAocGFydCA9PT0gJy4uJykge1xuICAgICAgdXArKztcbiAgICB9IGVsc2UgaWYgKHVwID4gMCkge1xuICAgICAgaWYgKHBhcnQgPT09ICcnKSB7XG4gICAgICAgIC8vIFRoZSBmaXJzdCBwYXJ0IGlzIGJsYW5rIGlmIHRoZSBwYXRoIGlzIGFic29sdXRlLiBUcnlpbmcgdG8gZ29cbiAgICAgICAgLy8gYWJvdmUgdGhlIHJvb3QgaXMgYSBuby1vcC4gVGhlcmVmb3JlIHdlIGNhbiByZW1vdmUgYWxsICcuLicgcGFydHNcbiAgICAgICAgLy8gZGlyZWN0bHkgYWZ0ZXIgdGhlIHJvb3QuXG4gICAgICAgIHBhcnRzLnNwbGljZShpICsgMSwgdXApO1xuICAgICAgICB1cCA9IDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXJ0cy5zcGxpY2UoaSwgMik7XG4gICAgICAgIHVwLS07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHBhdGggPSBwYXJ0cy5qb2luKCcvJyk7XG5cbiAgaWYgKHBhdGggPT09ICcnKSB7XG4gICAgcGF0aCA9IGlzQWJzb2x1dGUgPyAnLycgOiAnLic7XG4gIH1cblxuICBpZiAodXJsKSB7XG4gICAgdXJsLnBhdGggPSBwYXRoO1xuICAgIHJldHVybiB1cmxHZW5lcmF0ZSh1cmwpO1xuICB9XG4gIHJldHVybiBwYXRoO1xufVxuZXhwb3J0cy5ub3JtYWxpemUgPSBub3JtYWxpemU7XG5cbi8qKlxuICogSm9pbnMgdHdvIHBhdGhzL1VSTHMuXG4gKlxuICogQHBhcmFtIGFSb290IFRoZSByb290IHBhdGggb3IgVVJMLlxuICogQHBhcmFtIGFQYXRoIFRoZSBwYXRoIG9yIFVSTCB0byBiZSBqb2luZWQgd2l0aCB0aGUgcm9vdC5cbiAqXG4gKiAtIElmIGFQYXRoIGlzIGEgVVJMIG9yIGEgZGF0YSBVUkksIGFQYXRoIGlzIHJldHVybmVkLCB1bmxlc3MgYVBhdGggaXMgYVxuICogICBzY2hlbWUtcmVsYXRpdmUgVVJMOiBUaGVuIHRoZSBzY2hlbWUgb2YgYVJvb3QsIGlmIGFueSwgaXMgcHJlcGVuZGVkXG4gKiAgIGZpcnN0LlxuICogLSBPdGhlcndpc2UgYVBhdGggaXMgYSBwYXRoLiBJZiBhUm9vdCBpcyBhIFVSTCwgdGhlbiBpdHMgcGF0aCBwb3J0aW9uXG4gKiAgIGlzIHVwZGF0ZWQgd2l0aCB0aGUgcmVzdWx0IGFuZCBhUm9vdCBpcyByZXR1cm5lZC4gT3RoZXJ3aXNlIHRoZSByZXN1bHRcbiAqICAgaXMgcmV0dXJuZWQuXG4gKiAgIC0gSWYgYVBhdGggaXMgYWJzb2x1dGUsIHRoZSByZXN1bHQgaXMgYVBhdGguXG4gKiAgIC0gT3RoZXJ3aXNlIHRoZSB0d28gcGF0aHMgYXJlIGpvaW5lZCB3aXRoIGEgc2xhc2guXG4gKiAtIEpvaW5pbmcgZm9yIGV4YW1wbGUgJ2h0dHA6Ly8nIGFuZCAnd3d3LmV4YW1wbGUuY29tJyBpcyBhbHNvIHN1cHBvcnRlZC5cbiAqL1xuZnVuY3Rpb24gam9pbihhUm9vdCwgYVBhdGgpIHtcbiAgaWYgKGFSb290ID09PSBcIlwiKSB7XG4gICAgYVJvb3QgPSBcIi5cIjtcbiAgfVxuICBpZiAoYVBhdGggPT09IFwiXCIpIHtcbiAgICBhUGF0aCA9IFwiLlwiO1xuICB9XG4gIHZhciBhUGF0aFVybCA9IHVybFBhcnNlKGFQYXRoKTtcbiAgdmFyIGFSb290VXJsID0gdXJsUGFyc2UoYVJvb3QpO1xuICBpZiAoYVJvb3RVcmwpIHtcbiAgICBhUm9vdCA9IGFSb290VXJsLnBhdGggfHwgJy8nO1xuICB9XG5cbiAgLy8gYGpvaW4oZm9vLCAnLy93d3cuZXhhbXBsZS5vcmcnKWBcbiAgaWYgKGFQYXRoVXJsICYmICFhUGF0aFVybC5zY2hlbWUpIHtcbiAgICBpZiAoYVJvb3RVcmwpIHtcbiAgICAgIGFQYXRoVXJsLnNjaGVtZSA9IGFSb290VXJsLnNjaGVtZTtcbiAgICB9XG4gICAgcmV0dXJuIHVybEdlbmVyYXRlKGFQYXRoVXJsKTtcbiAgfVxuXG4gIGlmIChhUGF0aFVybCB8fCBhUGF0aC5tYXRjaChkYXRhVXJsUmVnZXhwKSkge1xuICAgIHJldHVybiBhUGF0aDtcbiAgfVxuXG4gIC8vIGBqb2luKCdodHRwOi8vJywgJ3d3dy5leGFtcGxlLmNvbScpYFxuICBpZiAoYVJvb3RVcmwgJiYgIWFSb290VXJsLmhvc3QgJiYgIWFSb290VXJsLnBhdGgpIHtcbiAgICBhUm9vdFVybC5ob3N0ID0gYVBhdGg7XG4gICAgcmV0dXJuIHVybEdlbmVyYXRlKGFSb290VXJsKTtcbiAgfVxuXG4gIHZhciBqb2luZWQgPSBhUGF0aC5jaGFyQXQoMCkgPT09ICcvJ1xuICAgID8gYVBhdGhcbiAgICA6IG5vcm1hbGl6ZShhUm9vdC5yZXBsYWNlKC9cXC8rJC8sICcnKSArICcvJyArIGFQYXRoKTtcblxuICBpZiAoYVJvb3RVcmwpIHtcbiAgICBhUm9vdFVybC5wYXRoID0gam9pbmVkO1xuICAgIHJldHVybiB1cmxHZW5lcmF0ZShhUm9vdFVybCk7XG4gIH1cbiAgcmV0dXJuIGpvaW5lZDtcbn1cbmV4cG9ydHMuam9pbiA9IGpvaW47XG5cbmV4cG9ydHMuaXNBYnNvbHV0ZSA9IGZ1bmN0aW9uIChhUGF0aCkge1xuICByZXR1cm4gYVBhdGguY2hhckF0KDApID09PSAnLycgfHwgdXJsUmVnZXhwLnRlc3QoYVBhdGgpO1xufTtcblxuLyoqXG4gKiBNYWtlIGEgcGF0aCByZWxhdGl2ZSB0byBhIFVSTCBvciBhbm90aGVyIHBhdGguXG4gKlxuICogQHBhcmFtIGFSb290IFRoZSByb290IHBhdGggb3IgVVJMLlxuICogQHBhcmFtIGFQYXRoIFRoZSBwYXRoIG9yIFVSTCB0byBiZSBtYWRlIHJlbGF0aXZlIHRvIGFSb290LlxuICovXG5mdW5jdGlvbiByZWxhdGl2ZShhUm9vdCwgYVBhdGgpIHtcbiAgaWYgKGFSb290ID09PSBcIlwiKSB7XG4gICAgYVJvb3QgPSBcIi5cIjtcbiAgfVxuXG4gIGFSb290ID0gYVJvb3QucmVwbGFjZSgvXFwvJC8sICcnKTtcblxuICAvLyBJdCBpcyBwb3NzaWJsZSBmb3IgdGhlIHBhdGggdG8gYmUgYWJvdmUgdGhlIHJvb3QuIEluIHRoaXMgY2FzZSwgc2ltcGx5XG4gIC8vIGNoZWNraW5nIHdoZXRoZXIgdGhlIHJvb3QgaXMgYSBwcmVmaXggb2YgdGhlIHBhdGggd29uJ3Qgd29yay4gSW5zdGVhZCwgd2VcbiAgLy8gbmVlZCB0byByZW1vdmUgY29tcG9uZW50cyBmcm9tIHRoZSByb290IG9uZSBieSBvbmUsIHVudGlsIGVpdGhlciB3ZSBmaW5kXG4gIC8vIGEgcHJlZml4IHRoYXQgZml0cywgb3Igd2UgcnVuIG91dCBvZiBjb21wb25lbnRzIHRvIHJlbW92ZS5cbiAgdmFyIGxldmVsID0gMDtcbiAgd2hpbGUgKGFQYXRoLmluZGV4T2YoYVJvb3QgKyAnLycpICE9PSAwKSB7XG4gICAgdmFyIGluZGV4ID0gYVJvb3QubGFzdEluZGV4T2YoXCIvXCIpO1xuICAgIGlmIChpbmRleCA8IDApIHtcbiAgICAgIHJldHVybiBhUGF0aDtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgb25seSBwYXJ0IG9mIHRoZSByb290IHRoYXQgaXMgbGVmdCBpcyB0aGUgc2NoZW1lIChpLmUuIGh0dHA6Ly8sXG4gICAgLy8gZmlsZTovLy8sIGV0Yy4pLCBvbmUgb3IgbW9yZSBzbGFzaGVzICgvKSwgb3Igc2ltcGx5IG5vdGhpbmcgYXQgYWxsLCB3ZVxuICAgIC8vIGhhdmUgZXhoYXVzdGVkIGFsbCBjb21wb25lbnRzLCBzbyB0aGUgcGF0aCBpcyBub3QgcmVsYXRpdmUgdG8gdGhlIHJvb3QuXG4gICAgYVJvb3QgPSBhUm9vdC5zbGljZSgwLCBpbmRleCk7XG4gICAgaWYgKGFSb290Lm1hdGNoKC9eKFteXFwvXSs6XFwvKT9cXC8qJC8pKSB7XG4gICAgICByZXR1cm4gYVBhdGg7XG4gICAgfVxuXG4gICAgKytsZXZlbDtcbiAgfVxuXG4gIC8vIE1ha2Ugc3VyZSB3ZSBhZGQgYSBcIi4uL1wiIGZvciBlYWNoIGNvbXBvbmVudCB3ZSByZW1vdmVkIGZyb20gdGhlIHJvb3QuXG4gIHJldHVybiBBcnJheShsZXZlbCArIDEpLmpvaW4oXCIuLi9cIikgKyBhUGF0aC5zdWJzdHIoYVJvb3QubGVuZ3RoICsgMSk7XG59XG5leHBvcnRzLnJlbGF0aXZlID0gcmVsYXRpdmU7XG5cbnZhciBzdXBwb3J0c051bGxQcm90byA9IChmdW5jdGlvbiAoKSB7XG4gIHZhciBvYmogPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICByZXR1cm4gISgnX19wcm90b19fJyBpbiBvYmopO1xufSgpKTtcblxuZnVuY3Rpb24gaWRlbnRpdHkgKHMpIHtcbiAgcmV0dXJuIHM7XG59XG5cbi8qKlxuICogQmVjYXVzZSBiZWhhdmlvciBnb2VzIHdhY2t5IHdoZW4geW91IHNldCBgX19wcm90b19fYCBvbiBvYmplY3RzLCB3ZVxuICogaGF2ZSB0byBwcmVmaXggYWxsIHRoZSBzdHJpbmdzIGluIG91ciBzZXQgd2l0aCBhbiBhcmJpdHJhcnkgY2hhcmFjdGVyLlxuICpcbiAqIFNlZSBodHRwczovL2dpdGh1Yi5jb20vbW96aWxsYS9zb3VyY2UtbWFwL3B1bGwvMzEgYW5kXG4gKiBodHRwczovL2dpdGh1Yi5jb20vbW96aWxsYS9zb3VyY2UtbWFwL2lzc3Vlcy8zMFxuICpcbiAqIEBwYXJhbSBTdHJpbmcgYVN0clxuICovXG5mdW5jdGlvbiB0b1NldFN0cmluZyhhU3RyKSB7XG4gIGlmIChpc1Byb3RvU3RyaW5nKGFTdHIpKSB7XG4gICAgcmV0dXJuICckJyArIGFTdHI7XG4gIH1cblxuICByZXR1cm4gYVN0cjtcbn1cbmV4cG9ydHMudG9TZXRTdHJpbmcgPSBzdXBwb3J0c051bGxQcm90byA/IGlkZW50aXR5IDogdG9TZXRTdHJpbmc7XG5cbmZ1bmN0aW9uIGZyb21TZXRTdHJpbmcoYVN0cikge1xuICBpZiAoaXNQcm90b1N0cmluZyhhU3RyKSkge1xuICAgIHJldHVybiBhU3RyLnNsaWNlKDEpO1xuICB9XG5cbiAgcmV0dXJuIGFTdHI7XG59XG5leHBvcnRzLmZyb21TZXRTdHJpbmcgPSBzdXBwb3J0c051bGxQcm90byA/IGlkZW50aXR5IDogZnJvbVNldFN0cmluZztcblxuZnVuY3Rpb24gaXNQcm90b1N0cmluZyhzKSB7XG4gIGlmICghcykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBsZW5ndGggPSBzLmxlbmd0aDtcblxuICBpZiAobGVuZ3RoIDwgOSAvKiBcIl9fcHJvdG9fX1wiLmxlbmd0aCAqLykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChzLmNoYXJDb2RlQXQobGVuZ3RoIC0gMSkgIT09IDk1ICAvKiAnXycgKi8gfHxcbiAgICAgIHMuY2hhckNvZGVBdChsZW5ndGggLSAyKSAhPT0gOTUgIC8qICdfJyAqLyB8fFxuICAgICAgcy5jaGFyQ29kZUF0KGxlbmd0aCAtIDMpICE9PSAxMTEgLyogJ28nICovIHx8XG4gICAgICBzLmNoYXJDb2RlQXQobGVuZ3RoIC0gNCkgIT09IDExNiAvKiAndCcgKi8gfHxcbiAgICAgIHMuY2hhckNvZGVBdChsZW5ndGggLSA1KSAhPT0gMTExIC8qICdvJyAqLyB8fFxuICAgICAgcy5jaGFyQ29kZUF0KGxlbmd0aCAtIDYpICE9PSAxMTQgLyogJ3InICovIHx8XG4gICAgICBzLmNoYXJDb2RlQXQobGVuZ3RoIC0gNykgIT09IDExMiAvKiAncCcgKi8gfHxcbiAgICAgIHMuY2hhckNvZGVBdChsZW5ndGggLSA4KSAhPT0gOTUgIC8qICdfJyAqLyB8fFxuICAgICAgcy5jaGFyQ29kZUF0KGxlbmd0aCAtIDkpICE9PSA5NSAgLyogJ18nICovKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZm9yICh2YXIgaSA9IGxlbmd0aCAtIDEwOyBpID49IDA7IGktLSkge1xuICAgIGlmIChzLmNoYXJDb2RlQXQoaSkgIT09IDM2IC8qICckJyAqLykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIENvbXBhcmF0b3IgYmV0d2VlbiB0d28gbWFwcGluZ3Mgd2hlcmUgdGhlIG9yaWdpbmFsIHBvc2l0aW9ucyBhcmUgY29tcGFyZWQuXG4gKlxuICogT3B0aW9uYWxseSBwYXNzIGluIGB0cnVlYCBhcyBgb25seUNvbXBhcmVHZW5lcmF0ZWRgIHRvIGNvbnNpZGVyIHR3b1xuICogbWFwcGluZ3Mgd2l0aCB0aGUgc2FtZSBvcmlnaW5hbCBzb3VyY2UvbGluZS9jb2x1bW4sIGJ1dCBkaWZmZXJlbnQgZ2VuZXJhdGVkXG4gKiBsaW5lIGFuZCBjb2x1bW4gdGhlIHNhbWUuIFVzZWZ1bCB3aGVuIHNlYXJjaGluZyBmb3IgYSBtYXBwaW5nIHdpdGggYVxuICogc3R1YmJlZCBvdXQgbWFwcGluZy5cbiAqL1xuZnVuY3Rpb24gY29tcGFyZUJ5T3JpZ2luYWxQb3NpdGlvbnMobWFwcGluZ0EsIG1hcHBpbmdCLCBvbmx5Q29tcGFyZU9yaWdpbmFsKSB7XG4gIHZhciBjbXAgPSBzdHJjbXAobWFwcGluZ0Euc291cmNlLCBtYXBwaW5nQi5zb3VyY2UpO1xuICBpZiAoY21wICE9PSAwKSB7XG4gICAgcmV0dXJuIGNtcDtcbiAgfVxuXG4gIGNtcCA9IG1hcHBpbmdBLm9yaWdpbmFsTGluZSAtIG1hcHBpbmdCLm9yaWdpbmFsTGluZTtcbiAgaWYgKGNtcCAhPT0gMCkge1xuICAgIHJldHVybiBjbXA7XG4gIH1cblxuICBjbXAgPSBtYXBwaW5nQS5vcmlnaW5hbENvbHVtbiAtIG1hcHBpbmdCLm9yaWdpbmFsQ29sdW1uO1xuICBpZiAoY21wICE9PSAwIHx8IG9ubHlDb21wYXJlT3JpZ2luYWwpIHtcbiAgICByZXR1cm4gY21wO1xuICB9XG5cbiAgY21wID0gbWFwcGluZ0EuZ2VuZXJhdGVkQ29sdW1uIC0gbWFwcGluZ0IuZ2VuZXJhdGVkQ29sdW1uO1xuICBpZiAoY21wICE9PSAwKSB7XG4gICAgcmV0dXJuIGNtcDtcbiAgfVxuXG4gIGNtcCA9IG1hcHBpbmdBLmdlbmVyYXRlZExpbmUgLSBtYXBwaW5nQi5nZW5lcmF0ZWRMaW5lO1xuICBpZiAoY21wICE9PSAwKSB7XG4gICAgcmV0dXJuIGNtcDtcbiAgfVxuXG4gIHJldHVybiBzdHJjbXAobWFwcGluZ0EubmFtZSwgbWFwcGluZ0IubmFtZSk7XG59XG5leHBvcnRzLmNvbXBhcmVCeU9yaWdpbmFsUG9zaXRpb25zID0gY29tcGFyZUJ5T3JpZ2luYWxQb3NpdGlvbnM7XG5cbi8qKlxuICogQ29tcGFyYXRvciBiZXR3ZWVuIHR3byBtYXBwaW5ncyB3aXRoIGRlZmxhdGVkIHNvdXJjZSBhbmQgbmFtZSBpbmRpY2VzIHdoZXJlXG4gKiB0aGUgZ2VuZXJhdGVkIHBvc2l0aW9ucyBhcmUgY29tcGFyZWQuXG4gKlxuICogT3B0aW9uYWxseSBwYXNzIGluIGB0cnVlYCBhcyBgb25seUNvbXBhcmVHZW5lcmF0ZWRgIHRvIGNvbnNpZGVyIHR3b1xuICogbWFwcGluZ3Mgd2l0aCB0aGUgc2FtZSBnZW5lcmF0ZWQgbGluZSBhbmQgY29sdW1uLCBidXQgZGlmZmVyZW50XG4gKiBzb3VyY2UvbmFtZS9vcmlnaW5hbCBsaW5lIGFuZCBjb2x1bW4gdGhlIHNhbWUuIFVzZWZ1bCB3aGVuIHNlYXJjaGluZyBmb3IgYVxuICogbWFwcGluZyB3aXRoIGEgc3R1YmJlZCBvdXQgbWFwcGluZy5cbiAqL1xuZnVuY3Rpb24gY29tcGFyZUJ5R2VuZXJhdGVkUG9zaXRpb25zRGVmbGF0ZWQobWFwcGluZ0EsIG1hcHBpbmdCLCBvbmx5Q29tcGFyZUdlbmVyYXRlZCkge1xuICB2YXIgY21wID0gbWFwcGluZ0EuZ2VuZXJhdGVkTGluZSAtIG1hcHBpbmdCLmdlbmVyYXRlZExpbmU7XG4gIGlmIChjbXAgIT09IDApIHtcbiAgICByZXR1cm4gY21wO1xuICB9XG5cbiAgY21wID0gbWFwcGluZ0EuZ2VuZXJhdGVkQ29sdW1uIC0gbWFwcGluZ0IuZ2VuZXJhdGVkQ29sdW1uO1xuICBpZiAoY21wICE9PSAwIHx8IG9ubHlDb21wYXJlR2VuZXJhdGVkKSB7XG4gICAgcmV0dXJuIGNtcDtcbiAgfVxuXG4gIGNtcCA9IHN0cmNtcChtYXBwaW5nQS5zb3VyY2UsIG1hcHBpbmdCLnNvdXJjZSk7XG4gIGlmIChjbXAgIT09IDApIHtcbiAgICByZXR1cm4gY21wO1xuICB9XG5cbiAgY21wID0gbWFwcGluZ0Eub3JpZ2luYWxMaW5lIC0gbWFwcGluZ0Iub3JpZ2luYWxMaW5lO1xuICBpZiAoY21wICE9PSAwKSB7XG4gICAgcmV0dXJuIGNtcDtcbiAgfVxuXG4gIGNtcCA9IG1hcHBpbmdBLm9yaWdpbmFsQ29sdW1uIC0gbWFwcGluZ0Iub3JpZ2luYWxDb2x1bW47XG4gIGlmIChjbXAgIT09IDApIHtcbiAgICByZXR1cm4gY21wO1xuICB9XG5cbiAgcmV0dXJuIHN0cmNtcChtYXBwaW5nQS5uYW1lLCBtYXBwaW5nQi5uYW1lKTtcbn1cbmV4cG9ydHMuY29tcGFyZUJ5R2VuZXJhdGVkUG9zaXRpb25zRGVmbGF0ZWQgPSBjb21wYXJlQnlHZW5lcmF0ZWRQb3NpdGlvbnNEZWZsYXRlZDtcblxuZnVuY3Rpb24gc3RyY21wKGFTdHIxLCBhU3RyMikge1xuICBpZiAoYVN0cjEgPT09IGFTdHIyKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICBpZiAoYVN0cjEgPT09IG51bGwpIHtcbiAgICByZXR1cm4gMTsgLy8gYVN0cjIgIT09IG51bGxcbiAgfVxuXG4gIGlmIChhU3RyMiA9PT0gbnVsbCkge1xuICAgIHJldHVybiAtMTsgLy8gYVN0cjEgIT09IG51bGxcbiAgfVxuXG4gIGlmIChhU3RyMSA+IGFTdHIyKSB7XG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICByZXR1cm4gLTE7XG59XG5cbi8qKlxuICogQ29tcGFyYXRvciBiZXR3ZWVuIHR3byBtYXBwaW5ncyB3aXRoIGluZmxhdGVkIHNvdXJjZSBhbmQgbmFtZSBzdHJpbmdzIHdoZXJlXG4gKiB0aGUgZ2VuZXJhdGVkIHBvc2l0aW9ucyBhcmUgY29tcGFyZWQuXG4gKi9cbmZ1bmN0aW9uIGNvbXBhcmVCeUdlbmVyYXRlZFBvc2l0aW9uc0luZmxhdGVkKG1hcHBpbmdBLCBtYXBwaW5nQikge1xuICB2YXIgY21wID0gbWFwcGluZ0EuZ2VuZXJhdGVkTGluZSAtIG1hcHBpbmdCLmdlbmVyYXRlZExpbmU7XG4gIGlmIChjbXAgIT09IDApIHtcbiAgICByZXR1cm4gY21wO1xuICB9XG5cbiAgY21wID0gbWFwcGluZ0EuZ2VuZXJhdGVkQ29sdW1uIC0gbWFwcGluZ0IuZ2VuZXJhdGVkQ29sdW1uO1xuICBpZiAoY21wICE9PSAwKSB7XG4gICAgcmV0dXJuIGNtcDtcbiAgfVxuXG4gIGNtcCA9IHN0cmNtcChtYXBwaW5nQS5zb3VyY2UsIG1hcHBpbmdCLnNvdXJjZSk7XG4gIGlmIChjbXAgIT09IDApIHtcbiAgICByZXR1cm4gY21wO1xuICB9XG5cbiAgY21wID0gbWFwcGluZ0Eub3JpZ2luYWxMaW5lIC0gbWFwcGluZ0Iub3JpZ2luYWxMaW5lO1xuICBpZiAoY21wICE9PSAwKSB7XG4gICAgcmV0dXJuIGNtcDtcbiAgfVxuXG4gIGNtcCA9IG1hcHBpbmdBLm9yaWdpbmFsQ29sdW1uIC0gbWFwcGluZ0Iub3JpZ2luYWxDb2x1bW47XG4gIGlmIChjbXAgIT09IDApIHtcbiAgICByZXR1cm4gY21wO1xuICB9XG5cbiAgcmV0dXJuIHN0cmNtcChtYXBwaW5nQS5uYW1lLCBtYXBwaW5nQi5uYW1lKTtcbn1cbmV4cG9ydHMuY29tcGFyZUJ5R2VuZXJhdGVkUG9zaXRpb25zSW5mbGF0ZWQgPSBjb21wYXJlQnlHZW5lcmF0ZWRQb3NpdGlvbnNJbmZsYXRlZDtcblxuLyoqXG4gKiBTdHJpcCBhbnkgSlNPTiBYU1NJIGF2b2lkYW5jZSBwcmVmaXggZnJvbSB0aGUgc3RyaW5nIChhcyBkb2N1bWVudGVkXG4gKiBpbiB0aGUgc291cmNlIG1hcHMgc3BlY2lmaWNhdGlvbiksIGFuZCB0aGVuIHBhcnNlIHRoZSBzdHJpbmcgYXNcbiAqIEpTT04uXG4gKi9cbmZ1bmN0aW9uIHBhcnNlU291cmNlTWFwSW5wdXQoc3RyKSB7XG4gIHJldHVybiBKU09OLnBhcnNlKHN0ci5yZXBsYWNlKC9eXFwpXX0nW15cXG5dKlxcbi8sICcnKSk7XG59XG5leHBvcnRzLnBhcnNlU291cmNlTWFwSW5wdXQgPSBwYXJzZVNvdXJjZU1hcElucHV0O1xuXG4vKipcbiAqIENvbXB1dGUgdGhlIFVSTCBvZiBhIHNvdXJjZSBnaXZlbiB0aGUgdGhlIHNvdXJjZSByb290LCB0aGUgc291cmNlJ3NcbiAqIFVSTCwgYW5kIHRoZSBzb3VyY2UgbWFwJ3MgVVJMLlxuICovXG5mdW5jdGlvbiBjb21wdXRlU291cmNlVVJMKHNvdXJjZVJvb3QsIHNvdXJjZVVSTCwgc291cmNlTWFwVVJMKSB7XG4gIHNvdXJjZVVSTCA9IHNvdXJjZVVSTCB8fCAnJztcblxuICBpZiAoc291cmNlUm9vdCkge1xuICAgIC8vIFRoaXMgZm9sbG93cyB3aGF0IENocm9tZSBkb2VzLlxuICAgIGlmIChzb3VyY2VSb290W3NvdXJjZVJvb3QubGVuZ3RoIC0gMV0gIT09ICcvJyAmJiBzb3VyY2VVUkxbMF0gIT09ICcvJykge1xuICAgICAgc291cmNlUm9vdCArPSAnLyc7XG4gICAgfVxuICAgIC8vIFRoZSBzcGVjIHNheXM6XG4gICAgLy8gICBMaW5lIDQ6IEFuIG9wdGlvbmFsIHNvdXJjZSByb290LCB1c2VmdWwgZm9yIHJlbG9jYXRpbmcgc291cmNlXG4gICAgLy8gICBmaWxlcyBvbiBhIHNlcnZlciBvciByZW1vdmluZyByZXBlYXRlZCB2YWx1ZXMgaW4gdGhlXG4gICAgLy8gICDigJxzb3VyY2Vz4oCdIGVudHJ5LiAgVGhpcyB2YWx1ZSBpcyBwcmVwZW5kZWQgdG8gdGhlIGluZGl2aWR1YWxcbiAgICAvLyAgIGVudHJpZXMgaW4gdGhlIOKAnHNvdXJjZeKAnSBmaWVsZC5cbiAgICBzb3VyY2VVUkwgPSBzb3VyY2VSb290ICsgc291cmNlVVJMO1xuICB9XG5cbiAgLy8gSGlzdG9yaWNhbGx5LCBTb3VyY2VNYXBDb25zdW1lciBkaWQgbm90IHRha2UgdGhlIHNvdXJjZU1hcFVSTCBhc1xuICAvLyBhIHBhcmFtZXRlci4gIFRoaXMgbW9kZSBpcyBzdGlsbCBzb21ld2hhdCBzdXBwb3J0ZWQsIHdoaWNoIGlzIHdoeVxuICAvLyB0aGlzIGNvZGUgYmxvY2sgaXMgY29uZGl0aW9uYWwuICBIb3dldmVyLCBpdCdzIHByZWZlcmFibGUgdG8gcGFzc1xuICAvLyB0aGUgc291cmNlIG1hcCBVUkwgdG8gU291cmNlTWFwQ29uc3VtZXIsIHNvIHRoYXQgdGhpcyBmdW5jdGlvblxuICAvLyBjYW4gaW1wbGVtZW50IHRoZSBzb3VyY2UgVVJMIHJlc29sdXRpb24gYWxnb3JpdGhtIGFzIG91dGxpbmVkIGluXG4gIC8vIHRoZSBzcGVjLiAgVGhpcyBibG9jayBpcyBiYXNpY2FsbHkgdGhlIGVxdWl2YWxlbnQgb2Y6XG4gIC8vICAgIG5ldyBVUkwoc291cmNlVVJMLCBzb3VyY2VNYXBVUkwpLnRvU3RyaW5nKClcbiAgLy8gLi4uIGV4Y2VwdCBpdCBhdm9pZHMgdXNpbmcgVVJMLCB3aGljaCB3YXNuJ3QgYXZhaWxhYmxlIGluIHRoZVxuICAvLyBvbGRlciByZWxlYXNlcyBvZiBub2RlIHN0aWxsIHN1cHBvcnRlZCBieSB0aGlzIGxpYnJhcnkuXG4gIC8vXG4gIC8vIFRoZSBzcGVjIHNheXM6XG4gIC8vICAgSWYgdGhlIHNvdXJjZXMgYXJlIG5vdCBhYnNvbHV0ZSBVUkxzIGFmdGVyIHByZXBlbmRpbmcgb2YgdGhlXG4gIC8vICAg4oCcc291cmNlUm9vdOKAnSwgdGhlIHNvdXJjZXMgYXJlIHJlc29sdmVkIHJlbGF0aXZlIHRvIHRoZVxuICAvLyAgIFNvdXJjZU1hcCAobGlrZSByZXNvbHZpbmcgc2NyaXB0IHNyYyBpbiBhIGh0bWwgZG9jdW1lbnQpLlxuICBpZiAoc291cmNlTWFwVVJMKSB7XG4gICAgdmFyIHBhcnNlZCA9IHVybFBhcnNlKHNvdXJjZU1hcFVSTCk7XG4gICAgaWYgKCFwYXJzZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcInNvdXJjZU1hcFVSTCBjb3VsZCBub3QgYmUgcGFyc2VkXCIpO1xuICAgIH1cbiAgICBpZiAocGFyc2VkLnBhdGgpIHtcbiAgICAgIC8vIFN0cmlwIHRoZSBsYXN0IHBhdGggY29tcG9uZW50LCBidXQga2VlcCB0aGUgXCIvXCIuXG4gICAgICB2YXIgaW5kZXggPSBwYXJzZWQucGF0aC5sYXN0SW5kZXhPZignLycpO1xuICAgICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgICAgcGFyc2VkLnBhdGggPSBwYXJzZWQucGF0aC5zdWJzdHJpbmcoMCwgaW5kZXggKyAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgc291cmNlVVJMID0gam9pbih1cmxHZW5lcmF0ZShwYXJzZWQpLCBzb3VyY2VVUkwpO1xuICB9XG5cbiAgcmV0dXJuIG5vcm1hbGl6ZShzb3VyY2VVUkwpO1xufVxuZXhwb3J0cy5jb21wdXRlU291cmNlVVJMID0gY29tcHV0ZVNvdXJjZVVSTDtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbGliL3V0aWwuanNcbi8vIG1vZHVsZSBpZCA9IDRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLyogLSotIE1vZGU6IGpzOyBqcy1pbmRlbnQtbGV2ZWw6IDI7IC0qLSAqL1xuLypcbiAqIENvcHlyaWdodCAyMDExIE1vemlsbGEgRm91bmRhdGlvbiBhbmQgY29udHJpYnV0b3JzXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTmV3IEJTRCBsaWNlbnNlLiBTZWUgTElDRU5TRSBvcjpcbiAqIGh0dHA6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9CU0QtMy1DbGF1c2VcbiAqL1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4vdXRpbCcpO1xudmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgaGFzTmF0aXZlTWFwID0gdHlwZW9mIE1hcCAhPT0gXCJ1bmRlZmluZWRcIjtcblxuLyoqXG4gKiBBIGRhdGEgc3RydWN0dXJlIHdoaWNoIGlzIGEgY29tYmluYXRpb24gb2YgYW4gYXJyYXkgYW5kIGEgc2V0LiBBZGRpbmcgYSBuZXdcbiAqIG1lbWJlciBpcyBPKDEpLCB0ZXN0aW5nIGZvciBtZW1iZXJzaGlwIGlzIE8oMSksIGFuZCBmaW5kaW5nIHRoZSBpbmRleCBvZiBhblxuICogZWxlbWVudCBpcyBPKDEpLiBSZW1vdmluZyBlbGVtZW50cyBmcm9tIHRoZSBzZXQgaXMgbm90IHN1cHBvcnRlZC4gT25seVxuICogc3RyaW5ncyBhcmUgc3VwcG9ydGVkIGZvciBtZW1iZXJzaGlwLlxuICovXG5mdW5jdGlvbiBBcnJheVNldCgpIHtcbiAgdGhpcy5fYXJyYXkgPSBbXTtcbiAgdGhpcy5fc2V0ID0gaGFzTmF0aXZlTWFwID8gbmV3IE1hcCgpIDogT2JqZWN0LmNyZWF0ZShudWxsKTtcbn1cblxuLyoqXG4gKiBTdGF0aWMgbWV0aG9kIGZvciBjcmVhdGluZyBBcnJheVNldCBpbnN0YW5jZXMgZnJvbSBhbiBleGlzdGluZyBhcnJheS5cbiAqL1xuQXJyYXlTZXQuZnJvbUFycmF5ID0gZnVuY3Rpb24gQXJyYXlTZXRfZnJvbUFycmF5KGFBcnJheSwgYUFsbG93RHVwbGljYXRlcykge1xuICB2YXIgc2V0ID0gbmV3IEFycmF5U2V0KCk7XG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBhQXJyYXkubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBzZXQuYWRkKGFBcnJheVtpXSwgYUFsbG93RHVwbGljYXRlcyk7XG4gIH1cbiAgcmV0dXJuIHNldDtcbn07XG5cbi8qKlxuICogUmV0dXJuIGhvdyBtYW55IHVuaXF1ZSBpdGVtcyBhcmUgaW4gdGhpcyBBcnJheVNldC4gSWYgZHVwbGljYXRlcyBoYXZlIGJlZW5cbiAqIGFkZGVkLCB0aGFuIHRob3NlIGRvIG5vdCBjb3VudCB0b3dhcmRzIHRoZSBzaXplLlxuICpcbiAqIEByZXR1cm5zIE51bWJlclxuICovXG5BcnJheVNldC5wcm90b3R5cGUuc2l6ZSA9IGZ1bmN0aW9uIEFycmF5U2V0X3NpemUoKSB7XG4gIHJldHVybiBoYXNOYXRpdmVNYXAgPyB0aGlzLl9zZXQuc2l6ZSA6IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRoaXMuX3NldCkubGVuZ3RoO1xufTtcblxuLyoqXG4gKiBBZGQgdGhlIGdpdmVuIHN0cmluZyB0byB0aGlzIHNldC5cbiAqXG4gKiBAcGFyYW0gU3RyaW5nIGFTdHJcbiAqL1xuQXJyYXlTZXQucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIEFycmF5U2V0X2FkZChhU3RyLCBhQWxsb3dEdXBsaWNhdGVzKSB7XG4gIHZhciBzU3RyID0gaGFzTmF0aXZlTWFwID8gYVN0ciA6IHV0aWwudG9TZXRTdHJpbmcoYVN0cik7XG4gIHZhciBpc0R1cGxpY2F0ZSA9IGhhc05hdGl2ZU1hcCA/IHRoaXMuaGFzKGFTdHIpIDogaGFzLmNhbGwodGhpcy5fc2V0LCBzU3RyKTtcbiAgdmFyIGlkeCA9IHRoaXMuX2FycmF5Lmxlbmd0aDtcbiAgaWYgKCFpc0R1cGxpY2F0ZSB8fCBhQWxsb3dEdXBsaWNhdGVzKSB7XG4gICAgdGhpcy5fYXJyYXkucHVzaChhU3RyKTtcbiAgfVxuICBpZiAoIWlzRHVwbGljYXRlKSB7XG4gICAgaWYgKGhhc05hdGl2ZU1hcCkge1xuICAgICAgdGhpcy5fc2V0LnNldChhU3RyLCBpZHgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9zZXRbc1N0cl0gPSBpZHg7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIElzIHRoZSBnaXZlbiBzdHJpbmcgYSBtZW1iZXIgb2YgdGhpcyBzZXQ/XG4gKlxuICogQHBhcmFtIFN0cmluZyBhU3RyXG4gKi9cbkFycmF5U2V0LnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiBBcnJheVNldF9oYXMoYVN0cikge1xuICBpZiAoaGFzTmF0aXZlTWFwKSB7XG4gICAgcmV0dXJuIHRoaXMuX3NldC5oYXMoYVN0cik7XG4gIH0gZWxzZSB7XG4gICAgdmFyIHNTdHIgPSB1dGlsLnRvU2V0U3RyaW5nKGFTdHIpO1xuICAgIHJldHVybiBoYXMuY2FsbCh0aGlzLl9zZXQsIHNTdHIpO1xuICB9XG59O1xuXG4vKipcbiAqIFdoYXQgaXMgdGhlIGluZGV4IG9mIHRoZSBnaXZlbiBzdHJpbmcgaW4gdGhlIGFycmF5P1xuICpcbiAqIEBwYXJhbSBTdHJpbmcgYVN0clxuICovXG5BcnJheVNldC5wcm90b3R5cGUuaW5kZXhPZiA9IGZ1bmN0aW9uIEFycmF5U2V0X2luZGV4T2YoYVN0cikge1xuICBpZiAoaGFzTmF0aXZlTWFwKSB7XG4gICAgdmFyIGlkeCA9IHRoaXMuX3NldC5nZXQoYVN0cik7XG4gICAgaWYgKGlkeCA+PSAwKSB7XG4gICAgICAgIHJldHVybiBpZHg7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBzU3RyID0gdXRpbC50b1NldFN0cmluZyhhU3RyKTtcbiAgICBpZiAoaGFzLmNhbGwodGhpcy5fc2V0LCBzU3RyKSkge1xuICAgICAgcmV0dXJuIHRoaXMuX3NldFtzU3RyXTtcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ1wiJyArIGFTdHIgKyAnXCIgaXMgbm90IGluIHRoZSBzZXQuJyk7XG59O1xuXG4vKipcbiAqIFdoYXQgaXMgdGhlIGVsZW1lbnQgYXQgdGhlIGdpdmVuIGluZGV4P1xuICpcbiAqIEBwYXJhbSBOdW1iZXIgYUlkeFxuICovXG5BcnJheVNldC5wcm90b3R5cGUuYXQgPSBmdW5jdGlvbiBBcnJheVNldF9hdChhSWR4KSB7XG4gIGlmIChhSWR4ID49IDAgJiYgYUlkeCA8IHRoaXMuX2FycmF5Lmxlbmd0aCkge1xuICAgIHJldHVybiB0aGlzLl9hcnJheVthSWR4XTtcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoJ05vIGVsZW1lbnQgaW5kZXhlZCBieSAnICsgYUlkeCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGFycmF5IHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgc2V0ICh3aGljaCBoYXMgdGhlIHByb3BlciBpbmRpY2VzXG4gKiBpbmRpY2F0ZWQgYnkgaW5kZXhPZikuIE5vdGUgdGhhdCB0aGlzIGlzIGEgY29weSBvZiB0aGUgaW50ZXJuYWwgYXJyYXkgdXNlZFxuICogZm9yIHN0b3JpbmcgdGhlIG1lbWJlcnMgc28gdGhhdCBubyBvbmUgY2FuIG1lc3Mgd2l0aCBpbnRlcm5hbCBzdGF0ZS5cbiAqL1xuQXJyYXlTZXQucHJvdG90eXBlLnRvQXJyYXkgPSBmdW5jdGlvbiBBcnJheVNldF90b0FycmF5KCkge1xuICByZXR1cm4gdGhpcy5fYXJyYXkuc2xpY2UoKTtcbn07XG5cbmV4cG9ydHMuQXJyYXlTZXQgPSBBcnJheVNldDtcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vbGliL2FycmF5LXNldC5qc1xuLy8gbW9kdWxlIGlkID0gNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKiAtKi0gTW9kZToganM7IGpzLWluZGVudC1sZXZlbDogMjsgLSotICovXG4vKlxuICogQ29weXJpZ2h0IDIwMTQgTW96aWxsYSBGb3VuZGF0aW9uIGFuZCBjb250cmlidXRvcnNcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBOZXcgQlNEIGxpY2Vuc2UuIFNlZSBMSUNFTlNFIG9yOlxuICogaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL0JTRC0zLUNsYXVzZVxuICovXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi91dGlsJyk7XG5cbi8qKlxuICogRGV0ZXJtaW5lIHdoZXRoZXIgbWFwcGluZ0IgaXMgYWZ0ZXIgbWFwcGluZ0Egd2l0aCByZXNwZWN0IHRvIGdlbmVyYXRlZFxuICogcG9zaXRpb24uXG4gKi9cbmZ1bmN0aW9uIGdlbmVyYXRlZFBvc2l0aW9uQWZ0ZXIobWFwcGluZ0EsIG1hcHBpbmdCKSB7XG4gIC8vIE9wdGltaXplZCBmb3IgbW9zdCBjb21tb24gY2FzZVxuICB2YXIgbGluZUEgPSBtYXBwaW5nQS5nZW5lcmF0ZWRMaW5lO1xuICB2YXIgbGluZUIgPSBtYXBwaW5nQi5nZW5lcmF0ZWRMaW5lO1xuICB2YXIgY29sdW1uQSA9IG1hcHBpbmdBLmdlbmVyYXRlZENvbHVtbjtcbiAgdmFyIGNvbHVtbkIgPSBtYXBwaW5nQi5nZW5lcmF0ZWRDb2x1bW47XG4gIHJldHVybiBsaW5lQiA+IGxpbmVBIHx8IGxpbmVCID09IGxpbmVBICYmIGNvbHVtbkIgPj0gY29sdW1uQSB8fFxuICAgICAgICAgdXRpbC5jb21wYXJlQnlHZW5lcmF0ZWRQb3NpdGlvbnNJbmZsYXRlZChtYXBwaW5nQSwgbWFwcGluZ0IpIDw9IDA7XG59XG5cbi8qKlxuICogQSBkYXRhIHN0cnVjdHVyZSB0byBwcm92aWRlIGEgc29ydGVkIHZpZXcgb2YgYWNjdW11bGF0ZWQgbWFwcGluZ3MgaW4gYVxuICogcGVyZm9ybWFuY2UgY29uc2Npb3VzIG1hbm5lci4gSXQgdHJhZGVzIGEgbmVnbGliYWJsZSBvdmVyaGVhZCBpbiBnZW5lcmFsXG4gKiBjYXNlIGZvciBhIGxhcmdlIHNwZWVkdXAgaW4gY2FzZSBvZiBtYXBwaW5ncyBiZWluZyBhZGRlZCBpbiBvcmRlci5cbiAqL1xuZnVuY3Rpb24gTWFwcGluZ0xpc3QoKSB7XG4gIHRoaXMuX2FycmF5ID0gW107XG4gIHRoaXMuX3NvcnRlZCA9IHRydWU7XG4gIC8vIFNlcnZlcyBhcyBpbmZpbXVtXG4gIHRoaXMuX2xhc3QgPSB7Z2VuZXJhdGVkTGluZTogLTEsIGdlbmVyYXRlZENvbHVtbjogMH07XG59XG5cbi8qKlxuICogSXRlcmF0ZSB0aHJvdWdoIGludGVybmFsIGl0ZW1zLiBUaGlzIG1ldGhvZCB0YWtlcyB0aGUgc2FtZSBhcmd1bWVudHMgdGhhdFxuICogYEFycmF5LnByb3RvdHlwZS5mb3JFYWNoYCB0YWtlcy5cbiAqXG4gKiBOT1RFOiBUaGUgb3JkZXIgb2YgdGhlIG1hcHBpbmdzIGlzIE5PVCBndWFyYW50ZWVkLlxuICovXG5NYXBwaW5nTGlzdC5wcm90b3R5cGUudW5zb3J0ZWRGb3JFYWNoID1cbiAgZnVuY3Rpb24gTWFwcGluZ0xpc3RfZm9yRWFjaChhQ2FsbGJhY2ssIGFUaGlzQXJnKSB7XG4gICAgdGhpcy5fYXJyYXkuZm9yRWFjaChhQ2FsbGJhY2ssIGFUaGlzQXJnKTtcbiAgfTtcblxuLyoqXG4gKiBBZGQgdGhlIGdpdmVuIHNvdXJjZSBtYXBwaW5nLlxuICpcbiAqIEBwYXJhbSBPYmplY3QgYU1hcHBpbmdcbiAqL1xuTWFwcGluZ0xpc3QucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIE1hcHBpbmdMaXN0X2FkZChhTWFwcGluZykge1xuICBpZiAoZ2VuZXJhdGVkUG9zaXRpb25BZnRlcih0aGlzLl9sYXN0LCBhTWFwcGluZykpIHtcbiAgICB0aGlzLl9sYXN0ID0gYU1hcHBpbmc7XG4gICAgdGhpcy5fYXJyYXkucHVzaChhTWFwcGluZyk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fc29ydGVkID0gZmFsc2U7XG4gICAgdGhpcy5fYXJyYXkucHVzaChhTWFwcGluZyk7XG4gIH1cbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZmxhdCwgc29ydGVkIGFycmF5IG9mIG1hcHBpbmdzLiBUaGUgbWFwcGluZ3MgYXJlIHNvcnRlZCBieVxuICogZ2VuZXJhdGVkIHBvc2l0aW9uLlxuICpcbiAqIFdBUk5JTkc6IFRoaXMgbWV0aG9kIHJldHVybnMgaW50ZXJuYWwgZGF0YSB3aXRob3V0IGNvcHlpbmcsIGZvclxuICogcGVyZm9ybWFuY2UuIFRoZSByZXR1cm4gdmFsdWUgbXVzdCBOT1QgYmUgbXV0YXRlZCwgYW5kIHNob3VsZCBiZSB0cmVhdGVkIGFzXG4gKiBhbiBpbW11dGFibGUgYm9ycm93LiBJZiB5b3Ugd2FudCB0byB0YWtlIG93bmVyc2hpcCwgeW91IG11c3QgbWFrZSB5b3VyIG93blxuICogY29weS5cbiAqL1xuTWFwcGluZ0xpc3QucHJvdG90eXBlLnRvQXJyYXkgPSBmdW5jdGlvbiBNYXBwaW5nTGlzdF90b0FycmF5KCkge1xuICBpZiAoIXRoaXMuX3NvcnRlZCkge1xuICAgIHRoaXMuX2FycmF5LnNvcnQodXRpbC5jb21wYXJlQnlHZW5lcmF0ZWRQb3NpdGlvbnNJbmZsYXRlZCk7XG4gICAgdGhpcy5fc29ydGVkID0gdHJ1ZTtcbiAgfVxuICByZXR1cm4gdGhpcy5fYXJyYXk7XG59O1xuXG5leHBvcnRzLk1hcHBpbmdMaXN0ID0gTWFwcGluZ0xpc3Q7XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL2xpYi9tYXBwaW5nLWxpc3QuanNcbi8vIG1vZHVsZSBpZCA9IDZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLyogLSotIE1vZGU6IGpzOyBqcy1pbmRlbnQtbGV2ZWw6IDI7IC0qLSAqL1xuLypcbiAqIENvcHlyaWdodCAyMDExIE1vemlsbGEgRm91bmRhdGlvbiBhbmQgY29udHJpYnV0b3JzXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTmV3IEJTRCBsaWNlbnNlLiBTZWUgTElDRU5TRSBvcjpcbiAqIGh0dHA6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9CU0QtMy1DbGF1c2VcbiAqL1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4vdXRpbCcpO1xudmFyIGJpbmFyeVNlYXJjaCA9IHJlcXVpcmUoJy4vYmluYXJ5LXNlYXJjaCcpO1xudmFyIEFycmF5U2V0ID0gcmVxdWlyZSgnLi9hcnJheS1zZXQnKS5BcnJheVNldDtcbnZhciBiYXNlNjRWTFEgPSByZXF1aXJlKCcuL2Jhc2U2NC12bHEnKTtcbnZhciBxdWlja1NvcnQgPSByZXF1aXJlKCcuL3F1aWNrLXNvcnQnKS5xdWlja1NvcnQ7XG5cbmZ1bmN0aW9uIFNvdXJjZU1hcENvbnN1bWVyKGFTb3VyY2VNYXAsIGFTb3VyY2VNYXBVUkwpIHtcbiAgdmFyIHNvdXJjZU1hcCA9IGFTb3VyY2VNYXA7XG4gIGlmICh0eXBlb2YgYVNvdXJjZU1hcCA9PT0gJ3N0cmluZycpIHtcbiAgICBzb3VyY2VNYXAgPSB1dGlsLnBhcnNlU291cmNlTWFwSW5wdXQoYVNvdXJjZU1hcCk7XG4gIH1cblxuICByZXR1cm4gc291cmNlTWFwLnNlY3Rpb25zICE9IG51bGxcbiAgICA/IG5ldyBJbmRleGVkU291cmNlTWFwQ29uc3VtZXIoc291cmNlTWFwLCBhU291cmNlTWFwVVJMKVxuICAgIDogbmV3IEJhc2ljU291cmNlTWFwQ29uc3VtZXIoc291cmNlTWFwLCBhU291cmNlTWFwVVJMKTtcbn1cblxuU291cmNlTWFwQ29uc3VtZXIuZnJvbVNvdXJjZU1hcCA9IGZ1bmN0aW9uKGFTb3VyY2VNYXAsIGFTb3VyY2VNYXBVUkwpIHtcbiAgcmV0dXJuIEJhc2ljU291cmNlTWFwQ29uc3VtZXIuZnJvbVNvdXJjZU1hcChhU291cmNlTWFwLCBhU291cmNlTWFwVVJMKTtcbn1cblxuLyoqXG4gKiBUaGUgdmVyc2lvbiBvZiB0aGUgc291cmNlIG1hcHBpbmcgc3BlYyB0aGF0IHdlIGFyZSBjb25zdW1pbmcuXG4gKi9cblNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5fdmVyc2lvbiA9IDM7XG5cbi8vIGBfX2dlbmVyYXRlZE1hcHBpbmdzYCBhbmQgYF9fb3JpZ2luYWxNYXBwaW5nc2AgYXJlIGFycmF5cyB0aGF0IGhvbGQgdGhlXG4vLyBwYXJzZWQgbWFwcGluZyBjb29yZGluYXRlcyBmcm9tIHRoZSBzb3VyY2UgbWFwJ3MgXCJtYXBwaW5nc1wiIGF0dHJpYnV0ZS4gVGhleVxuLy8gYXJlIGxhemlseSBpbnN0YW50aWF0ZWQsIGFjY2Vzc2VkIHZpYSB0aGUgYF9nZW5lcmF0ZWRNYXBwaW5nc2AgYW5kXG4vLyBgX29yaWdpbmFsTWFwcGluZ3NgIGdldHRlcnMgcmVzcGVjdGl2ZWx5LCBhbmQgd2Ugb25seSBwYXJzZSB0aGUgbWFwcGluZ3Ncbi8vIGFuZCBjcmVhdGUgdGhlc2UgYXJyYXlzIG9uY2UgcXVlcmllZCBmb3IgYSBzb3VyY2UgbG9jYXRpb24uIFdlIGp1bXAgdGhyb3VnaFxuLy8gdGhlc2UgaG9vcHMgYmVjYXVzZSB0aGVyZSBjYW4gYmUgbWFueSB0aG91c2FuZHMgb2YgbWFwcGluZ3MsIGFuZCBwYXJzaW5nXG4vLyB0aGVtIGlzIGV4cGVuc2l2ZSwgc28gd2Ugb25seSB3YW50IHRvIGRvIGl0IGlmIHdlIG11c3QuXG4vL1xuLy8gRWFjaCBvYmplY3QgaW4gdGhlIGFycmF5cyBpcyBvZiB0aGUgZm9ybTpcbi8vXG4vLyAgICAge1xuLy8gICAgICAgZ2VuZXJhdGVkTGluZTogVGhlIGxpbmUgbnVtYmVyIGluIHRoZSBnZW5lcmF0ZWQgY29kZSxcbi8vICAgICAgIGdlbmVyYXRlZENvbHVtbjogVGhlIGNvbHVtbiBudW1iZXIgaW4gdGhlIGdlbmVyYXRlZCBjb2RlLFxuLy8gICAgICAgc291cmNlOiBUaGUgcGF0aCB0byB0aGUgb3JpZ2luYWwgc291cmNlIGZpbGUgdGhhdCBnZW5lcmF0ZWQgdGhpc1xuLy8gICAgICAgICAgICAgICBjaHVuayBvZiBjb2RlLFxuLy8gICAgICAgb3JpZ2luYWxMaW5lOiBUaGUgbGluZSBudW1iZXIgaW4gdGhlIG9yaWdpbmFsIHNvdXJjZSB0aGF0XG4vLyAgICAgICAgICAgICAgICAgICAgIGNvcnJlc3BvbmRzIHRvIHRoaXMgY2h1bmsgb2YgZ2VuZXJhdGVkIGNvZGUsXG4vLyAgICAgICBvcmlnaW5hbENvbHVtbjogVGhlIGNvbHVtbiBudW1iZXIgaW4gdGhlIG9yaWdpbmFsIHNvdXJjZSB0aGF0XG4vLyAgICAgICAgICAgICAgICAgICAgICAgY29ycmVzcG9uZHMgdG8gdGhpcyBjaHVuayBvZiBnZW5lcmF0ZWQgY29kZSxcbi8vICAgICAgIG5hbWU6IFRoZSBuYW1lIG9mIHRoZSBvcmlnaW5hbCBzeW1ib2wgd2hpY2ggZ2VuZXJhdGVkIHRoaXMgY2h1bmsgb2Zcbi8vICAgICAgICAgICAgIGNvZGUuXG4vLyAgICAgfVxuLy9cbi8vIEFsbCBwcm9wZXJ0aWVzIGV4Y2VwdCBmb3IgYGdlbmVyYXRlZExpbmVgIGFuZCBgZ2VuZXJhdGVkQ29sdW1uYCBjYW4gYmVcbi8vIGBudWxsYC5cbi8vXG4vLyBgX2dlbmVyYXRlZE1hcHBpbmdzYCBpcyBvcmRlcmVkIGJ5IHRoZSBnZW5lcmF0ZWQgcG9zaXRpb25zLlxuLy9cbi8vIGBfb3JpZ2luYWxNYXBwaW5nc2AgaXMgb3JkZXJlZCBieSB0aGUgb3JpZ2luYWwgcG9zaXRpb25zLlxuXG5Tb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUuX19nZW5lcmF0ZWRNYXBwaW5ncyA9IG51bGw7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLCAnX2dlbmVyYXRlZE1hcHBpbmdzJywge1xuICBjb25maWd1cmFibGU6IHRydWUsXG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIGlmICghdGhpcy5fX2dlbmVyYXRlZE1hcHBpbmdzKSB7XG4gICAgICB0aGlzLl9wYXJzZU1hcHBpbmdzKHRoaXMuX21hcHBpbmdzLCB0aGlzLnNvdXJjZVJvb3QpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9fZ2VuZXJhdGVkTWFwcGluZ3M7XG4gIH1cbn0pO1xuXG5Tb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUuX19vcmlnaW5hbE1hcHBpbmdzID0gbnVsbDtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShTb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUsICdfb3JpZ2luYWxNYXBwaW5ncycsIHtcbiAgY29uZmlndXJhYmxlOiB0cnVlLFxuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXRoaXMuX19vcmlnaW5hbE1hcHBpbmdzKSB7XG4gICAgICB0aGlzLl9wYXJzZU1hcHBpbmdzKHRoaXMuX21hcHBpbmdzLCB0aGlzLnNvdXJjZVJvb3QpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9fb3JpZ2luYWxNYXBwaW5ncztcbiAgfVxufSk7XG5cblNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5fY2hhcklzTWFwcGluZ1NlcGFyYXRvciA9XG4gIGZ1bmN0aW9uIFNvdXJjZU1hcENvbnN1bWVyX2NoYXJJc01hcHBpbmdTZXBhcmF0b3IoYVN0ciwgaW5kZXgpIHtcbiAgICB2YXIgYyA9IGFTdHIuY2hhckF0KGluZGV4KTtcbiAgICByZXR1cm4gYyA9PT0gXCI7XCIgfHwgYyA9PT0gXCIsXCI7XG4gIH07XG5cbi8qKlxuICogUGFyc2UgdGhlIG1hcHBpbmdzIGluIGEgc3RyaW5nIGluIHRvIGEgZGF0YSBzdHJ1Y3R1cmUgd2hpY2ggd2UgY2FuIGVhc2lseVxuICogcXVlcnkgKHRoZSBvcmRlcmVkIGFycmF5cyBpbiB0aGUgYHRoaXMuX19nZW5lcmF0ZWRNYXBwaW5nc2AgYW5kXG4gKiBgdGhpcy5fX29yaWdpbmFsTWFwcGluZ3NgIHByb3BlcnRpZXMpLlxuICovXG5Tb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUuX3BhcnNlTWFwcGluZ3MgPVxuICBmdW5jdGlvbiBTb3VyY2VNYXBDb25zdW1lcl9wYXJzZU1hcHBpbmdzKGFTdHIsIGFTb3VyY2VSb290KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiU3ViY2xhc3NlcyBtdXN0IGltcGxlbWVudCBfcGFyc2VNYXBwaW5nc1wiKTtcbiAgfTtcblxuU291cmNlTWFwQ29uc3VtZXIuR0VORVJBVEVEX09SREVSID0gMTtcblNvdXJjZU1hcENvbnN1bWVyLk9SSUdJTkFMX09SREVSID0gMjtcblxuU291cmNlTWFwQ29uc3VtZXIuR1JFQVRFU1RfTE9XRVJfQk9VTkQgPSAxO1xuU291cmNlTWFwQ29uc3VtZXIuTEVBU1RfVVBQRVJfQk9VTkQgPSAyO1xuXG4vKipcbiAqIEl0ZXJhdGUgb3ZlciBlYWNoIG1hcHBpbmcgYmV0d2VlbiBhbiBvcmlnaW5hbCBzb3VyY2UvbGluZS9jb2x1bW4gYW5kIGFcbiAqIGdlbmVyYXRlZCBsaW5lL2NvbHVtbiBpbiB0aGlzIHNvdXJjZSBtYXAuXG4gKlxuICogQHBhcmFtIEZ1bmN0aW9uIGFDYWxsYmFja1xuICogICAgICAgIFRoZSBmdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aXRoIGVhY2ggbWFwcGluZy5cbiAqIEBwYXJhbSBPYmplY3QgYUNvbnRleHRcbiAqICAgICAgICBPcHRpb25hbC4gSWYgc3BlY2lmaWVkLCB0aGlzIG9iamVjdCB3aWxsIGJlIHRoZSB2YWx1ZSBvZiBgdGhpc2AgZXZlcnlcbiAqICAgICAgICB0aW1lIHRoYXQgYGFDYWxsYmFja2AgaXMgY2FsbGVkLlxuICogQHBhcmFtIGFPcmRlclxuICogICAgICAgIEVpdGhlciBgU291cmNlTWFwQ29uc3VtZXIuR0VORVJBVEVEX09SREVSYCBvclxuICogICAgICAgIGBTb3VyY2VNYXBDb25zdW1lci5PUklHSU5BTF9PUkRFUmAuIFNwZWNpZmllcyB3aGV0aGVyIHlvdSB3YW50IHRvXG4gKiAgICAgICAgaXRlcmF0ZSBvdmVyIHRoZSBtYXBwaW5ncyBzb3J0ZWQgYnkgdGhlIGdlbmVyYXRlZCBmaWxlJ3MgbGluZS9jb2x1bW5cbiAqICAgICAgICBvcmRlciBvciB0aGUgb3JpZ2luYWwncyBzb3VyY2UvbGluZS9jb2x1bW4gb3JkZXIsIHJlc3BlY3RpdmVseS4gRGVmYXVsdHMgdG9cbiAqICAgICAgICBgU291cmNlTWFwQ29uc3VtZXIuR0VORVJBVEVEX09SREVSYC5cbiAqL1xuU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLmVhY2hNYXBwaW5nID1cbiAgZnVuY3Rpb24gU291cmNlTWFwQ29uc3VtZXJfZWFjaE1hcHBpbmcoYUNhbGxiYWNrLCBhQ29udGV4dCwgYU9yZGVyKSB7XG4gICAgdmFyIGNvbnRleHQgPSBhQ29udGV4dCB8fCBudWxsO1xuICAgIHZhciBvcmRlciA9IGFPcmRlciB8fCBTb3VyY2VNYXBDb25zdW1lci5HRU5FUkFURURfT1JERVI7XG5cbiAgICB2YXIgbWFwcGluZ3M7XG4gICAgc3dpdGNoIChvcmRlcikge1xuICAgIGNhc2UgU291cmNlTWFwQ29uc3VtZXIuR0VORVJBVEVEX09SREVSOlxuICAgICAgbWFwcGluZ3MgPSB0aGlzLl9nZW5lcmF0ZWRNYXBwaW5ncztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgU291cmNlTWFwQ29uc3VtZXIuT1JJR0lOQUxfT1JERVI6XG4gICAgICBtYXBwaW5ncyA9IHRoaXMuX29yaWdpbmFsTWFwcGluZ3M7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBvcmRlciBvZiBpdGVyYXRpb24uXCIpO1xuICAgIH1cblxuICAgIHZhciBzb3VyY2VSb290ID0gdGhpcy5zb3VyY2VSb290O1xuICAgIG1hcHBpbmdzLm1hcChmdW5jdGlvbiAobWFwcGluZykge1xuICAgICAgdmFyIHNvdXJjZSA9IG1hcHBpbmcuc291cmNlID09PSBudWxsID8gbnVsbCA6IHRoaXMuX3NvdXJjZXMuYXQobWFwcGluZy5zb3VyY2UpO1xuICAgICAgc291cmNlID0gdXRpbC5jb21wdXRlU291cmNlVVJMKHNvdXJjZVJvb3QsIHNvdXJjZSwgdGhpcy5fc291cmNlTWFwVVJMKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgICBnZW5lcmF0ZWRMaW5lOiBtYXBwaW5nLmdlbmVyYXRlZExpbmUsXG4gICAgICAgIGdlbmVyYXRlZENvbHVtbjogbWFwcGluZy5nZW5lcmF0ZWRDb2x1bW4sXG4gICAgICAgIG9yaWdpbmFsTGluZTogbWFwcGluZy5vcmlnaW5hbExpbmUsXG4gICAgICAgIG9yaWdpbmFsQ29sdW1uOiBtYXBwaW5nLm9yaWdpbmFsQ29sdW1uLFxuICAgICAgICBuYW1lOiBtYXBwaW5nLm5hbWUgPT09IG51bGwgPyBudWxsIDogdGhpcy5fbmFtZXMuYXQobWFwcGluZy5uYW1lKVxuICAgICAgfTtcbiAgICB9LCB0aGlzKS5mb3JFYWNoKGFDYWxsYmFjaywgY29udGV4dCk7XG4gIH07XG5cbi8qKlxuICogUmV0dXJucyBhbGwgZ2VuZXJhdGVkIGxpbmUgYW5kIGNvbHVtbiBpbmZvcm1hdGlvbiBmb3IgdGhlIG9yaWdpbmFsIHNvdXJjZSxcbiAqIGxpbmUsIGFuZCBjb2x1bW4gcHJvdmlkZWQuIElmIG5vIGNvbHVtbiBpcyBwcm92aWRlZCwgcmV0dXJucyBhbGwgbWFwcGluZ3NcbiAqIGNvcnJlc3BvbmRpbmcgdG8gYSBlaXRoZXIgdGhlIGxpbmUgd2UgYXJlIHNlYXJjaGluZyBmb3Igb3IgdGhlIG5leHRcbiAqIGNsb3Nlc3QgbGluZSB0aGF0IGhhcyBhbnkgbWFwcGluZ3MuIE90aGVyd2lzZSwgcmV0dXJucyBhbGwgbWFwcGluZ3NcbiAqIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIGxpbmUgYW5kIGVpdGhlciB0aGUgY29sdW1uIHdlIGFyZSBzZWFyY2hpbmcgZm9yXG4gKiBvciB0aGUgbmV4dCBjbG9zZXN0IGNvbHVtbiB0aGF0IGhhcyBhbnkgb2Zmc2V0cy5cbiAqXG4gKiBUaGUgb25seSBhcmd1bWVudCBpcyBhbiBvYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogICAtIHNvdXJjZTogVGhlIGZpbGVuYW1lIG9mIHRoZSBvcmlnaW5hbCBzb3VyY2UuXG4gKiAgIC0gbGluZTogVGhlIGxpbmUgbnVtYmVyIGluIHRoZSBvcmlnaW5hbCBzb3VyY2UuICBUaGUgbGluZSBudW1iZXIgaXMgMS1iYXNlZC5cbiAqICAgLSBjb2x1bW46IE9wdGlvbmFsLiB0aGUgY29sdW1uIG51bWJlciBpbiB0aGUgb3JpZ2luYWwgc291cmNlLlxuICogICAgVGhlIGNvbHVtbiBudW1iZXIgaXMgMC1iYXNlZC5cbiAqXG4gKiBhbmQgYW4gYXJyYXkgb2Ygb2JqZWN0cyBpcyByZXR1cm5lZCwgZWFjaCB3aXRoIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczpcbiAqXG4gKiAgIC0gbGluZTogVGhlIGxpbmUgbnVtYmVyIGluIHRoZSBnZW5lcmF0ZWQgc291cmNlLCBvciBudWxsLiAgVGhlXG4gKiAgICBsaW5lIG51bWJlciBpcyAxLWJhc2VkLlxuICogICAtIGNvbHVtbjogVGhlIGNvbHVtbiBudW1iZXIgaW4gdGhlIGdlbmVyYXRlZCBzb3VyY2UsIG9yIG51bGwuXG4gKiAgICBUaGUgY29sdW1uIG51bWJlciBpcyAwLWJhc2VkLlxuICovXG5Tb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUuYWxsR2VuZXJhdGVkUG9zaXRpb25zRm9yID1cbiAgZnVuY3Rpb24gU291cmNlTWFwQ29uc3VtZXJfYWxsR2VuZXJhdGVkUG9zaXRpb25zRm9yKGFBcmdzKSB7XG4gICAgdmFyIGxpbmUgPSB1dGlsLmdldEFyZyhhQXJncywgJ2xpbmUnKTtcblxuICAgIC8vIFdoZW4gdGhlcmUgaXMgbm8gZXhhY3QgbWF0Y2gsIEJhc2ljU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLl9maW5kTWFwcGluZ1xuICAgIC8vIHJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBjbG9zZXN0IG1hcHBpbmcgbGVzcyB0aGFuIHRoZSBuZWVkbGUuIEJ5XG4gICAgLy8gc2V0dGluZyBuZWVkbGUub3JpZ2luYWxDb2x1bW4gdG8gMCwgd2UgdGh1cyBmaW5kIHRoZSBsYXN0IG1hcHBpbmcgZm9yXG4gICAgLy8gdGhlIGdpdmVuIGxpbmUsIHByb3ZpZGVkIHN1Y2ggYSBtYXBwaW5nIGV4aXN0cy5cbiAgICB2YXIgbmVlZGxlID0ge1xuICAgICAgc291cmNlOiB1dGlsLmdldEFyZyhhQXJncywgJ3NvdXJjZScpLFxuICAgICAgb3JpZ2luYWxMaW5lOiBsaW5lLFxuICAgICAgb3JpZ2luYWxDb2x1bW46IHV0aWwuZ2V0QXJnKGFBcmdzLCAnY29sdW1uJywgMClcbiAgICB9O1xuXG4gICAgbmVlZGxlLnNvdXJjZSA9IHRoaXMuX2ZpbmRTb3VyY2VJbmRleChuZWVkbGUuc291cmNlKTtcbiAgICBpZiAobmVlZGxlLnNvdXJjZSA8IDApIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICB2YXIgbWFwcGluZ3MgPSBbXTtcblxuICAgIHZhciBpbmRleCA9IHRoaXMuX2ZpbmRNYXBwaW5nKG5lZWRsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9vcmlnaW5hbE1hcHBpbmdzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwib3JpZ2luYWxMaW5lXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJvcmlnaW5hbENvbHVtblwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHV0aWwuY29tcGFyZUJ5T3JpZ2luYWxQb3NpdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmluYXJ5U2VhcmNoLkxFQVNUX1VQUEVSX0JPVU5EKTtcbiAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgdmFyIG1hcHBpbmcgPSB0aGlzLl9vcmlnaW5hbE1hcHBpbmdzW2luZGV4XTtcblxuICAgICAgaWYgKGFBcmdzLmNvbHVtbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhciBvcmlnaW5hbExpbmUgPSBtYXBwaW5nLm9yaWdpbmFsTGluZTtcblxuICAgICAgICAvLyBJdGVyYXRlIHVudGlsIGVpdGhlciB3ZSBydW4gb3V0IG9mIG1hcHBpbmdzLCBvciB3ZSBydW4gaW50b1xuICAgICAgICAvLyBhIG1hcHBpbmcgZm9yIGEgZGlmZmVyZW50IGxpbmUgdGhhbiB0aGUgb25lIHdlIGZvdW5kLiBTaW5jZVxuICAgICAgICAvLyBtYXBwaW5ncyBhcmUgc29ydGVkLCB0aGlzIGlzIGd1YXJhbnRlZWQgdG8gZmluZCBhbGwgbWFwcGluZ3MgZm9yXG4gICAgICAgIC8vIHRoZSBsaW5lIHdlIGZvdW5kLlxuICAgICAgICB3aGlsZSAobWFwcGluZyAmJiBtYXBwaW5nLm9yaWdpbmFsTGluZSA9PT0gb3JpZ2luYWxMaW5lKSB7XG4gICAgICAgICAgbWFwcGluZ3MucHVzaCh7XG4gICAgICAgICAgICBsaW5lOiB1dGlsLmdldEFyZyhtYXBwaW5nLCAnZ2VuZXJhdGVkTGluZScsIG51bGwpLFxuICAgICAgICAgICAgY29sdW1uOiB1dGlsLmdldEFyZyhtYXBwaW5nLCAnZ2VuZXJhdGVkQ29sdW1uJywgbnVsbCksXG4gICAgICAgICAgICBsYXN0Q29sdW1uOiB1dGlsLmdldEFyZyhtYXBwaW5nLCAnbGFzdEdlbmVyYXRlZENvbHVtbicsIG51bGwpXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBtYXBwaW5nID0gdGhpcy5fb3JpZ2luYWxNYXBwaW5nc1srK2luZGV4XTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIG9yaWdpbmFsQ29sdW1uID0gbWFwcGluZy5vcmlnaW5hbENvbHVtbjtcblxuICAgICAgICAvLyBJdGVyYXRlIHVudGlsIGVpdGhlciB3ZSBydW4gb3V0IG9mIG1hcHBpbmdzLCBvciB3ZSBydW4gaW50b1xuICAgICAgICAvLyBhIG1hcHBpbmcgZm9yIGEgZGlmZmVyZW50IGxpbmUgdGhhbiB0aGUgb25lIHdlIHdlcmUgc2VhcmNoaW5nIGZvci5cbiAgICAgICAgLy8gU2luY2UgbWFwcGluZ3MgYXJlIHNvcnRlZCwgdGhpcyBpcyBndWFyYW50ZWVkIHRvIGZpbmQgYWxsIG1hcHBpbmdzIGZvclxuICAgICAgICAvLyB0aGUgbGluZSB3ZSBhcmUgc2VhcmNoaW5nIGZvci5cbiAgICAgICAgd2hpbGUgKG1hcHBpbmcgJiZcbiAgICAgICAgICAgICAgIG1hcHBpbmcub3JpZ2luYWxMaW5lID09PSBsaW5lICYmXG4gICAgICAgICAgICAgICBtYXBwaW5nLm9yaWdpbmFsQ29sdW1uID09IG9yaWdpbmFsQ29sdW1uKSB7XG4gICAgICAgICAgbWFwcGluZ3MucHVzaCh7XG4gICAgICAgICAgICBsaW5lOiB1dGlsLmdldEFyZyhtYXBwaW5nLCAnZ2VuZXJhdGVkTGluZScsIG51bGwpLFxuICAgICAgICAgICAgY29sdW1uOiB1dGlsLmdldEFyZyhtYXBwaW5nLCAnZ2VuZXJhdGVkQ29sdW1uJywgbnVsbCksXG4gICAgICAgICAgICBsYXN0Q29sdW1uOiB1dGlsLmdldEFyZyhtYXBwaW5nLCAnbGFzdEdlbmVyYXRlZENvbHVtbicsIG51bGwpXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBtYXBwaW5nID0gdGhpcy5fb3JpZ2luYWxNYXBwaW5nc1srK2luZGV4XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBtYXBwaW5ncztcbiAgfTtcblxuZXhwb3J0cy5Tb3VyY2VNYXBDb25zdW1lciA9IFNvdXJjZU1hcENvbnN1bWVyO1xuXG4vKipcbiAqIEEgQmFzaWNTb3VyY2VNYXBDb25zdW1lciBpbnN0YW5jZSByZXByZXNlbnRzIGEgcGFyc2VkIHNvdXJjZSBtYXAgd2hpY2ggd2UgY2FuXG4gKiBxdWVyeSBmb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG9yaWdpbmFsIGZpbGUgcG9zaXRpb25zIGJ5IGdpdmluZyBpdCBhIGZpbGVcbiAqIHBvc2l0aW9uIGluIHRoZSBnZW5lcmF0ZWQgc291cmNlLlxuICpcbiAqIFRoZSBmaXJzdCBwYXJhbWV0ZXIgaXMgdGhlIHJhdyBzb3VyY2UgbWFwIChlaXRoZXIgYXMgYSBKU09OIHN0cmluZywgb3JcbiAqIGFscmVhZHkgcGFyc2VkIHRvIGFuIG9iamVjdCkuIEFjY29yZGluZyB0byB0aGUgc3BlYywgc291cmNlIG1hcHMgaGF2ZSB0aGVcbiAqIGZvbGxvd2luZyBhdHRyaWJ1dGVzOlxuICpcbiAqICAgLSB2ZXJzaW9uOiBXaGljaCB2ZXJzaW9uIG9mIHRoZSBzb3VyY2UgbWFwIHNwZWMgdGhpcyBtYXAgaXMgZm9sbG93aW5nLlxuICogICAtIHNvdXJjZXM6IEFuIGFycmF5IG9mIFVSTHMgdG8gdGhlIG9yaWdpbmFsIHNvdXJjZSBmaWxlcy5cbiAqICAgLSBuYW1lczogQW4gYXJyYXkgb2YgaWRlbnRpZmllcnMgd2hpY2ggY2FuIGJlIHJlZmVycmVuY2VkIGJ5IGluZGl2aWR1YWwgbWFwcGluZ3MuXG4gKiAgIC0gc291cmNlUm9vdDogT3B0aW9uYWwuIFRoZSBVUkwgcm9vdCBmcm9tIHdoaWNoIGFsbCBzb3VyY2VzIGFyZSByZWxhdGl2ZS5cbiAqICAgLSBzb3VyY2VzQ29udGVudDogT3B0aW9uYWwuIEFuIGFycmF5IG9mIGNvbnRlbnRzIG9mIHRoZSBvcmlnaW5hbCBzb3VyY2UgZmlsZXMuXG4gKiAgIC0gbWFwcGluZ3M6IEEgc3RyaW5nIG9mIGJhc2U2NCBWTFFzIHdoaWNoIGNvbnRhaW4gdGhlIGFjdHVhbCBtYXBwaW5ncy5cbiAqICAgLSBmaWxlOiBPcHRpb25hbC4gVGhlIGdlbmVyYXRlZCBmaWxlIHRoaXMgc291cmNlIG1hcCBpcyBhc3NvY2lhdGVkIHdpdGguXG4gKlxuICogSGVyZSBpcyBhbiBleGFtcGxlIHNvdXJjZSBtYXAsIHRha2VuIGZyb20gdGhlIHNvdXJjZSBtYXAgc3BlY1swXTpcbiAqXG4gKiAgICAge1xuICogICAgICAgdmVyc2lvbiA6IDMsXG4gKiAgICAgICBmaWxlOiBcIm91dC5qc1wiLFxuICogICAgICAgc291cmNlUm9vdCA6IFwiXCIsXG4gKiAgICAgICBzb3VyY2VzOiBbXCJmb28uanNcIiwgXCJiYXIuanNcIl0sXG4gKiAgICAgICBuYW1lczogW1wic3JjXCIsIFwibWFwc1wiLCBcImFyZVwiLCBcImZ1blwiXSxcbiAqICAgICAgIG1hcHBpbmdzOiBcIkFBLEFCOztBQkNERTtcIlxuICogICAgIH1cbiAqXG4gKiBUaGUgc2Vjb25kIHBhcmFtZXRlciwgaWYgZ2l2ZW4sIGlzIGEgc3RyaW5nIHdob3NlIHZhbHVlIGlzIHRoZSBVUkxcbiAqIGF0IHdoaWNoIHRoZSBzb3VyY2UgbWFwIHdhcyBmb3VuZC4gIFRoaXMgVVJMIGlzIHVzZWQgdG8gY29tcHV0ZSB0aGVcbiAqIHNvdXJjZXMgYXJyYXkuXG4gKlxuICogWzBdOiBodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9kb2N1bWVudC9kLzFVMVJHQWVoUXdSeXBVVG92RjFLUmxwaU9GemUwYi1fMmdjNmZBSDBLWTBrL2VkaXQ/cGxpPTEjXG4gKi9cbmZ1bmN0aW9uIEJhc2ljU291cmNlTWFwQ29uc3VtZXIoYVNvdXJjZU1hcCwgYVNvdXJjZU1hcFVSTCkge1xuICB2YXIgc291cmNlTWFwID0gYVNvdXJjZU1hcDtcbiAgaWYgKHR5cGVvZiBhU291cmNlTWFwID09PSAnc3RyaW5nJykge1xuICAgIHNvdXJjZU1hcCA9IHV0aWwucGFyc2VTb3VyY2VNYXBJbnB1dChhU291cmNlTWFwKTtcbiAgfVxuXG4gIHZhciB2ZXJzaW9uID0gdXRpbC5nZXRBcmcoc291cmNlTWFwLCAndmVyc2lvbicpO1xuICB2YXIgc291cmNlcyA9IHV0aWwuZ2V0QXJnKHNvdXJjZU1hcCwgJ3NvdXJjZXMnKTtcbiAgLy8gU2FzcyAzLjMgbGVhdmVzIG91dCB0aGUgJ25hbWVzJyBhcnJheSwgc28gd2UgZGV2aWF0ZSBmcm9tIHRoZSBzcGVjICh3aGljaFxuICAvLyByZXF1aXJlcyB0aGUgYXJyYXkpIHRvIHBsYXkgbmljZSBoZXJlLlxuICB2YXIgbmFtZXMgPSB1dGlsLmdldEFyZyhzb3VyY2VNYXAsICduYW1lcycsIFtdKTtcbiAgdmFyIHNvdXJjZVJvb3QgPSB1dGlsLmdldEFyZyhzb3VyY2VNYXAsICdzb3VyY2VSb290JywgbnVsbCk7XG4gIHZhciBzb3VyY2VzQ29udGVudCA9IHV0aWwuZ2V0QXJnKHNvdXJjZU1hcCwgJ3NvdXJjZXNDb250ZW50JywgbnVsbCk7XG4gIHZhciBtYXBwaW5ncyA9IHV0aWwuZ2V0QXJnKHNvdXJjZU1hcCwgJ21hcHBpbmdzJyk7XG4gIHZhciBmaWxlID0gdXRpbC5nZXRBcmcoc291cmNlTWFwLCAnZmlsZScsIG51bGwpO1xuXG4gIC8vIE9uY2UgYWdhaW4sIFNhc3MgZGV2aWF0ZXMgZnJvbSB0aGUgc3BlYyBhbmQgc3VwcGxpZXMgdGhlIHZlcnNpb24gYXMgYVxuICAvLyBzdHJpbmcgcmF0aGVyIHRoYW4gYSBudW1iZXIsIHNvIHdlIHVzZSBsb29zZSBlcXVhbGl0eSBjaGVja2luZyBoZXJlLlxuICBpZiAodmVyc2lvbiAhPSB0aGlzLl92ZXJzaW9uKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCB2ZXJzaW9uOiAnICsgdmVyc2lvbik7XG4gIH1cblxuICBpZiAoc291cmNlUm9vdCkge1xuICAgIHNvdXJjZVJvb3QgPSB1dGlsLm5vcm1hbGl6ZShzb3VyY2VSb290KTtcbiAgfVxuXG4gIHNvdXJjZXMgPSBzb3VyY2VzXG4gICAgLm1hcChTdHJpbmcpXG4gICAgLy8gU29tZSBzb3VyY2UgbWFwcyBwcm9kdWNlIHJlbGF0aXZlIHNvdXJjZSBwYXRocyBsaWtlIFwiLi9mb28uanNcIiBpbnN0ZWFkIG9mXG4gICAgLy8gXCJmb28uanNcIi4gIE5vcm1hbGl6ZSB0aGVzZSBmaXJzdCBzbyB0aGF0IGZ1dHVyZSBjb21wYXJpc29ucyB3aWxsIHN1Y2NlZWQuXG4gICAgLy8gU2VlIGJ1Z3ppbC5sYS8xMDkwNzY4LlxuICAgIC5tYXAodXRpbC5ub3JtYWxpemUpXG4gICAgLy8gQWx3YXlzIGVuc3VyZSB0aGF0IGFic29sdXRlIHNvdXJjZXMgYXJlIGludGVybmFsbHkgc3RvcmVkIHJlbGF0aXZlIHRvXG4gICAgLy8gdGhlIHNvdXJjZSByb290LCBpZiB0aGUgc291cmNlIHJvb3QgaXMgYWJzb2x1dGUuIE5vdCBkb2luZyB0aGlzIHdvdWxkXG4gICAgLy8gYmUgcGFydGljdWxhcmx5IHByb2JsZW1hdGljIHdoZW4gdGhlIHNvdXJjZSByb290IGlzIGEgcHJlZml4IG9mIHRoZVxuICAgIC8vIHNvdXJjZSAodmFsaWQsIGJ1dCB3aHk/PykuIFNlZSBnaXRodWIgaXNzdWUgIzE5OSBhbmQgYnVnemlsLmxhLzExODg5ODIuXG4gICAgLm1hcChmdW5jdGlvbiAoc291cmNlKSB7XG4gICAgICByZXR1cm4gc291cmNlUm9vdCAmJiB1dGlsLmlzQWJzb2x1dGUoc291cmNlUm9vdCkgJiYgdXRpbC5pc0Fic29sdXRlKHNvdXJjZSlcbiAgICAgICAgPyB1dGlsLnJlbGF0aXZlKHNvdXJjZVJvb3QsIHNvdXJjZSlcbiAgICAgICAgOiBzb3VyY2U7XG4gICAgfSk7XG5cbiAgLy8gUGFzcyBgdHJ1ZWAgYmVsb3cgdG8gYWxsb3cgZHVwbGljYXRlIG5hbWVzIGFuZCBzb3VyY2VzLiBXaGlsZSBzb3VyY2UgbWFwc1xuICAvLyBhcmUgaW50ZW5kZWQgdG8gYmUgY29tcHJlc3NlZCBhbmQgZGVkdXBsaWNhdGVkLCB0aGUgVHlwZVNjcmlwdCBjb21waWxlclxuICAvLyBzb21ldGltZXMgZ2VuZXJhdGVzIHNvdXJjZSBtYXBzIHdpdGggZHVwbGljYXRlcyBpbiB0aGVtLiBTZWUgR2l0aHViIGlzc3VlXG4gIC8vICM3MiBhbmQgYnVnemlsLmxhLzg4OTQ5Mi5cbiAgdGhpcy5fbmFtZXMgPSBBcnJheVNldC5mcm9tQXJyYXkobmFtZXMubWFwKFN0cmluZyksIHRydWUpO1xuICB0aGlzLl9zb3VyY2VzID0gQXJyYXlTZXQuZnJvbUFycmF5KHNvdXJjZXMsIHRydWUpO1xuXG4gIHRoaXMuX2Fic29sdXRlU291cmNlcyA9IHRoaXMuX3NvdXJjZXMudG9BcnJheSgpLm1hcChmdW5jdGlvbiAocykge1xuICAgIHJldHVybiB1dGlsLmNvbXB1dGVTb3VyY2VVUkwoc291cmNlUm9vdCwgcywgYVNvdXJjZU1hcFVSTCk7XG4gIH0pO1xuXG4gIHRoaXMuc291cmNlUm9vdCA9IHNvdXJjZVJvb3Q7XG4gIHRoaXMuc291cmNlc0NvbnRlbnQgPSBzb3VyY2VzQ29udGVudDtcbiAgdGhpcy5fbWFwcGluZ3MgPSBtYXBwaW5ncztcbiAgdGhpcy5fc291cmNlTWFwVVJMID0gYVNvdXJjZU1hcFVSTDtcbiAgdGhpcy5maWxlID0gZmlsZTtcbn1cblxuQmFzaWNTb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKFNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZSk7XG5CYXNpY1NvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5jb25zdW1lciA9IFNvdXJjZU1hcENvbnN1bWVyO1xuXG4vKipcbiAqIFV0aWxpdHkgZnVuY3Rpb24gdG8gZmluZCB0aGUgaW5kZXggb2YgYSBzb3VyY2UuICBSZXR1cm5zIC0xIGlmIG5vdFxuICogZm91bmQuXG4gKi9cbkJhc2ljU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLl9maW5kU291cmNlSW5kZXggPSBmdW5jdGlvbihhU291cmNlKSB7XG4gIHZhciByZWxhdGl2ZVNvdXJjZSA9IGFTb3VyY2U7XG4gIGlmICh0aGlzLnNvdXJjZVJvb3QgIT0gbnVsbCkge1xuICAgIHJlbGF0aXZlU291cmNlID0gdXRpbC5yZWxhdGl2ZSh0aGlzLnNvdXJjZVJvb3QsIHJlbGF0aXZlU291cmNlKTtcbiAgfVxuXG4gIGlmICh0aGlzLl9zb3VyY2VzLmhhcyhyZWxhdGl2ZVNvdXJjZSkpIHtcbiAgICByZXR1cm4gdGhpcy5fc291cmNlcy5pbmRleE9mKHJlbGF0aXZlU291cmNlKTtcbiAgfVxuXG4gIC8vIE1heWJlIGFTb3VyY2UgaXMgYW4gYWJzb2x1dGUgVVJMIGFzIHJldHVybmVkIGJ5IHxzb3VyY2VzfC4gIEluXG4gIC8vIHRoaXMgY2FzZSB3ZSBjYW4ndCBzaW1wbHkgdW5kbyB0aGUgdHJhbnNmb3JtLlxuICB2YXIgaTtcbiAgZm9yIChpID0gMDsgaSA8IHRoaXMuX2Fic29sdXRlU291cmNlcy5sZW5ndGg7ICsraSkge1xuICAgIGlmICh0aGlzLl9hYnNvbHV0ZVNvdXJjZXNbaV0gPT0gYVNvdXJjZSkge1xuICAgICAgcmV0dXJuIGk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIC0xO1xufTtcblxuLyoqXG4gKiBDcmVhdGUgYSBCYXNpY1NvdXJjZU1hcENvbnN1bWVyIGZyb20gYSBTb3VyY2VNYXBHZW5lcmF0b3IuXG4gKlxuICogQHBhcmFtIFNvdXJjZU1hcEdlbmVyYXRvciBhU291cmNlTWFwXG4gKiAgICAgICAgVGhlIHNvdXJjZSBtYXAgdGhhdCB3aWxsIGJlIGNvbnN1bWVkLlxuICogQHBhcmFtIFN0cmluZyBhU291cmNlTWFwVVJMXG4gKiAgICAgICAgVGhlIFVSTCBhdCB3aGljaCB0aGUgc291cmNlIG1hcCBjYW4gYmUgZm91bmQgKG9wdGlvbmFsKVxuICogQHJldHVybnMgQmFzaWNTb3VyY2VNYXBDb25zdW1lclxuICovXG5CYXNpY1NvdXJjZU1hcENvbnN1bWVyLmZyb21Tb3VyY2VNYXAgPVxuICBmdW5jdGlvbiBTb3VyY2VNYXBDb25zdW1lcl9mcm9tU291cmNlTWFwKGFTb3VyY2VNYXAsIGFTb3VyY2VNYXBVUkwpIHtcbiAgICB2YXIgc21jID0gT2JqZWN0LmNyZWF0ZShCYXNpY1NvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZSk7XG5cbiAgICB2YXIgbmFtZXMgPSBzbWMuX25hbWVzID0gQXJyYXlTZXQuZnJvbUFycmF5KGFTb3VyY2VNYXAuX25hbWVzLnRvQXJyYXkoKSwgdHJ1ZSk7XG4gICAgdmFyIHNvdXJjZXMgPSBzbWMuX3NvdXJjZXMgPSBBcnJheVNldC5mcm9tQXJyYXkoYVNvdXJjZU1hcC5fc291cmNlcy50b0FycmF5KCksIHRydWUpO1xuICAgIHNtYy5zb3VyY2VSb290ID0gYVNvdXJjZU1hcC5fc291cmNlUm9vdDtcbiAgICBzbWMuc291cmNlc0NvbnRlbnQgPSBhU291cmNlTWFwLl9nZW5lcmF0ZVNvdXJjZXNDb250ZW50KHNtYy5fc291cmNlcy50b0FycmF5KCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbWMuc291cmNlUm9vdCk7XG4gICAgc21jLmZpbGUgPSBhU291cmNlTWFwLl9maWxlO1xuICAgIHNtYy5fc291cmNlTWFwVVJMID0gYVNvdXJjZU1hcFVSTDtcbiAgICBzbWMuX2Fic29sdXRlU291cmNlcyA9IHNtYy5fc291cmNlcy50b0FycmF5KCkubWFwKGZ1bmN0aW9uIChzKSB7XG4gICAgICByZXR1cm4gdXRpbC5jb21wdXRlU291cmNlVVJMKHNtYy5zb3VyY2VSb290LCBzLCBhU291cmNlTWFwVVJMKTtcbiAgICB9KTtcblxuICAgIC8vIEJlY2F1c2Ugd2UgYXJlIG1vZGlmeWluZyB0aGUgZW50cmllcyAoYnkgY29udmVydGluZyBzdHJpbmcgc291cmNlcyBhbmRcbiAgICAvLyBuYW1lcyB0byBpbmRpY2VzIGludG8gdGhlIHNvdXJjZXMgYW5kIG5hbWVzIEFycmF5U2V0cyksIHdlIGhhdmUgdG8gbWFrZVxuICAgIC8vIGEgY29weSBvZiB0aGUgZW50cnkgb3IgZWxzZSBiYWQgdGhpbmdzIGhhcHBlbi4gU2hhcmVkIG11dGFibGUgc3RhdGVcbiAgICAvLyBzdHJpa2VzIGFnYWluISBTZWUgZ2l0aHViIGlzc3VlICMxOTEuXG5cbiAgICB2YXIgZ2VuZXJhdGVkTWFwcGluZ3MgPSBhU291cmNlTWFwLl9tYXBwaW5ncy50b0FycmF5KCkuc2xpY2UoKTtcbiAgICB2YXIgZGVzdEdlbmVyYXRlZE1hcHBpbmdzID0gc21jLl9fZ2VuZXJhdGVkTWFwcGluZ3MgPSBbXTtcbiAgICB2YXIgZGVzdE9yaWdpbmFsTWFwcGluZ3MgPSBzbWMuX19vcmlnaW5hbE1hcHBpbmdzID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gZ2VuZXJhdGVkTWFwcGluZ3MubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBzcmNNYXBwaW5nID0gZ2VuZXJhdGVkTWFwcGluZ3NbaV07XG4gICAgICB2YXIgZGVzdE1hcHBpbmcgPSBuZXcgTWFwcGluZztcbiAgICAgIGRlc3RNYXBwaW5nLmdlbmVyYXRlZExpbmUgPSBzcmNNYXBwaW5nLmdlbmVyYXRlZExpbmU7XG4gICAgICBkZXN0TWFwcGluZy5nZW5lcmF0ZWRDb2x1bW4gPSBzcmNNYXBwaW5nLmdlbmVyYXRlZENvbHVtbjtcblxuICAgICAgaWYgKHNyY01hcHBpbmcuc291cmNlKSB7XG4gICAgICAgIGRlc3RNYXBwaW5nLnNvdXJjZSA9IHNvdXJjZXMuaW5kZXhPZihzcmNNYXBwaW5nLnNvdXJjZSk7XG4gICAgICAgIGRlc3RNYXBwaW5nLm9yaWdpbmFsTGluZSA9IHNyY01hcHBpbmcub3JpZ2luYWxMaW5lO1xuICAgICAgICBkZXN0TWFwcGluZy5vcmlnaW5hbENvbHVtbiA9IHNyY01hcHBpbmcub3JpZ2luYWxDb2x1bW47XG5cbiAgICAgICAgaWYgKHNyY01hcHBpbmcubmFtZSkge1xuICAgICAgICAgIGRlc3RNYXBwaW5nLm5hbWUgPSBuYW1lcy5pbmRleE9mKHNyY01hcHBpbmcubmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBkZXN0T3JpZ2luYWxNYXBwaW5ncy5wdXNoKGRlc3RNYXBwaW5nKTtcbiAgICAgIH1cblxuICAgICAgZGVzdEdlbmVyYXRlZE1hcHBpbmdzLnB1c2goZGVzdE1hcHBpbmcpO1xuICAgIH1cblxuICAgIHF1aWNrU29ydChzbWMuX19vcmlnaW5hbE1hcHBpbmdzLCB1dGlsLmNvbXBhcmVCeU9yaWdpbmFsUG9zaXRpb25zKTtcblxuICAgIHJldHVybiBzbWM7XG4gIH07XG5cbi8qKlxuICogVGhlIHZlcnNpb24gb2YgdGhlIHNvdXJjZSBtYXBwaW5nIHNwZWMgdGhhdCB3ZSBhcmUgY29uc3VtaW5nLlxuICovXG5CYXNpY1NvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5fdmVyc2lvbiA9IDM7XG5cbi8qKlxuICogVGhlIGxpc3Qgb2Ygb3JpZ2luYWwgc291cmNlcy5cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KEJhc2ljU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLCAnc291cmNlcycsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2Fic29sdXRlU291cmNlcy5zbGljZSgpO1xuICB9XG59KTtcblxuLyoqXG4gKiBQcm92aWRlIHRoZSBKSVQgd2l0aCBhIG5pY2Ugc2hhcGUgLyBoaWRkZW4gY2xhc3MuXG4gKi9cbmZ1bmN0aW9uIE1hcHBpbmcoKSB7XG4gIHRoaXMuZ2VuZXJhdGVkTGluZSA9IDA7XG4gIHRoaXMuZ2VuZXJhdGVkQ29sdW1uID0gMDtcbiAgdGhpcy5zb3VyY2UgPSBudWxsO1xuICB0aGlzLm9yaWdpbmFsTGluZSA9IG51bGw7XG4gIHRoaXMub3JpZ2luYWxDb2x1bW4gPSBudWxsO1xuICB0aGlzLm5hbWUgPSBudWxsO1xufVxuXG4vKipcbiAqIFBhcnNlIHRoZSBtYXBwaW5ncyBpbiBhIHN0cmluZyBpbiB0byBhIGRhdGEgc3RydWN0dXJlIHdoaWNoIHdlIGNhbiBlYXNpbHlcbiAqIHF1ZXJ5ICh0aGUgb3JkZXJlZCBhcnJheXMgaW4gdGhlIGB0aGlzLl9fZ2VuZXJhdGVkTWFwcGluZ3NgIGFuZFxuICogYHRoaXMuX19vcmlnaW5hbE1hcHBpbmdzYCBwcm9wZXJ0aWVzKS5cbiAqL1xuQmFzaWNTb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUuX3BhcnNlTWFwcGluZ3MgPVxuICBmdW5jdGlvbiBTb3VyY2VNYXBDb25zdW1lcl9wYXJzZU1hcHBpbmdzKGFTdHIsIGFTb3VyY2VSb290KSB7XG4gICAgdmFyIGdlbmVyYXRlZExpbmUgPSAxO1xuICAgIHZhciBwcmV2aW91c0dlbmVyYXRlZENvbHVtbiA9IDA7XG4gICAgdmFyIHByZXZpb3VzT3JpZ2luYWxMaW5lID0gMDtcbiAgICB2YXIgcHJldmlvdXNPcmlnaW5hbENvbHVtbiA9IDA7XG4gICAgdmFyIHByZXZpb3VzU291cmNlID0gMDtcbiAgICB2YXIgcHJldmlvdXNOYW1lID0gMDtcbiAgICB2YXIgbGVuZ3RoID0gYVN0ci5sZW5ndGg7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgY2FjaGVkU2VnbWVudHMgPSB7fTtcbiAgICB2YXIgdGVtcCA9IHt9O1xuICAgIHZhciBvcmlnaW5hbE1hcHBpbmdzID0gW107XG4gICAgdmFyIGdlbmVyYXRlZE1hcHBpbmdzID0gW107XG4gICAgdmFyIG1hcHBpbmcsIHN0ciwgc2VnbWVudCwgZW5kLCB2YWx1ZTtcblxuICAgIHdoaWxlIChpbmRleCA8IGxlbmd0aCkge1xuICAgICAgaWYgKGFTdHIuY2hhckF0KGluZGV4KSA9PT0gJzsnKSB7XG4gICAgICAgIGdlbmVyYXRlZExpbmUrKztcbiAgICAgICAgaW5kZXgrKztcbiAgICAgICAgcHJldmlvdXNHZW5lcmF0ZWRDb2x1bW4gPSAwO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoYVN0ci5jaGFyQXQoaW5kZXgpID09PSAnLCcpIHtcbiAgICAgICAgaW5kZXgrKztcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBtYXBwaW5nID0gbmV3IE1hcHBpbmcoKTtcbiAgICAgICAgbWFwcGluZy5nZW5lcmF0ZWRMaW5lID0gZ2VuZXJhdGVkTGluZTtcblxuICAgICAgICAvLyBCZWNhdXNlIGVhY2ggb2Zmc2V0IGlzIGVuY29kZWQgcmVsYXRpdmUgdG8gdGhlIHByZXZpb3VzIG9uZSxcbiAgICAgICAgLy8gbWFueSBzZWdtZW50cyBvZnRlbiBoYXZlIHRoZSBzYW1lIGVuY29kaW5nLiBXZSBjYW4gZXhwbG9pdCB0aGlzXG4gICAgICAgIC8vIGZhY3QgYnkgY2FjaGluZyB0aGUgcGFyc2VkIHZhcmlhYmxlIGxlbmd0aCBmaWVsZHMgb2YgZWFjaCBzZWdtZW50LFxuICAgICAgICAvLyBhbGxvd2luZyB1cyB0byBhdm9pZCBhIHNlY29uZCBwYXJzZSBpZiB3ZSBlbmNvdW50ZXIgdGhlIHNhbWVcbiAgICAgICAgLy8gc2VnbWVudCBhZ2Fpbi5cbiAgICAgICAgZm9yIChlbmQgPSBpbmRleDsgZW5kIDwgbGVuZ3RoOyBlbmQrKykge1xuICAgICAgICAgIGlmICh0aGlzLl9jaGFySXNNYXBwaW5nU2VwYXJhdG9yKGFTdHIsIGVuZCkpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdHIgPSBhU3RyLnNsaWNlKGluZGV4LCBlbmQpO1xuXG4gICAgICAgIHNlZ21lbnQgPSBjYWNoZWRTZWdtZW50c1tzdHJdO1xuICAgICAgICBpZiAoc2VnbWVudCkge1xuICAgICAgICAgIGluZGV4ICs9IHN0ci5sZW5ndGg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2VnbWVudCA9IFtdO1xuICAgICAgICAgIHdoaWxlIChpbmRleCA8IGVuZCkge1xuICAgICAgICAgICAgYmFzZTY0VkxRLmRlY29kZShhU3RyLCBpbmRleCwgdGVtcCk7XG4gICAgICAgICAgICB2YWx1ZSA9IHRlbXAudmFsdWU7XG4gICAgICAgICAgICBpbmRleCA9IHRlbXAucmVzdDtcbiAgICAgICAgICAgIHNlZ21lbnQucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZvdW5kIGEgc291cmNlLCBidXQgbm8gbGluZSBhbmQgY29sdW1uJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNlZ21lbnQubGVuZ3RoID09PSAzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZvdW5kIGEgc291cmNlIGFuZCBsaW5lLCBidXQgbm8gY29sdW1uJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY2FjaGVkU2VnbWVudHNbc3RyXSA9IHNlZ21lbnQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZW5lcmF0ZWQgY29sdW1uLlxuICAgICAgICBtYXBwaW5nLmdlbmVyYXRlZENvbHVtbiA9IHByZXZpb3VzR2VuZXJhdGVkQ29sdW1uICsgc2VnbWVudFswXTtcbiAgICAgICAgcHJldmlvdXNHZW5lcmF0ZWRDb2x1bW4gPSBtYXBwaW5nLmdlbmVyYXRlZENvbHVtbjtcblxuICAgICAgICBpZiAoc2VnbWVudC5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgLy8gT3JpZ2luYWwgc291cmNlLlxuICAgICAgICAgIG1hcHBpbmcuc291cmNlID0gcHJldmlvdXNTb3VyY2UgKyBzZWdtZW50WzFdO1xuICAgICAgICAgIHByZXZpb3VzU291cmNlICs9IHNlZ21lbnRbMV07XG5cbiAgICAgICAgICAvLyBPcmlnaW5hbCBsaW5lLlxuICAgICAgICAgIG1hcHBpbmcub3JpZ2luYWxMaW5lID0gcHJldmlvdXNPcmlnaW5hbExpbmUgKyBzZWdtZW50WzJdO1xuICAgICAgICAgIHByZXZpb3VzT3JpZ2luYWxMaW5lID0gbWFwcGluZy5vcmlnaW5hbExpbmU7XG4gICAgICAgICAgLy8gTGluZXMgYXJlIHN0b3JlZCAwLWJhc2VkXG4gICAgICAgICAgbWFwcGluZy5vcmlnaW5hbExpbmUgKz0gMTtcblxuICAgICAgICAgIC8vIE9yaWdpbmFsIGNvbHVtbi5cbiAgICAgICAgICBtYXBwaW5nLm9yaWdpbmFsQ29sdW1uID0gcHJldmlvdXNPcmlnaW5hbENvbHVtbiArIHNlZ21lbnRbM107XG4gICAgICAgICAgcHJldmlvdXNPcmlnaW5hbENvbHVtbiA9IG1hcHBpbmcub3JpZ2luYWxDb2x1bW47XG5cbiAgICAgICAgICBpZiAoc2VnbWVudC5sZW5ndGggPiA0KSB7XG4gICAgICAgICAgICAvLyBPcmlnaW5hbCBuYW1lLlxuICAgICAgICAgICAgbWFwcGluZy5uYW1lID0gcHJldmlvdXNOYW1lICsgc2VnbWVudFs0XTtcbiAgICAgICAgICAgIHByZXZpb3VzTmFtZSArPSBzZWdtZW50WzRdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGdlbmVyYXRlZE1hcHBpbmdzLnB1c2gobWFwcGluZyk7XG4gICAgICAgIGlmICh0eXBlb2YgbWFwcGluZy5vcmlnaW5hbExpbmUgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgb3JpZ2luYWxNYXBwaW5ncy5wdXNoKG1hcHBpbmcpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcXVpY2tTb3J0KGdlbmVyYXRlZE1hcHBpbmdzLCB1dGlsLmNvbXBhcmVCeUdlbmVyYXRlZFBvc2l0aW9uc0RlZmxhdGVkKTtcbiAgICB0aGlzLl9fZ2VuZXJhdGVkTWFwcGluZ3MgPSBnZW5lcmF0ZWRNYXBwaW5ncztcblxuICAgIHF1aWNrU29ydChvcmlnaW5hbE1hcHBpbmdzLCB1dGlsLmNvbXBhcmVCeU9yaWdpbmFsUG9zaXRpb25zKTtcbiAgICB0aGlzLl9fb3JpZ2luYWxNYXBwaW5ncyA9IG9yaWdpbmFsTWFwcGluZ3M7XG4gIH07XG5cbi8qKlxuICogRmluZCB0aGUgbWFwcGluZyB0aGF0IGJlc3QgbWF0Y2hlcyB0aGUgaHlwb3RoZXRpY2FsIFwibmVlZGxlXCIgbWFwcGluZyB0aGF0XG4gKiB3ZSBhcmUgc2VhcmNoaW5nIGZvciBpbiB0aGUgZ2l2ZW4gXCJoYXlzdGFja1wiIG9mIG1hcHBpbmdzLlxuICovXG5CYXNpY1NvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5fZmluZE1hcHBpbmcgPVxuICBmdW5jdGlvbiBTb3VyY2VNYXBDb25zdW1lcl9maW5kTWFwcGluZyhhTmVlZGxlLCBhTWFwcGluZ3MsIGFMaW5lTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUNvbHVtbk5hbWUsIGFDb21wYXJhdG9yLCBhQmlhcykge1xuICAgIC8vIFRvIHJldHVybiB0aGUgcG9zaXRpb24gd2UgYXJlIHNlYXJjaGluZyBmb3IsIHdlIG11c3QgZmlyc3QgZmluZCB0aGVcbiAgICAvLyBtYXBwaW5nIGZvciB0aGUgZ2l2ZW4gcG9zaXRpb24gYW5kIHRoZW4gcmV0dXJuIHRoZSBvcHBvc2l0ZSBwb3NpdGlvbiBpdFxuICAgIC8vIHBvaW50cyB0by4gQmVjYXVzZSB0aGUgbWFwcGluZ3MgYXJlIHNvcnRlZCwgd2UgY2FuIHVzZSBiaW5hcnkgc2VhcmNoIHRvXG4gICAgLy8gZmluZCB0aGUgYmVzdCBtYXBwaW5nLlxuXG4gICAgaWYgKGFOZWVkbGVbYUxpbmVOYW1lXSA8PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdMaW5lIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEsIGdvdCAnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICsgYU5lZWRsZVthTGluZU5hbWVdKTtcbiAgICB9XG4gICAgaWYgKGFOZWVkbGVbYUNvbHVtbk5hbWVdIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQ29sdW1uIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAsIGdvdCAnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICsgYU5lZWRsZVthQ29sdW1uTmFtZV0pO1xuICAgIH1cblxuICAgIHJldHVybiBiaW5hcnlTZWFyY2guc2VhcmNoKGFOZWVkbGUsIGFNYXBwaW5ncywgYUNvbXBhcmF0b3IsIGFCaWFzKTtcbiAgfTtcblxuLyoqXG4gKiBDb21wdXRlIHRoZSBsYXN0IGNvbHVtbiBmb3IgZWFjaCBnZW5lcmF0ZWQgbWFwcGluZy4gVGhlIGxhc3QgY29sdW1uIGlzXG4gKiBpbmNsdXNpdmUuXG4gKi9cbkJhc2ljU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLmNvbXB1dGVDb2x1bW5TcGFucyA9XG4gIGZ1bmN0aW9uIFNvdXJjZU1hcENvbnN1bWVyX2NvbXB1dGVDb2x1bW5TcGFucygpIHtcbiAgICBmb3IgKHZhciBpbmRleCA9IDA7IGluZGV4IDwgdGhpcy5fZ2VuZXJhdGVkTWFwcGluZ3MubGVuZ3RoOyArK2luZGV4KSB7XG4gICAgICB2YXIgbWFwcGluZyA9IHRoaXMuX2dlbmVyYXRlZE1hcHBpbmdzW2luZGV4XTtcblxuICAgICAgLy8gTWFwcGluZ3MgZG8gbm90IGNvbnRhaW4gYSBmaWVsZCBmb3IgdGhlIGxhc3QgZ2VuZXJhdGVkIGNvbHVtbnQuIFdlXG4gICAgICAvLyBjYW4gY29tZSB1cCB3aXRoIGFuIG9wdGltaXN0aWMgZXN0aW1hdGUsIGhvd2V2ZXIsIGJ5IGFzc3VtaW5nIHRoYXRcbiAgICAgIC8vIG1hcHBpbmdzIGFyZSBjb250aWd1b3VzIChpLmUuIGdpdmVuIHR3byBjb25zZWN1dGl2ZSBtYXBwaW5ncywgdGhlXG4gICAgICAvLyBmaXJzdCBtYXBwaW5nIGVuZHMgd2hlcmUgdGhlIHNlY29uZCBvbmUgc3RhcnRzKS5cbiAgICAgIGlmIChpbmRleCArIDEgPCB0aGlzLl9nZW5lcmF0ZWRNYXBwaW5ncy5sZW5ndGgpIHtcbiAgICAgICAgdmFyIG5leHRNYXBwaW5nID0gdGhpcy5fZ2VuZXJhdGVkTWFwcGluZ3NbaW5kZXggKyAxXTtcblxuICAgICAgICBpZiAobWFwcGluZy5nZW5lcmF0ZWRMaW5lID09PSBuZXh0TWFwcGluZy5nZW5lcmF0ZWRMaW5lKSB7XG4gICAgICAgICAgbWFwcGluZy5sYXN0R2VuZXJhdGVkQ29sdW1uID0gbmV4dE1hcHBpbmcuZ2VuZXJhdGVkQ29sdW1uIC0gMTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBUaGUgbGFzdCBtYXBwaW5nIGZvciBlYWNoIGxpbmUgc3BhbnMgdGhlIGVudGlyZSBsaW5lLlxuICAgICAgbWFwcGluZy5sYXN0R2VuZXJhdGVkQ29sdW1uID0gSW5maW5pdHk7XG4gICAgfVxuICB9O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIG9yaWdpbmFsIHNvdXJjZSwgbGluZSwgYW5kIGNvbHVtbiBpbmZvcm1hdGlvbiBmb3IgdGhlIGdlbmVyYXRlZFxuICogc291cmNlJ3MgbGluZSBhbmQgY29sdW1uIHBvc2l0aW9ucyBwcm92aWRlZC4gVGhlIG9ubHkgYXJndW1lbnQgaXMgYW4gb2JqZWN0XG4gKiB3aXRoIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczpcbiAqXG4gKiAgIC0gbGluZTogVGhlIGxpbmUgbnVtYmVyIGluIHRoZSBnZW5lcmF0ZWQgc291cmNlLiAgVGhlIGxpbmUgbnVtYmVyXG4gKiAgICAgaXMgMS1iYXNlZC5cbiAqICAgLSBjb2x1bW46IFRoZSBjb2x1bW4gbnVtYmVyIGluIHRoZSBnZW5lcmF0ZWQgc291cmNlLiAgVGhlIGNvbHVtblxuICogICAgIG51bWJlciBpcyAwLWJhc2VkLlxuICogICAtIGJpYXM6IEVpdGhlciAnU291cmNlTWFwQ29uc3VtZXIuR1JFQVRFU1RfTE9XRVJfQk9VTkQnIG9yXG4gKiAgICAgJ1NvdXJjZU1hcENvbnN1bWVyLkxFQVNUX1VQUEVSX0JPVU5EJy4gU3BlY2lmaWVzIHdoZXRoZXIgdG8gcmV0dXJuIHRoZVxuICogICAgIGNsb3Nlc3QgZWxlbWVudCB0aGF0IGlzIHNtYWxsZXIgdGhhbiBvciBncmVhdGVyIHRoYW4gdGhlIG9uZSB3ZSBhcmVcbiAqICAgICBzZWFyY2hpbmcgZm9yLCByZXNwZWN0aXZlbHksIGlmIHRoZSBleGFjdCBlbGVtZW50IGNhbm5vdCBiZSBmb3VuZC5cbiAqICAgICBEZWZhdWx0cyB0byAnU291cmNlTWFwQ29uc3VtZXIuR1JFQVRFU1RfTE9XRVJfQk9VTkQnLlxuICpcbiAqIGFuZCBhbiBvYmplY3QgaXMgcmV0dXJuZWQgd2l0aCB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogICAtIHNvdXJjZTogVGhlIG9yaWdpbmFsIHNvdXJjZSBmaWxlLCBvciBudWxsLlxuICogICAtIGxpbmU6IFRoZSBsaW5lIG51bWJlciBpbiB0aGUgb3JpZ2luYWwgc291cmNlLCBvciBudWxsLiAgVGhlXG4gKiAgICAgbGluZSBudW1iZXIgaXMgMS1iYXNlZC5cbiAqICAgLSBjb2x1bW46IFRoZSBjb2x1bW4gbnVtYmVyIGluIHRoZSBvcmlnaW5hbCBzb3VyY2UsIG9yIG51bGwuICBUaGVcbiAqICAgICBjb2x1bW4gbnVtYmVyIGlzIDAtYmFzZWQuXG4gKiAgIC0gbmFtZTogVGhlIG9yaWdpbmFsIGlkZW50aWZpZXIsIG9yIG51bGwuXG4gKi9cbkJhc2ljU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLm9yaWdpbmFsUG9zaXRpb25Gb3IgPVxuICBmdW5jdGlvbiBTb3VyY2VNYXBDb25zdW1lcl9vcmlnaW5hbFBvc2l0aW9uRm9yKGFBcmdzKSB7XG4gICAgdmFyIG5lZWRsZSA9IHtcbiAgICAgIGdlbmVyYXRlZExpbmU6IHV0aWwuZ2V0QXJnKGFBcmdzLCAnbGluZScpLFxuICAgICAgZ2VuZXJhdGVkQ29sdW1uOiB1dGlsLmdldEFyZyhhQXJncywgJ2NvbHVtbicpXG4gICAgfTtcblxuICAgIHZhciBpbmRleCA9IHRoaXMuX2ZpbmRNYXBwaW5nKFxuICAgICAgbmVlZGxlLFxuICAgICAgdGhpcy5fZ2VuZXJhdGVkTWFwcGluZ3MsXG4gICAgICBcImdlbmVyYXRlZExpbmVcIixcbiAgICAgIFwiZ2VuZXJhdGVkQ29sdW1uXCIsXG4gICAgICB1dGlsLmNvbXBhcmVCeUdlbmVyYXRlZFBvc2l0aW9uc0RlZmxhdGVkLFxuICAgICAgdXRpbC5nZXRBcmcoYUFyZ3MsICdiaWFzJywgU291cmNlTWFwQ29uc3VtZXIuR1JFQVRFU1RfTE9XRVJfQk9VTkQpXG4gICAgKTtcblxuICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICB2YXIgbWFwcGluZyA9IHRoaXMuX2dlbmVyYXRlZE1hcHBpbmdzW2luZGV4XTtcblxuICAgICAgaWYgKG1hcHBpbmcuZ2VuZXJhdGVkTGluZSA9PT0gbmVlZGxlLmdlbmVyYXRlZExpbmUpIHtcbiAgICAgICAgdmFyIHNvdXJjZSA9IHV0aWwuZ2V0QXJnKG1hcHBpbmcsICdzb3VyY2UnLCBudWxsKTtcbiAgICAgICAgaWYgKHNvdXJjZSAhPT0gbnVsbCkge1xuICAgICAgICAgIHNvdXJjZSA9IHRoaXMuX3NvdXJjZXMuYXQoc291cmNlKTtcbiAgICAgICAgICBzb3VyY2UgPSB1dGlsLmNvbXB1dGVTb3VyY2VVUkwodGhpcy5zb3VyY2VSb290LCBzb3VyY2UsIHRoaXMuX3NvdXJjZU1hcFVSTCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIG5hbWUgPSB1dGlsLmdldEFyZyhtYXBwaW5nLCAnbmFtZScsIG51bGwpO1xuICAgICAgICBpZiAobmFtZSAhPT0gbnVsbCkge1xuICAgICAgICAgIG5hbWUgPSB0aGlzLl9uYW1lcy5hdChuYW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgICAgIGxpbmU6IHV0aWwuZ2V0QXJnKG1hcHBpbmcsICdvcmlnaW5hbExpbmUnLCBudWxsKSxcbiAgICAgICAgICBjb2x1bW46IHV0aWwuZ2V0QXJnKG1hcHBpbmcsICdvcmlnaW5hbENvbHVtbicsIG51bGwpLFxuICAgICAgICAgIG5hbWU6IG5hbWVcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgc291cmNlOiBudWxsLFxuICAgICAgbGluZTogbnVsbCxcbiAgICAgIGNvbHVtbjogbnVsbCxcbiAgICAgIG5hbWU6IG51bGxcbiAgICB9O1xuICB9O1xuXG4vKipcbiAqIFJldHVybiB0cnVlIGlmIHdlIGhhdmUgdGhlIHNvdXJjZSBjb250ZW50IGZvciBldmVyeSBzb3VyY2UgaW4gdGhlIHNvdXJjZVxuICogbWFwLCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cbkJhc2ljU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLmhhc0NvbnRlbnRzT2ZBbGxTb3VyY2VzID1cbiAgZnVuY3Rpb24gQmFzaWNTb3VyY2VNYXBDb25zdW1lcl9oYXNDb250ZW50c09mQWxsU291cmNlcygpIHtcbiAgICBpZiAoIXRoaXMuc291cmNlc0NvbnRlbnQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc291cmNlc0NvbnRlbnQubGVuZ3RoID49IHRoaXMuX3NvdXJjZXMuc2l6ZSgpICYmXG4gICAgICAhdGhpcy5zb3VyY2VzQ29udGVudC5zb21lKGZ1bmN0aW9uIChzYykgeyByZXR1cm4gc2MgPT0gbnVsbDsgfSk7XG4gIH07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgb3JpZ2luYWwgc291cmNlIGNvbnRlbnQuIFRoZSBvbmx5IGFyZ3VtZW50IGlzIHRoZSB1cmwgb2YgdGhlXG4gKiBvcmlnaW5hbCBzb3VyY2UgZmlsZS4gUmV0dXJucyBudWxsIGlmIG5vIG9yaWdpbmFsIHNvdXJjZSBjb250ZW50IGlzXG4gKiBhdmFpbGFibGUuXG4gKi9cbkJhc2ljU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLnNvdXJjZUNvbnRlbnRGb3IgPVxuICBmdW5jdGlvbiBTb3VyY2VNYXBDb25zdW1lcl9zb3VyY2VDb250ZW50Rm9yKGFTb3VyY2UsIG51bGxPbk1pc3NpbmcpIHtcbiAgICBpZiAoIXRoaXMuc291cmNlc0NvbnRlbnQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHZhciBpbmRleCA9IHRoaXMuX2ZpbmRTb3VyY2VJbmRleChhU291cmNlKTtcbiAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuc291cmNlc0NvbnRlbnRbaW5kZXhdO1xuICAgIH1cblxuICAgIHZhciByZWxhdGl2ZVNvdXJjZSA9IGFTb3VyY2U7XG4gICAgaWYgKHRoaXMuc291cmNlUm9vdCAhPSBudWxsKSB7XG4gICAgICByZWxhdGl2ZVNvdXJjZSA9IHV0aWwucmVsYXRpdmUodGhpcy5zb3VyY2VSb290LCByZWxhdGl2ZVNvdXJjZSk7XG4gICAgfVxuXG4gICAgdmFyIHVybDtcbiAgICBpZiAodGhpcy5zb3VyY2VSb290ICE9IG51bGxcbiAgICAgICAgJiYgKHVybCA9IHV0aWwudXJsUGFyc2UodGhpcy5zb3VyY2VSb290KSkpIHtcbiAgICAgIC8vIFhYWDogZmlsZTovLyBVUklzIGFuZCBhYnNvbHV0ZSBwYXRocyBsZWFkIHRvIHVuZXhwZWN0ZWQgYmVoYXZpb3IgZm9yXG4gICAgICAvLyBtYW55IHVzZXJzLiBXZSBjYW4gaGVscCB0aGVtIG91dCB3aGVuIHRoZXkgZXhwZWN0IGZpbGU6Ly8gVVJJcyB0b1xuICAgICAgLy8gYmVoYXZlIGxpa2UgaXQgd291bGQgaWYgdGhleSB3ZXJlIHJ1bm5pbmcgYSBsb2NhbCBIVFRQIHNlcnZlci4gU2VlXG4gICAgICAvLyBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD04ODU1OTcuXG4gICAgICB2YXIgZmlsZVVyaUFic1BhdGggPSByZWxhdGl2ZVNvdXJjZS5yZXBsYWNlKC9eZmlsZTpcXC9cXC8vLCBcIlwiKTtcbiAgICAgIGlmICh1cmwuc2NoZW1lID09IFwiZmlsZVwiXG4gICAgICAgICAgJiYgdGhpcy5fc291cmNlcy5oYXMoZmlsZVVyaUFic1BhdGgpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNvdXJjZXNDb250ZW50W3RoaXMuX3NvdXJjZXMuaW5kZXhPZihmaWxlVXJpQWJzUGF0aCldXG4gICAgICB9XG5cbiAgICAgIGlmICgoIXVybC5wYXRoIHx8IHVybC5wYXRoID09IFwiL1wiKVxuICAgICAgICAgICYmIHRoaXMuX3NvdXJjZXMuaGFzKFwiL1wiICsgcmVsYXRpdmVTb3VyY2UpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNvdXJjZXNDb250ZW50W3RoaXMuX3NvdXJjZXMuaW5kZXhPZihcIi9cIiArIHJlbGF0aXZlU291cmNlKV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHJlY3Vyc2l2ZWx5IGZyb21cbiAgICAvLyBJbmRleGVkU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLnNvdXJjZUNvbnRlbnRGb3IuIEluIHRoYXQgY2FzZSwgd2VcbiAgICAvLyBkb24ndCB3YW50IHRvIHRocm93IGlmIHdlIGNhbid0IGZpbmQgdGhlIHNvdXJjZSAtIHdlIGp1c3Qgd2FudCB0b1xuICAgIC8vIHJldHVybiBudWxsLCBzbyB3ZSBwcm92aWRlIGEgZmxhZyB0byBleGl0IGdyYWNlZnVsbHkuXG4gICAgaWYgKG51bGxPbk1pc3NpbmcpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignXCInICsgcmVsYXRpdmVTb3VyY2UgKyAnXCIgaXMgbm90IGluIHRoZSBTb3VyY2VNYXAuJyk7XG4gICAgfVxuICB9O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGdlbmVyYXRlZCBsaW5lIGFuZCBjb2x1bW4gaW5mb3JtYXRpb24gZm9yIHRoZSBvcmlnaW5hbCBzb3VyY2UsXG4gKiBsaW5lLCBhbmQgY29sdW1uIHBvc2l0aW9ucyBwcm92aWRlZC4gVGhlIG9ubHkgYXJndW1lbnQgaXMgYW4gb2JqZWN0IHdpdGhcbiAqIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczpcbiAqXG4gKiAgIC0gc291cmNlOiBUaGUgZmlsZW5hbWUgb2YgdGhlIG9yaWdpbmFsIHNvdXJjZS5cbiAqICAgLSBsaW5lOiBUaGUgbGluZSBudW1iZXIgaW4gdGhlIG9yaWdpbmFsIHNvdXJjZS4gIFRoZSBsaW5lIG51bWJlclxuICogICAgIGlzIDEtYmFzZWQuXG4gKiAgIC0gY29sdW1uOiBUaGUgY29sdW1uIG51bWJlciBpbiB0aGUgb3JpZ2luYWwgc291cmNlLiAgVGhlIGNvbHVtblxuICogICAgIG51bWJlciBpcyAwLWJhc2VkLlxuICogICAtIGJpYXM6IEVpdGhlciAnU291cmNlTWFwQ29uc3VtZXIuR1JFQVRFU1RfTE9XRVJfQk9VTkQnIG9yXG4gKiAgICAgJ1NvdXJjZU1hcENvbnN1bWVyLkxFQVNUX1VQUEVSX0JPVU5EJy4gU3BlY2lmaWVzIHdoZXRoZXIgdG8gcmV0dXJuIHRoZVxuICogICAgIGNsb3Nlc3QgZWxlbWVudCB0aGF0IGlzIHNtYWxsZXIgdGhhbiBvciBncmVhdGVyIHRoYW4gdGhlIG9uZSB3ZSBhcmVcbiAqICAgICBzZWFyY2hpbmcgZm9yLCByZXNwZWN0aXZlbHksIGlmIHRoZSBleGFjdCBlbGVtZW50IGNhbm5vdCBiZSBmb3VuZC5cbiAqICAgICBEZWZhdWx0cyB0byAnU291cmNlTWFwQ29uc3VtZXIuR1JFQVRFU1RfTE9XRVJfQk9VTkQnLlxuICpcbiAqIGFuZCBhbiBvYmplY3QgaXMgcmV0dXJuZWQgd2l0aCB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogICAtIGxpbmU6IFRoZSBsaW5lIG51bWJlciBpbiB0aGUgZ2VuZXJhdGVkIHNvdXJjZSwgb3IgbnVsbC4gIFRoZVxuICogICAgIGxpbmUgbnVtYmVyIGlzIDEtYmFzZWQuXG4gKiAgIC0gY29sdW1uOiBUaGUgY29sdW1uIG51bWJlciBpbiB0aGUgZ2VuZXJhdGVkIHNvdXJjZSwgb3IgbnVsbC5cbiAqICAgICBUaGUgY29sdW1uIG51bWJlciBpcyAwLWJhc2VkLlxuICovXG5CYXNpY1NvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5nZW5lcmF0ZWRQb3NpdGlvbkZvciA9XG4gIGZ1bmN0aW9uIFNvdXJjZU1hcENvbnN1bWVyX2dlbmVyYXRlZFBvc2l0aW9uRm9yKGFBcmdzKSB7XG4gICAgdmFyIHNvdXJjZSA9IHV0aWwuZ2V0QXJnKGFBcmdzLCAnc291cmNlJyk7XG4gICAgc291cmNlID0gdGhpcy5fZmluZFNvdXJjZUluZGV4KHNvdXJjZSk7XG4gICAgaWYgKHNvdXJjZSA8IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGxpbmU6IG51bGwsXG4gICAgICAgIGNvbHVtbjogbnVsbCxcbiAgICAgICAgbGFzdENvbHVtbjogbnVsbFxuICAgICAgfTtcbiAgICB9XG5cbiAgICB2YXIgbmVlZGxlID0ge1xuICAgICAgc291cmNlOiBzb3VyY2UsXG4gICAgICBvcmlnaW5hbExpbmU6IHV0aWwuZ2V0QXJnKGFBcmdzLCAnbGluZScpLFxuICAgICAgb3JpZ2luYWxDb2x1bW46IHV0aWwuZ2V0QXJnKGFBcmdzLCAnY29sdW1uJylcbiAgICB9O1xuXG4gICAgdmFyIGluZGV4ID0gdGhpcy5fZmluZE1hcHBpbmcoXG4gICAgICBuZWVkbGUsXG4gICAgICB0aGlzLl9vcmlnaW5hbE1hcHBpbmdzLFxuICAgICAgXCJvcmlnaW5hbExpbmVcIixcbiAgICAgIFwib3JpZ2luYWxDb2x1bW5cIixcbiAgICAgIHV0aWwuY29tcGFyZUJ5T3JpZ2luYWxQb3NpdGlvbnMsXG4gICAgICB1dGlsLmdldEFyZyhhQXJncywgJ2JpYXMnLCBTb3VyY2VNYXBDb25zdW1lci5HUkVBVEVTVF9MT1dFUl9CT1VORClcbiAgICApO1xuXG4gICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgIHZhciBtYXBwaW5nID0gdGhpcy5fb3JpZ2luYWxNYXBwaW5nc1tpbmRleF07XG5cbiAgICAgIGlmIChtYXBwaW5nLnNvdXJjZSA9PT0gbmVlZGxlLnNvdXJjZSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGxpbmU6IHV0aWwuZ2V0QXJnKG1hcHBpbmcsICdnZW5lcmF0ZWRMaW5lJywgbnVsbCksXG4gICAgICAgICAgY29sdW1uOiB1dGlsLmdldEFyZyhtYXBwaW5nLCAnZ2VuZXJhdGVkQ29sdW1uJywgbnVsbCksXG4gICAgICAgICAgbGFzdENvbHVtbjogdXRpbC5nZXRBcmcobWFwcGluZywgJ2xhc3RHZW5lcmF0ZWRDb2x1bW4nLCBudWxsKVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBsaW5lOiBudWxsLFxuICAgICAgY29sdW1uOiBudWxsLFxuICAgICAgbGFzdENvbHVtbjogbnVsbFxuICAgIH07XG4gIH07XG5cbmV4cG9ydHMuQmFzaWNTb3VyY2VNYXBDb25zdW1lciA9IEJhc2ljU291cmNlTWFwQ29uc3VtZXI7XG5cbi8qKlxuICogQW4gSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyIGluc3RhbmNlIHJlcHJlc2VudHMgYSBwYXJzZWQgc291cmNlIG1hcCB3aGljaFxuICogd2UgY2FuIHF1ZXJ5IGZvciBpbmZvcm1hdGlvbi4gSXQgZGlmZmVycyBmcm9tIEJhc2ljU291cmNlTWFwQ29uc3VtZXIgaW5cbiAqIHRoYXQgaXQgdGFrZXMgXCJpbmRleGVkXCIgc291cmNlIG1hcHMgKGkuZS4gb25lcyB3aXRoIGEgXCJzZWN0aW9uc1wiIGZpZWxkKSBhc1xuICogaW5wdXQuXG4gKlxuICogVGhlIGZpcnN0IHBhcmFtZXRlciBpcyBhIHJhdyBzb3VyY2UgbWFwIChlaXRoZXIgYXMgYSBKU09OIHN0cmluZywgb3IgYWxyZWFkeVxuICogcGFyc2VkIHRvIGFuIG9iamVjdCkuIEFjY29yZGluZyB0byB0aGUgc3BlYyBmb3IgaW5kZXhlZCBzb3VyY2UgbWFwcywgdGhleVxuICogaGF2ZSB0aGUgZm9sbG93aW5nIGF0dHJpYnV0ZXM6XG4gKlxuICogICAtIHZlcnNpb246IFdoaWNoIHZlcnNpb24gb2YgdGhlIHNvdXJjZSBtYXAgc3BlYyB0aGlzIG1hcCBpcyBmb2xsb3dpbmcuXG4gKiAgIC0gZmlsZTogT3B0aW9uYWwuIFRoZSBnZW5lcmF0ZWQgZmlsZSB0aGlzIHNvdXJjZSBtYXAgaXMgYXNzb2NpYXRlZCB3aXRoLlxuICogICAtIHNlY3Rpb25zOiBBIGxpc3Qgb2Ygc2VjdGlvbiBkZWZpbml0aW9ucy5cbiAqXG4gKiBFYWNoIHZhbHVlIHVuZGVyIHRoZSBcInNlY3Rpb25zXCIgZmllbGQgaGFzIHR3byBmaWVsZHM6XG4gKiAgIC0gb2Zmc2V0OiBUaGUgb2Zmc2V0IGludG8gdGhlIG9yaWdpbmFsIHNwZWNpZmllZCBhdCB3aGljaCB0aGlzIHNlY3Rpb25cbiAqICAgICAgIGJlZ2lucyB0byBhcHBseSwgZGVmaW5lZCBhcyBhbiBvYmplY3Qgd2l0aCBhIFwibGluZVwiIGFuZCBcImNvbHVtblwiXG4gKiAgICAgICBmaWVsZC5cbiAqICAgLSBtYXA6IEEgc291cmNlIG1hcCBkZWZpbml0aW9uLiBUaGlzIHNvdXJjZSBtYXAgY291bGQgYWxzbyBiZSBpbmRleGVkLFxuICogICAgICAgYnV0IGRvZXNuJ3QgaGF2ZSB0byBiZS5cbiAqXG4gKiBJbnN0ZWFkIG9mIHRoZSBcIm1hcFwiIGZpZWxkLCBpdCdzIGFsc28gcG9zc2libGUgdG8gaGF2ZSBhIFwidXJsXCIgZmllbGRcbiAqIHNwZWNpZnlpbmcgYSBVUkwgdG8gcmV0cmlldmUgYSBzb3VyY2UgbWFwIGZyb20sIGJ1dCB0aGF0J3MgY3VycmVudGx5XG4gKiB1bnN1cHBvcnRlZC5cbiAqXG4gKiBIZXJlJ3MgYW4gZXhhbXBsZSBzb3VyY2UgbWFwLCB0YWtlbiBmcm9tIHRoZSBzb3VyY2UgbWFwIHNwZWNbMF0sIGJ1dFxuICogbW9kaWZpZWQgdG8gb21pdCBhIHNlY3Rpb24gd2hpY2ggdXNlcyB0aGUgXCJ1cmxcIiBmaWVsZC5cbiAqXG4gKiAge1xuICogICAgdmVyc2lvbiA6IDMsXG4gKiAgICBmaWxlOiBcImFwcC5qc1wiLFxuICogICAgc2VjdGlvbnM6IFt7XG4gKiAgICAgIG9mZnNldDoge2xpbmU6MTAwLCBjb2x1bW46MTB9LFxuICogICAgICBtYXA6IHtcbiAqICAgICAgICB2ZXJzaW9uIDogMyxcbiAqICAgICAgICBmaWxlOiBcInNlY3Rpb24uanNcIixcbiAqICAgICAgICBzb3VyY2VzOiBbXCJmb28uanNcIiwgXCJiYXIuanNcIl0sXG4gKiAgICAgICAgbmFtZXM6IFtcInNyY1wiLCBcIm1hcHNcIiwgXCJhcmVcIiwgXCJmdW5cIl0sXG4gKiAgICAgICAgbWFwcGluZ3M6IFwiQUFBQSxFOztBQkNERTtcIlxuICogICAgICB9XG4gKiAgICB9XSxcbiAqICB9XG4gKlxuICogVGhlIHNlY29uZCBwYXJhbWV0ZXIsIGlmIGdpdmVuLCBpcyBhIHN0cmluZyB3aG9zZSB2YWx1ZSBpcyB0aGUgVVJMXG4gKiBhdCB3aGljaCB0aGUgc291cmNlIG1hcCB3YXMgZm91bmQuICBUaGlzIFVSTCBpcyB1c2VkIHRvIGNvbXB1dGUgdGhlXG4gKiBzb3VyY2VzIGFycmF5LlxuICpcbiAqIFswXTogaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vZG9jdW1lbnQvZC8xVTFSR0FlaFF3UnlwVVRvdkYxS1JscGlPRnplMGItXzJnYzZmQUgwS1kway9lZGl0I2hlYWRpbmc9aC41MzVlczN4ZXByZ3RcbiAqL1xuZnVuY3Rpb24gSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyKGFTb3VyY2VNYXAsIGFTb3VyY2VNYXBVUkwpIHtcbiAgdmFyIHNvdXJjZU1hcCA9IGFTb3VyY2VNYXA7XG4gIGlmICh0eXBlb2YgYVNvdXJjZU1hcCA9PT0gJ3N0cmluZycpIHtcbiAgICBzb3VyY2VNYXAgPSB1dGlsLnBhcnNlU291cmNlTWFwSW5wdXQoYVNvdXJjZU1hcCk7XG4gIH1cblxuICB2YXIgdmVyc2lvbiA9IHV0aWwuZ2V0QXJnKHNvdXJjZU1hcCwgJ3ZlcnNpb24nKTtcbiAgdmFyIHNlY3Rpb25zID0gdXRpbC5nZXRBcmcoc291cmNlTWFwLCAnc2VjdGlvbnMnKTtcblxuICBpZiAodmVyc2lvbiAhPSB0aGlzLl92ZXJzaW9uKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCB2ZXJzaW9uOiAnICsgdmVyc2lvbik7XG4gIH1cblxuICB0aGlzLl9zb3VyY2VzID0gbmV3IEFycmF5U2V0KCk7XG4gIHRoaXMuX25hbWVzID0gbmV3IEFycmF5U2V0KCk7XG5cbiAgdmFyIGxhc3RPZmZzZXQgPSB7XG4gICAgbGluZTogLTEsXG4gICAgY29sdW1uOiAwXG4gIH07XG4gIHRoaXMuX3NlY3Rpb25zID0gc2VjdGlvbnMubWFwKGZ1bmN0aW9uIChzKSB7XG4gICAgaWYgKHMudXJsKSB7XG4gICAgICAvLyBUaGUgdXJsIGZpZWxkIHdpbGwgcmVxdWlyZSBzdXBwb3J0IGZvciBhc3luY2hyb25pY2l0eS5cbiAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vbW96aWxsYS9zb3VyY2UtbWFwL2lzc3Vlcy8xNlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdTdXBwb3J0IGZvciB1cmwgZmllbGQgaW4gc2VjdGlvbnMgbm90IGltcGxlbWVudGVkLicpO1xuICAgIH1cbiAgICB2YXIgb2Zmc2V0ID0gdXRpbC5nZXRBcmcocywgJ29mZnNldCcpO1xuICAgIHZhciBvZmZzZXRMaW5lID0gdXRpbC5nZXRBcmcob2Zmc2V0LCAnbGluZScpO1xuICAgIHZhciBvZmZzZXRDb2x1bW4gPSB1dGlsLmdldEFyZyhvZmZzZXQsICdjb2x1bW4nKTtcblxuICAgIGlmIChvZmZzZXRMaW5lIDwgbGFzdE9mZnNldC5saW5lIHx8XG4gICAgICAgIChvZmZzZXRMaW5lID09PSBsYXN0T2Zmc2V0LmxpbmUgJiYgb2Zmc2V0Q29sdW1uIDwgbGFzdE9mZnNldC5jb2x1bW4pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NlY3Rpb24gb2Zmc2V0cyBtdXN0IGJlIG9yZGVyZWQgYW5kIG5vbi1vdmVybGFwcGluZy4nKTtcbiAgICB9XG4gICAgbGFzdE9mZnNldCA9IG9mZnNldDtcblxuICAgIHJldHVybiB7XG4gICAgICBnZW5lcmF0ZWRPZmZzZXQ6IHtcbiAgICAgICAgLy8gVGhlIG9mZnNldCBmaWVsZHMgYXJlIDAtYmFzZWQsIGJ1dCB3ZSB1c2UgMS1iYXNlZCBpbmRpY2VzIHdoZW5cbiAgICAgICAgLy8gZW5jb2RpbmcvZGVjb2RpbmcgZnJvbSBWTFEuXG4gICAgICAgIGdlbmVyYXRlZExpbmU6IG9mZnNldExpbmUgKyAxLFxuICAgICAgICBnZW5lcmF0ZWRDb2x1bW46IG9mZnNldENvbHVtbiArIDFcbiAgICAgIH0sXG4gICAgICBjb25zdW1lcjogbmV3IFNvdXJjZU1hcENvbnN1bWVyKHV0aWwuZ2V0QXJnKHMsICdtYXAnKSwgYVNvdXJjZU1hcFVSTClcbiAgICB9XG4gIH0pO1xufVxuXG5JbmRleGVkU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShTb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUpO1xuSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFNvdXJjZU1hcENvbnN1bWVyO1xuXG4vKipcbiAqIFRoZSB2ZXJzaW9uIG9mIHRoZSBzb3VyY2UgbWFwcGluZyBzcGVjIHRoYXQgd2UgYXJlIGNvbnN1bWluZy5cbiAqL1xuSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5fdmVyc2lvbiA9IDM7XG5cbi8qKlxuICogVGhlIGxpc3Qgb2Ygb3JpZ2luYWwgc291cmNlcy5cbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KEluZGV4ZWRTb3VyY2VNYXBDb25zdW1lci5wcm90b3R5cGUsICdzb3VyY2VzJywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc291cmNlcyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fc2VjdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdGhpcy5fc2VjdGlvbnNbaV0uY29uc3VtZXIuc291cmNlcy5sZW5ndGg7IGorKykge1xuICAgICAgICBzb3VyY2VzLnB1c2godGhpcy5fc2VjdGlvbnNbaV0uY29uc3VtZXIuc291cmNlc1tqXSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzb3VyY2VzO1xuICB9XG59KTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBvcmlnaW5hbCBzb3VyY2UsIGxpbmUsIGFuZCBjb2x1bW4gaW5mb3JtYXRpb24gZm9yIHRoZSBnZW5lcmF0ZWRcbiAqIHNvdXJjZSdzIGxpbmUgYW5kIGNvbHVtbiBwb3NpdGlvbnMgcHJvdmlkZWQuIFRoZSBvbmx5IGFyZ3VtZW50IGlzIGFuIG9iamVjdFxuICogd2l0aCB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogICAtIGxpbmU6IFRoZSBsaW5lIG51bWJlciBpbiB0aGUgZ2VuZXJhdGVkIHNvdXJjZS4gIFRoZSBsaW5lIG51bWJlclxuICogICAgIGlzIDEtYmFzZWQuXG4gKiAgIC0gY29sdW1uOiBUaGUgY29sdW1uIG51bWJlciBpbiB0aGUgZ2VuZXJhdGVkIHNvdXJjZS4gIFRoZSBjb2x1bW5cbiAqICAgICBudW1iZXIgaXMgMC1iYXNlZC5cbiAqXG4gKiBhbmQgYW4gb2JqZWN0IGlzIHJldHVybmVkIHdpdGggdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICpcbiAqICAgLSBzb3VyY2U6IFRoZSBvcmlnaW5hbCBzb3VyY2UgZmlsZSwgb3IgbnVsbC5cbiAqICAgLSBsaW5lOiBUaGUgbGluZSBudW1iZXIgaW4gdGhlIG9yaWdpbmFsIHNvdXJjZSwgb3IgbnVsbC4gIFRoZVxuICogICAgIGxpbmUgbnVtYmVyIGlzIDEtYmFzZWQuXG4gKiAgIC0gY29sdW1uOiBUaGUgY29sdW1uIG51bWJlciBpbiB0aGUgb3JpZ2luYWwgc291cmNlLCBvciBudWxsLiAgVGhlXG4gKiAgICAgY29sdW1uIG51bWJlciBpcyAwLWJhc2VkLlxuICogICAtIG5hbWU6IFRoZSBvcmlnaW5hbCBpZGVudGlmaWVyLCBvciBudWxsLlxuICovXG5JbmRleGVkU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLm9yaWdpbmFsUG9zaXRpb25Gb3IgPVxuICBmdW5jdGlvbiBJbmRleGVkU291cmNlTWFwQ29uc3VtZXJfb3JpZ2luYWxQb3NpdGlvbkZvcihhQXJncykge1xuICAgIHZhciBuZWVkbGUgPSB7XG4gICAgICBnZW5lcmF0ZWRMaW5lOiB1dGlsLmdldEFyZyhhQXJncywgJ2xpbmUnKSxcbiAgICAgIGdlbmVyYXRlZENvbHVtbjogdXRpbC5nZXRBcmcoYUFyZ3MsICdjb2x1bW4nKVxuICAgIH07XG5cbiAgICAvLyBGaW5kIHRoZSBzZWN0aW9uIGNvbnRhaW5pbmcgdGhlIGdlbmVyYXRlZCBwb3NpdGlvbiB3ZSdyZSB0cnlpbmcgdG8gbWFwXG4gICAgLy8gdG8gYW4gb3JpZ2luYWwgcG9zaXRpb24uXG4gICAgdmFyIHNlY3Rpb25JbmRleCA9IGJpbmFyeVNlYXJjaC5zZWFyY2gobmVlZGxlLCB0aGlzLl9zZWN0aW9ucyxcbiAgICAgIGZ1bmN0aW9uKG5lZWRsZSwgc2VjdGlvbikge1xuICAgICAgICB2YXIgY21wID0gbmVlZGxlLmdlbmVyYXRlZExpbmUgLSBzZWN0aW9uLmdlbmVyYXRlZE9mZnNldC5nZW5lcmF0ZWRMaW5lO1xuICAgICAgICBpZiAoY21wKSB7XG4gICAgICAgICAgcmV0dXJuIGNtcDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAobmVlZGxlLmdlbmVyYXRlZENvbHVtbiAtXG4gICAgICAgICAgICAgICAgc2VjdGlvbi5nZW5lcmF0ZWRPZmZzZXQuZ2VuZXJhdGVkQ29sdW1uKTtcbiAgICAgIH0pO1xuICAgIHZhciBzZWN0aW9uID0gdGhpcy5fc2VjdGlvbnNbc2VjdGlvbkluZGV4XTtcblxuICAgIGlmICghc2VjdGlvbikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc291cmNlOiBudWxsLFxuICAgICAgICBsaW5lOiBudWxsLFxuICAgICAgICBjb2x1bW46IG51bGwsXG4gICAgICAgIG5hbWU6IG51bGxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlY3Rpb24uY29uc3VtZXIub3JpZ2luYWxQb3NpdGlvbkZvcih7XG4gICAgICBsaW5lOiBuZWVkbGUuZ2VuZXJhdGVkTGluZSAtXG4gICAgICAgIChzZWN0aW9uLmdlbmVyYXRlZE9mZnNldC5nZW5lcmF0ZWRMaW5lIC0gMSksXG4gICAgICBjb2x1bW46IG5lZWRsZS5nZW5lcmF0ZWRDb2x1bW4gLVxuICAgICAgICAoc2VjdGlvbi5nZW5lcmF0ZWRPZmZzZXQuZ2VuZXJhdGVkTGluZSA9PT0gbmVlZGxlLmdlbmVyYXRlZExpbmVcbiAgICAgICAgID8gc2VjdGlvbi5nZW5lcmF0ZWRPZmZzZXQuZ2VuZXJhdGVkQ29sdW1uIC0gMVxuICAgICAgICAgOiAwKSxcbiAgICAgIGJpYXM6IGFBcmdzLmJpYXNcbiAgICB9KTtcbiAgfTtcblxuLyoqXG4gKiBSZXR1cm4gdHJ1ZSBpZiB3ZSBoYXZlIHRoZSBzb3VyY2UgY29udGVudCBmb3IgZXZlcnkgc291cmNlIGluIHRoZSBzb3VyY2VcbiAqIG1hcCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5JbmRleGVkU291cmNlTWFwQ29uc3VtZXIucHJvdG90eXBlLmhhc0NvbnRlbnRzT2ZBbGxTb3VyY2VzID1cbiAgZnVuY3Rpb24gSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyX2hhc0NvbnRlbnRzT2ZBbGxTb3VyY2VzKCkge1xuICAgIHJldHVybiB0aGlzLl9zZWN0aW9ucy5ldmVyeShmdW5jdGlvbiAocykge1xuICAgICAgcmV0dXJuIHMuY29uc3VtZXIuaGFzQ29udGVudHNPZkFsbFNvdXJjZXMoKTtcbiAgICB9KTtcbiAgfTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBvcmlnaW5hbCBzb3VyY2UgY29udGVudC4gVGhlIG9ubHkgYXJndW1lbnQgaXMgdGhlIHVybCBvZiB0aGVcbiAqIG9yaWdpbmFsIHNvdXJjZSBmaWxlLiBSZXR1cm5zIG51bGwgaWYgbm8gb3JpZ2luYWwgc291cmNlIGNvbnRlbnQgaXNcbiAqIGF2YWlsYWJsZS5cbiAqL1xuSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5zb3VyY2VDb250ZW50Rm9yID1cbiAgZnVuY3Rpb24gSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyX3NvdXJjZUNvbnRlbnRGb3IoYVNvdXJjZSwgbnVsbE9uTWlzc2luZykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fc2VjdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBzZWN0aW9uID0gdGhpcy5fc2VjdGlvbnNbaV07XG5cbiAgICAgIHZhciBjb250ZW50ID0gc2VjdGlvbi5jb25zdW1lci5zb3VyY2VDb250ZW50Rm9yKGFTb3VyY2UsIHRydWUpO1xuICAgICAgaWYgKGNvbnRlbnQpIHtcbiAgICAgICAgcmV0dXJuIGNvbnRlbnQ7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChudWxsT25NaXNzaW5nKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1wiJyArIGFTb3VyY2UgKyAnXCIgaXMgbm90IGluIHRoZSBTb3VyY2VNYXAuJyk7XG4gICAgfVxuICB9O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGdlbmVyYXRlZCBsaW5lIGFuZCBjb2x1bW4gaW5mb3JtYXRpb24gZm9yIHRoZSBvcmlnaW5hbCBzb3VyY2UsXG4gKiBsaW5lLCBhbmQgY29sdW1uIHBvc2l0aW9ucyBwcm92aWRlZC4gVGhlIG9ubHkgYXJndW1lbnQgaXMgYW4gb2JqZWN0IHdpdGhcbiAqIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczpcbiAqXG4gKiAgIC0gc291cmNlOiBUaGUgZmlsZW5hbWUgb2YgdGhlIG9yaWdpbmFsIHNvdXJjZS5cbiAqICAgLSBsaW5lOiBUaGUgbGluZSBudW1iZXIgaW4gdGhlIG9yaWdpbmFsIHNvdXJjZS4gIFRoZSBsaW5lIG51bWJlclxuICogICAgIGlzIDEtYmFzZWQuXG4gKiAgIC0gY29sdW1uOiBUaGUgY29sdW1uIG51bWJlciBpbiB0aGUgb3JpZ2luYWwgc291cmNlLiAgVGhlIGNvbHVtblxuICogICAgIG51bWJlciBpcyAwLWJhc2VkLlxuICpcbiAqIGFuZCBhbiBvYmplY3QgaXMgcmV0dXJuZWQgd2l0aCB0aGUgZm9sbG93aW5nIHByb3BlcnRpZXM6XG4gKlxuICogICAtIGxpbmU6IFRoZSBsaW5lIG51bWJlciBpbiB0aGUgZ2VuZXJhdGVkIHNvdXJjZSwgb3IgbnVsbC4gIFRoZVxuICogICAgIGxpbmUgbnVtYmVyIGlzIDEtYmFzZWQuIFxuICogICAtIGNvbHVtbjogVGhlIGNvbHVtbiBudW1iZXIgaW4gdGhlIGdlbmVyYXRlZCBzb3VyY2UsIG9yIG51bGwuXG4gKiAgICAgVGhlIGNvbHVtbiBudW1iZXIgaXMgMC1iYXNlZC5cbiAqL1xuSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5nZW5lcmF0ZWRQb3NpdGlvbkZvciA9XG4gIGZ1bmN0aW9uIEluZGV4ZWRTb3VyY2VNYXBDb25zdW1lcl9nZW5lcmF0ZWRQb3NpdGlvbkZvcihhQXJncykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fc2VjdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBzZWN0aW9uID0gdGhpcy5fc2VjdGlvbnNbaV07XG5cbiAgICAgIC8vIE9ubHkgY29uc2lkZXIgdGhpcyBzZWN0aW9uIGlmIHRoZSByZXF1ZXN0ZWQgc291cmNlIGlzIGluIHRoZSBsaXN0IG9mXG4gICAgICAvLyBzb3VyY2VzIG9mIHRoZSBjb25zdW1lci5cbiAgICAgIGlmIChzZWN0aW9uLmNvbnN1bWVyLl9maW5kU291cmNlSW5kZXgodXRpbC5nZXRBcmcoYUFyZ3MsICdzb3VyY2UnKSkgPT09IC0xKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgdmFyIGdlbmVyYXRlZFBvc2l0aW9uID0gc2VjdGlvbi5jb25zdW1lci5nZW5lcmF0ZWRQb3NpdGlvbkZvcihhQXJncyk7XG4gICAgICBpZiAoZ2VuZXJhdGVkUG9zaXRpb24pIHtcbiAgICAgICAgdmFyIHJldCA9IHtcbiAgICAgICAgICBsaW5lOiBnZW5lcmF0ZWRQb3NpdGlvbi5saW5lICtcbiAgICAgICAgICAgIChzZWN0aW9uLmdlbmVyYXRlZE9mZnNldC5nZW5lcmF0ZWRMaW5lIC0gMSksXG4gICAgICAgICAgY29sdW1uOiBnZW5lcmF0ZWRQb3NpdGlvbi5jb2x1bW4gK1xuICAgICAgICAgICAgKHNlY3Rpb24uZ2VuZXJhdGVkT2Zmc2V0LmdlbmVyYXRlZExpbmUgPT09IGdlbmVyYXRlZFBvc2l0aW9uLmxpbmVcbiAgICAgICAgICAgICA/IHNlY3Rpb24uZ2VuZXJhdGVkT2Zmc2V0LmdlbmVyYXRlZENvbHVtbiAtIDFcbiAgICAgICAgICAgICA6IDApXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiByZXQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGxpbmU6IG51bGwsXG4gICAgICBjb2x1bW46IG51bGxcbiAgICB9O1xuICB9O1xuXG4vKipcbiAqIFBhcnNlIHRoZSBtYXBwaW5ncyBpbiBhIHN0cmluZyBpbiB0byBhIGRhdGEgc3RydWN0dXJlIHdoaWNoIHdlIGNhbiBlYXNpbHlcbiAqIHF1ZXJ5ICh0aGUgb3JkZXJlZCBhcnJheXMgaW4gdGhlIGB0aGlzLl9fZ2VuZXJhdGVkTWFwcGluZ3NgIGFuZFxuICogYHRoaXMuX19vcmlnaW5hbE1hcHBpbmdzYCBwcm9wZXJ0aWVzKS5cbiAqL1xuSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyLnByb3RvdHlwZS5fcGFyc2VNYXBwaW5ncyA9XG4gIGZ1bmN0aW9uIEluZGV4ZWRTb3VyY2VNYXBDb25zdW1lcl9wYXJzZU1hcHBpbmdzKGFTdHIsIGFTb3VyY2VSb290KSB7XG4gICAgdGhpcy5fX2dlbmVyYXRlZE1hcHBpbmdzID0gW107XG4gICAgdGhpcy5fX29yaWdpbmFsTWFwcGluZ3MgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX3NlY3Rpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgc2VjdGlvbiA9IHRoaXMuX3NlY3Rpb25zW2ldO1xuICAgICAgdmFyIHNlY3Rpb25NYXBwaW5ncyA9IHNlY3Rpb24uY29uc3VtZXIuX2dlbmVyYXRlZE1hcHBpbmdzO1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBzZWN0aW9uTWFwcGluZ3MubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgdmFyIG1hcHBpbmcgPSBzZWN0aW9uTWFwcGluZ3Nbal07XG5cbiAgICAgICAgdmFyIHNvdXJjZSA9IHNlY3Rpb24uY29uc3VtZXIuX3NvdXJjZXMuYXQobWFwcGluZy5zb3VyY2UpO1xuICAgICAgICBzb3VyY2UgPSB1dGlsLmNvbXB1dGVTb3VyY2VVUkwoc2VjdGlvbi5jb25zdW1lci5zb3VyY2VSb290LCBzb3VyY2UsIHRoaXMuX3NvdXJjZU1hcFVSTCk7XG4gICAgICAgIHRoaXMuX3NvdXJjZXMuYWRkKHNvdXJjZSk7XG4gICAgICAgIHNvdXJjZSA9IHRoaXMuX3NvdXJjZXMuaW5kZXhPZihzb3VyY2UpO1xuXG4gICAgICAgIHZhciBuYW1lID0gbnVsbDtcbiAgICAgICAgaWYgKG1hcHBpbmcubmFtZSkge1xuICAgICAgICAgIG5hbWUgPSBzZWN0aW9uLmNvbnN1bWVyLl9uYW1lcy5hdChtYXBwaW5nLm5hbWUpO1xuICAgICAgICAgIHRoaXMuX25hbWVzLmFkZChuYW1lKTtcbiAgICAgICAgICBuYW1lID0gdGhpcy5fbmFtZXMuaW5kZXhPZihuYW1lKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoZSBtYXBwaW5ncyBjb21pbmcgZnJvbSB0aGUgY29uc3VtZXIgZm9yIHRoZSBzZWN0aW9uIGhhdmVcbiAgICAgICAgLy8gZ2VuZXJhdGVkIHBvc2l0aW9ucyByZWxhdGl2ZSB0byB0aGUgc3RhcnQgb2YgdGhlIHNlY3Rpb24sIHNvIHdlXG4gICAgICAgIC8vIG5lZWQgdG8gb2Zmc2V0IHRoZW0gdG8gYmUgcmVsYXRpdmUgdG8gdGhlIHN0YXJ0IG9mIHRoZSBjb25jYXRlbmF0ZWRcbiAgICAgICAgLy8gZ2VuZXJhdGVkIGZpbGUuXG4gICAgICAgIHZhciBhZGp1c3RlZE1hcHBpbmcgPSB7XG4gICAgICAgICAgc291cmNlOiBzb3VyY2UsXG4gICAgICAgICAgZ2VuZXJhdGVkTGluZTogbWFwcGluZy5nZW5lcmF0ZWRMaW5lICtcbiAgICAgICAgICAgIChzZWN0aW9uLmdlbmVyYXRlZE9mZnNldC5nZW5lcmF0ZWRMaW5lIC0gMSksXG4gICAgICAgICAgZ2VuZXJhdGVkQ29sdW1uOiBtYXBwaW5nLmdlbmVyYXRlZENvbHVtbiArXG4gICAgICAgICAgICAoc2VjdGlvbi5nZW5lcmF0ZWRPZmZzZXQuZ2VuZXJhdGVkTGluZSA9PT0gbWFwcGluZy5nZW5lcmF0ZWRMaW5lXG4gICAgICAgICAgICA/IHNlY3Rpb24uZ2VuZXJhdGVkT2Zmc2V0LmdlbmVyYXRlZENvbHVtbiAtIDFcbiAgICAgICAgICAgIDogMCksXG4gICAgICAgICAgb3JpZ2luYWxMaW5lOiBtYXBwaW5nLm9yaWdpbmFsTGluZSxcbiAgICAgICAgICBvcmlnaW5hbENvbHVtbjogbWFwcGluZy5vcmlnaW5hbENvbHVtbixcbiAgICAgICAgICBuYW1lOiBuYW1lXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5fX2dlbmVyYXRlZE1hcHBpbmdzLnB1c2goYWRqdXN0ZWRNYXBwaW5nKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhZGp1c3RlZE1hcHBpbmcub3JpZ2luYWxMaW5lID09PSAnbnVtYmVyJykge1xuICAgICAgICAgIHRoaXMuX19vcmlnaW5hbE1hcHBpbmdzLnB1c2goYWRqdXN0ZWRNYXBwaW5nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHF1aWNrU29ydCh0aGlzLl9fZ2VuZXJhdGVkTWFwcGluZ3MsIHV0aWwuY29tcGFyZUJ5R2VuZXJhdGVkUG9zaXRpb25zRGVmbGF0ZWQpO1xuICAgIHF1aWNrU29ydCh0aGlzLl9fb3JpZ2luYWxNYXBwaW5ncywgdXRpbC5jb21wYXJlQnlPcmlnaW5hbFBvc2l0aW9ucyk7XG4gIH07XG5cbmV4cG9ydHMuSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyID0gSW5kZXhlZFNvdXJjZU1hcENvbnN1bWVyO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9saWIvc291cmNlLW1hcC1jb25zdW1lci5qc1xuLy8gbW9kdWxlIGlkID0gN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKiAtKi0gTW9kZToganM7IGpzLWluZGVudC1sZXZlbDogMjsgLSotICovXG4vKlxuICogQ29weXJpZ2h0IDIwMTEgTW96aWxsYSBGb3VuZGF0aW9uIGFuZCBjb250cmlidXRvcnNcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBOZXcgQlNEIGxpY2Vuc2UuIFNlZSBMSUNFTlNFIG9yOlxuICogaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL0JTRC0zLUNsYXVzZVxuICovXG5cbmV4cG9ydHMuR1JFQVRFU1RfTE9XRVJfQk9VTkQgPSAxO1xuZXhwb3J0cy5MRUFTVF9VUFBFUl9CT1VORCA9IDI7XG5cbi8qKlxuICogUmVjdXJzaXZlIGltcGxlbWVudGF0aW9uIG9mIGJpbmFyeSBzZWFyY2guXG4gKlxuICogQHBhcmFtIGFMb3cgSW5kaWNlcyBoZXJlIGFuZCBsb3dlciBkbyBub3QgY29udGFpbiB0aGUgbmVlZGxlLlxuICogQHBhcmFtIGFIaWdoIEluZGljZXMgaGVyZSBhbmQgaGlnaGVyIGRvIG5vdCBjb250YWluIHRoZSBuZWVkbGUuXG4gKiBAcGFyYW0gYU5lZWRsZSBUaGUgZWxlbWVudCBiZWluZyBzZWFyY2hlZCBmb3IuXG4gKiBAcGFyYW0gYUhheXN0YWNrIFRoZSBub24tZW1wdHkgYXJyYXkgYmVpbmcgc2VhcmNoZWQuXG4gKiBAcGFyYW0gYUNvbXBhcmUgRnVuY3Rpb24gd2hpY2ggdGFrZXMgdHdvIGVsZW1lbnRzIGFuZCByZXR1cm5zIC0xLCAwLCBvciAxLlxuICogQHBhcmFtIGFCaWFzIEVpdGhlciAnYmluYXJ5U2VhcmNoLkdSRUFURVNUX0xPV0VSX0JPVU5EJyBvclxuICogICAgICdiaW5hcnlTZWFyY2guTEVBU1RfVVBQRVJfQk9VTkQnLiBTcGVjaWZpZXMgd2hldGhlciB0byByZXR1cm4gdGhlXG4gKiAgICAgY2xvc2VzdCBlbGVtZW50IHRoYXQgaXMgc21hbGxlciB0aGFuIG9yIGdyZWF0ZXIgdGhhbiB0aGUgb25lIHdlIGFyZVxuICogICAgIHNlYXJjaGluZyBmb3IsIHJlc3BlY3RpdmVseSwgaWYgdGhlIGV4YWN0IGVsZW1lbnQgY2Fubm90IGJlIGZvdW5kLlxuICovXG5mdW5jdGlvbiByZWN1cnNpdmVTZWFyY2goYUxvdywgYUhpZ2gsIGFOZWVkbGUsIGFIYXlzdGFjaywgYUNvbXBhcmUsIGFCaWFzKSB7XG4gIC8vIFRoaXMgZnVuY3Rpb24gdGVybWluYXRlcyB3aGVuIG9uZSBvZiB0aGUgZm9sbG93aW5nIGlzIHRydWU6XG4gIC8vXG4gIC8vICAgMS4gV2UgZmluZCB0aGUgZXhhY3QgZWxlbWVudCB3ZSBhcmUgbG9va2luZyBmb3IuXG4gIC8vXG4gIC8vICAgMi4gV2UgZGlkIG5vdCBmaW5kIHRoZSBleGFjdCBlbGVtZW50LCBidXQgd2UgY2FuIHJldHVybiB0aGUgaW5kZXggb2ZcbiAgLy8gICAgICB0aGUgbmV4dC1jbG9zZXN0IGVsZW1lbnQuXG4gIC8vXG4gIC8vICAgMy4gV2UgZGlkIG5vdCBmaW5kIHRoZSBleGFjdCBlbGVtZW50LCBhbmQgdGhlcmUgaXMgbm8gbmV4dC1jbG9zZXN0XG4gIC8vICAgICAgZWxlbWVudCB0aGFuIHRoZSBvbmUgd2UgYXJlIHNlYXJjaGluZyBmb3IsIHNvIHdlIHJldHVybiAtMS5cbiAgdmFyIG1pZCA9IE1hdGguZmxvb3IoKGFIaWdoIC0gYUxvdykgLyAyKSArIGFMb3c7XG4gIHZhciBjbXAgPSBhQ29tcGFyZShhTmVlZGxlLCBhSGF5c3RhY2tbbWlkXSwgdHJ1ZSk7XG4gIGlmIChjbXAgPT09IDApIHtcbiAgICAvLyBGb3VuZCB0aGUgZWxlbWVudCB3ZSBhcmUgbG9va2luZyBmb3IuXG4gICAgcmV0dXJuIG1pZDtcbiAgfVxuICBlbHNlIGlmIChjbXAgPiAwKSB7XG4gICAgLy8gT3VyIG5lZWRsZSBpcyBncmVhdGVyIHRoYW4gYUhheXN0YWNrW21pZF0uXG4gICAgaWYgKGFIaWdoIC0gbWlkID4gMSkge1xuICAgICAgLy8gVGhlIGVsZW1lbnQgaXMgaW4gdGhlIHVwcGVyIGhhbGYuXG4gICAgICByZXR1cm4gcmVjdXJzaXZlU2VhcmNoKG1pZCwgYUhpZ2gsIGFOZWVkbGUsIGFIYXlzdGFjaywgYUNvbXBhcmUsIGFCaWFzKTtcbiAgICB9XG5cbiAgICAvLyBUaGUgZXhhY3QgbmVlZGxlIGVsZW1lbnQgd2FzIG5vdCBmb3VuZCBpbiB0aGlzIGhheXN0YWNrLiBEZXRlcm1pbmUgaWZcbiAgICAvLyB3ZSBhcmUgaW4gdGVybWluYXRpb24gY2FzZSAoMykgb3IgKDIpIGFuZCByZXR1cm4gdGhlIGFwcHJvcHJpYXRlIHRoaW5nLlxuICAgIGlmIChhQmlhcyA9PSBleHBvcnRzLkxFQVNUX1VQUEVSX0JPVU5EKSB7XG4gICAgICByZXR1cm4gYUhpZ2ggPCBhSGF5c3RhY2subGVuZ3RoID8gYUhpZ2ggOiAtMTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG1pZDtcbiAgICB9XG4gIH1cbiAgZWxzZSB7XG4gICAgLy8gT3VyIG5lZWRsZSBpcyBsZXNzIHRoYW4gYUhheXN0YWNrW21pZF0uXG4gICAgaWYgKG1pZCAtIGFMb3cgPiAxKSB7XG4gICAgICAvLyBUaGUgZWxlbWVudCBpcyBpbiB0aGUgbG93ZXIgaGFsZi5cbiAgICAgIHJldHVybiByZWN1cnNpdmVTZWFyY2goYUxvdywgbWlkLCBhTmVlZGxlLCBhSGF5c3RhY2ssIGFDb21wYXJlLCBhQmlhcyk7XG4gICAgfVxuXG4gICAgLy8gd2UgYXJlIGluIHRlcm1pbmF0aW9uIGNhc2UgKDMpIG9yICgyKSBhbmQgcmV0dXJuIHRoZSBhcHByb3ByaWF0ZSB0aGluZy5cbiAgICBpZiAoYUJpYXMgPT0gZXhwb3J0cy5MRUFTVF9VUFBFUl9CT1VORCkge1xuICAgICAgcmV0dXJuIG1pZDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGFMb3cgPCAwID8gLTEgOiBhTG93O1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFRoaXMgaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgYmluYXJ5IHNlYXJjaCB3aGljaCB3aWxsIGFsd2F5cyB0cnkgYW5kIHJldHVyblxuICogdGhlIGluZGV4IG9mIHRoZSBjbG9zZXN0IGVsZW1lbnQgaWYgdGhlcmUgaXMgbm8gZXhhY3QgaGl0LiBUaGlzIGlzIGJlY2F1c2VcbiAqIG1hcHBpbmdzIGJldHdlZW4gb3JpZ2luYWwgYW5kIGdlbmVyYXRlZCBsaW5lL2NvbCBwYWlycyBhcmUgc2luZ2xlIHBvaW50cyxcbiAqIGFuZCB0aGVyZSBpcyBhbiBpbXBsaWNpdCByZWdpb24gYmV0d2VlbiBlYWNoIG9mIHRoZW0sIHNvIGEgbWlzcyBqdXN0IG1lYW5zXG4gKiB0aGF0IHlvdSBhcmVuJ3Qgb24gdGhlIHZlcnkgc3RhcnQgb2YgYSByZWdpb24uXG4gKlxuICogQHBhcmFtIGFOZWVkbGUgVGhlIGVsZW1lbnQgeW91IGFyZSBsb29raW5nIGZvci5cbiAqIEBwYXJhbSBhSGF5c3RhY2sgVGhlIGFycmF5IHRoYXQgaXMgYmVpbmcgc2VhcmNoZWQuXG4gKiBAcGFyYW0gYUNvbXBhcmUgQSBmdW5jdGlvbiB3aGljaCB0YWtlcyB0aGUgbmVlZGxlIGFuZCBhbiBlbGVtZW50IGluIHRoZVxuICogICAgIGFycmF5IGFuZCByZXR1cm5zIC0xLCAwLCBvciAxIGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZSBuZWVkbGUgaXMgbGVzc1xuICogICAgIHRoYW4sIGVxdWFsIHRvLCBvciBncmVhdGVyIHRoYW4gdGhlIGVsZW1lbnQsIHJlc3BlY3RpdmVseS5cbiAqIEBwYXJhbSBhQmlhcyBFaXRoZXIgJ2JpbmFyeVNlYXJjaC5HUkVBVEVTVF9MT1dFUl9CT1VORCcgb3JcbiAqICAgICAnYmluYXJ5U2VhcmNoLkxFQVNUX1VQUEVSX0JPVU5EJy4gU3BlY2lmaWVzIHdoZXRoZXIgdG8gcmV0dXJuIHRoZVxuICogICAgIGNsb3Nlc3QgZWxlbWVudCB0aGF0IGlzIHNtYWxsZXIgdGhhbiBvciBncmVhdGVyIHRoYW4gdGhlIG9uZSB3ZSBhcmVcbiAqICAgICBzZWFyY2hpbmcgZm9yLCByZXNwZWN0aXZlbHksIGlmIHRoZSBleGFjdCBlbGVtZW50IGNhbm5vdCBiZSBmb3VuZC5cbiAqICAgICBEZWZhdWx0cyB0byAnYmluYXJ5U2VhcmNoLkdSRUFURVNUX0xPV0VSX0JPVU5EJy5cbiAqL1xuZXhwb3J0cy5zZWFyY2ggPSBmdW5jdGlvbiBzZWFyY2goYU5lZWRsZSwgYUhheXN0YWNrLCBhQ29tcGFyZSwgYUJpYXMpIHtcbiAgaWYgKGFIYXlzdGFjay5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICB2YXIgaW5kZXggPSByZWN1cnNpdmVTZWFyY2goLTEsIGFIYXlzdGFjay5sZW5ndGgsIGFOZWVkbGUsIGFIYXlzdGFjayxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFDb21wYXJlLCBhQmlhcyB8fCBleHBvcnRzLkdSRUFURVNUX0xPV0VSX0JPVU5EKTtcbiAgaWYgKGluZGV4IDwgMCkge1xuICAgIHJldHVybiAtMTtcbiAgfVxuXG4gIC8vIFdlIGhhdmUgZm91bmQgZWl0aGVyIHRoZSBleGFjdCBlbGVtZW50LCBvciB0aGUgbmV4dC1jbG9zZXN0IGVsZW1lbnQgdGhhblxuICAvLyB0aGUgb25lIHdlIGFyZSBzZWFyY2hpbmcgZm9yLiBIb3dldmVyLCB0aGVyZSBtYXkgYmUgbW9yZSB0aGFuIG9uZSBzdWNoXG4gIC8vIGVsZW1lbnQuIE1ha2Ugc3VyZSB3ZSBhbHdheXMgcmV0dXJuIHRoZSBzbWFsbGVzdCBvZiB0aGVzZS5cbiAgd2hpbGUgKGluZGV4IC0gMSA+PSAwKSB7XG4gICAgaWYgKGFDb21wYXJlKGFIYXlzdGFja1tpbmRleF0sIGFIYXlzdGFja1tpbmRleCAtIDFdLCB0cnVlKSAhPT0gMCkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIC0taW5kZXg7XG4gIH1cblxuICByZXR1cm4gaW5kZXg7XG59O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9saWIvYmluYXJ5LXNlYXJjaC5qc1xuLy8gbW9kdWxlIGlkID0gOFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKiAtKi0gTW9kZToganM7IGpzLWluZGVudC1sZXZlbDogMjsgLSotICovXG4vKlxuICogQ29weXJpZ2h0IDIwMTEgTW96aWxsYSBGb3VuZGF0aW9uIGFuZCBjb250cmlidXRvcnNcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBOZXcgQlNEIGxpY2Vuc2UuIFNlZSBMSUNFTlNFIG9yOlxuICogaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL0JTRC0zLUNsYXVzZVxuICovXG5cbi8vIEl0IHR1cm5zIG91dCB0aGF0IHNvbWUgKG1vc3Q/KSBKYXZhU2NyaXB0IGVuZ2luZXMgZG9uJ3Qgc2VsZi1ob3N0XG4vLyBgQXJyYXkucHJvdG90eXBlLnNvcnRgLiBUaGlzIG1ha2VzIHNlbnNlIGJlY2F1c2UgQysrIHdpbGwgbGlrZWx5IHJlbWFpblxuLy8gZmFzdGVyIHRoYW4gSlMgd2hlbiBkb2luZyByYXcgQ1BVLWludGVuc2l2ZSBzb3J0aW5nLiBIb3dldmVyLCB3aGVuIHVzaW5nIGFcbi8vIGN1c3RvbSBjb21wYXJhdG9yIGZ1bmN0aW9uLCBjYWxsaW5nIGJhY2sgYW5kIGZvcnRoIGJldHdlZW4gdGhlIFZNJ3MgQysrIGFuZFxuLy8gSklUJ2QgSlMgaXMgcmF0aGVyIHNsb3cgKmFuZCogbG9zZXMgSklUIHR5cGUgaW5mb3JtYXRpb24sIHJlc3VsdGluZyBpblxuLy8gd29yc2UgZ2VuZXJhdGVkIGNvZGUgZm9yIHRoZSBjb21wYXJhdG9yIGZ1bmN0aW9uIHRoYW4gd291bGQgYmUgb3B0aW1hbC4gSW5cbi8vIGZhY3QsIHdoZW4gc29ydGluZyB3aXRoIGEgY29tcGFyYXRvciwgdGhlc2UgY29zdHMgb3V0d2VpZ2ggdGhlIGJlbmVmaXRzIG9mXG4vLyBzb3J0aW5nIGluIEMrKy4gQnkgdXNpbmcgb3VyIG93biBKUy1pbXBsZW1lbnRlZCBRdWljayBTb3J0IChiZWxvdyksIHdlIGdldFxuLy8gYSB+MzUwMG1zIG1lYW4gc3BlZWQtdXAgaW4gYGJlbmNoL2JlbmNoLmh0bWxgLlxuXG4vKipcbiAqIFN3YXAgdGhlIGVsZW1lbnRzIGluZGV4ZWQgYnkgYHhgIGFuZCBgeWAgaW4gdGhlIGFycmF5IGBhcnlgLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IGFyeVxuICogICAgICAgIFRoZSBhcnJheS5cbiAqIEBwYXJhbSB7TnVtYmVyfSB4XG4gKiAgICAgICAgVGhlIGluZGV4IG9mIHRoZSBmaXJzdCBpdGVtLlxuICogQHBhcmFtIHtOdW1iZXJ9IHlcbiAqICAgICAgICBUaGUgaW5kZXggb2YgdGhlIHNlY29uZCBpdGVtLlxuICovXG5mdW5jdGlvbiBzd2FwKGFyeSwgeCwgeSkge1xuICB2YXIgdGVtcCA9IGFyeVt4XTtcbiAgYXJ5W3hdID0gYXJ5W3ldO1xuICBhcnlbeV0gPSB0ZW1wO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSByYW5kb20gaW50ZWdlciB3aXRoaW4gdGhlIHJhbmdlIGBsb3cgLi4gaGlnaGAgaW5jbHVzaXZlLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBsb3dcbiAqICAgICAgICBUaGUgbG93ZXIgYm91bmQgb24gdGhlIHJhbmdlLlxuICogQHBhcmFtIHtOdW1iZXJ9IGhpZ2hcbiAqICAgICAgICBUaGUgdXBwZXIgYm91bmQgb24gdGhlIHJhbmdlLlxuICovXG5mdW5jdGlvbiByYW5kb21JbnRJblJhbmdlKGxvdywgaGlnaCkge1xuICByZXR1cm4gTWF0aC5yb3VuZChsb3cgKyAoTWF0aC5yYW5kb20oKSAqIChoaWdoIC0gbG93KSkpO1xufVxuXG4vKipcbiAqIFRoZSBRdWljayBTb3J0IGFsZ29yaXRobS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBhcnlcbiAqICAgICAgICBBbiBhcnJheSB0byBzb3J0LlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY29tcGFyYXRvclxuICogICAgICAgIEZ1bmN0aW9uIHRvIHVzZSB0byBjb21wYXJlIHR3byBpdGVtcy5cbiAqIEBwYXJhbSB7TnVtYmVyfSBwXG4gKiAgICAgICAgU3RhcnQgaW5kZXggb2YgdGhlIGFycmF5XG4gKiBAcGFyYW0ge051bWJlcn0gclxuICogICAgICAgIEVuZCBpbmRleCBvZiB0aGUgYXJyYXlcbiAqL1xuZnVuY3Rpb24gZG9RdWlja1NvcnQoYXJ5LCBjb21wYXJhdG9yLCBwLCByKSB7XG4gIC8vIElmIG91ciBsb3dlciBib3VuZCBpcyBsZXNzIHRoYW4gb3VyIHVwcGVyIGJvdW5kLCB3ZSAoMSkgcGFydGl0aW9uIHRoZVxuICAvLyBhcnJheSBpbnRvIHR3byBwaWVjZXMgYW5kICgyKSByZWN1cnNlIG9uIGVhY2ggaGFsZi4gSWYgaXQgaXMgbm90LCB0aGlzIGlzXG4gIC8vIHRoZSBlbXB0eSBhcnJheSBhbmQgb3VyIGJhc2UgY2FzZS5cblxuICBpZiAocCA8IHIpIHtcbiAgICAvLyAoMSkgUGFydGl0aW9uaW5nLlxuICAgIC8vXG4gICAgLy8gVGhlIHBhcnRpdGlvbmluZyBjaG9vc2VzIGEgcGl2b3QgYmV0d2VlbiBgcGAgYW5kIGByYCBhbmQgbW92ZXMgYWxsXG4gICAgLy8gZWxlbWVudHMgdGhhdCBhcmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBwaXZvdCB0byB0aGUgYmVmb3JlIGl0LCBhbmRcbiAgICAvLyBhbGwgdGhlIGVsZW1lbnRzIHRoYXQgYXJlIGdyZWF0ZXIgdGhhbiBpdCBhZnRlciBpdC4gVGhlIGVmZmVjdCBpcyB0aGF0XG4gICAgLy8gb25jZSBwYXJ0aXRpb24gaXMgZG9uZSwgdGhlIHBpdm90IGlzIGluIHRoZSBleGFjdCBwbGFjZSBpdCB3aWxsIGJlIHdoZW5cbiAgICAvLyB0aGUgYXJyYXkgaXMgcHV0IGluIHNvcnRlZCBvcmRlciwgYW5kIGl0IHdpbGwgbm90IG5lZWQgdG8gYmUgbW92ZWRcbiAgICAvLyBhZ2Fpbi4gVGhpcyBydW5zIGluIE8obikgdGltZS5cblxuICAgIC8vIEFsd2F5cyBjaG9vc2UgYSByYW5kb20gcGl2b3Qgc28gdGhhdCBhbiBpbnB1dCBhcnJheSB3aGljaCBpcyByZXZlcnNlXG4gICAgLy8gc29ydGVkIGRvZXMgbm90IGNhdXNlIE8obl4yKSBydW5uaW5nIHRpbWUuXG4gICAgdmFyIHBpdm90SW5kZXggPSByYW5kb21JbnRJblJhbmdlKHAsIHIpO1xuICAgIHZhciBpID0gcCAtIDE7XG5cbiAgICBzd2FwKGFyeSwgcGl2b3RJbmRleCwgcik7XG4gICAgdmFyIHBpdm90ID0gYXJ5W3JdO1xuXG4gICAgLy8gSW1tZWRpYXRlbHkgYWZ0ZXIgYGpgIGlzIGluY3JlbWVudGVkIGluIHRoaXMgbG9vcCwgdGhlIGZvbGxvd2luZyBob2xkXG4gICAgLy8gdHJ1ZTpcbiAgICAvL1xuICAgIC8vICAgKiBFdmVyeSBlbGVtZW50IGluIGBhcnlbcCAuLiBpXWAgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBwaXZvdC5cbiAgICAvL1xuICAgIC8vICAgKiBFdmVyeSBlbGVtZW50IGluIGBhcnlbaSsxIC4uIGotMV1gIGlzIGdyZWF0ZXIgdGhhbiB0aGUgcGl2b3QuXG4gICAgZm9yICh2YXIgaiA9IHA7IGogPCByOyBqKyspIHtcbiAgICAgIGlmIChjb21wYXJhdG9yKGFyeVtqXSwgcGl2b3QpIDw9IDApIHtcbiAgICAgICAgaSArPSAxO1xuICAgICAgICBzd2FwKGFyeSwgaSwgaik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc3dhcChhcnksIGkgKyAxLCBqKTtcbiAgICB2YXIgcSA9IGkgKyAxO1xuXG4gICAgLy8gKDIpIFJlY3Vyc2Ugb24gZWFjaCBoYWxmLlxuXG4gICAgZG9RdWlja1NvcnQoYXJ5LCBjb21wYXJhdG9yLCBwLCBxIC0gMSk7XG4gICAgZG9RdWlja1NvcnQoYXJ5LCBjb21wYXJhdG9yLCBxICsgMSwgcik7XG4gIH1cbn1cblxuLyoqXG4gKiBTb3J0IHRoZSBnaXZlbiBhcnJheSBpbi1wbGFjZSB3aXRoIHRoZSBnaXZlbiBjb21wYXJhdG9yIGZ1bmN0aW9uLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IGFyeVxuICogICAgICAgIEFuIGFycmF5IHRvIHNvcnQuXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjb21wYXJhdG9yXG4gKiAgICAgICAgRnVuY3Rpb24gdG8gdXNlIHRvIGNvbXBhcmUgdHdvIGl0ZW1zLlxuICovXG5leHBvcnRzLnF1aWNrU29ydCA9IGZ1bmN0aW9uIChhcnksIGNvbXBhcmF0b3IpIHtcbiAgZG9RdWlja1NvcnQoYXJ5LCBjb21wYXJhdG9yLCAwLCBhcnkubGVuZ3RoIC0gMSk7XG59O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9saWIvcXVpY2stc29ydC5qc1xuLy8gbW9kdWxlIGlkID0gOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCIvKiAtKi0gTW9kZToganM7IGpzLWluZGVudC1sZXZlbDogMjsgLSotICovXG4vKlxuICogQ29weXJpZ2h0IDIwMTEgTW96aWxsYSBGb3VuZGF0aW9uIGFuZCBjb250cmlidXRvcnNcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBOZXcgQlNEIGxpY2Vuc2UuIFNlZSBMSUNFTlNFIG9yOlxuICogaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL0JTRC0zLUNsYXVzZVxuICovXG5cbnZhciBTb3VyY2VNYXBHZW5lcmF0b3IgPSByZXF1aXJlKCcuL3NvdXJjZS1tYXAtZ2VuZXJhdG9yJykuU291cmNlTWFwR2VuZXJhdG9yO1xudmFyIHV0aWwgPSByZXF1aXJlKCcuL3V0aWwnKTtcblxuLy8gTWF0Y2hlcyBhIFdpbmRvd3Mtc3R5bGUgYFxcclxcbmAgbmV3bGluZSBvciBhIGBcXG5gIG5ld2xpbmUgdXNlZCBieSBhbGwgb3RoZXJcbi8vIG9wZXJhdGluZyBzeXN0ZW1zIHRoZXNlIGRheXMgKGNhcHR1cmluZyB0aGUgcmVzdWx0KS5cbnZhciBSRUdFWF9ORVdMSU5FID0gLyhcXHI/XFxuKS87XG5cbi8vIE5ld2xpbmUgY2hhcmFjdGVyIGNvZGUgZm9yIGNoYXJDb2RlQXQoKSBjb21wYXJpc29uc1xudmFyIE5FV0xJTkVfQ09ERSA9IDEwO1xuXG4vLyBQcml2YXRlIHN5bWJvbCBmb3IgaWRlbnRpZnlpbmcgYFNvdXJjZU5vZGVgcyB3aGVuIG11bHRpcGxlIHZlcnNpb25zIG9mXG4vLyB0aGUgc291cmNlLW1hcCBsaWJyYXJ5IGFyZSBsb2FkZWQuIFRoaXMgTVVTVCBOT1QgQ0hBTkdFIGFjcm9zc1xuLy8gdmVyc2lvbnMhXG52YXIgaXNTb3VyY2VOb2RlID0gXCIkJCRpc1NvdXJjZU5vZGUkJCRcIjtcblxuLyoqXG4gKiBTb3VyY2VOb2RlcyBwcm92aWRlIGEgd2F5IHRvIGFic3RyYWN0IG92ZXIgaW50ZXJwb2xhdGluZy9jb25jYXRlbmF0aW5nXG4gKiBzbmlwcGV0cyBvZiBnZW5lcmF0ZWQgSmF2YVNjcmlwdCBzb3VyY2UgY29kZSB3aGlsZSBtYWludGFpbmluZyB0aGUgbGluZSBhbmRcbiAqIGNvbHVtbiBpbmZvcm1hdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhlIG9yaWdpbmFsIHNvdXJjZSBjb2RlLlxuICpcbiAqIEBwYXJhbSBhTGluZSBUaGUgb3JpZ2luYWwgbGluZSBudW1iZXIuXG4gKiBAcGFyYW0gYUNvbHVtbiBUaGUgb3JpZ2luYWwgY29sdW1uIG51bWJlci5cbiAqIEBwYXJhbSBhU291cmNlIFRoZSBvcmlnaW5hbCBzb3VyY2UncyBmaWxlbmFtZS5cbiAqIEBwYXJhbSBhQ2h1bmtzIE9wdGlvbmFsLiBBbiBhcnJheSBvZiBzdHJpbmdzIHdoaWNoIGFyZSBzbmlwcGV0cyBvZlxuICogICAgICAgIGdlbmVyYXRlZCBKUywgb3Igb3RoZXIgU291cmNlTm9kZXMuXG4gKiBAcGFyYW0gYU5hbWUgVGhlIG9yaWdpbmFsIGlkZW50aWZpZXIuXG4gKi9cbmZ1bmN0aW9uIFNvdXJjZU5vZGUoYUxpbmUsIGFDb2x1bW4sIGFTb3VyY2UsIGFDaHVua3MsIGFOYW1lKSB7XG4gIHRoaXMuY2hpbGRyZW4gPSBbXTtcbiAgdGhpcy5zb3VyY2VDb250ZW50cyA9IHt9O1xuICB0aGlzLmxpbmUgPSBhTGluZSA9PSBudWxsID8gbnVsbCA6IGFMaW5lO1xuICB0aGlzLmNvbHVtbiA9IGFDb2x1bW4gPT0gbnVsbCA/IG51bGwgOiBhQ29sdW1uO1xuICB0aGlzLnNvdXJjZSA9IGFTb3VyY2UgPT0gbnVsbCA/IG51bGwgOiBhU291cmNlO1xuICB0aGlzLm5hbWUgPSBhTmFtZSA9PSBudWxsID8gbnVsbCA6IGFOYW1lO1xuICB0aGlzW2lzU291cmNlTm9kZV0gPSB0cnVlO1xuICBpZiAoYUNodW5rcyAhPSBudWxsKSB0aGlzLmFkZChhQ2h1bmtzKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgU291cmNlTm9kZSBmcm9tIGdlbmVyYXRlZCBjb2RlIGFuZCBhIFNvdXJjZU1hcENvbnN1bWVyLlxuICpcbiAqIEBwYXJhbSBhR2VuZXJhdGVkQ29kZSBUaGUgZ2VuZXJhdGVkIGNvZGVcbiAqIEBwYXJhbSBhU291cmNlTWFwQ29uc3VtZXIgVGhlIFNvdXJjZU1hcCBmb3IgdGhlIGdlbmVyYXRlZCBjb2RlXG4gKiBAcGFyYW0gYVJlbGF0aXZlUGF0aCBPcHRpb25hbC4gVGhlIHBhdGggdGhhdCByZWxhdGl2ZSBzb3VyY2VzIGluIHRoZVxuICogICAgICAgIFNvdXJjZU1hcENvbnN1bWVyIHNob3VsZCBiZSByZWxhdGl2ZSB0by5cbiAqL1xuU291cmNlTm9kZS5mcm9tU3RyaW5nV2l0aFNvdXJjZU1hcCA9XG4gIGZ1bmN0aW9uIFNvdXJjZU5vZGVfZnJvbVN0cmluZ1dpdGhTb3VyY2VNYXAoYUdlbmVyYXRlZENvZGUsIGFTb3VyY2VNYXBDb25zdW1lciwgYVJlbGF0aXZlUGF0aCkge1xuICAgIC8vIFRoZSBTb3VyY2VOb2RlIHdlIHdhbnQgdG8gZmlsbCB3aXRoIHRoZSBnZW5lcmF0ZWQgY29kZVxuICAgIC8vIGFuZCB0aGUgU291cmNlTWFwXG4gICAgdmFyIG5vZGUgPSBuZXcgU291cmNlTm9kZSgpO1xuXG4gICAgLy8gQWxsIGV2ZW4gaW5kaWNlcyBvZiB0aGlzIGFycmF5IGFyZSBvbmUgbGluZSBvZiB0aGUgZ2VuZXJhdGVkIGNvZGUsXG4gICAgLy8gd2hpbGUgYWxsIG9kZCBpbmRpY2VzIGFyZSB0aGUgbmV3bGluZXMgYmV0d2VlbiB0d28gYWRqYWNlbnQgbGluZXNcbiAgICAvLyAoc2luY2UgYFJFR0VYX05FV0xJTkVgIGNhcHR1cmVzIGl0cyBtYXRjaCkuXG4gICAgLy8gUHJvY2Vzc2VkIGZyYWdtZW50cyBhcmUgYWNjZXNzZWQgYnkgY2FsbGluZyBgc2hpZnROZXh0TGluZWAuXG4gICAgdmFyIHJlbWFpbmluZ0xpbmVzID0gYUdlbmVyYXRlZENvZGUuc3BsaXQoUkVHRVhfTkVXTElORSk7XG4gICAgdmFyIHJlbWFpbmluZ0xpbmVzSW5kZXggPSAwO1xuICAgIHZhciBzaGlmdE5leHRMaW5lID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgbGluZUNvbnRlbnRzID0gZ2V0TmV4dExpbmUoKTtcbiAgICAgIC8vIFRoZSBsYXN0IGxpbmUgb2YgYSBmaWxlIG1pZ2h0IG5vdCBoYXZlIGEgbmV3bGluZS5cbiAgICAgIHZhciBuZXdMaW5lID0gZ2V0TmV4dExpbmUoKSB8fCBcIlwiO1xuICAgICAgcmV0dXJuIGxpbmVDb250ZW50cyArIG5ld0xpbmU7XG5cbiAgICAgIGZ1bmN0aW9uIGdldE5leHRMaW5lKCkge1xuICAgICAgICByZXR1cm4gcmVtYWluaW5nTGluZXNJbmRleCA8IHJlbWFpbmluZ0xpbmVzLmxlbmd0aCA/XG4gICAgICAgICAgICByZW1haW5pbmdMaW5lc1tyZW1haW5pbmdMaW5lc0luZGV4KytdIDogdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBXZSBuZWVkIHRvIHJlbWVtYmVyIHRoZSBwb3NpdGlvbiBvZiBcInJlbWFpbmluZ0xpbmVzXCJcbiAgICB2YXIgbGFzdEdlbmVyYXRlZExpbmUgPSAxLCBsYXN0R2VuZXJhdGVkQ29sdW1uID0gMDtcblxuICAgIC8vIFRoZSBnZW5lcmF0ZSBTb3VyY2VOb2RlcyB3ZSBuZWVkIGEgY29kZSByYW5nZS5cbiAgICAvLyBUbyBleHRyYWN0IGl0IGN1cnJlbnQgYW5kIGxhc3QgbWFwcGluZyBpcyB1c2VkLlxuICAgIC8vIEhlcmUgd2Ugc3RvcmUgdGhlIGxhc3QgbWFwcGluZy5cbiAgICB2YXIgbGFzdE1hcHBpbmcgPSBudWxsO1xuXG4gICAgYVNvdXJjZU1hcENvbnN1bWVyLmVhY2hNYXBwaW5nKGZ1bmN0aW9uIChtYXBwaW5nKSB7XG4gICAgICBpZiAobGFzdE1hcHBpbmcgIT09IG51bGwpIHtcbiAgICAgICAgLy8gV2UgYWRkIHRoZSBjb2RlIGZyb20gXCJsYXN0TWFwcGluZ1wiIHRvIFwibWFwcGluZ1wiOlxuICAgICAgICAvLyBGaXJzdCBjaGVjayBpZiB0aGVyZSBpcyBhIG5ldyBsaW5lIGluIGJldHdlZW4uXG4gICAgICAgIGlmIChsYXN0R2VuZXJhdGVkTGluZSA8IG1hcHBpbmcuZ2VuZXJhdGVkTGluZSkge1xuICAgICAgICAgIC8vIEFzc29jaWF0ZSBmaXJzdCBsaW5lIHdpdGggXCJsYXN0TWFwcGluZ1wiXG4gICAgICAgICAgYWRkTWFwcGluZ1dpdGhDb2RlKGxhc3RNYXBwaW5nLCBzaGlmdE5leHRMaW5lKCkpO1xuICAgICAgICAgIGxhc3RHZW5lcmF0ZWRMaW5lKys7XG4gICAgICAgICAgbGFzdEdlbmVyYXRlZENvbHVtbiA9IDA7XG4gICAgICAgICAgLy8gVGhlIHJlbWFpbmluZyBjb2RlIGlzIGFkZGVkIHdpdGhvdXQgbWFwcGluZ1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFRoZXJlIGlzIG5vIG5ldyBsaW5lIGluIGJldHdlZW4uXG4gICAgICAgICAgLy8gQXNzb2NpYXRlIHRoZSBjb2RlIGJldHdlZW4gXCJsYXN0R2VuZXJhdGVkQ29sdW1uXCIgYW5kXG4gICAgICAgICAgLy8gXCJtYXBwaW5nLmdlbmVyYXRlZENvbHVtblwiIHdpdGggXCJsYXN0TWFwcGluZ1wiXG4gICAgICAgICAgdmFyIG5leHRMaW5lID0gcmVtYWluaW5nTGluZXNbcmVtYWluaW5nTGluZXNJbmRleF0gfHwgJyc7XG4gICAgICAgICAgdmFyIGNvZGUgPSBuZXh0TGluZS5zdWJzdHIoMCwgbWFwcGluZy5nZW5lcmF0ZWRDb2x1bW4gLVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RHZW5lcmF0ZWRDb2x1bW4pO1xuICAgICAgICAgIHJlbWFpbmluZ0xpbmVzW3JlbWFpbmluZ0xpbmVzSW5kZXhdID0gbmV4dExpbmUuc3Vic3RyKG1hcHBpbmcuZ2VuZXJhdGVkQ29sdW1uIC1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0R2VuZXJhdGVkQ29sdW1uKTtcbiAgICAgICAgICBsYXN0R2VuZXJhdGVkQ29sdW1uID0gbWFwcGluZy5nZW5lcmF0ZWRDb2x1bW47XG4gICAgICAgICAgYWRkTWFwcGluZ1dpdGhDb2RlKGxhc3RNYXBwaW5nLCBjb2RlKTtcbiAgICAgICAgICAvLyBObyBtb3JlIHJlbWFpbmluZyBjb2RlLCBjb250aW51ZVxuICAgICAgICAgIGxhc3RNYXBwaW5nID0gbWFwcGluZztcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIFdlIGFkZCB0aGUgZ2VuZXJhdGVkIGNvZGUgdW50aWwgdGhlIGZpcnN0IG1hcHBpbmdcbiAgICAgIC8vIHRvIHRoZSBTb3VyY2VOb2RlIHdpdGhvdXQgYW55IG1hcHBpbmcuXG4gICAgICAvLyBFYWNoIGxpbmUgaXMgYWRkZWQgYXMgc2VwYXJhdGUgc3RyaW5nLlxuICAgICAgd2hpbGUgKGxhc3RHZW5lcmF0ZWRMaW5lIDwgbWFwcGluZy5nZW5lcmF0ZWRMaW5lKSB7XG4gICAgICAgIG5vZGUuYWRkKHNoaWZ0TmV4dExpbmUoKSk7XG4gICAgICAgIGxhc3RHZW5lcmF0ZWRMaW5lKys7XG4gICAgICB9XG4gICAgICBpZiAobGFzdEdlbmVyYXRlZENvbHVtbiA8IG1hcHBpbmcuZ2VuZXJhdGVkQ29sdW1uKSB7XG4gICAgICAgIHZhciBuZXh0TGluZSA9IHJlbWFpbmluZ0xpbmVzW3JlbWFpbmluZ0xpbmVzSW5kZXhdIHx8ICcnO1xuICAgICAgICBub2RlLmFkZChuZXh0TGluZS5zdWJzdHIoMCwgbWFwcGluZy5nZW5lcmF0ZWRDb2x1bW4pKTtcbiAgICAgICAgcmVtYWluaW5nTGluZXNbcmVtYWluaW5nTGluZXNJbmRleF0gPSBuZXh0TGluZS5zdWJzdHIobWFwcGluZy5nZW5lcmF0ZWRDb2x1bW4pO1xuICAgICAgICBsYXN0R2VuZXJhdGVkQ29sdW1uID0gbWFwcGluZy5nZW5lcmF0ZWRDb2x1bW47XG4gICAgICB9XG4gICAgICBsYXN0TWFwcGluZyA9IG1hcHBpbmc7XG4gICAgfSwgdGhpcyk7XG4gICAgLy8gV2UgaGF2ZSBwcm9jZXNzZWQgYWxsIG1hcHBpbmdzLlxuICAgIGlmIChyZW1haW5pbmdMaW5lc0luZGV4IDwgcmVtYWluaW5nTGluZXMubGVuZ3RoKSB7XG4gICAgICBpZiAobGFzdE1hcHBpbmcpIHtcbiAgICAgICAgLy8gQXNzb2NpYXRlIHRoZSByZW1haW5pbmcgY29kZSBpbiB0aGUgY3VycmVudCBsaW5lIHdpdGggXCJsYXN0TWFwcGluZ1wiXG4gICAgICAgIGFkZE1hcHBpbmdXaXRoQ29kZShsYXN0TWFwcGluZywgc2hpZnROZXh0TGluZSgpKTtcbiAgICAgIH1cbiAgICAgIC8vIGFuZCBhZGQgdGhlIHJlbWFpbmluZyBsaW5lcyB3aXRob3V0IGFueSBtYXBwaW5nXG4gICAgICBub2RlLmFkZChyZW1haW5pbmdMaW5lcy5zcGxpY2UocmVtYWluaW5nTGluZXNJbmRleCkuam9pbihcIlwiKSk7XG4gICAgfVxuXG4gICAgLy8gQ29weSBzb3VyY2VzQ29udGVudCBpbnRvIFNvdXJjZU5vZGVcbiAgICBhU291cmNlTWFwQ29uc3VtZXIuc291cmNlcy5mb3JFYWNoKGZ1bmN0aW9uIChzb3VyY2VGaWxlKSB7XG4gICAgICB2YXIgY29udGVudCA9IGFTb3VyY2VNYXBDb25zdW1lci5zb3VyY2VDb250ZW50Rm9yKHNvdXJjZUZpbGUpO1xuICAgICAgaWYgKGNvbnRlbnQgIT0gbnVsbCkge1xuICAgICAgICBpZiAoYVJlbGF0aXZlUGF0aCAhPSBudWxsKSB7XG4gICAgICAgICAgc291cmNlRmlsZSA9IHV0aWwuam9pbihhUmVsYXRpdmVQYXRoLCBzb3VyY2VGaWxlKTtcbiAgICAgICAgfVxuICAgICAgICBub2RlLnNldFNvdXJjZUNvbnRlbnQoc291cmNlRmlsZSwgY29udGVudCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gbm9kZTtcblxuICAgIGZ1bmN0aW9uIGFkZE1hcHBpbmdXaXRoQ29kZShtYXBwaW5nLCBjb2RlKSB7XG4gICAgICBpZiAobWFwcGluZyA9PT0gbnVsbCB8fCBtYXBwaW5nLnNvdXJjZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIG5vZGUuYWRkKGNvZGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHNvdXJjZSA9IGFSZWxhdGl2ZVBhdGhcbiAgICAgICAgICA/IHV0aWwuam9pbihhUmVsYXRpdmVQYXRoLCBtYXBwaW5nLnNvdXJjZSlcbiAgICAgICAgICA6IG1hcHBpbmcuc291cmNlO1xuICAgICAgICBub2RlLmFkZChuZXcgU291cmNlTm9kZShtYXBwaW5nLm9yaWdpbmFsTGluZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwcGluZy5vcmlnaW5hbENvbHVtbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXBwaW5nLm5hbWUpKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbi8qKlxuICogQWRkIGEgY2h1bmsgb2YgZ2VuZXJhdGVkIEpTIHRvIHRoaXMgc291cmNlIG5vZGUuXG4gKlxuICogQHBhcmFtIGFDaHVuayBBIHN0cmluZyBzbmlwcGV0IG9mIGdlbmVyYXRlZCBKUyBjb2RlLCBhbm90aGVyIGluc3RhbmNlIG9mXG4gKiAgICAgICAgU291cmNlTm9kZSwgb3IgYW4gYXJyYXkgd2hlcmUgZWFjaCBtZW1iZXIgaXMgb25lIG9mIHRob3NlIHRoaW5ncy5cbiAqL1xuU291cmNlTm9kZS5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gU291cmNlTm9kZV9hZGQoYUNodW5rKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGFDaHVuaykpIHtcbiAgICBhQ2h1bmsuZm9yRWFjaChmdW5jdGlvbiAoY2h1bmspIHtcbiAgICAgIHRoaXMuYWRkKGNodW5rKTtcbiAgICB9LCB0aGlzKTtcbiAgfVxuICBlbHNlIGlmIChhQ2h1bmtbaXNTb3VyY2VOb2RlXSB8fCB0eXBlb2YgYUNodW5rID09PSBcInN0cmluZ1wiKSB7XG4gICAgaWYgKGFDaHVuaykge1xuICAgICAgdGhpcy5jaGlsZHJlbi5wdXNoKGFDaHVuayk7XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICBcIkV4cGVjdGVkIGEgU291cmNlTm9kZSwgc3RyaW5nLCBvciBhbiBhcnJheSBvZiBTb3VyY2VOb2RlcyBhbmQgc3RyaW5ncy4gR290IFwiICsgYUNodW5rXG4gICAgKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQWRkIGEgY2h1bmsgb2YgZ2VuZXJhdGVkIEpTIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhpcyBzb3VyY2Ugbm9kZS5cbiAqXG4gKiBAcGFyYW0gYUNodW5rIEEgc3RyaW5nIHNuaXBwZXQgb2YgZ2VuZXJhdGVkIEpTIGNvZGUsIGFub3RoZXIgaW5zdGFuY2Ugb2ZcbiAqICAgICAgICBTb3VyY2VOb2RlLCBvciBhbiBhcnJheSB3aGVyZSBlYWNoIG1lbWJlciBpcyBvbmUgb2YgdGhvc2UgdGhpbmdzLlxuICovXG5Tb3VyY2VOb2RlLnByb3RvdHlwZS5wcmVwZW5kID0gZnVuY3Rpb24gU291cmNlTm9kZV9wcmVwZW5kKGFDaHVuaykge1xuICBpZiAoQXJyYXkuaXNBcnJheShhQ2h1bmspKSB7XG4gICAgZm9yICh2YXIgaSA9IGFDaHVuay5sZW5ndGgtMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHRoaXMucHJlcGVuZChhQ2h1bmtbaV0pO1xuICAgIH1cbiAgfVxuICBlbHNlIGlmIChhQ2h1bmtbaXNTb3VyY2VOb2RlXSB8fCB0eXBlb2YgYUNodW5rID09PSBcInN0cmluZ1wiKSB7XG4gICAgdGhpcy5jaGlsZHJlbi51bnNoaWZ0KGFDaHVuayk7XG4gIH1cbiAgZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgIFwiRXhwZWN0ZWQgYSBTb3VyY2VOb2RlLCBzdHJpbmcsIG9yIGFuIGFycmF5IG9mIFNvdXJjZU5vZGVzIGFuZCBzdHJpbmdzLiBHb3QgXCIgKyBhQ2h1bmtcbiAgICApO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBXYWxrIG92ZXIgdGhlIHRyZWUgb2YgSlMgc25pcHBldHMgaW4gdGhpcyBub2RlIGFuZCBpdHMgY2hpbGRyZW4uIFRoZVxuICogd2Fsa2luZyBmdW5jdGlvbiBpcyBjYWxsZWQgb25jZSBmb3IgZWFjaCBzbmlwcGV0IG9mIEpTIGFuZCBpcyBwYXNzZWQgdGhhdFxuICogc25pcHBldCBhbmQgdGhlIGl0cyBvcmlnaW5hbCBhc3NvY2lhdGVkIHNvdXJjZSdzIGxpbmUvY29sdW1uIGxvY2F0aW9uLlxuICpcbiAqIEBwYXJhbSBhRm4gVGhlIHRyYXZlcnNhbCBmdW5jdGlvbi5cbiAqL1xuU291cmNlTm9kZS5wcm90b3R5cGUud2FsayA9IGZ1bmN0aW9uIFNvdXJjZU5vZGVfd2FsayhhRm4pIHtcbiAgdmFyIGNodW5rO1xuICBmb3IgKHZhciBpID0gMCwgbGVuID0gdGhpcy5jaGlsZHJlbi5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGNodW5rID0gdGhpcy5jaGlsZHJlbltpXTtcbiAgICBpZiAoY2h1bmtbaXNTb3VyY2VOb2RlXSkge1xuICAgICAgY2h1bmsud2FsayhhRm4pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGlmIChjaHVuayAhPT0gJycpIHtcbiAgICAgICAgYUZuKGNodW5rLCB7IHNvdXJjZTogdGhpcy5zb3VyY2UsXG4gICAgICAgICAgICAgICAgICAgICBsaW5lOiB0aGlzLmxpbmUsXG4gICAgICAgICAgICAgICAgICAgICBjb2x1bW46IHRoaXMuY29sdW1uLFxuICAgICAgICAgICAgICAgICAgICAgbmFtZTogdGhpcy5uYW1lIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBMaWtlIGBTdHJpbmcucHJvdG90eXBlLmpvaW5gIGV4Y2VwdCBmb3IgU291cmNlTm9kZXMuIEluc2VydHMgYGFTdHJgIGJldHdlZW5cbiAqIGVhY2ggb2YgYHRoaXMuY2hpbGRyZW5gLlxuICpcbiAqIEBwYXJhbSBhU2VwIFRoZSBzZXBhcmF0b3IuXG4gKi9cblNvdXJjZU5vZGUucHJvdG90eXBlLmpvaW4gPSBmdW5jdGlvbiBTb3VyY2VOb2RlX2pvaW4oYVNlcCkge1xuICB2YXIgbmV3Q2hpbGRyZW47XG4gIHZhciBpO1xuICB2YXIgbGVuID0gdGhpcy5jaGlsZHJlbi5sZW5ndGg7XG4gIGlmIChsZW4gPiAwKSB7XG4gICAgbmV3Q2hpbGRyZW4gPSBbXTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuLTE7IGkrKykge1xuICAgICAgbmV3Q2hpbGRyZW4ucHVzaCh0aGlzLmNoaWxkcmVuW2ldKTtcbiAgICAgIG5ld0NoaWxkcmVuLnB1c2goYVNlcCk7XG4gICAgfVxuICAgIG5ld0NoaWxkcmVuLnB1c2godGhpcy5jaGlsZHJlbltpXSk7XG4gICAgdGhpcy5jaGlsZHJlbiA9IG5ld0NoaWxkcmVuO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBDYWxsIFN0cmluZy5wcm90b3R5cGUucmVwbGFjZSBvbiB0aGUgdmVyeSByaWdodC1tb3N0IHNvdXJjZSBzbmlwcGV0LiBVc2VmdWxcbiAqIGZvciB0cmltbWluZyB3aGl0ZXNwYWNlIGZyb20gdGhlIGVuZCBvZiBhIHNvdXJjZSBub2RlLCBldGMuXG4gKlxuICogQHBhcmFtIGFQYXR0ZXJuIFRoZSBwYXR0ZXJuIHRvIHJlcGxhY2UuXG4gKiBAcGFyYW0gYVJlcGxhY2VtZW50IFRoZSB0aGluZyB0byByZXBsYWNlIHRoZSBwYXR0ZXJuIHdpdGguXG4gKi9cblNvdXJjZU5vZGUucHJvdG90eXBlLnJlcGxhY2VSaWdodCA9IGZ1bmN0aW9uIFNvdXJjZU5vZGVfcmVwbGFjZVJpZ2h0KGFQYXR0ZXJuLCBhUmVwbGFjZW1lbnQpIHtcbiAgdmFyIGxhc3RDaGlsZCA9IHRoaXMuY2hpbGRyZW5bdGhpcy5jaGlsZHJlbi5sZW5ndGggLSAxXTtcbiAgaWYgKGxhc3RDaGlsZFtpc1NvdXJjZU5vZGVdKSB7XG4gICAgbGFzdENoaWxkLnJlcGxhY2VSaWdodChhUGF0dGVybiwgYVJlcGxhY2VtZW50KTtcbiAgfVxuICBlbHNlIGlmICh0eXBlb2YgbGFzdENoaWxkID09PSAnc3RyaW5nJykge1xuICAgIHRoaXMuY2hpbGRyZW5bdGhpcy5jaGlsZHJlbi5sZW5ndGggLSAxXSA9IGxhc3RDaGlsZC5yZXBsYWNlKGFQYXR0ZXJuLCBhUmVwbGFjZW1lbnQpO1xuICB9XG4gIGVsc2Uge1xuICAgIHRoaXMuY2hpbGRyZW4ucHVzaCgnJy5yZXBsYWNlKGFQYXR0ZXJuLCBhUmVwbGFjZW1lbnQpKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IHRoZSBzb3VyY2UgY29udGVudCBmb3IgYSBzb3VyY2UgZmlsZS4gVGhpcyB3aWxsIGJlIGFkZGVkIHRvIHRoZSBTb3VyY2VNYXBHZW5lcmF0b3JcbiAqIGluIHRoZSBzb3VyY2VzQ29udGVudCBmaWVsZC5cbiAqXG4gKiBAcGFyYW0gYVNvdXJjZUZpbGUgVGhlIGZpbGVuYW1lIG9mIHRoZSBzb3VyY2UgZmlsZVxuICogQHBhcmFtIGFTb3VyY2VDb250ZW50IFRoZSBjb250ZW50IG9mIHRoZSBzb3VyY2UgZmlsZVxuICovXG5Tb3VyY2VOb2RlLnByb3RvdHlwZS5zZXRTb3VyY2VDb250ZW50ID1cbiAgZnVuY3Rpb24gU291cmNlTm9kZV9zZXRTb3VyY2VDb250ZW50KGFTb3VyY2VGaWxlLCBhU291cmNlQ29udGVudCkge1xuICAgIHRoaXMuc291cmNlQ29udGVudHNbdXRpbC50b1NldFN0cmluZyhhU291cmNlRmlsZSldID0gYVNvdXJjZUNvbnRlbnQ7XG4gIH07XG5cbi8qKlxuICogV2FsayBvdmVyIHRoZSB0cmVlIG9mIFNvdXJjZU5vZGVzLiBUaGUgd2Fsa2luZyBmdW5jdGlvbiBpcyBjYWxsZWQgZm9yIGVhY2hcbiAqIHNvdXJjZSBmaWxlIGNvbnRlbnQgYW5kIGlzIHBhc3NlZCB0aGUgZmlsZW5hbWUgYW5kIHNvdXJjZSBjb250ZW50LlxuICpcbiAqIEBwYXJhbSBhRm4gVGhlIHRyYXZlcnNhbCBmdW5jdGlvbi5cbiAqL1xuU291cmNlTm9kZS5wcm90b3R5cGUud2Fsa1NvdXJjZUNvbnRlbnRzID1cbiAgZnVuY3Rpb24gU291cmNlTm9kZV93YWxrU291cmNlQ29udGVudHMoYUZuKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGlmICh0aGlzLmNoaWxkcmVuW2ldW2lzU291cmNlTm9kZV0pIHtcbiAgICAgICAgdGhpcy5jaGlsZHJlbltpXS53YWxrU291cmNlQ29udGVudHMoYUZuKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgc291cmNlcyA9IE9iamVjdC5rZXlzKHRoaXMuc291cmNlQ29udGVudHMpO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBzb3VyY2VzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBhRm4odXRpbC5mcm9tU2V0U3RyaW5nKHNvdXJjZXNbaV0pLCB0aGlzLnNvdXJjZUNvbnRlbnRzW3NvdXJjZXNbaV1dKTtcbiAgICB9XG4gIH07XG5cbi8qKlxuICogUmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBzb3VyY2Ugbm9kZS4gV2Fsa3Mgb3ZlciB0aGUgdHJlZVxuICogYW5kIGNvbmNhdGVuYXRlcyBhbGwgdGhlIHZhcmlvdXMgc25pcHBldHMgdG9nZXRoZXIgdG8gb25lIHN0cmluZy5cbiAqL1xuU291cmNlTm9kZS5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiBTb3VyY2VOb2RlX3RvU3RyaW5nKCkge1xuICB2YXIgc3RyID0gXCJcIjtcbiAgdGhpcy53YWxrKGZ1bmN0aW9uIChjaHVuaykge1xuICAgIHN0ciArPSBjaHVuaztcbiAgfSk7XG4gIHJldHVybiBzdHI7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHNvdXJjZSBub2RlIGFsb25nIHdpdGggYSBzb3VyY2VcbiAqIG1hcC5cbiAqL1xuU291cmNlTm9kZS5wcm90b3R5cGUudG9TdHJpbmdXaXRoU291cmNlTWFwID0gZnVuY3Rpb24gU291cmNlTm9kZV90b1N0cmluZ1dpdGhTb3VyY2VNYXAoYUFyZ3MpIHtcbiAgdmFyIGdlbmVyYXRlZCA9IHtcbiAgICBjb2RlOiBcIlwiLFxuICAgIGxpbmU6IDEsXG4gICAgY29sdW1uOiAwXG4gIH07XG4gIHZhciBtYXAgPSBuZXcgU291cmNlTWFwR2VuZXJhdG9yKGFBcmdzKTtcbiAgdmFyIHNvdXJjZU1hcHBpbmdBY3RpdmUgPSBmYWxzZTtcbiAgdmFyIGxhc3RPcmlnaW5hbFNvdXJjZSA9IG51bGw7XG4gIHZhciBsYXN0T3JpZ2luYWxMaW5lID0gbnVsbDtcbiAgdmFyIGxhc3RPcmlnaW5hbENvbHVtbiA9IG51bGw7XG4gIHZhciBsYXN0T3JpZ2luYWxOYW1lID0gbnVsbDtcbiAgdGhpcy53YWxrKGZ1bmN0aW9uIChjaHVuaywgb3JpZ2luYWwpIHtcbiAgICBnZW5lcmF0ZWQuY29kZSArPSBjaHVuaztcbiAgICBpZiAob3JpZ2luYWwuc291cmNlICE9PSBudWxsXG4gICAgICAgICYmIG9yaWdpbmFsLmxpbmUgIT09IG51bGxcbiAgICAgICAgJiYgb3JpZ2luYWwuY29sdW1uICE9PSBudWxsKSB7XG4gICAgICBpZihsYXN0T3JpZ2luYWxTb3VyY2UgIT09IG9yaWdpbmFsLnNvdXJjZVxuICAgICAgICAgfHwgbGFzdE9yaWdpbmFsTGluZSAhPT0gb3JpZ2luYWwubGluZVxuICAgICAgICAgfHwgbGFzdE9yaWdpbmFsQ29sdW1uICE9PSBvcmlnaW5hbC5jb2x1bW5cbiAgICAgICAgIHx8IGxhc3RPcmlnaW5hbE5hbWUgIT09IG9yaWdpbmFsLm5hbWUpIHtcbiAgICAgICAgbWFwLmFkZE1hcHBpbmcoe1xuICAgICAgICAgIHNvdXJjZTogb3JpZ2luYWwuc291cmNlLFxuICAgICAgICAgIG9yaWdpbmFsOiB7XG4gICAgICAgICAgICBsaW5lOiBvcmlnaW5hbC5saW5lLFxuICAgICAgICAgICAgY29sdW1uOiBvcmlnaW5hbC5jb2x1bW5cbiAgICAgICAgICB9LFxuICAgICAgICAgIGdlbmVyYXRlZDoge1xuICAgICAgICAgICAgbGluZTogZ2VuZXJhdGVkLmxpbmUsXG4gICAgICAgICAgICBjb2x1bW46IGdlbmVyYXRlZC5jb2x1bW5cbiAgICAgICAgICB9LFxuICAgICAgICAgIG5hbWU6IG9yaWdpbmFsLm5hbWVcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBsYXN0T3JpZ2luYWxTb3VyY2UgPSBvcmlnaW5hbC5zb3VyY2U7XG4gICAgICBsYXN0T3JpZ2luYWxMaW5lID0gb3JpZ2luYWwubGluZTtcbiAgICAgIGxhc3RPcmlnaW5hbENvbHVtbiA9IG9yaWdpbmFsLmNvbHVtbjtcbiAgICAgIGxhc3RPcmlnaW5hbE5hbWUgPSBvcmlnaW5hbC5uYW1lO1xuICAgICAgc291cmNlTWFwcGluZ0FjdGl2ZSA9IHRydWU7XG4gICAgfSBlbHNlIGlmIChzb3VyY2VNYXBwaW5nQWN0aXZlKSB7XG4gICAgICBtYXAuYWRkTWFwcGluZyh7XG4gICAgICAgIGdlbmVyYXRlZDoge1xuICAgICAgICAgIGxpbmU6IGdlbmVyYXRlZC5saW5lLFxuICAgICAgICAgIGNvbHVtbjogZ2VuZXJhdGVkLmNvbHVtblxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGxhc3RPcmlnaW5hbFNvdXJjZSA9IG51bGw7XG4gICAgICBzb3VyY2VNYXBwaW5nQWN0aXZlID0gZmFsc2U7XG4gICAgfVxuICAgIGZvciAodmFyIGlkeCA9IDAsIGxlbmd0aCA9IGNodW5rLmxlbmd0aDsgaWR4IDwgbGVuZ3RoOyBpZHgrKykge1xuICAgICAgaWYgKGNodW5rLmNoYXJDb2RlQXQoaWR4KSA9PT0gTkVXTElORV9DT0RFKSB7XG4gICAgICAgIGdlbmVyYXRlZC5saW5lKys7XG4gICAgICAgIGdlbmVyYXRlZC5jb2x1bW4gPSAwO1xuICAgICAgICAvLyBNYXBwaW5ncyBlbmQgYXQgZW9sXG4gICAgICAgIGlmIChpZHggKyAxID09PSBsZW5ndGgpIHtcbiAgICAgICAgICBsYXN0T3JpZ2luYWxTb3VyY2UgPSBudWxsO1xuICAgICAgICAgIHNvdXJjZU1hcHBpbmdBY3RpdmUgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIGlmIChzb3VyY2VNYXBwaW5nQWN0aXZlKSB7XG4gICAgICAgICAgbWFwLmFkZE1hcHBpbmcoe1xuICAgICAgICAgICAgc291cmNlOiBvcmlnaW5hbC5zb3VyY2UsXG4gICAgICAgICAgICBvcmlnaW5hbDoge1xuICAgICAgICAgICAgICBsaW5lOiBvcmlnaW5hbC5saW5lLFxuICAgICAgICAgICAgICBjb2x1bW46IG9yaWdpbmFsLmNvbHVtblxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdlbmVyYXRlZDoge1xuICAgICAgICAgICAgICBsaW5lOiBnZW5lcmF0ZWQubGluZSxcbiAgICAgICAgICAgICAgY29sdW1uOiBnZW5lcmF0ZWQuY29sdW1uXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbmFtZTogb3JpZ2luYWwubmFtZVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBnZW5lcmF0ZWQuY29sdW1uKys7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgdGhpcy53YWxrU291cmNlQ29udGVudHMoZnVuY3Rpb24gKHNvdXJjZUZpbGUsIHNvdXJjZUNvbnRlbnQpIHtcbiAgICBtYXAuc2V0U291cmNlQ29udGVudChzb3VyY2VGaWxlLCBzb3VyY2VDb250ZW50KTtcbiAgfSk7XG5cbiAgcmV0dXJuIHsgY29kZTogZ2VuZXJhdGVkLmNvZGUsIG1hcDogbWFwIH07XG59O1xuXG5leHBvcnRzLlNvdXJjZU5vZGUgPSBTb3VyY2VOb2RlO1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9saWIvc291cmNlLW5vZGUuanNcbi8vIG1vZHVsZSBpZCA9IDEwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0= \ No newline at end of file diff --git a/node_modules/source-map/dist/source-map.js b/node_modules/source-map/dist/source-map.js new file mode 100644 index 0000000..b4eb087 --- /dev/null +++ b/node_modules/source-map/dist/source-map.js @@ -0,0 +1,3233 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["sourceMap"] = factory(); + else + root["sourceMap"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + + /* + * Copyright 2009-2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE.txt or: + * http://opensource.org/licenses/BSD-3-Clause + */ + exports.SourceMapGenerator = __webpack_require__(1).SourceMapGenerator; + exports.SourceMapConsumer = __webpack_require__(7).SourceMapConsumer; + exports.SourceNode = __webpack_require__(10).SourceNode; + + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var base64VLQ = __webpack_require__(2); + var util = __webpack_require__(4); + var ArraySet = __webpack_require__(5).ArraySet; + var MappingList = __webpack_require__(6).MappingList; + + /** + * An instance of the SourceMapGenerator represents a source map which is + * being built incrementally. You may pass an object with the following + * properties: + * + * - file: The filename of the generated source. + * - sourceRoot: A root for all relative URLs in this source map. + */ + function SourceMapGenerator(aArgs) { + if (!aArgs) { + aArgs = {}; + } + this._file = util.getArg(aArgs, 'file', null); + this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); + this._skipValidation = util.getArg(aArgs, 'skipValidation', false); + this._sources = new ArraySet(); + this._names = new ArraySet(); + this._mappings = new MappingList(); + this._sourcesContents = null; + } + + SourceMapGenerator.prototype._version = 3; + + /** + * Creates a new SourceMapGenerator based on a SourceMapConsumer + * + * @param aSourceMapConsumer The SourceMap. + */ + SourceMapGenerator.fromSourceMap = + function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { + var sourceRoot = aSourceMapConsumer.sourceRoot; + var generator = new SourceMapGenerator({ + file: aSourceMapConsumer.file, + sourceRoot: sourceRoot + }); + aSourceMapConsumer.eachMapping(function (mapping) { + var newMapping = { + generated: { + line: mapping.generatedLine, + column: mapping.generatedColumn + } + }; + + if (mapping.source != null) { + newMapping.source = mapping.source; + if (sourceRoot != null) { + newMapping.source = util.relative(sourceRoot, newMapping.source); + } + + newMapping.original = { + line: mapping.originalLine, + column: mapping.originalColumn + }; + + if (mapping.name != null) { + newMapping.name = mapping.name; + } + } + + generator.addMapping(newMapping); + }); + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var sourceRelative = sourceFile; + if (sourceRoot !== null) { + sourceRelative = util.relative(sourceRoot, sourceFile); + } + + if (!generator._sources.has(sourceRelative)) { + generator._sources.add(sourceRelative); + } + + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + generator.setSourceContent(sourceFile, content); + } + }); + return generator; + }; + + /** + * Add a single mapping from original source line and column to the generated + * source's line and column for this source map being created. The mapping + * object should have the following properties: + * + * - generated: An object with the generated line and column positions. + * - original: An object with the original line and column positions. + * - source: The original source file (relative to the sourceRoot). + * - name: An optional original token name for this mapping. + */ + SourceMapGenerator.prototype.addMapping = + function SourceMapGenerator_addMapping(aArgs) { + var generated = util.getArg(aArgs, 'generated'); + var original = util.getArg(aArgs, 'original', null); + var source = util.getArg(aArgs, 'source', null); + var name = util.getArg(aArgs, 'name', null); + + if (!this._skipValidation) { + this._validateMapping(generated, original, source, name); + } + + if (source != null) { + source = String(source); + if (!this._sources.has(source)) { + this._sources.add(source); + } + } + + if (name != null) { + name = String(name); + if (!this._names.has(name)) { + this._names.add(name); + } + } + + this._mappings.add({ + generatedLine: generated.line, + generatedColumn: generated.column, + originalLine: original != null && original.line, + originalColumn: original != null && original.column, + source: source, + name: name + }); + }; + + /** + * Set the source content for a source file. + */ + SourceMapGenerator.prototype.setSourceContent = + function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { + var source = aSourceFile; + if (this._sourceRoot != null) { + source = util.relative(this._sourceRoot, source); + } + + if (aSourceContent != null) { + // Add the source content to the _sourcesContents map. + // Create a new _sourcesContents map if the property is null. + if (!this._sourcesContents) { + this._sourcesContents = Object.create(null); + } + this._sourcesContents[util.toSetString(source)] = aSourceContent; + } else if (this._sourcesContents) { + // Remove the source file from the _sourcesContents map. + // If the _sourcesContents map is empty, set the property to null. + delete this._sourcesContents[util.toSetString(source)]; + if (Object.keys(this._sourcesContents).length === 0) { + this._sourcesContents = null; + } + } + }; + + /** + * Applies the mappings of a sub-source-map for a specific source file to the + * source map being generated. Each mapping to the supplied source file is + * rewritten using the supplied source map. Note: The resolution for the + * resulting mappings is the minimium of this map and the supplied map. + * + * @param aSourceMapConsumer The source map to be applied. + * @param aSourceFile Optional. The filename of the source file. + * If omitted, SourceMapConsumer's file property will be used. + * @param aSourceMapPath Optional. The dirname of the path to the source map + * to be applied. If relative, it is relative to the SourceMapConsumer. + * This parameter is needed when the two source maps aren't in the same + * directory, and the source map to be applied contains relative source + * paths. If so, those relative source paths need to be rewritten + * relative to the SourceMapGenerator. + */ + SourceMapGenerator.prototype.applySourceMap = + function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { + var sourceFile = aSourceFile; + // If aSourceFile is omitted, we will use the file property of the SourceMap + if (aSourceFile == null) { + if (aSourceMapConsumer.file == null) { + throw new Error( + 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + + 'or the source map\'s "file" property. Both were omitted.' + ); + } + sourceFile = aSourceMapConsumer.file; + } + var sourceRoot = this._sourceRoot; + // Make "sourceFile" relative if an absolute Url is passed. + if (sourceRoot != null) { + sourceFile = util.relative(sourceRoot, sourceFile); + } + // Applying the SourceMap can add and remove items from the sources and + // the names array. + var newSources = new ArraySet(); + var newNames = new ArraySet(); + + // Find mappings for the "sourceFile" + this._mappings.unsortedForEach(function (mapping) { + if (mapping.source === sourceFile && mapping.originalLine != null) { + // Check if it can be mapped by the source map, then update the mapping. + var original = aSourceMapConsumer.originalPositionFor({ + line: mapping.originalLine, + column: mapping.originalColumn + }); + if (original.source != null) { + // Copy mapping + mapping.source = original.source; + if (aSourceMapPath != null) { + mapping.source = util.join(aSourceMapPath, mapping.source) + } + if (sourceRoot != null) { + mapping.source = util.relative(sourceRoot, mapping.source); + } + mapping.originalLine = original.line; + mapping.originalColumn = original.column; + if (original.name != null) { + mapping.name = original.name; + } + } + } + + var source = mapping.source; + if (source != null && !newSources.has(source)) { + newSources.add(source); + } + + var name = mapping.name; + if (name != null && !newNames.has(name)) { + newNames.add(name); + } + + }, this); + this._sources = newSources; + this._names = newNames; + + // Copy sourcesContents of applied map. + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aSourceMapPath != null) { + sourceFile = util.join(aSourceMapPath, sourceFile); + } + if (sourceRoot != null) { + sourceFile = util.relative(sourceRoot, sourceFile); + } + this.setSourceContent(sourceFile, content); + } + }, this); + }; + + /** + * A mapping can have one of the three levels of data: + * + * 1. Just the generated position. + * 2. The Generated position, original position, and original source. + * 3. Generated and original position, original source, as well as a name + * token. + * + * To maintain consistency, we validate that any new mapping being added falls + * in to one of these categories. + */ + SourceMapGenerator.prototype._validateMapping = + function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, + aName) { + // When aOriginal is truthy but has empty values for .line and .column, + // it is most likely a programmer error. In this case we throw a very + // specific error message to try to guide them the right way. + // For example: https://github.com/Polymer/polymer-bundler/pull/519 + if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') { + throw new Error( + 'original.line and original.column are not numbers -- you probably meant to omit ' + + 'the original mapping entirely and only map the generated position. If so, pass ' + + 'null for the original mapping instead of an object with empty or null values.' + ); + } + + if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aGenerated.line > 0 && aGenerated.column >= 0 + && !aOriginal && !aSource && !aName) { + // Case 1. + return; + } + else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aOriginal && 'line' in aOriginal && 'column' in aOriginal + && aGenerated.line > 0 && aGenerated.column >= 0 + && aOriginal.line > 0 && aOriginal.column >= 0 + && aSource) { + // Cases 2 and 3. + return; + } + else { + throw new Error('Invalid mapping: ' + JSON.stringify({ + generated: aGenerated, + source: aSource, + original: aOriginal, + name: aName + })); + } + }; + + /** + * Serialize the accumulated mappings in to the stream of base 64 VLQs + * specified by the source map format. + */ + SourceMapGenerator.prototype._serializeMappings = + function SourceMapGenerator_serializeMappings() { + var previousGeneratedColumn = 0; + var previousGeneratedLine = 1; + var previousOriginalColumn = 0; + var previousOriginalLine = 0; + var previousName = 0; + var previousSource = 0; + var result = ''; + var next; + var mapping; + var nameIdx; + var sourceIdx; + + var mappings = this._mappings.toArray(); + for (var i = 0, len = mappings.length; i < len; i++) { + mapping = mappings[i]; + next = '' + + if (mapping.generatedLine !== previousGeneratedLine) { + previousGeneratedColumn = 0; + while (mapping.generatedLine !== previousGeneratedLine) { + next += ';'; + previousGeneratedLine++; + } + } + else { + if (i > 0) { + if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) { + continue; + } + next += ','; + } + } + + next += base64VLQ.encode(mapping.generatedColumn + - previousGeneratedColumn); + previousGeneratedColumn = mapping.generatedColumn; + + if (mapping.source != null) { + sourceIdx = this._sources.indexOf(mapping.source); + next += base64VLQ.encode(sourceIdx - previousSource); + previousSource = sourceIdx; + + // lines are stored 0-based in SourceMap spec version 3 + next += base64VLQ.encode(mapping.originalLine - 1 + - previousOriginalLine); + previousOriginalLine = mapping.originalLine - 1; + + next += base64VLQ.encode(mapping.originalColumn + - previousOriginalColumn); + previousOriginalColumn = mapping.originalColumn; + + if (mapping.name != null) { + nameIdx = this._names.indexOf(mapping.name); + next += base64VLQ.encode(nameIdx - previousName); + previousName = nameIdx; + } + } + + result += next; + } + + return result; + }; + + SourceMapGenerator.prototype._generateSourcesContent = + function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { + return aSources.map(function (source) { + if (!this._sourcesContents) { + return null; + } + if (aSourceRoot != null) { + source = util.relative(aSourceRoot, source); + } + var key = util.toSetString(source); + return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) + ? this._sourcesContents[key] + : null; + }, this); + }; + + /** + * Externalize the source map. + */ + SourceMapGenerator.prototype.toJSON = + function SourceMapGenerator_toJSON() { + var map = { + version: this._version, + sources: this._sources.toArray(), + names: this._names.toArray(), + mappings: this._serializeMappings() + }; + if (this._file != null) { + map.file = this._file; + } + if (this._sourceRoot != null) { + map.sourceRoot = this._sourceRoot; + } + if (this._sourcesContents) { + map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); + } + + return map; + }; + + /** + * Render the source map being generated to a string. + */ + SourceMapGenerator.prototype.toString = + function SourceMapGenerator_toString() { + return JSON.stringify(this.toJSON()); + }; + + exports.SourceMapGenerator = SourceMapGenerator; + + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + * + * Based on the Base 64 VLQ implementation in Closure Compiler: + * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java + * + * Copyright 2011 The Closure Compiler Authors. All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + */ + + var base64 = __webpack_require__(3); + + // A single base 64 digit can contain 6 bits of data. For the base 64 variable + // length quantities we use in the source map spec, the first bit is the sign, + // the next four bits are the actual value, and the 6th bit is the + // continuation bit. The continuation bit tells us whether there are more + // digits in this value following this digit. + // + // Continuation + // | Sign + // | | + // V V + // 101011 + + var VLQ_BASE_SHIFT = 5; + + // binary: 100000 + var VLQ_BASE = 1 << VLQ_BASE_SHIFT; + + // binary: 011111 + var VLQ_BASE_MASK = VLQ_BASE - 1; + + // binary: 100000 + var VLQ_CONTINUATION_BIT = VLQ_BASE; + + /** + * Converts from a two-complement value to a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) + * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) + */ + function toVLQSigned(aValue) { + return aValue < 0 + ? ((-aValue) << 1) + 1 + : (aValue << 1) + 0; + } + + /** + * Converts to a two-complement value from a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 + * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 + */ + function fromVLQSigned(aValue) { + var isNegative = (aValue & 1) === 1; + var shifted = aValue >> 1; + return isNegative + ? -shifted + : shifted; + } + + /** + * Returns the base 64 VLQ encoded value. + */ + exports.encode = function base64VLQ_encode(aValue) { + var encoded = ""; + var digit; + + var vlq = toVLQSigned(aValue); + + do { + digit = vlq & VLQ_BASE_MASK; + vlq >>>= VLQ_BASE_SHIFT; + if (vlq > 0) { + // There are still more digits in this value, so we must make sure the + // continuation bit is marked. + digit |= VLQ_CONTINUATION_BIT; + } + encoded += base64.encode(digit); + } while (vlq > 0); + + return encoded; + }; + + /** + * Decodes the next base 64 VLQ value from the given string and returns the + * value and the rest of the string via the out parameter. + */ + exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { + var strLen = aStr.length; + var result = 0; + var shift = 0; + var continuation, digit; + + do { + if (aIndex >= strLen) { + throw new Error("Expected more digits in base 64 VLQ value."); + } + + digit = base64.decode(aStr.charCodeAt(aIndex++)); + if (digit === -1) { + throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); + } + + continuation = !!(digit & VLQ_CONTINUATION_BIT); + digit &= VLQ_BASE_MASK; + result = result + (digit << shift); + shift += VLQ_BASE_SHIFT; + } while (continuation); + + aOutParam.value = fromVLQSigned(result); + aOutParam.rest = aIndex; + }; + + +/***/ }), +/* 3 */ +/***/ (function(module, exports) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); + + /** + * Encode an integer in the range of 0 to 63 to a single base 64 digit. + */ + exports.encode = function (number) { + if (0 <= number && number < intToCharMap.length) { + return intToCharMap[number]; + } + throw new TypeError("Must be between 0 and 63: " + number); + }; + + /** + * Decode a single base 64 character code digit to an integer. Returns -1 on + * failure. + */ + exports.decode = function (charCode) { + var bigA = 65; // 'A' + var bigZ = 90; // 'Z' + + var littleA = 97; // 'a' + var littleZ = 122; // 'z' + + var zero = 48; // '0' + var nine = 57; // '9' + + var plus = 43; // '+' + var slash = 47; // '/' + + var littleOffset = 26; + var numberOffset = 52; + + // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ + if (bigA <= charCode && charCode <= bigZ) { + return (charCode - bigA); + } + + // 26 - 51: abcdefghijklmnopqrstuvwxyz + if (littleA <= charCode && charCode <= littleZ) { + return (charCode - littleA + littleOffset); + } + + // 52 - 61: 0123456789 + if (zero <= charCode && charCode <= nine) { + return (charCode - zero + numberOffset); + } + + // 62: + + if (charCode == plus) { + return 62; + } + + // 63: / + if (charCode == slash) { + return 63; + } + + // Invalid base64 digit. + return -1; + }; + + +/***/ }), +/* 4 */ +/***/ (function(module, exports) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + /** + * This is a helper function for getting values from parameter/options + * objects. + * + * @param args The object we are extracting values from + * @param name The name of the property we are getting. + * @param defaultValue An optional value to return if the property is missing + * from the object. If this is not specified and the property is missing, an + * error will be thrown. + */ + function getArg(aArgs, aName, aDefaultValue) { + if (aName in aArgs) { + return aArgs[aName]; + } else if (arguments.length === 3) { + return aDefaultValue; + } else { + throw new Error('"' + aName + '" is a required argument.'); + } + } + exports.getArg = getArg; + + var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/; + var dataUrlRegexp = /^data:.+\,.+$/; + + function urlParse(aUrl) { + var match = aUrl.match(urlRegexp); + if (!match) { + return null; + } + return { + scheme: match[1], + auth: match[2], + host: match[3], + port: match[4], + path: match[5] + }; + } + exports.urlParse = urlParse; + + function urlGenerate(aParsedUrl) { + var url = ''; + if (aParsedUrl.scheme) { + url += aParsedUrl.scheme + ':'; + } + url += '//'; + if (aParsedUrl.auth) { + url += aParsedUrl.auth + '@'; + } + if (aParsedUrl.host) { + url += aParsedUrl.host; + } + if (aParsedUrl.port) { + url += ":" + aParsedUrl.port + } + if (aParsedUrl.path) { + url += aParsedUrl.path; + } + return url; + } + exports.urlGenerate = urlGenerate; + + /** + * Normalizes a path, or the path portion of a URL: + * + * - Replaces consecutive slashes with one slash. + * - Removes unnecessary '.' parts. + * - Removes unnecessary '/..' parts. + * + * Based on code in the Node.js 'path' core module. + * + * @param aPath The path or url to normalize. + */ + function normalize(aPath) { + var path = aPath; + var url = urlParse(aPath); + if (url) { + if (!url.path) { + return aPath; + } + path = url.path; + } + var isAbsolute = exports.isAbsolute(path); + + var parts = path.split(/\/+/); + for (var part, up = 0, i = parts.length - 1; i >= 0; i--) { + part = parts[i]; + if (part === '.') { + parts.splice(i, 1); + } else if (part === '..') { + up++; + } else if (up > 0) { + if (part === '') { + // The first part is blank if the path is absolute. Trying to go + // above the root is a no-op. Therefore we can remove all '..' parts + // directly after the root. + parts.splice(i + 1, up); + up = 0; + } else { + parts.splice(i, 2); + up--; + } + } + } + path = parts.join('/'); + + if (path === '') { + path = isAbsolute ? '/' : '.'; + } + + if (url) { + url.path = path; + return urlGenerate(url); + } + return path; + } + exports.normalize = normalize; + + /** + * Joins two paths/URLs. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be joined with the root. + * + * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a + * scheme-relative URL: Then the scheme of aRoot, if any, is prepended + * first. + * - Otherwise aPath is a path. If aRoot is a URL, then its path portion + * is updated with the result and aRoot is returned. Otherwise the result + * is returned. + * - If aPath is absolute, the result is aPath. + * - Otherwise the two paths are joined with a slash. + * - Joining for example 'http://' and 'www.example.com' is also supported. + */ + function join(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + if (aPath === "") { + aPath = "."; + } + var aPathUrl = urlParse(aPath); + var aRootUrl = urlParse(aRoot); + if (aRootUrl) { + aRoot = aRootUrl.path || '/'; + } + + // `join(foo, '//www.example.org')` + if (aPathUrl && !aPathUrl.scheme) { + if (aRootUrl) { + aPathUrl.scheme = aRootUrl.scheme; + } + return urlGenerate(aPathUrl); + } + + if (aPathUrl || aPath.match(dataUrlRegexp)) { + return aPath; + } + + // `join('http://', 'www.example.com')` + if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { + aRootUrl.host = aPath; + return urlGenerate(aRootUrl); + } + + var joined = aPath.charAt(0) === '/' + ? aPath + : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); + + if (aRootUrl) { + aRootUrl.path = joined; + return urlGenerate(aRootUrl); + } + return joined; + } + exports.join = join; + + exports.isAbsolute = function (aPath) { + return aPath.charAt(0) === '/' || urlRegexp.test(aPath); + }; + + /** + * Make a path relative to a URL or another path. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be made relative to aRoot. + */ + function relative(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + + aRoot = aRoot.replace(/\/$/, ''); + + // It is possible for the path to be above the root. In this case, simply + // checking whether the root is a prefix of the path won't work. Instead, we + // need to remove components from the root one by one, until either we find + // a prefix that fits, or we run out of components to remove. + var level = 0; + while (aPath.indexOf(aRoot + '/') !== 0) { + var index = aRoot.lastIndexOf("/"); + if (index < 0) { + return aPath; + } + + // If the only part of the root that is left is the scheme (i.e. http://, + // file:///, etc.), one or more slashes (/), or simply nothing at all, we + // have exhausted all components, so the path is not relative to the root. + aRoot = aRoot.slice(0, index); + if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { + return aPath; + } + + ++level; + } + + // Make sure we add a "../" for each component we removed from the root. + return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); + } + exports.relative = relative; + + var supportsNullProto = (function () { + var obj = Object.create(null); + return !('__proto__' in obj); + }()); + + function identity (s) { + return s; + } + + /** + * Because behavior goes wacky when you set `__proto__` on objects, we + * have to prefix all the strings in our set with an arbitrary character. + * + * See https://github.com/mozilla/source-map/pull/31 and + * https://github.com/mozilla/source-map/issues/30 + * + * @param String aStr + */ + function toSetString(aStr) { + if (isProtoString(aStr)) { + return '$' + aStr; + } + + return aStr; + } + exports.toSetString = supportsNullProto ? identity : toSetString; + + function fromSetString(aStr) { + if (isProtoString(aStr)) { + return aStr.slice(1); + } + + return aStr; + } + exports.fromSetString = supportsNullProto ? identity : fromSetString; + + function isProtoString(s) { + if (!s) { + return false; + } + + var length = s.length; + + if (length < 9 /* "__proto__".length */) { + return false; + } + + if (s.charCodeAt(length - 1) !== 95 /* '_' */ || + s.charCodeAt(length - 2) !== 95 /* '_' */ || + s.charCodeAt(length - 3) !== 111 /* 'o' */ || + s.charCodeAt(length - 4) !== 116 /* 't' */ || + s.charCodeAt(length - 5) !== 111 /* 'o' */ || + s.charCodeAt(length - 6) !== 114 /* 'r' */ || + s.charCodeAt(length - 7) !== 112 /* 'p' */ || + s.charCodeAt(length - 8) !== 95 /* '_' */ || + s.charCodeAt(length - 9) !== 95 /* '_' */) { + return false; + } + + for (var i = length - 10; i >= 0; i--) { + if (s.charCodeAt(i) !== 36 /* '$' */) { + return false; + } + } + + return true; + } + + /** + * Comparator between two mappings where the original positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same original source/line/column, but different generated + * line and column the same. Useful when searching for a mapping with a + * stubbed out mapping. + */ + function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { + var cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0 || onlyCompareOriginal) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + return strcmp(mappingA.name, mappingB.name); + } + exports.compareByOriginalPositions = compareByOriginalPositions; + + /** + * Comparator between two mappings with deflated source and name indices where + * the generated positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same generated line and column, but different + * source/name/original line and column the same. Useful when searching for a + * mapping with a stubbed out mapping. + */ + function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0 || onlyCompareGenerated) { + return cmp; + } + + cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return strcmp(mappingA.name, mappingB.name); + } + exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; + + function strcmp(aStr1, aStr2) { + if (aStr1 === aStr2) { + return 0; + } + + if (aStr1 === null) { + return 1; // aStr2 !== null + } + + if (aStr2 === null) { + return -1; // aStr1 !== null + } + + if (aStr1 > aStr2) { + return 1; + } + + return -1; + } + + /** + * Comparator between two mappings with inflated source and name strings where + * the generated positions are compared. + */ + function compareByGeneratedPositionsInflated(mappingA, mappingB) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return strcmp(mappingA.name, mappingB.name); + } + exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; + + /** + * Strip any JSON XSSI avoidance prefix from the string (as documented + * in the source maps specification), and then parse the string as + * JSON. + */ + function parseSourceMapInput(str) { + return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, '')); + } + exports.parseSourceMapInput = parseSourceMapInput; + + /** + * Compute the URL of a source given the the source root, the source's + * URL, and the source map's URL. + */ + function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) { + sourceURL = sourceURL || ''; + + if (sourceRoot) { + // This follows what Chrome does. + if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') { + sourceRoot += '/'; + } + // The spec says: + // Line 4: An optional source root, useful for relocating source + // files on a server or removing repeated values in the + // “sources” entry. This value is prepended to the individual + // entries in the “source” field. + sourceURL = sourceRoot + sourceURL; + } + + // Historically, SourceMapConsumer did not take the sourceMapURL as + // a parameter. This mode is still somewhat supported, which is why + // this code block is conditional. However, it's preferable to pass + // the source map URL to SourceMapConsumer, so that this function + // can implement the source URL resolution algorithm as outlined in + // the spec. This block is basically the equivalent of: + // new URL(sourceURL, sourceMapURL).toString() + // ... except it avoids using URL, which wasn't available in the + // older releases of node still supported by this library. + // + // The spec says: + // If the sources are not absolute URLs after prepending of the + // “sourceRoot”, the sources are resolved relative to the + // SourceMap (like resolving script src in a html document). + if (sourceMapURL) { + var parsed = urlParse(sourceMapURL); + if (!parsed) { + throw new Error("sourceMapURL could not be parsed"); + } + if (parsed.path) { + // Strip the last path component, but keep the "/". + var index = parsed.path.lastIndexOf('/'); + if (index >= 0) { + parsed.path = parsed.path.substring(0, index + 1); + } + } + sourceURL = join(urlGenerate(parsed), sourceURL); + } + + return normalize(sourceURL); + } + exports.computeSourceURL = computeSourceURL; + + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var util = __webpack_require__(4); + var has = Object.prototype.hasOwnProperty; + var hasNativeMap = typeof Map !== "undefined"; + + /** + * A data structure which is a combination of an array and a set. Adding a new + * member is O(1), testing for membership is O(1), and finding the index of an + * element is O(1). Removing elements from the set is not supported. Only + * strings are supported for membership. + */ + function ArraySet() { + this._array = []; + this._set = hasNativeMap ? new Map() : Object.create(null); + } + + /** + * Static method for creating ArraySet instances from an existing array. + */ + ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { + var set = new ArraySet(); + for (var i = 0, len = aArray.length; i < len; i++) { + set.add(aArray[i], aAllowDuplicates); + } + return set; + }; + + /** + * Return how many unique items are in this ArraySet. If duplicates have been + * added, than those do not count towards the size. + * + * @returns Number + */ + ArraySet.prototype.size = function ArraySet_size() { + return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length; + }; + + /** + * Add the given string to this set. + * + * @param String aStr + */ + ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { + var sStr = hasNativeMap ? aStr : util.toSetString(aStr); + var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr); + var idx = this._array.length; + if (!isDuplicate || aAllowDuplicates) { + this._array.push(aStr); + } + if (!isDuplicate) { + if (hasNativeMap) { + this._set.set(aStr, idx); + } else { + this._set[sStr] = idx; + } + } + }; + + /** + * Is the given string a member of this set? + * + * @param String aStr + */ + ArraySet.prototype.has = function ArraySet_has(aStr) { + if (hasNativeMap) { + return this._set.has(aStr); + } else { + var sStr = util.toSetString(aStr); + return has.call(this._set, sStr); + } + }; + + /** + * What is the index of the given string in the array? + * + * @param String aStr + */ + ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) { + if (hasNativeMap) { + var idx = this._set.get(aStr); + if (idx >= 0) { + return idx; + } + } else { + var sStr = util.toSetString(aStr); + if (has.call(this._set, sStr)) { + return this._set[sStr]; + } + } + + throw new Error('"' + aStr + '" is not in the set.'); + }; + + /** + * What is the element at the given index? + * + * @param Number aIdx + */ + ArraySet.prototype.at = function ArraySet_at(aIdx) { + if (aIdx >= 0 && aIdx < this._array.length) { + return this._array[aIdx]; + } + throw new Error('No element indexed by ' + aIdx); + }; + + /** + * Returns the array representation of this set (which has the proper indices + * indicated by indexOf). Note that this is a copy of the internal array used + * for storing the members so that no one can mess with internal state. + */ + ArraySet.prototype.toArray = function ArraySet_toArray() { + return this._array.slice(); + }; + + exports.ArraySet = ArraySet; + + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2014 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var util = __webpack_require__(4); + + /** + * Determine whether mappingB is after mappingA with respect to generated + * position. + */ + function generatedPositionAfter(mappingA, mappingB) { + // Optimized for most common case + var lineA = mappingA.generatedLine; + var lineB = mappingB.generatedLine; + var columnA = mappingA.generatedColumn; + var columnB = mappingB.generatedColumn; + return lineB > lineA || lineB == lineA && columnB >= columnA || + util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0; + } + + /** + * A data structure to provide a sorted view of accumulated mappings in a + * performance conscious manner. It trades a neglibable overhead in general + * case for a large speedup in case of mappings being added in order. + */ + function MappingList() { + this._array = []; + this._sorted = true; + // Serves as infimum + this._last = {generatedLine: -1, generatedColumn: 0}; + } + + /** + * Iterate through internal items. This method takes the same arguments that + * `Array.prototype.forEach` takes. + * + * NOTE: The order of the mappings is NOT guaranteed. + */ + MappingList.prototype.unsortedForEach = + function MappingList_forEach(aCallback, aThisArg) { + this._array.forEach(aCallback, aThisArg); + }; + + /** + * Add the given source mapping. + * + * @param Object aMapping + */ + MappingList.prototype.add = function MappingList_add(aMapping) { + if (generatedPositionAfter(this._last, aMapping)) { + this._last = aMapping; + this._array.push(aMapping); + } else { + this._sorted = false; + this._array.push(aMapping); + } + }; + + /** + * Returns the flat, sorted array of mappings. The mappings are sorted by + * generated position. + * + * WARNING: This method returns internal data without copying, for + * performance. The return value must NOT be mutated, and should be treated as + * an immutable borrow. If you want to take ownership, you must make your own + * copy. + */ + MappingList.prototype.toArray = function MappingList_toArray() { + if (!this._sorted) { + this._array.sort(util.compareByGeneratedPositionsInflated); + this._sorted = true; + } + return this._array; + }; + + exports.MappingList = MappingList; + + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var util = __webpack_require__(4); + var binarySearch = __webpack_require__(8); + var ArraySet = __webpack_require__(5).ArraySet; + var base64VLQ = __webpack_require__(2); + var quickSort = __webpack_require__(9).quickSort; + + function SourceMapConsumer(aSourceMap, aSourceMapURL) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = util.parseSourceMapInput(aSourceMap); + } + + return sourceMap.sections != null + ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL) + : new BasicSourceMapConsumer(sourceMap, aSourceMapURL); + } + + SourceMapConsumer.fromSourceMap = function(aSourceMap, aSourceMapURL) { + return BasicSourceMapConsumer.fromSourceMap(aSourceMap, aSourceMapURL); + } + + /** + * The version of the source mapping spec that we are consuming. + */ + SourceMapConsumer.prototype._version = 3; + + // `__generatedMappings` and `__originalMappings` are arrays that hold the + // parsed mapping coordinates from the source map's "mappings" attribute. They + // are lazily instantiated, accessed via the `_generatedMappings` and + // `_originalMappings` getters respectively, and we only parse the mappings + // and create these arrays once queried for a source location. We jump through + // these hoops because there can be many thousands of mappings, and parsing + // them is expensive, so we only want to do it if we must. + // + // Each object in the arrays is of the form: + // + // { + // generatedLine: The line number in the generated code, + // generatedColumn: The column number in the generated code, + // source: The path to the original source file that generated this + // chunk of code, + // originalLine: The line number in the original source that + // corresponds to this chunk of generated code, + // originalColumn: The column number in the original source that + // corresponds to this chunk of generated code, + // name: The name of the original symbol which generated this chunk of + // code. + // } + // + // All properties except for `generatedLine` and `generatedColumn` can be + // `null`. + // + // `_generatedMappings` is ordered by the generated positions. + // + // `_originalMappings` is ordered by the original positions. + + SourceMapConsumer.prototype.__generatedMappings = null; + Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', { + configurable: true, + enumerable: true, + get: function () { + if (!this.__generatedMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__generatedMappings; + } + }); + + SourceMapConsumer.prototype.__originalMappings = null; + Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { + configurable: true, + enumerable: true, + get: function () { + if (!this.__originalMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__originalMappings; + } + }); + + SourceMapConsumer.prototype._charIsMappingSeparator = + function SourceMapConsumer_charIsMappingSeparator(aStr, index) { + var c = aStr.charAt(index); + return c === ";" || c === ","; + }; + + /** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ + SourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + throw new Error("Subclasses must implement _parseMappings"); + }; + + SourceMapConsumer.GENERATED_ORDER = 1; + SourceMapConsumer.ORIGINAL_ORDER = 2; + + SourceMapConsumer.GREATEST_LOWER_BOUND = 1; + SourceMapConsumer.LEAST_UPPER_BOUND = 2; + + /** + * Iterate over each mapping between an original source/line/column and a + * generated line/column in this source map. + * + * @param Function aCallback + * The function that is called with each mapping. + * @param Object aContext + * Optional. If specified, this object will be the value of `this` every + * time that `aCallback` is called. + * @param aOrder + * Either `SourceMapConsumer.GENERATED_ORDER` or + * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to + * iterate over the mappings sorted by the generated file's line/column + * order or the original's source/line/column order, respectively. Defaults to + * `SourceMapConsumer.GENERATED_ORDER`. + */ + SourceMapConsumer.prototype.eachMapping = + function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { + var context = aContext || null; + var order = aOrder || SourceMapConsumer.GENERATED_ORDER; + + var mappings; + switch (order) { + case SourceMapConsumer.GENERATED_ORDER: + mappings = this._generatedMappings; + break; + case SourceMapConsumer.ORIGINAL_ORDER: + mappings = this._originalMappings; + break; + default: + throw new Error("Unknown order of iteration."); + } + + var sourceRoot = this.sourceRoot; + mappings.map(function (mapping) { + var source = mapping.source === null ? null : this._sources.at(mapping.source); + source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL); + return { + source: source, + generatedLine: mapping.generatedLine, + generatedColumn: mapping.generatedColumn, + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: mapping.name === null ? null : this._names.at(mapping.name) + }; + }, this).forEach(aCallback, context); + }; + + /** + * Returns all generated line and column information for the original source, + * line, and column provided. If no column is provided, returns all mappings + * corresponding to a either the line we are searching for or the next + * closest line that has any mappings. Otherwise, returns all mappings + * corresponding to the given line and either the column we are searching for + * or the next closest column that has any offsets. + * + * The only argument is an object with the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. The line number is 1-based. + * - column: Optional. the column number in the original source. + * The column number is 0-based. + * + * and an array of objects is returned, each with the following properties: + * + * - line: The line number in the generated source, or null. The + * line number is 1-based. + * - column: The column number in the generated source, or null. + * The column number is 0-based. + */ + SourceMapConsumer.prototype.allGeneratedPositionsFor = + function SourceMapConsumer_allGeneratedPositionsFor(aArgs) { + var line = util.getArg(aArgs, 'line'); + + // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping + // returns the index of the closest mapping less than the needle. By + // setting needle.originalColumn to 0, we thus find the last mapping for + // the given line, provided such a mapping exists. + var needle = { + source: util.getArg(aArgs, 'source'), + originalLine: line, + originalColumn: util.getArg(aArgs, 'column', 0) + }; + + needle.source = this._findSourceIndex(needle.source); + if (needle.source < 0) { + return []; + } + + var mappings = []; + + var index = this._findMapping(needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + binarySearch.LEAST_UPPER_BOUND); + if (index >= 0) { + var mapping = this._originalMappings[index]; + + if (aArgs.column === undefined) { + var originalLine = mapping.originalLine; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we found. Since + // mappings are sorted, this is guaranteed to find all mappings for + // the line we found. + while (mapping && mapping.originalLine === originalLine) { + mappings.push({ + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } + } else { + var originalColumn = mapping.originalColumn; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we were searching for. + // Since mappings are sorted, this is guaranteed to find all mappings for + // the line we are searching for. + while (mapping && + mapping.originalLine === line && + mapping.originalColumn == originalColumn) { + mappings.push({ + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } + } + } + + return mappings; + }; + + exports.SourceMapConsumer = SourceMapConsumer; + + /** + * A BasicSourceMapConsumer instance represents a parsed source map which we can + * query for information about the original file positions by giving it a file + * position in the generated source. + * + * The first parameter is the raw source map (either as a JSON string, or + * already parsed to an object). According to the spec, source maps have the + * following attributes: + * + * - version: Which version of the source map spec this map is following. + * - sources: An array of URLs to the original source files. + * - names: An array of identifiers which can be referrenced by individual mappings. + * - sourceRoot: Optional. The URL root from which all sources are relative. + * - sourcesContent: Optional. An array of contents of the original source files. + * - mappings: A string of base64 VLQs which contain the actual mappings. + * - file: Optional. The generated file this source map is associated with. + * + * Here is an example source map, taken from the source map spec[0]: + * + * { + * version : 3, + * file: "out.js", + * sourceRoot : "", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AA,AB;;ABCDE;" + * } + * + * The second parameter, if given, is a string whose value is the URL + * at which the source map was found. This URL is used to compute the + * sources array. + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# + */ + function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = util.parseSourceMapInput(aSourceMap); + } + + var version = util.getArg(sourceMap, 'version'); + var sources = util.getArg(sourceMap, 'sources'); + // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which + // requires the array) to play nice here. + var names = util.getArg(sourceMap, 'names', []); + var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); + var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); + var mappings = util.getArg(sourceMap, 'mappings'); + var file = util.getArg(sourceMap, 'file', null); + + // Once again, Sass deviates from the spec and supplies the version as a + // string rather than a number, so we use loose equality checking here. + if (version != this._version) { + throw new Error('Unsupported version: ' + version); + } + + if (sourceRoot) { + sourceRoot = util.normalize(sourceRoot); + } + + sources = sources + .map(String) + // Some source maps produce relative source paths like "./foo.js" instead of + // "foo.js". Normalize these first so that future comparisons will succeed. + // See bugzil.la/1090768. + .map(util.normalize) + // Always ensure that absolute sources are internally stored relative to + // the source root, if the source root is absolute. Not doing this would + // be particularly problematic when the source root is a prefix of the + // source (valid, but why??). See github issue #199 and bugzil.la/1188982. + .map(function (source) { + return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) + ? util.relative(sourceRoot, source) + : source; + }); + + // Pass `true` below to allow duplicate names and sources. While source maps + // are intended to be compressed and deduplicated, the TypeScript compiler + // sometimes generates source maps with duplicates in them. See Github issue + // #72 and bugzil.la/889492. + this._names = ArraySet.fromArray(names.map(String), true); + this._sources = ArraySet.fromArray(sources, true); + + this._absoluteSources = this._sources.toArray().map(function (s) { + return util.computeSourceURL(sourceRoot, s, aSourceMapURL); + }); + + this.sourceRoot = sourceRoot; + this.sourcesContent = sourcesContent; + this._mappings = mappings; + this._sourceMapURL = aSourceMapURL; + this.file = file; + } + + BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); + BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer; + + /** + * Utility function to find the index of a source. Returns -1 if not + * found. + */ + BasicSourceMapConsumer.prototype._findSourceIndex = function(aSource) { + var relativeSource = aSource; + if (this.sourceRoot != null) { + relativeSource = util.relative(this.sourceRoot, relativeSource); + } + + if (this._sources.has(relativeSource)) { + return this._sources.indexOf(relativeSource); + } + + // Maybe aSource is an absolute URL as returned by |sources|. In + // this case we can't simply undo the transform. + var i; + for (i = 0; i < this._absoluteSources.length; ++i) { + if (this._absoluteSources[i] == aSource) { + return i; + } + } + + return -1; + }; + + /** + * Create a BasicSourceMapConsumer from a SourceMapGenerator. + * + * @param SourceMapGenerator aSourceMap + * The source map that will be consumed. + * @param String aSourceMapURL + * The URL at which the source map can be found (optional) + * @returns BasicSourceMapConsumer + */ + BasicSourceMapConsumer.fromSourceMap = + function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) { + var smc = Object.create(BasicSourceMapConsumer.prototype); + + var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); + var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); + smc.sourceRoot = aSourceMap._sourceRoot; + smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), + smc.sourceRoot); + smc.file = aSourceMap._file; + smc._sourceMapURL = aSourceMapURL; + smc._absoluteSources = smc._sources.toArray().map(function (s) { + return util.computeSourceURL(smc.sourceRoot, s, aSourceMapURL); + }); + + // Because we are modifying the entries (by converting string sources and + // names to indices into the sources and names ArraySets), we have to make + // a copy of the entry or else bad things happen. Shared mutable state + // strikes again! See github issue #191. + + var generatedMappings = aSourceMap._mappings.toArray().slice(); + var destGeneratedMappings = smc.__generatedMappings = []; + var destOriginalMappings = smc.__originalMappings = []; + + for (var i = 0, length = generatedMappings.length; i < length; i++) { + var srcMapping = generatedMappings[i]; + var destMapping = new Mapping; + destMapping.generatedLine = srcMapping.generatedLine; + destMapping.generatedColumn = srcMapping.generatedColumn; + + if (srcMapping.source) { + destMapping.source = sources.indexOf(srcMapping.source); + destMapping.originalLine = srcMapping.originalLine; + destMapping.originalColumn = srcMapping.originalColumn; + + if (srcMapping.name) { + destMapping.name = names.indexOf(srcMapping.name); + } + + destOriginalMappings.push(destMapping); + } + + destGeneratedMappings.push(destMapping); + } + + quickSort(smc.__originalMappings, util.compareByOriginalPositions); + + return smc; + }; + + /** + * The version of the source mapping spec that we are consuming. + */ + BasicSourceMapConsumer.prototype._version = 3; + + /** + * The list of original sources. + */ + Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', { + get: function () { + return this._absoluteSources.slice(); + } + }); + + /** + * Provide the JIT with a nice shape / hidden class. + */ + function Mapping() { + this.generatedLine = 0; + this.generatedColumn = 0; + this.source = null; + this.originalLine = null; + this.originalColumn = null; + this.name = null; + } + + /** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ + BasicSourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + var generatedLine = 1; + var previousGeneratedColumn = 0; + var previousOriginalLine = 0; + var previousOriginalColumn = 0; + var previousSource = 0; + var previousName = 0; + var length = aStr.length; + var index = 0; + var cachedSegments = {}; + var temp = {}; + var originalMappings = []; + var generatedMappings = []; + var mapping, str, segment, end, value; + + while (index < length) { + if (aStr.charAt(index) === ';') { + generatedLine++; + index++; + previousGeneratedColumn = 0; + } + else if (aStr.charAt(index) === ',') { + index++; + } + else { + mapping = new Mapping(); + mapping.generatedLine = generatedLine; + + // Because each offset is encoded relative to the previous one, + // many segments often have the same encoding. We can exploit this + // fact by caching the parsed variable length fields of each segment, + // allowing us to avoid a second parse if we encounter the same + // segment again. + for (end = index; end < length; end++) { + if (this._charIsMappingSeparator(aStr, end)) { + break; + } + } + str = aStr.slice(index, end); + + segment = cachedSegments[str]; + if (segment) { + index += str.length; + } else { + segment = []; + while (index < end) { + base64VLQ.decode(aStr, index, temp); + value = temp.value; + index = temp.rest; + segment.push(value); + } + + if (segment.length === 2) { + throw new Error('Found a source, but no line and column'); + } + + if (segment.length === 3) { + throw new Error('Found a source and line, but no column'); + } + + cachedSegments[str] = segment; + } + + // Generated column. + mapping.generatedColumn = previousGeneratedColumn + segment[0]; + previousGeneratedColumn = mapping.generatedColumn; + + if (segment.length > 1) { + // Original source. + mapping.source = previousSource + segment[1]; + previousSource += segment[1]; + + // Original line. + mapping.originalLine = previousOriginalLine + segment[2]; + previousOriginalLine = mapping.originalLine; + // Lines are stored 0-based + mapping.originalLine += 1; + + // Original column. + mapping.originalColumn = previousOriginalColumn + segment[3]; + previousOriginalColumn = mapping.originalColumn; + + if (segment.length > 4) { + // Original name. + mapping.name = previousName + segment[4]; + previousName += segment[4]; + } + } + + generatedMappings.push(mapping); + if (typeof mapping.originalLine === 'number') { + originalMappings.push(mapping); + } + } + } + + quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated); + this.__generatedMappings = generatedMappings; + + quickSort(originalMappings, util.compareByOriginalPositions); + this.__originalMappings = originalMappings; + }; + + /** + * Find the mapping that best matches the hypothetical "needle" mapping that + * we are searching for in the given "haystack" of mappings. + */ + BasicSourceMapConsumer.prototype._findMapping = + function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, + aColumnName, aComparator, aBias) { + // To return the position we are searching for, we must first find the + // mapping for the given position and then return the opposite position it + // points to. Because the mappings are sorted, we can use binary search to + // find the best mapping. + + if (aNeedle[aLineName] <= 0) { + throw new TypeError('Line must be greater than or equal to 1, got ' + + aNeedle[aLineName]); + } + if (aNeedle[aColumnName] < 0) { + throw new TypeError('Column must be greater than or equal to 0, got ' + + aNeedle[aColumnName]); + } + + return binarySearch.search(aNeedle, aMappings, aComparator, aBias); + }; + + /** + * Compute the last column for each generated mapping. The last column is + * inclusive. + */ + BasicSourceMapConsumer.prototype.computeColumnSpans = + function SourceMapConsumer_computeColumnSpans() { + for (var index = 0; index < this._generatedMappings.length; ++index) { + var mapping = this._generatedMappings[index]; + + // Mappings do not contain a field for the last generated columnt. We + // can come up with an optimistic estimate, however, by assuming that + // mappings are contiguous (i.e. given two consecutive mappings, the + // first mapping ends where the second one starts). + if (index + 1 < this._generatedMappings.length) { + var nextMapping = this._generatedMappings[index + 1]; + + if (mapping.generatedLine === nextMapping.generatedLine) { + mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1; + continue; + } + } + + // The last mapping for each line spans the entire line. + mapping.lastGeneratedColumn = Infinity; + } + }; + + /** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. The line number + * is 1-based. + * - column: The column number in the generated source. The column + * number is 0-based. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. The + * line number is 1-based. + * - column: The column number in the original source, or null. The + * column number is 0-based. + * - name: The original identifier, or null. + */ + BasicSourceMapConsumer.prototype.originalPositionFor = + function SourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; + + var index = this._findMapping( + needle, + this._generatedMappings, + "generatedLine", + "generatedColumn", + util.compareByGeneratedPositionsDeflated, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._generatedMappings[index]; + + if (mapping.generatedLine === needle.generatedLine) { + var source = util.getArg(mapping, 'source', null); + if (source !== null) { + source = this._sources.at(source); + source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL); + } + var name = util.getArg(mapping, 'name', null); + if (name !== null) { + name = this._names.at(name); + } + return { + source: source, + line: util.getArg(mapping, 'originalLine', null), + column: util.getArg(mapping, 'originalColumn', null), + name: name + }; + } + } + + return { + source: null, + line: null, + column: null, + name: null + }; + }; + + /** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ + BasicSourceMapConsumer.prototype.hasContentsOfAllSources = + function BasicSourceMapConsumer_hasContentsOfAllSources() { + if (!this.sourcesContent) { + return false; + } + return this.sourcesContent.length >= this._sources.size() && + !this.sourcesContent.some(function (sc) { return sc == null; }); + }; + + /** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ + BasicSourceMapConsumer.prototype.sourceContentFor = + function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + if (!this.sourcesContent) { + return null; + } + + var index = this._findSourceIndex(aSource); + if (index >= 0) { + return this.sourcesContent[index]; + } + + var relativeSource = aSource; + if (this.sourceRoot != null) { + relativeSource = util.relative(this.sourceRoot, relativeSource); + } + + var url; + if (this.sourceRoot != null + && (url = util.urlParse(this.sourceRoot))) { + // XXX: file:// URIs and absolute paths lead to unexpected behavior for + // many users. We can help them out when they expect file:// URIs to + // behave like it would if they were running a local HTTP server. See + // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. + var fileUriAbsPath = relativeSource.replace(/^file:\/\//, ""); + if (url.scheme == "file" + && this._sources.has(fileUriAbsPath)) { + return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] + } + + if ((!url.path || url.path == "/") + && this._sources.has("/" + relativeSource)) { + return this.sourcesContent[this._sources.indexOf("/" + relativeSource)]; + } + } + + // This function is used recursively from + // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we + // don't want to throw if we can't find the source - we just want to + // return null, so we provide a flag to exit gracefully. + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + relativeSource + '" is not in the SourceMap.'); + } + }; + + /** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. The line number + * is 1-based. + * - column: The column number in the original source. The column + * number is 0-based. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. The + * line number is 1-based. + * - column: The column number in the generated source, or null. + * The column number is 0-based. + */ + BasicSourceMapConsumer.prototype.generatedPositionFor = + function SourceMapConsumer_generatedPositionFor(aArgs) { + var source = util.getArg(aArgs, 'source'); + source = this._findSourceIndex(source); + if (source < 0) { + return { + line: null, + column: null, + lastColumn: null + }; + } + + var needle = { + source: source, + originalLine: util.getArg(aArgs, 'line'), + originalColumn: util.getArg(aArgs, 'column') + }; + + var index = this._findMapping( + needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._originalMappings[index]; + + if (mapping.source === needle.source) { + return { + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }; + } + } + + return { + line: null, + column: null, + lastColumn: null + }; + }; + + exports.BasicSourceMapConsumer = BasicSourceMapConsumer; + + /** + * An IndexedSourceMapConsumer instance represents a parsed source map which + * we can query for information. It differs from BasicSourceMapConsumer in + * that it takes "indexed" source maps (i.e. ones with a "sections" field) as + * input. + * + * The first parameter is a raw source map (either as a JSON string, or already + * parsed to an object). According to the spec for indexed source maps, they + * have the following attributes: + * + * - version: Which version of the source map spec this map is following. + * - file: Optional. The generated file this source map is associated with. + * - sections: A list of section definitions. + * + * Each value under the "sections" field has two fields: + * - offset: The offset into the original specified at which this section + * begins to apply, defined as an object with a "line" and "column" + * field. + * - map: A source map definition. This source map could also be indexed, + * but doesn't have to be. + * + * Instead of the "map" field, it's also possible to have a "url" field + * specifying a URL to retrieve a source map from, but that's currently + * unsupported. + * + * Here's an example source map, taken from the source map spec[0], but + * modified to omit a section which uses the "url" field. + * + * { + * version : 3, + * file: "app.js", + * sections: [{ + * offset: {line:100, column:10}, + * map: { + * version : 3, + * file: "section.js", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AAAA,E;;ABCDE;" + * } + * }], + * } + * + * The second parameter, if given, is a string whose value is the URL + * at which the source map was found. This URL is used to compute the + * sources array. + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt + */ + function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = util.parseSourceMapInput(aSourceMap); + } + + var version = util.getArg(sourceMap, 'version'); + var sections = util.getArg(sourceMap, 'sections'); + + if (version != this._version) { + throw new Error('Unsupported version: ' + version); + } + + this._sources = new ArraySet(); + this._names = new ArraySet(); + + var lastOffset = { + line: -1, + column: 0 + }; + this._sections = sections.map(function (s) { + if (s.url) { + // The url field will require support for asynchronicity. + // See https://github.com/mozilla/source-map/issues/16 + throw new Error('Support for url field in sections not implemented.'); + } + var offset = util.getArg(s, 'offset'); + var offsetLine = util.getArg(offset, 'line'); + var offsetColumn = util.getArg(offset, 'column'); + + if (offsetLine < lastOffset.line || + (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { + throw new Error('Section offsets must be ordered and non-overlapping.'); + } + lastOffset = offset; + + return { + generatedOffset: { + // The offset fields are 0-based, but we use 1-based indices when + // encoding/decoding from VLQ. + generatedLine: offsetLine + 1, + generatedColumn: offsetColumn + 1 + }, + consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL) + } + }); + } + + IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); + IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer; + + /** + * The version of the source mapping spec that we are consuming. + */ + IndexedSourceMapConsumer.prototype._version = 3; + + /** + * The list of original sources. + */ + Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', { + get: function () { + var sources = []; + for (var i = 0; i < this._sections.length; i++) { + for (var j = 0; j < this._sections[i].consumer.sources.length; j++) { + sources.push(this._sections[i].consumer.sources[j]); + } + } + return sources; + } + }); + + /** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. The line number + * is 1-based. + * - column: The column number in the generated source. The column + * number is 0-based. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. The + * line number is 1-based. + * - column: The column number in the original source, or null. The + * column number is 0-based. + * - name: The original identifier, or null. + */ + IndexedSourceMapConsumer.prototype.originalPositionFor = + function IndexedSourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; + + // Find the section containing the generated position we're trying to map + // to an original position. + var sectionIndex = binarySearch.search(needle, this._sections, + function(needle, section) { + var cmp = needle.generatedLine - section.generatedOffset.generatedLine; + if (cmp) { + return cmp; + } + + return (needle.generatedColumn - + section.generatedOffset.generatedColumn); + }); + var section = this._sections[sectionIndex]; + + if (!section) { + return { + source: null, + line: null, + column: null, + name: null + }; + } + + return section.consumer.originalPositionFor({ + line: needle.generatedLine - + (section.generatedOffset.generatedLine - 1), + column: needle.generatedColumn - + (section.generatedOffset.generatedLine === needle.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + bias: aArgs.bias + }); + }; + + /** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ + IndexedSourceMapConsumer.prototype.hasContentsOfAllSources = + function IndexedSourceMapConsumer_hasContentsOfAllSources() { + return this._sections.every(function (s) { + return s.consumer.hasContentsOfAllSources(); + }); + }; + + /** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ + IndexedSourceMapConsumer.prototype.sourceContentFor = + function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + + var content = section.consumer.sourceContentFor(aSource, true); + if (content) { + return content; + } + } + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + aSource + '" is not in the SourceMap.'); + } + }; + + /** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. The line number + * is 1-based. + * - column: The column number in the original source. The column + * number is 0-based. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. The + * line number is 1-based. + * - column: The column number in the generated source, or null. + * The column number is 0-based. + */ + IndexedSourceMapConsumer.prototype.generatedPositionFor = + function IndexedSourceMapConsumer_generatedPositionFor(aArgs) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + + // Only consider this section if the requested source is in the list of + // sources of the consumer. + if (section.consumer._findSourceIndex(util.getArg(aArgs, 'source')) === -1) { + continue; + } + var generatedPosition = section.consumer.generatedPositionFor(aArgs); + if (generatedPosition) { + var ret = { + line: generatedPosition.line + + (section.generatedOffset.generatedLine - 1), + column: generatedPosition.column + + (section.generatedOffset.generatedLine === generatedPosition.line + ? section.generatedOffset.generatedColumn - 1 + : 0) + }; + return ret; + } + } + + return { + line: null, + column: null + }; + }; + + /** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ + IndexedSourceMapConsumer.prototype._parseMappings = + function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) { + this.__generatedMappings = []; + this.__originalMappings = []; + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + var sectionMappings = section.consumer._generatedMappings; + for (var j = 0; j < sectionMappings.length; j++) { + var mapping = sectionMappings[j]; + + var source = section.consumer._sources.at(mapping.source); + source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL); + this._sources.add(source); + source = this._sources.indexOf(source); + + var name = null; + if (mapping.name) { + name = section.consumer._names.at(mapping.name); + this._names.add(name); + name = this._names.indexOf(name); + } + + // The mappings coming from the consumer for the section have + // generated positions relative to the start of the section, so we + // need to offset them to be relative to the start of the concatenated + // generated file. + var adjustedMapping = { + source: source, + generatedLine: mapping.generatedLine + + (section.generatedOffset.generatedLine - 1), + generatedColumn: mapping.generatedColumn + + (section.generatedOffset.generatedLine === mapping.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: name + }; + + this.__generatedMappings.push(adjustedMapping); + if (typeof adjustedMapping.originalLine === 'number') { + this.__originalMappings.push(adjustedMapping); + } + } + } + + quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated); + quickSort(this.__originalMappings, util.compareByOriginalPositions); + }; + + exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; + + +/***/ }), +/* 8 */ +/***/ (function(module, exports) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + exports.GREATEST_LOWER_BOUND = 1; + exports.LEAST_UPPER_BOUND = 2; + + /** + * Recursive implementation of binary search. + * + * @param aLow Indices here and lower do not contain the needle. + * @param aHigh Indices here and higher do not contain the needle. + * @param aNeedle The element being searched for. + * @param aHaystack The non-empty array being searched. + * @param aCompare Function which takes two elements and returns -1, 0, or 1. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + */ + function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { + // This function terminates when one of the following is true: + // + // 1. We find the exact element we are looking for. + // + // 2. We did not find the exact element, but we can return the index of + // the next-closest element. + // + // 3. We did not find the exact element, and there is no next-closest + // element than the one we are searching for, so we return -1. + var mid = Math.floor((aHigh - aLow) / 2) + aLow; + var cmp = aCompare(aNeedle, aHaystack[mid], true); + if (cmp === 0) { + // Found the element we are looking for. + return mid; + } + else if (cmp > 0) { + // Our needle is greater than aHaystack[mid]. + if (aHigh - mid > 1) { + // The element is in the upper half. + return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias); + } + + // The exact needle element was not found in this haystack. Determine if + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return aHigh < aHaystack.length ? aHigh : -1; + } else { + return mid; + } + } + else { + // Our needle is less than aHaystack[mid]. + if (mid - aLow > 1) { + // The element is in the lower half. + return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias); + } + + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return mid; + } else { + return aLow < 0 ? -1 : aLow; + } + } + } + + /** + * This is an implementation of binary search which will always try and return + * the index of the closest element if there is no exact hit. This is because + * mappings between original and generated line/col pairs are single points, + * and there is an implicit region between each of them, so a miss just means + * that you aren't on the very start of a region. + * + * @param aNeedle The element you are looking for. + * @param aHaystack The array that is being searched. + * @param aCompare A function which takes the needle and an element in the + * array and returns -1, 0, or 1 depending on whether the needle is less + * than, equal to, or greater than the element, respectively. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. + */ + exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { + if (aHaystack.length === 0) { + return -1; + } + + var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, + aCompare, aBias || exports.GREATEST_LOWER_BOUND); + if (index < 0) { + return -1; + } + + // We have found either the exact element, or the next-closest element than + // the one we are searching for. However, there may be more than one such + // element. Make sure we always return the smallest of these. + while (index - 1 >= 0) { + if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { + break; + } + --index; + } + + return index; + }; + + +/***/ }), +/* 9 */ +/***/ (function(module, exports) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + // It turns out that some (most?) JavaScript engines don't self-host + // `Array.prototype.sort`. This makes sense because C++ will likely remain + // faster than JS when doing raw CPU-intensive sorting. However, when using a + // custom comparator function, calling back and forth between the VM's C++ and + // JIT'd JS is rather slow *and* loses JIT type information, resulting in + // worse generated code for the comparator function than would be optimal. In + // fact, when sorting with a comparator, these costs outweigh the benefits of + // sorting in C++. By using our own JS-implemented Quick Sort (below), we get + // a ~3500ms mean speed-up in `bench/bench.html`. + + /** + * Swap the elements indexed by `x` and `y` in the array `ary`. + * + * @param {Array} ary + * The array. + * @param {Number} x + * The index of the first item. + * @param {Number} y + * The index of the second item. + */ + function swap(ary, x, y) { + var temp = ary[x]; + ary[x] = ary[y]; + ary[y] = temp; + } + + /** + * Returns a random integer within the range `low .. high` inclusive. + * + * @param {Number} low + * The lower bound on the range. + * @param {Number} high + * The upper bound on the range. + */ + function randomIntInRange(low, high) { + return Math.round(low + (Math.random() * (high - low))); + } + + /** + * The Quick Sort algorithm. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + * @param {Number} p + * Start index of the array + * @param {Number} r + * End index of the array + */ + function doQuickSort(ary, comparator, p, r) { + // If our lower bound is less than our upper bound, we (1) partition the + // array into two pieces and (2) recurse on each half. If it is not, this is + // the empty array and our base case. + + if (p < r) { + // (1) Partitioning. + // + // The partitioning chooses a pivot between `p` and `r` and moves all + // elements that are less than or equal to the pivot to the before it, and + // all the elements that are greater than it after it. The effect is that + // once partition is done, the pivot is in the exact place it will be when + // the array is put in sorted order, and it will not need to be moved + // again. This runs in O(n) time. + + // Always choose a random pivot so that an input array which is reverse + // sorted does not cause O(n^2) running time. + var pivotIndex = randomIntInRange(p, r); + var i = p - 1; + + swap(ary, pivotIndex, r); + var pivot = ary[r]; + + // Immediately after `j` is incremented in this loop, the following hold + // true: + // + // * Every element in `ary[p .. i]` is less than or equal to the pivot. + // + // * Every element in `ary[i+1 .. j-1]` is greater than the pivot. + for (var j = p; j < r; j++) { + if (comparator(ary[j], pivot) <= 0) { + i += 1; + swap(ary, i, j); + } + } + + swap(ary, i + 1, j); + var q = i + 1; + + // (2) Recurse on each half. + + doQuickSort(ary, comparator, p, q - 1); + doQuickSort(ary, comparator, q + 1, r); + } + } + + /** + * Sort the given array in-place with the given comparator function. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + */ + exports.quickSort = function (ary, comparator) { + doQuickSort(ary, comparator, 0, ary.length - 1); + }; + + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + + /* -*- Mode: js; js-indent-level: 2; -*- */ + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var SourceMapGenerator = __webpack_require__(1).SourceMapGenerator; + var util = __webpack_require__(4); + + // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other + // operating systems these days (capturing the result). + var REGEX_NEWLINE = /(\r?\n)/; + + // Newline character code for charCodeAt() comparisons + var NEWLINE_CODE = 10; + + // Private symbol for identifying `SourceNode`s when multiple versions of + // the source-map library are loaded. This MUST NOT CHANGE across + // versions! + var isSourceNode = "$$$isSourceNode$$$"; + + /** + * SourceNodes provide a way to abstract over interpolating/concatenating + * snippets of generated JavaScript source code while maintaining the line and + * column information associated with the original source code. + * + * @param aLine The original line number. + * @param aColumn The original column number. + * @param aSource The original source's filename. + * @param aChunks Optional. An array of strings which are snippets of + * generated JS, or other SourceNodes. + * @param aName The original identifier. + */ + function SourceNode(aLine, aColumn, aSource, aChunks, aName) { + this.children = []; + this.sourceContents = {}; + this.line = aLine == null ? null : aLine; + this.column = aColumn == null ? null : aColumn; + this.source = aSource == null ? null : aSource; + this.name = aName == null ? null : aName; + this[isSourceNode] = true; + if (aChunks != null) this.add(aChunks); + } + + /** + * Creates a SourceNode from generated code and a SourceMapConsumer. + * + * @param aGeneratedCode The generated code + * @param aSourceMapConsumer The SourceMap for the generated code + * @param aRelativePath Optional. The path that relative sources in the + * SourceMapConsumer should be relative to. + */ + SourceNode.fromStringWithSourceMap = + function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) { + // The SourceNode we want to fill with the generated code + // and the SourceMap + var node = new SourceNode(); + + // All even indices of this array are one line of the generated code, + // while all odd indices are the newlines between two adjacent lines + // (since `REGEX_NEWLINE` captures its match). + // Processed fragments are accessed by calling `shiftNextLine`. + var remainingLines = aGeneratedCode.split(REGEX_NEWLINE); + var remainingLinesIndex = 0; + var shiftNextLine = function() { + var lineContents = getNextLine(); + // The last line of a file might not have a newline. + var newLine = getNextLine() || ""; + return lineContents + newLine; + + function getNextLine() { + return remainingLinesIndex < remainingLines.length ? + remainingLines[remainingLinesIndex++] : undefined; + } + }; + + // We need to remember the position of "remainingLines" + var lastGeneratedLine = 1, lastGeneratedColumn = 0; + + // The generate SourceNodes we need a code range. + // To extract it current and last mapping is used. + // Here we store the last mapping. + var lastMapping = null; + + aSourceMapConsumer.eachMapping(function (mapping) { + if (lastMapping !== null) { + // We add the code from "lastMapping" to "mapping": + // First check if there is a new line in between. + if (lastGeneratedLine < mapping.generatedLine) { + // Associate first line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + lastGeneratedLine++; + lastGeneratedColumn = 0; + // The remaining code is added without mapping + } else { + // There is no new line in between. + // Associate the code between "lastGeneratedColumn" and + // "mapping.generatedColumn" with "lastMapping" + var nextLine = remainingLines[remainingLinesIndex] || ''; + var code = nextLine.substr(0, mapping.generatedColumn - + lastGeneratedColumn); + remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn - + lastGeneratedColumn); + lastGeneratedColumn = mapping.generatedColumn; + addMappingWithCode(lastMapping, code); + // No more remaining code, continue + lastMapping = mapping; + return; + } + } + // We add the generated code until the first mapping + // to the SourceNode without any mapping. + // Each line is added as separate string. + while (lastGeneratedLine < mapping.generatedLine) { + node.add(shiftNextLine()); + lastGeneratedLine++; + } + if (lastGeneratedColumn < mapping.generatedColumn) { + var nextLine = remainingLines[remainingLinesIndex] || ''; + node.add(nextLine.substr(0, mapping.generatedColumn)); + remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn); + lastGeneratedColumn = mapping.generatedColumn; + } + lastMapping = mapping; + }, this); + // We have processed all mappings. + if (remainingLinesIndex < remainingLines.length) { + if (lastMapping) { + // Associate the remaining code in the current line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + } + // and add the remaining lines without any mapping + node.add(remainingLines.splice(remainingLinesIndex).join("")); + } + + // Copy sourcesContent into SourceNode + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aRelativePath != null) { + sourceFile = util.join(aRelativePath, sourceFile); + } + node.setSourceContent(sourceFile, content); + } + }); + + return node; + + function addMappingWithCode(mapping, code) { + if (mapping === null || mapping.source === undefined) { + node.add(code); + } else { + var source = aRelativePath + ? util.join(aRelativePath, mapping.source) + : mapping.source; + node.add(new SourceNode(mapping.originalLine, + mapping.originalColumn, + source, + code, + mapping.name)); + } + } + }; + + /** + * Add a chunk of generated JS to this source node. + * + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. + */ + SourceNode.prototype.add = function SourceNode_add(aChunk) { + if (Array.isArray(aChunk)) { + aChunk.forEach(function (chunk) { + this.add(chunk); + }, this); + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + if (aChunk) { + this.children.push(aChunk); + } + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; + }; + + /** + * Add a chunk of generated JS to the beginning of this source node. + * + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. + */ + SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { + if (Array.isArray(aChunk)) { + for (var i = aChunk.length-1; i >= 0; i--) { + this.prepend(aChunk[i]); + } + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + this.children.unshift(aChunk); + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; + }; + + /** + * Walk over the tree of JS snippets in this node and its children. The + * walking function is called once for each snippet of JS and is passed that + * snippet and the its original associated source's line/column location. + * + * @param aFn The traversal function. + */ + SourceNode.prototype.walk = function SourceNode_walk(aFn) { + var chunk; + for (var i = 0, len = this.children.length; i < len; i++) { + chunk = this.children[i]; + if (chunk[isSourceNode]) { + chunk.walk(aFn); + } + else { + if (chunk !== '') { + aFn(chunk, { source: this.source, + line: this.line, + column: this.column, + name: this.name }); + } + } + } + }; + + /** + * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between + * each of `this.children`. + * + * @param aSep The separator. + */ + SourceNode.prototype.join = function SourceNode_join(aSep) { + var newChildren; + var i; + var len = this.children.length; + if (len > 0) { + newChildren = []; + for (i = 0; i < len-1; i++) { + newChildren.push(this.children[i]); + newChildren.push(aSep); + } + newChildren.push(this.children[i]); + this.children = newChildren; + } + return this; + }; + + /** + * Call String.prototype.replace on the very right-most source snippet. Useful + * for trimming whitespace from the end of a source node, etc. + * + * @param aPattern The pattern to replace. + * @param aReplacement The thing to replace the pattern with. + */ + SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { + var lastChild = this.children[this.children.length - 1]; + if (lastChild[isSourceNode]) { + lastChild.replaceRight(aPattern, aReplacement); + } + else if (typeof lastChild === 'string') { + this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); + } + else { + this.children.push(''.replace(aPattern, aReplacement)); + } + return this; + }; + + /** + * Set the source content for a source file. This will be added to the SourceMapGenerator + * in the sourcesContent field. + * + * @param aSourceFile The filename of the source file + * @param aSourceContent The content of the source file + */ + SourceNode.prototype.setSourceContent = + function SourceNode_setSourceContent(aSourceFile, aSourceContent) { + this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; + }; + + /** + * Walk over the tree of SourceNodes. The walking function is called for each + * source file content and is passed the filename and source content. + * + * @param aFn The traversal function. + */ + SourceNode.prototype.walkSourceContents = + function SourceNode_walkSourceContents(aFn) { + for (var i = 0, len = this.children.length; i < len; i++) { + if (this.children[i][isSourceNode]) { + this.children[i].walkSourceContents(aFn); + } + } + + var sources = Object.keys(this.sourceContents); + for (var i = 0, len = sources.length; i < len; i++) { + aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); + } + }; + + /** + * Return the string representation of this source node. Walks over the tree + * and concatenates all the various snippets together to one string. + */ + SourceNode.prototype.toString = function SourceNode_toString() { + var str = ""; + this.walk(function (chunk) { + str += chunk; + }); + return str; + }; + + /** + * Returns the string representation of this source node along with a source + * map. + */ + SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { + var generated = { + code: "", + line: 1, + column: 0 + }; + var map = new SourceMapGenerator(aArgs); + var sourceMappingActive = false; + var lastOriginalSource = null; + var lastOriginalLine = null; + var lastOriginalColumn = null; + var lastOriginalName = null; + this.walk(function (chunk, original) { + generated.code += chunk; + if (original.source !== null + && original.line !== null + && original.column !== null) { + if(lastOriginalSource !== original.source + || lastOriginalLine !== original.line + || lastOriginalColumn !== original.column + || lastOriginalName !== original.name) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + lastOriginalSource = original.source; + lastOriginalLine = original.line; + lastOriginalColumn = original.column; + lastOriginalName = original.name; + sourceMappingActive = true; + } else if (sourceMappingActive) { + map.addMapping({ + generated: { + line: generated.line, + column: generated.column + } + }); + lastOriginalSource = null; + sourceMappingActive = false; + } + for (var idx = 0, length = chunk.length; idx < length; idx++) { + if (chunk.charCodeAt(idx) === NEWLINE_CODE) { + generated.line++; + generated.column = 0; + // Mappings end at eol + if (idx + 1 === length) { + lastOriginalSource = null; + sourceMappingActive = false; + } else if (sourceMappingActive) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + } else { + generated.column++; + } + } + }); + this.walkSourceContents(function (sourceFile, sourceContent) { + map.setSourceContent(sourceFile, sourceContent); + }); + + return { code: generated.code, map: map }; + }; + + exports.SourceNode = SourceNode; + + +/***/ }) +/******/ ]) +}); +; \ No newline at end of file diff --git a/node_modules/source-map/dist/source-map.min.js b/node_modules/source-map/dist/source-map.min.js new file mode 100644 index 0000000..c7c72da --- /dev/null +++ b/node_modules/source-map/dist/source-map.min.js @@ -0,0 +1,2 @@ +!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.sourceMap=n():e.sourceMap=n()}(this,function(){return function(e){function n(t){if(r[t])return r[t].exports;var o=r[t]={exports:{},id:t,loaded:!1};return e[t].call(o.exports,o,o.exports,n),o.loaded=!0,o.exports}var r={};return n.m=e,n.c=r,n.p="",n(0)}([function(e,n,r){n.SourceMapGenerator=r(1).SourceMapGenerator,n.SourceMapConsumer=r(7).SourceMapConsumer,n.SourceNode=r(10).SourceNode},function(e,n,r){function t(e){e||(e={}),this._file=i.getArg(e,"file",null),this._sourceRoot=i.getArg(e,"sourceRoot",null),this._skipValidation=i.getArg(e,"skipValidation",!1),this._sources=new s,this._names=new s,this._mappings=new a,this._sourcesContents=null}var o=r(2),i=r(4),s=r(5).ArraySet,a=r(6).MappingList;t.prototype._version=3,t.fromSourceMap=function(e){var n=e.sourceRoot,r=new t({file:e.file,sourceRoot:n});return e.eachMapping(function(e){var t={generated:{line:e.generatedLine,column:e.generatedColumn}};null!=e.source&&(t.source=e.source,null!=n&&(t.source=i.relative(n,t.source)),t.original={line:e.originalLine,column:e.originalColumn},null!=e.name&&(t.name=e.name)),r.addMapping(t)}),e.sources.forEach(function(t){var o=t;null!==n&&(o=i.relative(n,t)),r._sources.has(o)||r._sources.add(o);var s=e.sourceContentFor(t);null!=s&&r.setSourceContent(t,s)}),r},t.prototype.addMapping=function(e){var n=i.getArg(e,"generated"),r=i.getArg(e,"original",null),t=i.getArg(e,"source",null),o=i.getArg(e,"name",null);this._skipValidation||this._validateMapping(n,r,t,o),null!=t&&(t=String(t),this._sources.has(t)||this._sources.add(t)),null!=o&&(o=String(o),this._names.has(o)||this._names.add(o)),this._mappings.add({generatedLine:n.line,generatedColumn:n.column,originalLine:null!=r&&r.line,originalColumn:null!=r&&r.column,source:t,name:o})},t.prototype.setSourceContent=function(e,n){var r=e;null!=this._sourceRoot&&(r=i.relative(this._sourceRoot,r)),null!=n?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[i.toSetString(r)]=n):this._sourcesContents&&(delete this._sourcesContents[i.toSetString(r)],0===Object.keys(this._sourcesContents).length&&(this._sourcesContents=null))},t.prototype.applySourceMap=function(e,n,r){var t=n;if(null==n){if(null==e.file)throw new Error('SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map\'s "file" property. Both were omitted.');t=e.file}var o=this._sourceRoot;null!=o&&(t=i.relative(o,t));var a=new s,u=new s;this._mappings.unsortedForEach(function(n){if(n.source===t&&null!=n.originalLine){var s=e.originalPositionFor({line:n.originalLine,column:n.originalColumn});null!=s.source&&(n.source=s.source,null!=r&&(n.source=i.join(r,n.source)),null!=o&&(n.source=i.relative(o,n.source)),n.originalLine=s.line,n.originalColumn=s.column,null!=s.name&&(n.name=s.name))}var l=n.source;null==l||a.has(l)||a.add(l);var c=n.name;null==c||u.has(c)||u.add(c)},this),this._sources=a,this._names=u,e.sources.forEach(function(n){var t=e.sourceContentFor(n);null!=t&&(null!=r&&(n=i.join(r,n)),null!=o&&(n=i.relative(o,n)),this.setSourceContent(n,t))},this)},t.prototype._validateMapping=function(e,n,r,t){if(n&&"number"!=typeof n.line&&"number"!=typeof n.column)throw new Error("original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.");if((!(e&&"line"in e&&"column"in e&&e.line>0&&e.column>=0)||n||r||t)&&!(e&&"line"in e&&"column"in e&&n&&"line"in n&&"column"in n&&e.line>0&&e.column>=0&&n.line>0&&n.column>=0&&r))throw new Error("Invalid mapping: "+JSON.stringify({generated:e,source:r,original:n,name:t}))},t.prototype._serializeMappings=function(){for(var e,n,r,t,s=0,a=1,u=0,l=0,c=0,g=0,p="",h=this._mappings.toArray(),f=0,d=h.length;f0){if(!i.compareByGeneratedPositionsInflated(n,h[f-1]))continue;e+=","}e+=o.encode(n.generatedColumn-s),s=n.generatedColumn,null!=n.source&&(t=this._sources.indexOf(n.source),e+=o.encode(t-g),g=t,e+=o.encode(n.originalLine-1-l),l=n.originalLine-1,e+=o.encode(n.originalColumn-u),u=n.originalColumn,null!=n.name&&(r=this._names.indexOf(n.name),e+=o.encode(r-c),c=r)),p+=e}return p},t.prototype._generateSourcesContent=function(e,n){return e.map(function(e){if(!this._sourcesContents)return null;null!=n&&(e=i.relative(n,e));var r=i.toSetString(e);return Object.prototype.hasOwnProperty.call(this._sourcesContents,r)?this._sourcesContents[r]:null},this)},t.prototype.toJSON=function(){var e={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return null!=this._file&&(e.file=this._file),null!=this._sourceRoot&&(e.sourceRoot=this._sourceRoot),this._sourcesContents&&(e.sourcesContent=this._generateSourcesContent(e.sources,e.sourceRoot)),e},t.prototype.toString=function(){return JSON.stringify(this.toJSON())},n.SourceMapGenerator=t},function(e,n,r){function t(e){return e<0?(-e<<1)+1:(e<<1)+0}function o(e){var n=1===(1&e),r=e>>1;return n?-r:r}var i=r(3),s=5,a=1<>>=s,o>0&&(n|=l),r+=i.encode(n);while(o>0);return r},n.decode=function(e,n,r){var t,a,c=e.length,g=0,p=0;do{if(n>=c)throw new Error("Expected more digits in base 64 VLQ value.");if(a=i.decode(e.charCodeAt(n++)),a===-1)throw new Error("Invalid base64 digit: "+e.charAt(n-1));t=!!(a&l),a&=u,g+=a<=0;c--)s=u[c],"."===s?u.splice(c,1):".."===s?l++:l>0&&(""===s?(u.splice(c+1,l),l=0):(u.splice(c,2),l--));return r=u.join("/"),""===r&&(r=a?"/":"."),i?(i.path=r,o(i)):r}function s(e,n){""===e&&(e="."),""===n&&(n=".");var r=t(n),s=t(e);if(s&&(e=s.path||"/"),r&&!r.scheme)return s&&(r.scheme=s.scheme),o(r);if(r||n.match(y))return n;if(s&&!s.host&&!s.path)return s.host=n,o(s);var a="/"===n.charAt(0)?n:i(e.replace(/\/+$/,"")+"/"+n);return s?(s.path=a,o(s)):a}function a(e,n){""===e&&(e="."),e=e.replace(/\/$/,"");for(var r=0;0!==n.indexOf(e+"/");){var t=e.lastIndexOf("/");if(t<0)return n;if(e=e.slice(0,t),e.match(/^([^\/]+:\/)?\/*$/))return n;++r}return Array(r+1).join("../")+n.substr(e.length+1)}function u(e){return e}function l(e){return g(e)?"$"+e:e}function c(e){return g(e)?e.slice(1):e}function g(e){if(!e)return!1;var n=e.length;if(n<9)return!1;if(95!==e.charCodeAt(n-1)||95!==e.charCodeAt(n-2)||111!==e.charCodeAt(n-3)||116!==e.charCodeAt(n-4)||111!==e.charCodeAt(n-5)||114!==e.charCodeAt(n-6)||112!==e.charCodeAt(n-7)||95!==e.charCodeAt(n-8)||95!==e.charCodeAt(n-9))return!1;for(var r=n-10;r>=0;r--)if(36!==e.charCodeAt(r))return!1;return!0}function p(e,n,r){var t=f(e.source,n.source);return 0!==t?t:(t=e.originalLine-n.originalLine,0!==t?t:(t=e.originalColumn-n.originalColumn,0!==t||r?t:(t=e.generatedColumn-n.generatedColumn,0!==t?t:(t=e.generatedLine-n.generatedLine,0!==t?t:f(e.name,n.name)))))}function h(e,n,r){var t=e.generatedLine-n.generatedLine;return 0!==t?t:(t=e.generatedColumn-n.generatedColumn,0!==t||r?t:(t=f(e.source,n.source),0!==t?t:(t=e.originalLine-n.originalLine,0!==t?t:(t=e.originalColumn-n.originalColumn,0!==t?t:f(e.name,n.name)))))}function f(e,n){return e===n?0:null===e?1:null===n?-1:e>n?1:-1}function d(e,n){var r=e.generatedLine-n.generatedLine;return 0!==r?r:(r=e.generatedColumn-n.generatedColumn,0!==r?r:(r=f(e.source,n.source),0!==r?r:(r=e.originalLine-n.originalLine,0!==r?r:(r=e.originalColumn-n.originalColumn,0!==r?r:f(e.name,n.name)))))}function m(e){return JSON.parse(e.replace(/^\)]}'[^\n]*\n/,""))}function _(e,n,r){if(n=n||"",e&&("/"!==e[e.length-1]&&"/"!==n[0]&&(e+="/"),n=e+n),r){var a=t(r);if(!a)throw new Error("sourceMapURL could not be parsed");if(a.path){var u=a.path.lastIndexOf("/");u>=0&&(a.path=a.path.substring(0,u+1))}n=s(o(a),n)}return i(n)}n.getArg=r;var v=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/,y=/^data:.+\,.+$/;n.urlParse=t,n.urlGenerate=o,n.normalize=i,n.join=s,n.isAbsolute=function(e){return"/"===e.charAt(0)||v.test(e)},n.relative=a;var C=function(){var e=Object.create(null);return!("__proto__"in e)}();n.toSetString=C?u:l,n.fromSetString=C?u:c,n.compareByOriginalPositions=p,n.compareByGeneratedPositionsDeflated=h,n.compareByGeneratedPositionsInflated=d,n.parseSourceMapInput=m,n.computeSourceURL=_},function(e,n,r){function t(){this._array=[],this._set=s?new Map:Object.create(null)}var o=r(4),i=Object.prototype.hasOwnProperty,s="undefined"!=typeof Map;t.fromArray=function(e,n){for(var r=new t,o=0,i=e.length;o=0)return n}else{var r=o.toSetString(e);if(i.call(this._set,r))return this._set[r]}throw new Error('"'+e+'" is not in the set.')},t.prototype.at=function(e){if(e>=0&&er||t==r&&s>=o||i.compareByGeneratedPositionsInflated(e,n)<=0}function o(){this._array=[],this._sorted=!0,this._last={generatedLine:-1,generatedColumn:0}}var i=r(4);o.prototype.unsortedForEach=function(e,n){this._array.forEach(e,n)},o.prototype.add=function(e){t(this._last,e)?(this._last=e,this._array.push(e)):(this._sorted=!1,this._array.push(e))},o.prototype.toArray=function(){return this._sorted||(this._array.sort(i.compareByGeneratedPositionsInflated),this._sorted=!0),this._array},n.MappingList=o},function(e,n,r){function t(e,n){var r=e;return"string"==typeof e&&(r=a.parseSourceMapInput(e)),null!=r.sections?new s(r,n):new o(r,n)}function o(e,n){var r=e;"string"==typeof e&&(r=a.parseSourceMapInput(e));var t=a.getArg(r,"version"),o=a.getArg(r,"sources"),i=a.getArg(r,"names",[]),s=a.getArg(r,"sourceRoot",null),u=a.getArg(r,"sourcesContent",null),c=a.getArg(r,"mappings"),g=a.getArg(r,"file",null);if(t!=this._version)throw new Error("Unsupported version: "+t);s&&(s=a.normalize(s)),o=o.map(String).map(a.normalize).map(function(e){return s&&a.isAbsolute(s)&&a.isAbsolute(e)?a.relative(s,e):e}),this._names=l.fromArray(i.map(String),!0),this._sources=l.fromArray(o,!0),this._absoluteSources=this._sources.toArray().map(function(e){return a.computeSourceURL(s,e,n)}),this.sourceRoot=s,this.sourcesContent=u,this._mappings=c,this._sourceMapURL=n,this.file=g}function i(){this.generatedLine=0,this.generatedColumn=0,this.source=null,this.originalLine=null,this.originalColumn=null,this.name=null}function s(e,n){var r=e;"string"==typeof e&&(r=a.parseSourceMapInput(e));var o=a.getArg(r,"version"),i=a.getArg(r,"sections");if(o!=this._version)throw new Error("Unsupported version: "+o);this._sources=new l,this._names=new l;var s={line:-1,column:0};this._sections=i.map(function(e){if(e.url)throw new Error("Support for url field in sections not implemented.");var r=a.getArg(e,"offset"),o=a.getArg(r,"line"),i=a.getArg(r,"column");if(o=0){var i=this._originalMappings[o];if(void 0===e.column)for(var s=i.originalLine;i&&i.originalLine===s;)t.push({line:a.getArg(i,"generatedLine",null),column:a.getArg(i,"generatedColumn",null),lastColumn:a.getArg(i,"lastGeneratedColumn",null)}),i=this._originalMappings[++o];else for(var l=i.originalColumn;i&&i.originalLine===n&&i.originalColumn==l;)t.push({line:a.getArg(i,"generatedLine",null),column:a.getArg(i,"generatedColumn",null),lastColumn:a.getArg(i,"lastGeneratedColumn",null)}),i=this._originalMappings[++o]}return t},n.SourceMapConsumer=t,o.prototype=Object.create(t.prototype),o.prototype.consumer=t,o.prototype._findSourceIndex=function(e){var n=e;if(null!=this.sourceRoot&&(n=a.relative(this.sourceRoot,n)),this._sources.has(n))return this._sources.indexOf(n);var r;for(r=0;r1&&(r.source=d+o[1],d+=o[1],r.originalLine=h+o[2],h=r.originalLine,r.originalLine+=1,r.originalColumn=f+o[3],f=r.originalColumn,o.length>4&&(r.name=m+o[4],m+=o[4])),A.push(r),"number"==typeof r.originalLine&&S.push(r)}g(A,a.compareByGeneratedPositionsDeflated),this.__generatedMappings=A,g(S,a.compareByOriginalPositions),this.__originalMappings=S},o.prototype._findMapping=function(e,n,r,t,o,i){if(e[r]<=0)throw new TypeError("Line must be greater than or equal to 1, got "+e[r]);if(e[t]<0)throw new TypeError("Column must be greater than or equal to 0, got "+e[t]);return u.search(e,n,o,i)},o.prototype.computeColumnSpans=function(){for(var e=0;e=0){var o=this._generatedMappings[r];if(o.generatedLine===n.generatedLine){var i=a.getArg(o,"source",null);null!==i&&(i=this._sources.at(i),i=a.computeSourceURL(this.sourceRoot,i,this._sourceMapURL));var s=a.getArg(o,"name",null);return null!==s&&(s=this._names.at(s)),{source:i,line:a.getArg(o,"originalLine",null),column:a.getArg(o,"originalColumn",null),name:s}}}return{source:null,line:null,column:null,name:null}},o.prototype.hasContentsOfAllSources=function(){return!!this.sourcesContent&&(this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some(function(e){return null==e}))},o.prototype.sourceContentFor=function(e,n){if(!this.sourcesContent)return null;var r=this._findSourceIndex(e);if(r>=0)return this.sourcesContent[r];var t=e;null!=this.sourceRoot&&(t=a.relative(this.sourceRoot,t));var o;if(null!=this.sourceRoot&&(o=a.urlParse(this.sourceRoot))){var i=t.replace(/^file:\/\//,"");if("file"==o.scheme&&this._sources.has(i))return this.sourcesContent[this._sources.indexOf(i)];if((!o.path||"/"==o.path)&&this._sources.has("/"+t))return this.sourcesContent[this._sources.indexOf("/"+t)]}if(n)return null;throw new Error('"'+t+'" is not in the SourceMap.')},o.prototype.generatedPositionFor=function(e){var n=a.getArg(e,"source");if(n=this._findSourceIndex(n),n<0)return{line:null,column:null,lastColumn:null};var r={source:n,originalLine:a.getArg(e,"line"),originalColumn:a.getArg(e,"column")},o=this._findMapping(r,this._originalMappings,"originalLine","originalColumn",a.compareByOriginalPositions,a.getArg(e,"bias",t.GREATEST_LOWER_BOUND));if(o>=0){var i=this._originalMappings[o];if(i.source===r.source)return{line:a.getArg(i,"generatedLine",null),column:a.getArg(i,"generatedColumn",null),lastColumn:a.getArg(i,"lastGeneratedColumn",null)}}return{line:null,column:null,lastColumn:null}},n.BasicSourceMapConsumer=o,s.prototype=Object.create(t.prototype),s.prototype.constructor=t,s.prototype._version=3,Object.defineProperty(s.prototype,"sources",{get:function(){for(var e=[],n=0;n0?t-u>1?r(u,t,o,i,s,a):a==n.LEAST_UPPER_BOUND?t1?r(e,u,o,i,s,a):a==n.LEAST_UPPER_BOUND?u:e<0?-1:e}n.GREATEST_LOWER_BOUND=1,n.LEAST_UPPER_BOUND=2,n.search=function(e,t,o,i){if(0===t.length)return-1;var s=r(-1,t.length,e,t,o,i||n.GREATEST_LOWER_BOUND);if(s<0)return-1;for(;s-1>=0&&0===o(t[s],t[s-1],!0);)--s;return s}},function(e,n){function r(e,n,r){var t=e[n];e[n]=e[r],e[r]=t}function t(e,n){return Math.round(e+Math.random()*(n-e))}function o(e,n,i,s){if(i=0;n--)this.prepend(e[n]);else{if(!e[u]&&"string"!=typeof e)throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+e);this.children.unshift(e)}return this},t.prototype.walk=function(e){for(var n,r=0,t=this.children.length;r0){for(n=[],r=0;r 0 && aGenerated.column >= 0\n\t && !aOriginal && !aSource && !aName) {\n\t // Case 1.\n\t return;\n\t }\n\t else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated\n\t && aOriginal && 'line' in aOriginal && 'column' in aOriginal\n\t && aGenerated.line > 0 && aGenerated.column >= 0\n\t && aOriginal.line > 0 && aOriginal.column >= 0\n\t && aSource) {\n\t // Cases 2 and 3.\n\t return;\n\t }\n\t else {\n\t throw new Error('Invalid mapping: ' + JSON.stringify({\n\t generated: aGenerated,\n\t source: aSource,\n\t original: aOriginal,\n\t name: aName\n\t }));\n\t }\n\t };\n\t\n\t/**\n\t * Serialize the accumulated mappings in to the stream of base 64 VLQs\n\t * specified by the source map format.\n\t */\n\tSourceMapGenerator.prototype._serializeMappings =\n\t function SourceMapGenerator_serializeMappings() {\n\t var previousGeneratedColumn = 0;\n\t var previousGeneratedLine = 1;\n\t var previousOriginalColumn = 0;\n\t var previousOriginalLine = 0;\n\t var previousName = 0;\n\t var previousSource = 0;\n\t var result = '';\n\t var next;\n\t var mapping;\n\t var nameIdx;\n\t var sourceIdx;\n\t\n\t var mappings = this._mappings.toArray();\n\t for (var i = 0, len = mappings.length; i < len; i++) {\n\t mapping = mappings[i];\n\t next = ''\n\t\n\t if (mapping.generatedLine !== previousGeneratedLine) {\n\t previousGeneratedColumn = 0;\n\t while (mapping.generatedLine !== previousGeneratedLine) {\n\t next += ';';\n\t previousGeneratedLine++;\n\t }\n\t }\n\t else {\n\t if (i > 0) {\n\t if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {\n\t continue;\n\t }\n\t next += ',';\n\t }\n\t }\n\t\n\t next += base64VLQ.encode(mapping.generatedColumn\n\t - previousGeneratedColumn);\n\t previousGeneratedColumn = mapping.generatedColumn;\n\t\n\t if (mapping.source != null) {\n\t sourceIdx = this._sources.indexOf(mapping.source);\n\t next += base64VLQ.encode(sourceIdx - previousSource);\n\t previousSource = sourceIdx;\n\t\n\t // lines are stored 0-based in SourceMap spec version 3\n\t next += base64VLQ.encode(mapping.originalLine - 1\n\t - previousOriginalLine);\n\t previousOriginalLine = mapping.originalLine - 1;\n\t\n\t next += base64VLQ.encode(mapping.originalColumn\n\t - previousOriginalColumn);\n\t previousOriginalColumn = mapping.originalColumn;\n\t\n\t if (mapping.name != null) {\n\t nameIdx = this._names.indexOf(mapping.name);\n\t next += base64VLQ.encode(nameIdx - previousName);\n\t previousName = nameIdx;\n\t }\n\t }\n\t\n\t result += next;\n\t }\n\t\n\t return result;\n\t };\n\t\n\tSourceMapGenerator.prototype._generateSourcesContent =\n\t function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {\n\t return aSources.map(function (source) {\n\t if (!this._sourcesContents) {\n\t return null;\n\t }\n\t if (aSourceRoot != null) {\n\t source = util.relative(aSourceRoot, source);\n\t }\n\t var key = util.toSetString(source);\n\t return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)\n\t ? this._sourcesContents[key]\n\t : null;\n\t }, this);\n\t };\n\t\n\t/**\n\t * Externalize the source map.\n\t */\n\tSourceMapGenerator.prototype.toJSON =\n\t function SourceMapGenerator_toJSON() {\n\t var map = {\n\t version: this._version,\n\t sources: this._sources.toArray(),\n\t names: this._names.toArray(),\n\t mappings: this._serializeMappings()\n\t };\n\t if (this._file != null) {\n\t map.file = this._file;\n\t }\n\t if (this._sourceRoot != null) {\n\t map.sourceRoot = this._sourceRoot;\n\t }\n\t if (this._sourcesContents) {\n\t map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);\n\t }\n\t\n\t return map;\n\t };\n\t\n\t/**\n\t * Render the source map being generated to a string.\n\t */\n\tSourceMapGenerator.prototype.toString =\n\t function SourceMapGenerator_toString() {\n\t return JSON.stringify(this.toJSON());\n\t };\n\t\n\texports.SourceMapGenerator = SourceMapGenerator;\n\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t *\n\t * Based on the Base 64 VLQ implementation in Closure Compiler:\n\t * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java\n\t *\n\t * Copyright 2011 The Closure Compiler Authors. All rights reserved.\n\t * Redistribution and use in source and binary forms, with or without\n\t * modification, are permitted provided that the following conditions are\n\t * met:\n\t *\n\t * * Redistributions of source code must retain the above copyright\n\t * notice, this list of conditions and the following disclaimer.\n\t * * Redistributions in binary form must reproduce the above\n\t * copyright notice, this list of conditions and the following\n\t * disclaimer in the documentation and/or other materials provided\n\t * with the distribution.\n\t * * Neither the name of Google Inc. nor the names of its\n\t * contributors may be used to endorse or promote products derived\n\t * from this software without specific prior written permission.\n\t *\n\t * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\t * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n\t * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n\t * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n\t * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n\t * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n\t * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n\t * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n\t * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\t * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\t * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\t */\n\t\n\tvar base64 = __webpack_require__(3);\n\t\n\t// A single base 64 digit can contain 6 bits of data. For the base 64 variable\n\t// length quantities we use in the source map spec, the first bit is the sign,\n\t// the next four bits are the actual value, and the 6th bit is the\n\t// continuation bit. The continuation bit tells us whether there are more\n\t// digits in this value following this digit.\n\t//\n\t// Continuation\n\t// | Sign\n\t// | |\n\t// V V\n\t// 101011\n\t\n\tvar VLQ_BASE_SHIFT = 5;\n\t\n\t// binary: 100000\n\tvar VLQ_BASE = 1 << VLQ_BASE_SHIFT;\n\t\n\t// binary: 011111\n\tvar VLQ_BASE_MASK = VLQ_BASE - 1;\n\t\n\t// binary: 100000\n\tvar VLQ_CONTINUATION_BIT = VLQ_BASE;\n\t\n\t/**\n\t * Converts from a two-complement value to a value where the sign bit is\n\t * placed in the least significant bit. For example, as decimals:\n\t * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)\n\t * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)\n\t */\n\tfunction toVLQSigned(aValue) {\n\t return aValue < 0\n\t ? ((-aValue) << 1) + 1\n\t : (aValue << 1) + 0;\n\t}\n\t\n\t/**\n\t * Converts to a two-complement value from a value where the sign bit is\n\t * placed in the least significant bit. For example, as decimals:\n\t * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1\n\t * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2\n\t */\n\tfunction fromVLQSigned(aValue) {\n\t var isNegative = (aValue & 1) === 1;\n\t var shifted = aValue >> 1;\n\t return isNegative\n\t ? -shifted\n\t : shifted;\n\t}\n\t\n\t/**\n\t * Returns the base 64 VLQ encoded value.\n\t */\n\texports.encode = function base64VLQ_encode(aValue) {\n\t var encoded = \"\";\n\t var digit;\n\t\n\t var vlq = toVLQSigned(aValue);\n\t\n\t do {\n\t digit = vlq & VLQ_BASE_MASK;\n\t vlq >>>= VLQ_BASE_SHIFT;\n\t if (vlq > 0) {\n\t // There are still more digits in this value, so we must make sure the\n\t // continuation bit is marked.\n\t digit |= VLQ_CONTINUATION_BIT;\n\t }\n\t encoded += base64.encode(digit);\n\t } while (vlq > 0);\n\t\n\t return encoded;\n\t};\n\t\n\t/**\n\t * Decodes the next base 64 VLQ value from the given string and returns the\n\t * value and the rest of the string via the out parameter.\n\t */\n\texports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {\n\t var strLen = aStr.length;\n\t var result = 0;\n\t var shift = 0;\n\t var continuation, digit;\n\t\n\t do {\n\t if (aIndex >= strLen) {\n\t throw new Error(\"Expected more digits in base 64 VLQ value.\");\n\t }\n\t\n\t digit = base64.decode(aStr.charCodeAt(aIndex++));\n\t if (digit === -1) {\n\t throw new Error(\"Invalid base64 digit: \" + aStr.charAt(aIndex - 1));\n\t }\n\t\n\t continuation = !!(digit & VLQ_CONTINUATION_BIT);\n\t digit &= VLQ_BASE_MASK;\n\t result = result + (digit << shift);\n\t shift += VLQ_BASE_SHIFT;\n\t } while (continuation);\n\t\n\t aOutParam.value = fromVLQSigned(result);\n\t aOutParam.rest = aIndex;\n\t};\n\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\tvar intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');\n\t\n\t/**\n\t * Encode an integer in the range of 0 to 63 to a single base 64 digit.\n\t */\n\texports.encode = function (number) {\n\t if (0 <= number && number < intToCharMap.length) {\n\t return intToCharMap[number];\n\t }\n\t throw new TypeError(\"Must be between 0 and 63: \" + number);\n\t};\n\t\n\t/**\n\t * Decode a single base 64 character code digit to an integer. Returns -1 on\n\t * failure.\n\t */\n\texports.decode = function (charCode) {\n\t var bigA = 65; // 'A'\n\t var bigZ = 90; // 'Z'\n\t\n\t var littleA = 97; // 'a'\n\t var littleZ = 122; // 'z'\n\t\n\t var zero = 48; // '0'\n\t var nine = 57; // '9'\n\t\n\t var plus = 43; // '+'\n\t var slash = 47; // '/'\n\t\n\t var littleOffset = 26;\n\t var numberOffset = 52;\n\t\n\t // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ\n\t if (bigA <= charCode && charCode <= bigZ) {\n\t return (charCode - bigA);\n\t }\n\t\n\t // 26 - 51: abcdefghijklmnopqrstuvwxyz\n\t if (littleA <= charCode && charCode <= littleZ) {\n\t return (charCode - littleA + littleOffset);\n\t }\n\t\n\t // 52 - 61: 0123456789\n\t if (zero <= charCode && charCode <= nine) {\n\t return (charCode - zero + numberOffset);\n\t }\n\t\n\t // 62: +\n\t if (charCode == plus) {\n\t return 62;\n\t }\n\t\n\t // 63: /\n\t if (charCode == slash) {\n\t return 63;\n\t }\n\t\n\t // Invalid base64 digit.\n\t return -1;\n\t};\n\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\t/**\n\t * This is a helper function for getting values from parameter/options\n\t * objects.\n\t *\n\t * @param args The object we are extracting values from\n\t * @param name The name of the property we are getting.\n\t * @param defaultValue An optional value to return if the property is missing\n\t * from the object. If this is not specified and the property is missing, an\n\t * error will be thrown.\n\t */\n\tfunction getArg(aArgs, aName, aDefaultValue) {\n\t if (aName in aArgs) {\n\t return aArgs[aName];\n\t } else if (arguments.length === 3) {\n\t return aDefaultValue;\n\t } else {\n\t throw new Error('\"' + aName + '\" is a required argument.');\n\t }\n\t}\n\texports.getArg = getArg;\n\t\n\tvar urlRegexp = /^(?:([\\w+\\-.]+):)?\\/\\/(?:(\\w+:\\w+)@)?([\\w.-]*)(?::(\\d+))?(.*)$/;\n\tvar dataUrlRegexp = /^data:.+\\,.+$/;\n\t\n\tfunction urlParse(aUrl) {\n\t var match = aUrl.match(urlRegexp);\n\t if (!match) {\n\t return null;\n\t }\n\t return {\n\t scheme: match[1],\n\t auth: match[2],\n\t host: match[3],\n\t port: match[4],\n\t path: match[5]\n\t };\n\t}\n\texports.urlParse = urlParse;\n\t\n\tfunction urlGenerate(aParsedUrl) {\n\t var url = '';\n\t if (aParsedUrl.scheme) {\n\t url += aParsedUrl.scheme + ':';\n\t }\n\t url += '//';\n\t if (aParsedUrl.auth) {\n\t url += aParsedUrl.auth + '@';\n\t }\n\t if (aParsedUrl.host) {\n\t url += aParsedUrl.host;\n\t }\n\t if (aParsedUrl.port) {\n\t url += \":\" + aParsedUrl.port\n\t }\n\t if (aParsedUrl.path) {\n\t url += aParsedUrl.path;\n\t }\n\t return url;\n\t}\n\texports.urlGenerate = urlGenerate;\n\t\n\t/**\n\t * Normalizes a path, or the path portion of a URL:\n\t *\n\t * - Replaces consecutive slashes with one slash.\n\t * - Removes unnecessary '.' parts.\n\t * - Removes unnecessary '/..' parts.\n\t *\n\t * Based on code in the Node.js 'path' core module.\n\t *\n\t * @param aPath The path or url to normalize.\n\t */\n\tfunction normalize(aPath) {\n\t var path = aPath;\n\t var url = urlParse(aPath);\n\t if (url) {\n\t if (!url.path) {\n\t return aPath;\n\t }\n\t path = url.path;\n\t }\n\t var isAbsolute = exports.isAbsolute(path);\n\t\n\t var parts = path.split(/\\/+/);\n\t for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {\n\t part = parts[i];\n\t if (part === '.') {\n\t parts.splice(i, 1);\n\t } else if (part === '..') {\n\t up++;\n\t } else if (up > 0) {\n\t if (part === '') {\n\t // The first part is blank if the path is absolute. Trying to go\n\t // above the root is a no-op. Therefore we can remove all '..' parts\n\t // directly after the root.\n\t parts.splice(i + 1, up);\n\t up = 0;\n\t } else {\n\t parts.splice(i, 2);\n\t up--;\n\t }\n\t }\n\t }\n\t path = parts.join('/');\n\t\n\t if (path === '') {\n\t path = isAbsolute ? '/' : '.';\n\t }\n\t\n\t if (url) {\n\t url.path = path;\n\t return urlGenerate(url);\n\t }\n\t return path;\n\t}\n\texports.normalize = normalize;\n\t\n\t/**\n\t * Joins two paths/URLs.\n\t *\n\t * @param aRoot The root path or URL.\n\t * @param aPath The path or URL to be joined with the root.\n\t *\n\t * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a\n\t * scheme-relative URL: Then the scheme of aRoot, if any, is prepended\n\t * first.\n\t * - Otherwise aPath is a path. If aRoot is a URL, then its path portion\n\t * is updated with the result and aRoot is returned. Otherwise the result\n\t * is returned.\n\t * - If aPath is absolute, the result is aPath.\n\t * - Otherwise the two paths are joined with a slash.\n\t * - Joining for example 'http://' and 'www.example.com' is also supported.\n\t */\n\tfunction join(aRoot, aPath) {\n\t if (aRoot === \"\") {\n\t aRoot = \".\";\n\t }\n\t if (aPath === \"\") {\n\t aPath = \".\";\n\t }\n\t var aPathUrl = urlParse(aPath);\n\t var aRootUrl = urlParse(aRoot);\n\t if (aRootUrl) {\n\t aRoot = aRootUrl.path || '/';\n\t }\n\t\n\t // `join(foo, '//www.example.org')`\n\t if (aPathUrl && !aPathUrl.scheme) {\n\t if (aRootUrl) {\n\t aPathUrl.scheme = aRootUrl.scheme;\n\t }\n\t return urlGenerate(aPathUrl);\n\t }\n\t\n\t if (aPathUrl || aPath.match(dataUrlRegexp)) {\n\t return aPath;\n\t }\n\t\n\t // `join('http://', 'www.example.com')`\n\t if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {\n\t aRootUrl.host = aPath;\n\t return urlGenerate(aRootUrl);\n\t }\n\t\n\t var joined = aPath.charAt(0) === '/'\n\t ? aPath\n\t : normalize(aRoot.replace(/\\/+$/, '') + '/' + aPath);\n\t\n\t if (aRootUrl) {\n\t aRootUrl.path = joined;\n\t return urlGenerate(aRootUrl);\n\t }\n\t return joined;\n\t}\n\texports.join = join;\n\t\n\texports.isAbsolute = function (aPath) {\n\t return aPath.charAt(0) === '/' || urlRegexp.test(aPath);\n\t};\n\t\n\t/**\n\t * Make a path relative to a URL or another path.\n\t *\n\t * @param aRoot The root path or URL.\n\t * @param aPath The path or URL to be made relative to aRoot.\n\t */\n\tfunction relative(aRoot, aPath) {\n\t if (aRoot === \"\") {\n\t aRoot = \".\";\n\t }\n\t\n\t aRoot = aRoot.replace(/\\/$/, '');\n\t\n\t // It is possible for the path to be above the root. In this case, simply\n\t // checking whether the root is a prefix of the path won't work. Instead, we\n\t // need to remove components from the root one by one, until either we find\n\t // a prefix that fits, or we run out of components to remove.\n\t var level = 0;\n\t while (aPath.indexOf(aRoot + '/') !== 0) {\n\t var index = aRoot.lastIndexOf(\"/\");\n\t if (index < 0) {\n\t return aPath;\n\t }\n\t\n\t // If the only part of the root that is left is the scheme (i.e. http://,\n\t // file:///, etc.), one or more slashes (/), or simply nothing at all, we\n\t // have exhausted all components, so the path is not relative to the root.\n\t aRoot = aRoot.slice(0, index);\n\t if (aRoot.match(/^([^\\/]+:\\/)?\\/*$/)) {\n\t return aPath;\n\t }\n\t\n\t ++level;\n\t }\n\t\n\t // Make sure we add a \"../\" for each component we removed from the root.\n\t return Array(level + 1).join(\"../\") + aPath.substr(aRoot.length + 1);\n\t}\n\texports.relative = relative;\n\t\n\tvar supportsNullProto = (function () {\n\t var obj = Object.create(null);\n\t return !('__proto__' in obj);\n\t}());\n\t\n\tfunction identity (s) {\n\t return s;\n\t}\n\t\n\t/**\n\t * Because behavior goes wacky when you set `__proto__` on objects, we\n\t * have to prefix all the strings in our set with an arbitrary character.\n\t *\n\t * See https://github.com/mozilla/source-map/pull/31 and\n\t * https://github.com/mozilla/source-map/issues/30\n\t *\n\t * @param String aStr\n\t */\n\tfunction toSetString(aStr) {\n\t if (isProtoString(aStr)) {\n\t return '$' + aStr;\n\t }\n\t\n\t return aStr;\n\t}\n\texports.toSetString = supportsNullProto ? identity : toSetString;\n\t\n\tfunction fromSetString(aStr) {\n\t if (isProtoString(aStr)) {\n\t return aStr.slice(1);\n\t }\n\t\n\t return aStr;\n\t}\n\texports.fromSetString = supportsNullProto ? identity : fromSetString;\n\t\n\tfunction isProtoString(s) {\n\t if (!s) {\n\t return false;\n\t }\n\t\n\t var length = s.length;\n\t\n\t if (length < 9 /* \"__proto__\".length */) {\n\t return false;\n\t }\n\t\n\t if (s.charCodeAt(length - 1) !== 95 /* '_' */ ||\n\t s.charCodeAt(length - 2) !== 95 /* '_' */ ||\n\t s.charCodeAt(length - 3) !== 111 /* 'o' */ ||\n\t s.charCodeAt(length - 4) !== 116 /* 't' */ ||\n\t s.charCodeAt(length - 5) !== 111 /* 'o' */ ||\n\t s.charCodeAt(length - 6) !== 114 /* 'r' */ ||\n\t s.charCodeAt(length - 7) !== 112 /* 'p' */ ||\n\t s.charCodeAt(length - 8) !== 95 /* '_' */ ||\n\t s.charCodeAt(length - 9) !== 95 /* '_' */) {\n\t return false;\n\t }\n\t\n\t for (var i = length - 10; i >= 0; i--) {\n\t if (s.charCodeAt(i) !== 36 /* '$' */) {\n\t return false;\n\t }\n\t }\n\t\n\t return true;\n\t}\n\t\n\t/**\n\t * Comparator between two mappings where the original positions are compared.\n\t *\n\t * Optionally pass in `true` as `onlyCompareGenerated` to consider two\n\t * mappings with the same original source/line/column, but different generated\n\t * line and column the same. Useful when searching for a mapping with a\n\t * stubbed out mapping.\n\t */\n\tfunction compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {\n\t var cmp = strcmp(mappingA.source, mappingB.source);\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.originalLine - mappingB.originalLine;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.originalColumn - mappingB.originalColumn;\n\t if (cmp !== 0 || onlyCompareOriginal) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.generatedLine - mappingB.generatedLine;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t return strcmp(mappingA.name, mappingB.name);\n\t}\n\texports.compareByOriginalPositions = compareByOriginalPositions;\n\t\n\t/**\n\t * Comparator between two mappings with deflated source and name indices where\n\t * the generated positions are compared.\n\t *\n\t * Optionally pass in `true` as `onlyCompareGenerated` to consider two\n\t * mappings with the same generated line and column, but different\n\t * source/name/original line and column the same. Useful when searching for a\n\t * mapping with a stubbed out mapping.\n\t */\n\tfunction compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {\n\t var cmp = mappingA.generatedLine - mappingB.generatedLine;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n\t if (cmp !== 0 || onlyCompareGenerated) {\n\t return cmp;\n\t }\n\t\n\t cmp = strcmp(mappingA.source, mappingB.source);\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.originalLine - mappingB.originalLine;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.originalColumn - mappingB.originalColumn;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t return strcmp(mappingA.name, mappingB.name);\n\t}\n\texports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;\n\t\n\tfunction strcmp(aStr1, aStr2) {\n\t if (aStr1 === aStr2) {\n\t return 0;\n\t }\n\t\n\t if (aStr1 === null) {\n\t return 1; // aStr2 !== null\n\t }\n\t\n\t if (aStr2 === null) {\n\t return -1; // aStr1 !== null\n\t }\n\t\n\t if (aStr1 > aStr2) {\n\t return 1;\n\t }\n\t\n\t return -1;\n\t}\n\t\n\t/**\n\t * Comparator between two mappings with inflated source and name strings where\n\t * the generated positions are compared.\n\t */\n\tfunction compareByGeneratedPositionsInflated(mappingA, mappingB) {\n\t var cmp = mappingA.generatedLine - mappingB.generatedLine;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = strcmp(mappingA.source, mappingB.source);\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.originalLine - mappingB.originalLine;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t cmp = mappingA.originalColumn - mappingB.originalColumn;\n\t if (cmp !== 0) {\n\t return cmp;\n\t }\n\t\n\t return strcmp(mappingA.name, mappingB.name);\n\t}\n\texports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;\n\t\n\t/**\n\t * Strip any JSON XSSI avoidance prefix from the string (as documented\n\t * in the source maps specification), and then parse the string as\n\t * JSON.\n\t */\n\tfunction parseSourceMapInput(str) {\n\t return JSON.parse(str.replace(/^\\)]}'[^\\n]*\\n/, ''));\n\t}\n\texports.parseSourceMapInput = parseSourceMapInput;\n\t\n\t/**\n\t * Compute the URL of a source given the the source root, the source's\n\t * URL, and the source map's URL.\n\t */\n\tfunction computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {\n\t sourceURL = sourceURL || '';\n\t\n\t if (sourceRoot) {\n\t // This follows what Chrome does.\n\t if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {\n\t sourceRoot += '/';\n\t }\n\t // The spec says:\n\t // Line 4: An optional source root, useful for relocating source\n\t // files on a server or removing repeated values in the\n\t // “sources” entry. This value is prepended to the individual\n\t // entries in the “source” field.\n\t sourceURL = sourceRoot + sourceURL;\n\t }\n\t\n\t // Historically, SourceMapConsumer did not take the sourceMapURL as\n\t // a parameter. This mode is still somewhat supported, which is why\n\t // this code block is conditional. However, it's preferable to pass\n\t // the source map URL to SourceMapConsumer, so that this function\n\t // can implement the source URL resolution algorithm as outlined in\n\t // the spec. This block is basically the equivalent of:\n\t // new URL(sourceURL, sourceMapURL).toString()\n\t // ... except it avoids using URL, which wasn't available in the\n\t // older releases of node still supported by this library.\n\t //\n\t // The spec says:\n\t // If the sources are not absolute URLs after prepending of the\n\t // “sourceRoot”, the sources are resolved relative to the\n\t // SourceMap (like resolving script src in a html document).\n\t if (sourceMapURL) {\n\t var parsed = urlParse(sourceMapURL);\n\t if (!parsed) {\n\t throw new Error(\"sourceMapURL could not be parsed\");\n\t }\n\t if (parsed.path) {\n\t // Strip the last path component, but keep the \"/\".\n\t var index = parsed.path.lastIndexOf('/');\n\t if (index >= 0) {\n\t parsed.path = parsed.path.substring(0, index + 1);\n\t }\n\t }\n\t sourceURL = join(urlGenerate(parsed), sourceURL);\n\t }\n\t\n\t return normalize(sourceURL);\n\t}\n\texports.computeSourceURL = computeSourceURL;\n\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\tvar util = __webpack_require__(4);\n\tvar has = Object.prototype.hasOwnProperty;\n\tvar hasNativeMap = typeof Map !== \"undefined\";\n\t\n\t/**\n\t * A data structure which is a combination of an array and a set. Adding a new\n\t * member is O(1), testing for membership is O(1), and finding the index of an\n\t * element is O(1). Removing elements from the set is not supported. Only\n\t * strings are supported for membership.\n\t */\n\tfunction ArraySet() {\n\t this._array = [];\n\t this._set = hasNativeMap ? new Map() : Object.create(null);\n\t}\n\t\n\t/**\n\t * Static method for creating ArraySet instances from an existing array.\n\t */\n\tArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {\n\t var set = new ArraySet();\n\t for (var i = 0, len = aArray.length; i < len; i++) {\n\t set.add(aArray[i], aAllowDuplicates);\n\t }\n\t return set;\n\t};\n\t\n\t/**\n\t * Return how many unique items are in this ArraySet. If duplicates have been\n\t * added, than those do not count towards the size.\n\t *\n\t * @returns Number\n\t */\n\tArraySet.prototype.size = function ArraySet_size() {\n\t return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;\n\t};\n\t\n\t/**\n\t * Add the given string to this set.\n\t *\n\t * @param String aStr\n\t */\n\tArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {\n\t var sStr = hasNativeMap ? aStr : util.toSetString(aStr);\n\t var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);\n\t var idx = this._array.length;\n\t if (!isDuplicate || aAllowDuplicates) {\n\t this._array.push(aStr);\n\t }\n\t if (!isDuplicate) {\n\t if (hasNativeMap) {\n\t this._set.set(aStr, idx);\n\t } else {\n\t this._set[sStr] = idx;\n\t }\n\t }\n\t};\n\t\n\t/**\n\t * Is the given string a member of this set?\n\t *\n\t * @param String aStr\n\t */\n\tArraySet.prototype.has = function ArraySet_has(aStr) {\n\t if (hasNativeMap) {\n\t return this._set.has(aStr);\n\t } else {\n\t var sStr = util.toSetString(aStr);\n\t return has.call(this._set, sStr);\n\t }\n\t};\n\t\n\t/**\n\t * What is the index of the given string in the array?\n\t *\n\t * @param String aStr\n\t */\n\tArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {\n\t if (hasNativeMap) {\n\t var idx = this._set.get(aStr);\n\t if (idx >= 0) {\n\t return idx;\n\t }\n\t } else {\n\t var sStr = util.toSetString(aStr);\n\t if (has.call(this._set, sStr)) {\n\t return this._set[sStr];\n\t }\n\t }\n\t\n\t throw new Error('\"' + aStr + '\" is not in the set.');\n\t};\n\t\n\t/**\n\t * What is the element at the given index?\n\t *\n\t * @param Number aIdx\n\t */\n\tArraySet.prototype.at = function ArraySet_at(aIdx) {\n\t if (aIdx >= 0 && aIdx < this._array.length) {\n\t return this._array[aIdx];\n\t }\n\t throw new Error('No element indexed by ' + aIdx);\n\t};\n\t\n\t/**\n\t * Returns the array representation of this set (which has the proper indices\n\t * indicated by indexOf). Note that this is a copy of the internal array used\n\t * for storing the members so that no one can mess with internal state.\n\t */\n\tArraySet.prototype.toArray = function ArraySet_toArray() {\n\t return this._array.slice();\n\t};\n\t\n\texports.ArraySet = ArraySet;\n\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2014 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\tvar util = __webpack_require__(4);\n\t\n\t/**\n\t * Determine whether mappingB is after mappingA with respect to generated\n\t * position.\n\t */\n\tfunction generatedPositionAfter(mappingA, mappingB) {\n\t // Optimized for most common case\n\t var lineA = mappingA.generatedLine;\n\t var lineB = mappingB.generatedLine;\n\t var columnA = mappingA.generatedColumn;\n\t var columnB = mappingB.generatedColumn;\n\t return lineB > lineA || lineB == lineA && columnB >= columnA ||\n\t util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;\n\t}\n\t\n\t/**\n\t * A data structure to provide a sorted view of accumulated mappings in a\n\t * performance conscious manner. It trades a neglibable overhead in general\n\t * case for a large speedup in case of mappings being added in order.\n\t */\n\tfunction MappingList() {\n\t this._array = [];\n\t this._sorted = true;\n\t // Serves as infimum\n\t this._last = {generatedLine: -1, generatedColumn: 0};\n\t}\n\t\n\t/**\n\t * Iterate through internal items. This method takes the same arguments that\n\t * `Array.prototype.forEach` takes.\n\t *\n\t * NOTE: The order of the mappings is NOT guaranteed.\n\t */\n\tMappingList.prototype.unsortedForEach =\n\t function MappingList_forEach(aCallback, aThisArg) {\n\t this._array.forEach(aCallback, aThisArg);\n\t };\n\t\n\t/**\n\t * Add the given source mapping.\n\t *\n\t * @param Object aMapping\n\t */\n\tMappingList.prototype.add = function MappingList_add(aMapping) {\n\t if (generatedPositionAfter(this._last, aMapping)) {\n\t this._last = aMapping;\n\t this._array.push(aMapping);\n\t } else {\n\t this._sorted = false;\n\t this._array.push(aMapping);\n\t }\n\t};\n\t\n\t/**\n\t * Returns the flat, sorted array of mappings. The mappings are sorted by\n\t * generated position.\n\t *\n\t * WARNING: This method returns internal data without copying, for\n\t * performance. The return value must NOT be mutated, and should be treated as\n\t * an immutable borrow. If you want to take ownership, you must make your own\n\t * copy.\n\t */\n\tMappingList.prototype.toArray = function MappingList_toArray() {\n\t if (!this._sorted) {\n\t this._array.sort(util.compareByGeneratedPositionsInflated);\n\t this._sorted = true;\n\t }\n\t return this._array;\n\t};\n\t\n\texports.MappingList = MappingList;\n\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\tvar util = __webpack_require__(4);\n\tvar binarySearch = __webpack_require__(8);\n\tvar ArraySet = __webpack_require__(5).ArraySet;\n\tvar base64VLQ = __webpack_require__(2);\n\tvar quickSort = __webpack_require__(9).quickSort;\n\t\n\tfunction SourceMapConsumer(aSourceMap, aSourceMapURL) {\n\t var sourceMap = aSourceMap;\n\t if (typeof aSourceMap === 'string') {\n\t sourceMap = util.parseSourceMapInput(aSourceMap);\n\t }\n\t\n\t return sourceMap.sections != null\n\t ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)\n\t : new BasicSourceMapConsumer(sourceMap, aSourceMapURL);\n\t}\n\t\n\tSourceMapConsumer.fromSourceMap = function(aSourceMap, aSourceMapURL) {\n\t return BasicSourceMapConsumer.fromSourceMap(aSourceMap, aSourceMapURL);\n\t}\n\t\n\t/**\n\t * The version of the source mapping spec that we are consuming.\n\t */\n\tSourceMapConsumer.prototype._version = 3;\n\t\n\t// `__generatedMappings` and `__originalMappings` are arrays that hold the\n\t// parsed mapping coordinates from the source map's \"mappings\" attribute. They\n\t// are lazily instantiated, accessed via the `_generatedMappings` and\n\t// `_originalMappings` getters respectively, and we only parse the mappings\n\t// and create these arrays once queried for a source location. We jump through\n\t// these hoops because there can be many thousands of mappings, and parsing\n\t// them is expensive, so we only want to do it if we must.\n\t//\n\t// Each object in the arrays is of the form:\n\t//\n\t// {\n\t// generatedLine: The line number in the generated code,\n\t// generatedColumn: The column number in the generated code,\n\t// source: The path to the original source file that generated this\n\t// chunk of code,\n\t// originalLine: The line number in the original source that\n\t// corresponds to this chunk of generated code,\n\t// originalColumn: The column number in the original source that\n\t// corresponds to this chunk of generated code,\n\t// name: The name of the original symbol which generated this chunk of\n\t// code.\n\t// }\n\t//\n\t// All properties except for `generatedLine` and `generatedColumn` can be\n\t// `null`.\n\t//\n\t// `_generatedMappings` is ordered by the generated positions.\n\t//\n\t// `_originalMappings` is ordered by the original positions.\n\t\n\tSourceMapConsumer.prototype.__generatedMappings = null;\n\tObject.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {\n\t configurable: true,\n\t enumerable: true,\n\t get: function () {\n\t if (!this.__generatedMappings) {\n\t this._parseMappings(this._mappings, this.sourceRoot);\n\t }\n\t\n\t return this.__generatedMappings;\n\t }\n\t});\n\t\n\tSourceMapConsumer.prototype.__originalMappings = null;\n\tObject.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {\n\t configurable: true,\n\t enumerable: true,\n\t get: function () {\n\t if (!this.__originalMappings) {\n\t this._parseMappings(this._mappings, this.sourceRoot);\n\t }\n\t\n\t return this.__originalMappings;\n\t }\n\t});\n\t\n\tSourceMapConsumer.prototype._charIsMappingSeparator =\n\t function SourceMapConsumer_charIsMappingSeparator(aStr, index) {\n\t var c = aStr.charAt(index);\n\t return c === \";\" || c === \",\";\n\t };\n\t\n\t/**\n\t * Parse the mappings in a string in to a data structure which we can easily\n\t * query (the ordered arrays in the `this.__generatedMappings` and\n\t * `this.__originalMappings` properties).\n\t */\n\tSourceMapConsumer.prototype._parseMappings =\n\t function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {\n\t throw new Error(\"Subclasses must implement _parseMappings\");\n\t };\n\t\n\tSourceMapConsumer.GENERATED_ORDER = 1;\n\tSourceMapConsumer.ORIGINAL_ORDER = 2;\n\t\n\tSourceMapConsumer.GREATEST_LOWER_BOUND = 1;\n\tSourceMapConsumer.LEAST_UPPER_BOUND = 2;\n\t\n\t/**\n\t * Iterate over each mapping between an original source/line/column and a\n\t * generated line/column in this source map.\n\t *\n\t * @param Function aCallback\n\t * The function that is called with each mapping.\n\t * @param Object aContext\n\t * Optional. If specified, this object will be the value of `this` every\n\t * time that `aCallback` is called.\n\t * @param aOrder\n\t * Either `SourceMapConsumer.GENERATED_ORDER` or\n\t * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to\n\t * iterate over the mappings sorted by the generated file's line/column\n\t * order or the original's source/line/column order, respectively. Defaults to\n\t * `SourceMapConsumer.GENERATED_ORDER`.\n\t */\n\tSourceMapConsumer.prototype.eachMapping =\n\t function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {\n\t var context = aContext || null;\n\t var order = aOrder || SourceMapConsumer.GENERATED_ORDER;\n\t\n\t var mappings;\n\t switch (order) {\n\t case SourceMapConsumer.GENERATED_ORDER:\n\t mappings = this._generatedMappings;\n\t break;\n\t case SourceMapConsumer.ORIGINAL_ORDER:\n\t mappings = this._originalMappings;\n\t break;\n\t default:\n\t throw new Error(\"Unknown order of iteration.\");\n\t }\n\t\n\t var sourceRoot = this.sourceRoot;\n\t mappings.map(function (mapping) {\n\t var source = mapping.source === null ? null : this._sources.at(mapping.source);\n\t source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);\n\t return {\n\t source: source,\n\t generatedLine: mapping.generatedLine,\n\t generatedColumn: mapping.generatedColumn,\n\t originalLine: mapping.originalLine,\n\t originalColumn: mapping.originalColumn,\n\t name: mapping.name === null ? null : this._names.at(mapping.name)\n\t };\n\t }, this).forEach(aCallback, context);\n\t };\n\t\n\t/**\n\t * Returns all generated line and column information for the original source,\n\t * line, and column provided. If no column is provided, returns all mappings\n\t * corresponding to a either the line we are searching for or the next\n\t * closest line that has any mappings. Otherwise, returns all mappings\n\t * corresponding to the given line and either the column we are searching for\n\t * or the next closest column that has any offsets.\n\t *\n\t * The only argument is an object with the following properties:\n\t *\n\t * - source: The filename of the original source.\n\t * - line: The line number in the original source. The line number is 1-based.\n\t * - column: Optional. the column number in the original source.\n\t * The column number is 0-based.\n\t *\n\t * and an array of objects is returned, each with the following properties:\n\t *\n\t * - line: The line number in the generated source, or null. The\n\t * line number is 1-based.\n\t * - column: The column number in the generated source, or null.\n\t * The column number is 0-based.\n\t */\n\tSourceMapConsumer.prototype.allGeneratedPositionsFor =\n\t function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {\n\t var line = util.getArg(aArgs, 'line');\n\t\n\t // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping\n\t // returns the index of the closest mapping less than the needle. By\n\t // setting needle.originalColumn to 0, we thus find the last mapping for\n\t // the given line, provided such a mapping exists.\n\t var needle = {\n\t source: util.getArg(aArgs, 'source'),\n\t originalLine: line,\n\t originalColumn: util.getArg(aArgs, 'column', 0)\n\t };\n\t\n\t needle.source = this._findSourceIndex(needle.source);\n\t if (needle.source < 0) {\n\t return [];\n\t }\n\t\n\t var mappings = [];\n\t\n\t var index = this._findMapping(needle,\n\t this._originalMappings,\n\t \"originalLine\",\n\t \"originalColumn\",\n\t util.compareByOriginalPositions,\n\t binarySearch.LEAST_UPPER_BOUND);\n\t if (index >= 0) {\n\t var mapping = this._originalMappings[index];\n\t\n\t if (aArgs.column === undefined) {\n\t var originalLine = mapping.originalLine;\n\t\n\t // Iterate until either we run out of mappings, or we run into\n\t // a mapping for a different line than the one we found. Since\n\t // mappings are sorted, this is guaranteed to find all mappings for\n\t // the line we found.\n\t while (mapping && mapping.originalLine === originalLine) {\n\t mappings.push({\n\t line: util.getArg(mapping, 'generatedLine', null),\n\t column: util.getArg(mapping, 'generatedColumn', null),\n\t lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)\n\t });\n\t\n\t mapping = this._originalMappings[++index];\n\t }\n\t } else {\n\t var originalColumn = mapping.originalColumn;\n\t\n\t // Iterate until either we run out of mappings, or we run into\n\t // a mapping for a different line than the one we were searching for.\n\t // Since mappings are sorted, this is guaranteed to find all mappings for\n\t // the line we are searching for.\n\t while (mapping &&\n\t mapping.originalLine === line &&\n\t mapping.originalColumn == originalColumn) {\n\t mappings.push({\n\t line: util.getArg(mapping, 'generatedLine', null),\n\t column: util.getArg(mapping, 'generatedColumn', null),\n\t lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)\n\t });\n\t\n\t mapping = this._originalMappings[++index];\n\t }\n\t }\n\t }\n\t\n\t return mappings;\n\t };\n\t\n\texports.SourceMapConsumer = SourceMapConsumer;\n\t\n\t/**\n\t * A BasicSourceMapConsumer instance represents a parsed source map which we can\n\t * query for information about the original file positions by giving it a file\n\t * position in the generated source.\n\t *\n\t * The first parameter is the raw source map (either as a JSON string, or\n\t * already parsed to an object). According to the spec, source maps have the\n\t * following attributes:\n\t *\n\t * - version: Which version of the source map spec this map is following.\n\t * - sources: An array of URLs to the original source files.\n\t * - names: An array of identifiers which can be referrenced by individual mappings.\n\t * - sourceRoot: Optional. The URL root from which all sources are relative.\n\t * - sourcesContent: Optional. An array of contents of the original source files.\n\t * - mappings: A string of base64 VLQs which contain the actual mappings.\n\t * - file: Optional. The generated file this source map is associated with.\n\t *\n\t * Here is an example source map, taken from the source map spec[0]:\n\t *\n\t * {\n\t * version : 3,\n\t * file: \"out.js\",\n\t * sourceRoot : \"\",\n\t * sources: [\"foo.js\", \"bar.js\"],\n\t * names: [\"src\", \"maps\", \"are\", \"fun\"],\n\t * mappings: \"AA,AB;;ABCDE;\"\n\t * }\n\t *\n\t * The second parameter, if given, is a string whose value is the URL\n\t * at which the source map was found. This URL is used to compute the\n\t * sources array.\n\t *\n\t * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#\n\t */\n\tfunction BasicSourceMapConsumer(aSourceMap, aSourceMapURL) {\n\t var sourceMap = aSourceMap;\n\t if (typeof aSourceMap === 'string') {\n\t sourceMap = util.parseSourceMapInput(aSourceMap);\n\t }\n\t\n\t var version = util.getArg(sourceMap, 'version');\n\t var sources = util.getArg(sourceMap, 'sources');\n\t // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which\n\t // requires the array) to play nice here.\n\t var names = util.getArg(sourceMap, 'names', []);\n\t var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);\n\t var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);\n\t var mappings = util.getArg(sourceMap, 'mappings');\n\t var file = util.getArg(sourceMap, 'file', null);\n\t\n\t // Once again, Sass deviates from the spec and supplies the version as a\n\t // string rather than a number, so we use loose equality checking here.\n\t if (version != this._version) {\n\t throw new Error('Unsupported version: ' + version);\n\t }\n\t\n\t if (sourceRoot) {\n\t sourceRoot = util.normalize(sourceRoot);\n\t }\n\t\n\t sources = sources\n\t .map(String)\n\t // Some source maps produce relative source paths like \"./foo.js\" instead of\n\t // \"foo.js\". Normalize these first so that future comparisons will succeed.\n\t // See bugzil.la/1090768.\n\t .map(util.normalize)\n\t // Always ensure that absolute sources are internally stored relative to\n\t // the source root, if the source root is absolute. Not doing this would\n\t // be particularly problematic when the source root is a prefix of the\n\t // source (valid, but why??). See github issue #199 and bugzil.la/1188982.\n\t .map(function (source) {\n\t return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source)\n\t ? util.relative(sourceRoot, source)\n\t : source;\n\t });\n\t\n\t // Pass `true` below to allow duplicate names and sources. While source maps\n\t // are intended to be compressed and deduplicated, the TypeScript compiler\n\t // sometimes generates source maps with duplicates in them. See Github issue\n\t // #72 and bugzil.la/889492.\n\t this._names = ArraySet.fromArray(names.map(String), true);\n\t this._sources = ArraySet.fromArray(sources, true);\n\t\n\t this._absoluteSources = this._sources.toArray().map(function (s) {\n\t return util.computeSourceURL(sourceRoot, s, aSourceMapURL);\n\t });\n\t\n\t this.sourceRoot = sourceRoot;\n\t this.sourcesContent = sourcesContent;\n\t this._mappings = mappings;\n\t this._sourceMapURL = aSourceMapURL;\n\t this.file = file;\n\t}\n\t\n\tBasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);\n\tBasicSourceMapConsumer.prototype.consumer = SourceMapConsumer;\n\t\n\t/**\n\t * Utility function to find the index of a source. Returns -1 if not\n\t * found.\n\t */\n\tBasicSourceMapConsumer.prototype._findSourceIndex = function(aSource) {\n\t var relativeSource = aSource;\n\t if (this.sourceRoot != null) {\n\t relativeSource = util.relative(this.sourceRoot, relativeSource);\n\t }\n\t\n\t if (this._sources.has(relativeSource)) {\n\t return this._sources.indexOf(relativeSource);\n\t }\n\t\n\t // Maybe aSource is an absolute URL as returned by |sources|. In\n\t // this case we can't simply undo the transform.\n\t var i;\n\t for (i = 0; i < this._absoluteSources.length; ++i) {\n\t if (this._absoluteSources[i] == aSource) {\n\t return i;\n\t }\n\t }\n\t\n\t return -1;\n\t};\n\t\n\t/**\n\t * Create a BasicSourceMapConsumer from a SourceMapGenerator.\n\t *\n\t * @param SourceMapGenerator aSourceMap\n\t * The source map that will be consumed.\n\t * @param String aSourceMapURL\n\t * The URL at which the source map can be found (optional)\n\t * @returns BasicSourceMapConsumer\n\t */\n\tBasicSourceMapConsumer.fromSourceMap =\n\t function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) {\n\t var smc = Object.create(BasicSourceMapConsumer.prototype);\n\t\n\t var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);\n\t var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);\n\t smc.sourceRoot = aSourceMap._sourceRoot;\n\t smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),\n\t smc.sourceRoot);\n\t smc.file = aSourceMap._file;\n\t smc._sourceMapURL = aSourceMapURL;\n\t smc._absoluteSources = smc._sources.toArray().map(function (s) {\n\t return util.computeSourceURL(smc.sourceRoot, s, aSourceMapURL);\n\t });\n\t\n\t // Because we are modifying the entries (by converting string sources and\n\t // names to indices into the sources and names ArraySets), we have to make\n\t // a copy of the entry or else bad things happen. Shared mutable state\n\t // strikes again! See github issue #191.\n\t\n\t var generatedMappings = aSourceMap._mappings.toArray().slice();\n\t var destGeneratedMappings = smc.__generatedMappings = [];\n\t var destOriginalMappings = smc.__originalMappings = [];\n\t\n\t for (var i = 0, length = generatedMappings.length; i < length; i++) {\n\t var srcMapping = generatedMappings[i];\n\t var destMapping = new Mapping;\n\t destMapping.generatedLine = srcMapping.generatedLine;\n\t destMapping.generatedColumn = srcMapping.generatedColumn;\n\t\n\t if (srcMapping.source) {\n\t destMapping.source = sources.indexOf(srcMapping.source);\n\t destMapping.originalLine = srcMapping.originalLine;\n\t destMapping.originalColumn = srcMapping.originalColumn;\n\t\n\t if (srcMapping.name) {\n\t destMapping.name = names.indexOf(srcMapping.name);\n\t }\n\t\n\t destOriginalMappings.push(destMapping);\n\t }\n\t\n\t destGeneratedMappings.push(destMapping);\n\t }\n\t\n\t quickSort(smc.__originalMappings, util.compareByOriginalPositions);\n\t\n\t return smc;\n\t };\n\t\n\t/**\n\t * The version of the source mapping spec that we are consuming.\n\t */\n\tBasicSourceMapConsumer.prototype._version = 3;\n\t\n\t/**\n\t * The list of original sources.\n\t */\n\tObject.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {\n\t get: function () {\n\t return this._absoluteSources.slice();\n\t }\n\t});\n\t\n\t/**\n\t * Provide the JIT with a nice shape / hidden class.\n\t */\n\tfunction Mapping() {\n\t this.generatedLine = 0;\n\t this.generatedColumn = 0;\n\t this.source = null;\n\t this.originalLine = null;\n\t this.originalColumn = null;\n\t this.name = null;\n\t}\n\t\n\t/**\n\t * Parse the mappings in a string in to a data structure which we can easily\n\t * query (the ordered arrays in the `this.__generatedMappings` and\n\t * `this.__originalMappings` properties).\n\t */\n\tBasicSourceMapConsumer.prototype._parseMappings =\n\t function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {\n\t var generatedLine = 1;\n\t var previousGeneratedColumn = 0;\n\t var previousOriginalLine = 0;\n\t var previousOriginalColumn = 0;\n\t var previousSource = 0;\n\t var previousName = 0;\n\t var length = aStr.length;\n\t var index = 0;\n\t var cachedSegments = {};\n\t var temp = {};\n\t var originalMappings = [];\n\t var generatedMappings = [];\n\t var mapping, str, segment, end, value;\n\t\n\t while (index < length) {\n\t if (aStr.charAt(index) === ';') {\n\t generatedLine++;\n\t index++;\n\t previousGeneratedColumn = 0;\n\t }\n\t else if (aStr.charAt(index) === ',') {\n\t index++;\n\t }\n\t else {\n\t mapping = new Mapping();\n\t mapping.generatedLine = generatedLine;\n\t\n\t // Because each offset is encoded relative to the previous one,\n\t // many segments often have the same encoding. We can exploit this\n\t // fact by caching the parsed variable length fields of each segment,\n\t // allowing us to avoid a second parse if we encounter the same\n\t // segment again.\n\t for (end = index; end < length; end++) {\n\t if (this._charIsMappingSeparator(aStr, end)) {\n\t break;\n\t }\n\t }\n\t str = aStr.slice(index, end);\n\t\n\t segment = cachedSegments[str];\n\t if (segment) {\n\t index += str.length;\n\t } else {\n\t segment = [];\n\t while (index < end) {\n\t base64VLQ.decode(aStr, index, temp);\n\t value = temp.value;\n\t index = temp.rest;\n\t segment.push(value);\n\t }\n\t\n\t if (segment.length === 2) {\n\t throw new Error('Found a source, but no line and column');\n\t }\n\t\n\t if (segment.length === 3) {\n\t throw new Error('Found a source and line, but no column');\n\t }\n\t\n\t cachedSegments[str] = segment;\n\t }\n\t\n\t // Generated column.\n\t mapping.generatedColumn = previousGeneratedColumn + segment[0];\n\t previousGeneratedColumn = mapping.generatedColumn;\n\t\n\t if (segment.length > 1) {\n\t // Original source.\n\t mapping.source = previousSource + segment[1];\n\t previousSource += segment[1];\n\t\n\t // Original line.\n\t mapping.originalLine = previousOriginalLine + segment[2];\n\t previousOriginalLine = mapping.originalLine;\n\t // Lines are stored 0-based\n\t mapping.originalLine += 1;\n\t\n\t // Original column.\n\t mapping.originalColumn = previousOriginalColumn + segment[3];\n\t previousOriginalColumn = mapping.originalColumn;\n\t\n\t if (segment.length > 4) {\n\t // Original name.\n\t mapping.name = previousName + segment[4];\n\t previousName += segment[4];\n\t }\n\t }\n\t\n\t generatedMappings.push(mapping);\n\t if (typeof mapping.originalLine === 'number') {\n\t originalMappings.push(mapping);\n\t }\n\t }\n\t }\n\t\n\t quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated);\n\t this.__generatedMappings = generatedMappings;\n\t\n\t quickSort(originalMappings, util.compareByOriginalPositions);\n\t this.__originalMappings = originalMappings;\n\t };\n\t\n\t/**\n\t * Find the mapping that best matches the hypothetical \"needle\" mapping that\n\t * we are searching for in the given \"haystack\" of mappings.\n\t */\n\tBasicSourceMapConsumer.prototype._findMapping =\n\t function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName,\n\t aColumnName, aComparator, aBias) {\n\t // To return the position we are searching for, we must first find the\n\t // mapping for the given position and then return the opposite position it\n\t // points to. Because the mappings are sorted, we can use binary search to\n\t // find the best mapping.\n\t\n\t if (aNeedle[aLineName] <= 0) {\n\t throw new TypeError('Line must be greater than or equal to 1, got '\n\t + aNeedle[aLineName]);\n\t }\n\t if (aNeedle[aColumnName] < 0) {\n\t throw new TypeError('Column must be greater than or equal to 0, got '\n\t + aNeedle[aColumnName]);\n\t }\n\t\n\t return binarySearch.search(aNeedle, aMappings, aComparator, aBias);\n\t };\n\t\n\t/**\n\t * Compute the last column for each generated mapping. The last column is\n\t * inclusive.\n\t */\n\tBasicSourceMapConsumer.prototype.computeColumnSpans =\n\t function SourceMapConsumer_computeColumnSpans() {\n\t for (var index = 0; index < this._generatedMappings.length; ++index) {\n\t var mapping = this._generatedMappings[index];\n\t\n\t // Mappings do not contain a field for the last generated columnt. We\n\t // can come up with an optimistic estimate, however, by assuming that\n\t // mappings are contiguous (i.e. given two consecutive mappings, the\n\t // first mapping ends where the second one starts).\n\t if (index + 1 < this._generatedMappings.length) {\n\t var nextMapping = this._generatedMappings[index + 1];\n\t\n\t if (mapping.generatedLine === nextMapping.generatedLine) {\n\t mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1;\n\t continue;\n\t }\n\t }\n\t\n\t // The last mapping for each line spans the entire line.\n\t mapping.lastGeneratedColumn = Infinity;\n\t }\n\t };\n\t\n\t/**\n\t * Returns the original source, line, and column information for the generated\n\t * source's line and column positions provided. The only argument is an object\n\t * with the following properties:\n\t *\n\t * - line: The line number in the generated source. The line number\n\t * is 1-based.\n\t * - column: The column number in the generated source. The column\n\t * number is 0-based.\n\t * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or\n\t * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the\n\t * closest element that is smaller than or greater than the one we are\n\t * searching for, respectively, if the exact element cannot be found.\n\t * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.\n\t *\n\t * and an object is returned with the following properties:\n\t *\n\t * - source: The original source file, or null.\n\t * - line: The line number in the original source, or null. The\n\t * line number is 1-based.\n\t * - column: The column number in the original source, or null. The\n\t * column number is 0-based.\n\t * - name: The original identifier, or null.\n\t */\n\tBasicSourceMapConsumer.prototype.originalPositionFor =\n\t function SourceMapConsumer_originalPositionFor(aArgs) {\n\t var needle = {\n\t generatedLine: util.getArg(aArgs, 'line'),\n\t generatedColumn: util.getArg(aArgs, 'column')\n\t };\n\t\n\t var index = this._findMapping(\n\t needle,\n\t this._generatedMappings,\n\t \"generatedLine\",\n\t \"generatedColumn\",\n\t util.compareByGeneratedPositionsDeflated,\n\t util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)\n\t );\n\t\n\t if (index >= 0) {\n\t var mapping = this._generatedMappings[index];\n\t\n\t if (mapping.generatedLine === needle.generatedLine) {\n\t var source = util.getArg(mapping, 'source', null);\n\t if (source !== null) {\n\t source = this._sources.at(source);\n\t source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL);\n\t }\n\t var name = util.getArg(mapping, 'name', null);\n\t if (name !== null) {\n\t name = this._names.at(name);\n\t }\n\t return {\n\t source: source,\n\t line: util.getArg(mapping, 'originalLine', null),\n\t column: util.getArg(mapping, 'originalColumn', null),\n\t name: name\n\t };\n\t }\n\t }\n\t\n\t return {\n\t source: null,\n\t line: null,\n\t column: null,\n\t name: null\n\t };\n\t };\n\t\n\t/**\n\t * Return true if we have the source content for every source in the source\n\t * map, false otherwise.\n\t */\n\tBasicSourceMapConsumer.prototype.hasContentsOfAllSources =\n\t function BasicSourceMapConsumer_hasContentsOfAllSources() {\n\t if (!this.sourcesContent) {\n\t return false;\n\t }\n\t return this.sourcesContent.length >= this._sources.size() &&\n\t !this.sourcesContent.some(function (sc) { return sc == null; });\n\t };\n\t\n\t/**\n\t * Returns the original source content. The only argument is the url of the\n\t * original source file. Returns null if no original source content is\n\t * available.\n\t */\n\tBasicSourceMapConsumer.prototype.sourceContentFor =\n\t function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {\n\t if (!this.sourcesContent) {\n\t return null;\n\t }\n\t\n\t var index = this._findSourceIndex(aSource);\n\t if (index >= 0) {\n\t return this.sourcesContent[index];\n\t }\n\t\n\t var relativeSource = aSource;\n\t if (this.sourceRoot != null) {\n\t relativeSource = util.relative(this.sourceRoot, relativeSource);\n\t }\n\t\n\t var url;\n\t if (this.sourceRoot != null\n\t && (url = util.urlParse(this.sourceRoot))) {\n\t // XXX: file:// URIs and absolute paths lead to unexpected behavior for\n\t // many users. We can help them out when they expect file:// URIs to\n\t // behave like it would if they were running a local HTTP server. See\n\t // https://bugzilla.mozilla.org/show_bug.cgi?id=885597.\n\t var fileUriAbsPath = relativeSource.replace(/^file:\\/\\//, \"\");\n\t if (url.scheme == \"file\"\n\t && this._sources.has(fileUriAbsPath)) {\n\t return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]\n\t }\n\t\n\t if ((!url.path || url.path == \"/\")\n\t && this._sources.has(\"/\" + relativeSource)) {\n\t return this.sourcesContent[this._sources.indexOf(\"/\" + relativeSource)];\n\t }\n\t }\n\t\n\t // This function is used recursively from\n\t // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we\n\t // don't want to throw if we can't find the source - we just want to\n\t // return null, so we provide a flag to exit gracefully.\n\t if (nullOnMissing) {\n\t return null;\n\t }\n\t else {\n\t throw new Error('\"' + relativeSource + '\" is not in the SourceMap.');\n\t }\n\t };\n\t\n\t/**\n\t * Returns the generated line and column information for the original source,\n\t * line, and column positions provided. The only argument is an object with\n\t * the following properties:\n\t *\n\t * - source: The filename of the original source.\n\t * - line: The line number in the original source. The line number\n\t * is 1-based.\n\t * - column: The column number in the original source. The column\n\t * number is 0-based.\n\t * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or\n\t * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the\n\t * closest element that is smaller than or greater than the one we are\n\t * searching for, respectively, if the exact element cannot be found.\n\t * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.\n\t *\n\t * and an object is returned with the following properties:\n\t *\n\t * - line: The line number in the generated source, or null. The\n\t * line number is 1-based.\n\t * - column: The column number in the generated source, or null.\n\t * The column number is 0-based.\n\t */\n\tBasicSourceMapConsumer.prototype.generatedPositionFor =\n\t function SourceMapConsumer_generatedPositionFor(aArgs) {\n\t var source = util.getArg(aArgs, 'source');\n\t source = this._findSourceIndex(source);\n\t if (source < 0) {\n\t return {\n\t line: null,\n\t column: null,\n\t lastColumn: null\n\t };\n\t }\n\t\n\t var needle = {\n\t source: source,\n\t originalLine: util.getArg(aArgs, 'line'),\n\t originalColumn: util.getArg(aArgs, 'column')\n\t };\n\t\n\t var index = this._findMapping(\n\t needle,\n\t this._originalMappings,\n\t \"originalLine\",\n\t \"originalColumn\",\n\t util.compareByOriginalPositions,\n\t util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)\n\t );\n\t\n\t if (index >= 0) {\n\t var mapping = this._originalMappings[index];\n\t\n\t if (mapping.source === needle.source) {\n\t return {\n\t line: util.getArg(mapping, 'generatedLine', null),\n\t column: util.getArg(mapping, 'generatedColumn', null),\n\t lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)\n\t };\n\t }\n\t }\n\t\n\t return {\n\t line: null,\n\t column: null,\n\t lastColumn: null\n\t };\n\t };\n\t\n\texports.BasicSourceMapConsumer = BasicSourceMapConsumer;\n\t\n\t/**\n\t * An IndexedSourceMapConsumer instance represents a parsed source map which\n\t * we can query for information. It differs from BasicSourceMapConsumer in\n\t * that it takes \"indexed\" source maps (i.e. ones with a \"sections\" field) as\n\t * input.\n\t *\n\t * The first parameter is a raw source map (either as a JSON string, or already\n\t * parsed to an object). According to the spec for indexed source maps, they\n\t * have the following attributes:\n\t *\n\t * - version: Which version of the source map spec this map is following.\n\t * - file: Optional. The generated file this source map is associated with.\n\t * - sections: A list of section definitions.\n\t *\n\t * Each value under the \"sections\" field has two fields:\n\t * - offset: The offset into the original specified at which this section\n\t * begins to apply, defined as an object with a \"line\" and \"column\"\n\t * field.\n\t * - map: A source map definition. This source map could also be indexed,\n\t * but doesn't have to be.\n\t *\n\t * Instead of the \"map\" field, it's also possible to have a \"url\" field\n\t * specifying a URL to retrieve a source map from, but that's currently\n\t * unsupported.\n\t *\n\t * Here's an example source map, taken from the source map spec[0], but\n\t * modified to omit a section which uses the \"url\" field.\n\t *\n\t * {\n\t * version : 3,\n\t * file: \"app.js\",\n\t * sections: [{\n\t * offset: {line:100, column:10},\n\t * map: {\n\t * version : 3,\n\t * file: \"section.js\",\n\t * sources: [\"foo.js\", \"bar.js\"],\n\t * names: [\"src\", \"maps\", \"are\", \"fun\"],\n\t * mappings: \"AAAA,E;;ABCDE;\"\n\t * }\n\t * }],\n\t * }\n\t *\n\t * The second parameter, if given, is a string whose value is the URL\n\t * at which the source map was found. This URL is used to compute the\n\t * sources array.\n\t *\n\t * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt\n\t */\n\tfunction IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {\n\t var sourceMap = aSourceMap;\n\t if (typeof aSourceMap === 'string') {\n\t sourceMap = util.parseSourceMapInput(aSourceMap);\n\t }\n\t\n\t var version = util.getArg(sourceMap, 'version');\n\t var sections = util.getArg(sourceMap, 'sections');\n\t\n\t if (version != this._version) {\n\t throw new Error('Unsupported version: ' + version);\n\t }\n\t\n\t this._sources = new ArraySet();\n\t this._names = new ArraySet();\n\t\n\t var lastOffset = {\n\t line: -1,\n\t column: 0\n\t };\n\t this._sections = sections.map(function (s) {\n\t if (s.url) {\n\t // The url field will require support for asynchronicity.\n\t // See https://github.com/mozilla/source-map/issues/16\n\t throw new Error('Support for url field in sections not implemented.');\n\t }\n\t var offset = util.getArg(s, 'offset');\n\t var offsetLine = util.getArg(offset, 'line');\n\t var offsetColumn = util.getArg(offset, 'column');\n\t\n\t if (offsetLine < lastOffset.line ||\n\t (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) {\n\t throw new Error('Section offsets must be ordered and non-overlapping.');\n\t }\n\t lastOffset = offset;\n\t\n\t return {\n\t generatedOffset: {\n\t // The offset fields are 0-based, but we use 1-based indices when\n\t // encoding/decoding from VLQ.\n\t generatedLine: offsetLine + 1,\n\t generatedColumn: offsetColumn + 1\n\t },\n\t consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL)\n\t }\n\t });\n\t}\n\t\n\tIndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);\n\tIndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer;\n\t\n\t/**\n\t * The version of the source mapping spec that we are consuming.\n\t */\n\tIndexedSourceMapConsumer.prototype._version = 3;\n\t\n\t/**\n\t * The list of original sources.\n\t */\n\tObject.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', {\n\t get: function () {\n\t var sources = [];\n\t for (var i = 0; i < this._sections.length; i++) {\n\t for (var j = 0; j < this._sections[i].consumer.sources.length; j++) {\n\t sources.push(this._sections[i].consumer.sources[j]);\n\t }\n\t }\n\t return sources;\n\t }\n\t});\n\t\n\t/**\n\t * Returns the original source, line, and column information for the generated\n\t * source's line and column positions provided. The only argument is an object\n\t * with the following properties:\n\t *\n\t * - line: The line number in the generated source. The line number\n\t * is 1-based.\n\t * - column: The column number in the generated source. The column\n\t * number is 0-based.\n\t *\n\t * and an object is returned with the following properties:\n\t *\n\t * - source: The original source file, or null.\n\t * - line: The line number in the original source, or null. The\n\t * line number is 1-based.\n\t * - column: The column number in the original source, or null. The\n\t * column number is 0-based.\n\t * - name: The original identifier, or null.\n\t */\n\tIndexedSourceMapConsumer.prototype.originalPositionFor =\n\t function IndexedSourceMapConsumer_originalPositionFor(aArgs) {\n\t var needle = {\n\t generatedLine: util.getArg(aArgs, 'line'),\n\t generatedColumn: util.getArg(aArgs, 'column')\n\t };\n\t\n\t // Find the section containing the generated position we're trying to map\n\t // to an original position.\n\t var sectionIndex = binarySearch.search(needle, this._sections,\n\t function(needle, section) {\n\t var cmp = needle.generatedLine - section.generatedOffset.generatedLine;\n\t if (cmp) {\n\t return cmp;\n\t }\n\t\n\t return (needle.generatedColumn -\n\t section.generatedOffset.generatedColumn);\n\t });\n\t var section = this._sections[sectionIndex];\n\t\n\t if (!section) {\n\t return {\n\t source: null,\n\t line: null,\n\t column: null,\n\t name: null\n\t };\n\t }\n\t\n\t return section.consumer.originalPositionFor({\n\t line: needle.generatedLine -\n\t (section.generatedOffset.generatedLine - 1),\n\t column: needle.generatedColumn -\n\t (section.generatedOffset.generatedLine === needle.generatedLine\n\t ? section.generatedOffset.generatedColumn - 1\n\t : 0),\n\t bias: aArgs.bias\n\t });\n\t };\n\t\n\t/**\n\t * Return true if we have the source content for every source in the source\n\t * map, false otherwise.\n\t */\n\tIndexedSourceMapConsumer.prototype.hasContentsOfAllSources =\n\t function IndexedSourceMapConsumer_hasContentsOfAllSources() {\n\t return this._sections.every(function (s) {\n\t return s.consumer.hasContentsOfAllSources();\n\t });\n\t };\n\t\n\t/**\n\t * Returns the original source content. The only argument is the url of the\n\t * original source file. Returns null if no original source content is\n\t * available.\n\t */\n\tIndexedSourceMapConsumer.prototype.sourceContentFor =\n\t function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {\n\t for (var i = 0; i < this._sections.length; i++) {\n\t var section = this._sections[i];\n\t\n\t var content = section.consumer.sourceContentFor(aSource, true);\n\t if (content) {\n\t return content;\n\t }\n\t }\n\t if (nullOnMissing) {\n\t return null;\n\t }\n\t else {\n\t throw new Error('\"' + aSource + '\" is not in the SourceMap.');\n\t }\n\t };\n\t\n\t/**\n\t * Returns the generated line and column information for the original source,\n\t * line, and column positions provided. The only argument is an object with\n\t * the following properties:\n\t *\n\t * - source: The filename of the original source.\n\t * - line: The line number in the original source. The line number\n\t * is 1-based.\n\t * - column: The column number in the original source. The column\n\t * number is 0-based.\n\t *\n\t * and an object is returned with the following properties:\n\t *\n\t * - line: The line number in the generated source, or null. The\n\t * line number is 1-based. \n\t * - column: The column number in the generated source, or null.\n\t * The column number is 0-based.\n\t */\n\tIndexedSourceMapConsumer.prototype.generatedPositionFor =\n\t function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {\n\t for (var i = 0; i < this._sections.length; i++) {\n\t var section = this._sections[i];\n\t\n\t // Only consider this section if the requested source is in the list of\n\t // sources of the consumer.\n\t if (section.consumer._findSourceIndex(util.getArg(aArgs, 'source')) === -1) {\n\t continue;\n\t }\n\t var generatedPosition = section.consumer.generatedPositionFor(aArgs);\n\t if (generatedPosition) {\n\t var ret = {\n\t line: generatedPosition.line +\n\t (section.generatedOffset.generatedLine - 1),\n\t column: generatedPosition.column +\n\t (section.generatedOffset.generatedLine === generatedPosition.line\n\t ? section.generatedOffset.generatedColumn - 1\n\t : 0)\n\t };\n\t return ret;\n\t }\n\t }\n\t\n\t return {\n\t line: null,\n\t column: null\n\t };\n\t };\n\t\n\t/**\n\t * Parse the mappings in a string in to a data structure which we can easily\n\t * query (the ordered arrays in the `this.__generatedMappings` and\n\t * `this.__originalMappings` properties).\n\t */\n\tIndexedSourceMapConsumer.prototype._parseMappings =\n\t function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) {\n\t this.__generatedMappings = [];\n\t this.__originalMappings = [];\n\t for (var i = 0; i < this._sections.length; i++) {\n\t var section = this._sections[i];\n\t var sectionMappings = section.consumer._generatedMappings;\n\t for (var j = 0; j < sectionMappings.length; j++) {\n\t var mapping = sectionMappings[j];\n\t\n\t var source = section.consumer._sources.at(mapping.source);\n\t source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL);\n\t this._sources.add(source);\n\t source = this._sources.indexOf(source);\n\t\n\t var name = null;\n\t if (mapping.name) {\n\t name = section.consumer._names.at(mapping.name);\n\t this._names.add(name);\n\t name = this._names.indexOf(name);\n\t }\n\t\n\t // The mappings coming from the consumer for the section have\n\t // generated positions relative to the start of the section, so we\n\t // need to offset them to be relative to the start of the concatenated\n\t // generated file.\n\t var adjustedMapping = {\n\t source: source,\n\t generatedLine: mapping.generatedLine +\n\t (section.generatedOffset.generatedLine - 1),\n\t generatedColumn: mapping.generatedColumn +\n\t (section.generatedOffset.generatedLine === mapping.generatedLine\n\t ? section.generatedOffset.generatedColumn - 1\n\t : 0),\n\t originalLine: mapping.originalLine,\n\t originalColumn: mapping.originalColumn,\n\t name: name\n\t };\n\t\n\t this.__generatedMappings.push(adjustedMapping);\n\t if (typeof adjustedMapping.originalLine === 'number') {\n\t this.__originalMappings.push(adjustedMapping);\n\t }\n\t }\n\t }\n\t\n\t quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated);\n\t quickSort(this.__originalMappings, util.compareByOriginalPositions);\n\t };\n\t\n\texports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;\n\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\texports.GREATEST_LOWER_BOUND = 1;\n\texports.LEAST_UPPER_BOUND = 2;\n\t\n\t/**\n\t * Recursive implementation of binary search.\n\t *\n\t * @param aLow Indices here and lower do not contain the needle.\n\t * @param aHigh Indices here and higher do not contain the needle.\n\t * @param aNeedle The element being searched for.\n\t * @param aHaystack The non-empty array being searched.\n\t * @param aCompare Function which takes two elements and returns -1, 0, or 1.\n\t * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or\n\t * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the\n\t * closest element that is smaller than or greater than the one we are\n\t * searching for, respectively, if the exact element cannot be found.\n\t */\n\tfunction recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) {\n\t // This function terminates when one of the following is true:\n\t //\n\t // 1. We find the exact element we are looking for.\n\t //\n\t // 2. We did not find the exact element, but we can return the index of\n\t // the next-closest element.\n\t //\n\t // 3. We did not find the exact element, and there is no next-closest\n\t // element than the one we are searching for, so we return -1.\n\t var mid = Math.floor((aHigh - aLow) / 2) + aLow;\n\t var cmp = aCompare(aNeedle, aHaystack[mid], true);\n\t if (cmp === 0) {\n\t // Found the element we are looking for.\n\t return mid;\n\t }\n\t else if (cmp > 0) {\n\t // Our needle is greater than aHaystack[mid].\n\t if (aHigh - mid > 1) {\n\t // The element is in the upper half.\n\t return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias);\n\t }\n\t\n\t // The exact needle element was not found in this haystack. Determine if\n\t // we are in termination case (3) or (2) and return the appropriate thing.\n\t if (aBias == exports.LEAST_UPPER_BOUND) {\n\t return aHigh < aHaystack.length ? aHigh : -1;\n\t } else {\n\t return mid;\n\t }\n\t }\n\t else {\n\t // Our needle is less than aHaystack[mid].\n\t if (mid - aLow > 1) {\n\t // The element is in the lower half.\n\t return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias);\n\t }\n\t\n\t // we are in termination case (3) or (2) and return the appropriate thing.\n\t if (aBias == exports.LEAST_UPPER_BOUND) {\n\t return mid;\n\t } else {\n\t return aLow < 0 ? -1 : aLow;\n\t }\n\t }\n\t}\n\t\n\t/**\n\t * This is an implementation of binary search which will always try and return\n\t * the index of the closest element if there is no exact hit. This is because\n\t * mappings between original and generated line/col pairs are single points,\n\t * and there is an implicit region between each of them, so a miss just means\n\t * that you aren't on the very start of a region.\n\t *\n\t * @param aNeedle The element you are looking for.\n\t * @param aHaystack The array that is being searched.\n\t * @param aCompare A function which takes the needle and an element in the\n\t * array and returns -1, 0, or 1 depending on whether the needle is less\n\t * than, equal to, or greater than the element, respectively.\n\t * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or\n\t * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the\n\t * closest element that is smaller than or greater than the one we are\n\t * searching for, respectively, if the exact element cannot be found.\n\t * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'.\n\t */\n\texports.search = function search(aNeedle, aHaystack, aCompare, aBias) {\n\t if (aHaystack.length === 0) {\n\t return -1;\n\t }\n\t\n\t var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack,\n\t aCompare, aBias || exports.GREATEST_LOWER_BOUND);\n\t if (index < 0) {\n\t return -1;\n\t }\n\t\n\t // We have found either the exact element, or the next-closest element than\n\t // the one we are searching for. However, there may be more than one such\n\t // element. Make sure we always return the smallest of these.\n\t while (index - 1 >= 0) {\n\t if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {\n\t break;\n\t }\n\t --index;\n\t }\n\t\n\t return index;\n\t};\n\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\t// It turns out that some (most?) JavaScript engines don't self-host\n\t// `Array.prototype.sort`. This makes sense because C++ will likely remain\n\t// faster than JS when doing raw CPU-intensive sorting. However, when using a\n\t// custom comparator function, calling back and forth between the VM's C++ and\n\t// JIT'd JS is rather slow *and* loses JIT type information, resulting in\n\t// worse generated code for the comparator function than would be optimal. In\n\t// fact, when sorting with a comparator, these costs outweigh the benefits of\n\t// sorting in C++. By using our own JS-implemented Quick Sort (below), we get\n\t// a ~3500ms mean speed-up in `bench/bench.html`.\n\t\n\t/**\n\t * Swap the elements indexed by `x` and `y` in the array `ary`.\n\t *\n\t * @param {Array} ary\n\t * The array.\n\t * @param {Number} x\n\t * The index of the first item.\n\t * @param {Number} y\n\t * The index of the second item.\n\t */\n\tfunction swap(ary, x, y) {\n\t var temp = ary[x];\n\t ary[x] = ary[y];\n\t ary[y] = temp;\n\t}\n\t\n\t/**\n\t * Returns a random integer within the range `low .. high` inclusive.\n\t *\n\t * @param {Number} low\n\t * The lower bound on the range.\n\t * @param {Number} high\n\t * The upper bound on the range.\n\t */\n\tfunction randomIntInRange(low, high) {\n\t return Math.round(low + (Math.random() * (high - low)));\n\t}\n\t\n\t/**\n\t * The Quick Sort algorithm.\n\t *\n\t * @param {Array} ary\n\t * An array to sort.\n\t * @param {function} comparator\n\t * Function to use to compare two items.\n\t * @param {Number} p\n\t * Start index of the array\n\t * @param {Number} r\n\t * End index of the array\n\t */\n\tfunction doQuickSort(ary, comparator, p, r) {\n\t // If our lower bound is less than our upper bound, we (1) partition the\n\t // array into two pieces and (2) recurse on each half. If it is not, this is\n\t // the empty array and our base case.\n\t\n\t if (p < r) {\n\t // (1) Partitioning.\n\t //\n\t // The partitioning chooses a pivot between `p` and `r` and moves all\n\t // elements that are less than or equal to the pivot to the before it, and\n\t // all the elements that are greater than it after it. The effect is that\n\t // once partition is done, the pivot is in the exact place it will be when\n\t // the array is put in sorted order, and it will not need to be moved\n\t // again. This runs in O(n) time.\n\t\n\t // Always choose a random pivot so that an input array which is reverse\n\t // sorted does not cause O(n^2) running time.\n\t var pivotIndex = randomIntInRange(p, r);\n\t var i = p - 1;\n\t\n\t swap(ary, pivotIndex, r);\n\t var pivot = ary[r];\n\t\n\t // Immediately after `j` is incremented in this loop, the following hold\n\t // true:\n\t //\n\t // * Every element in `ary[p .. i]` is less than or equal to the pivot.\n\t //\n\t // * Every element in `ary[i+1 .. j-1]` is greater than the pivot.\n\t for (var j = p; j < r; j++) {\n\t if (comparator(ary[j], pivot) <= 0) {\n\t i += 1;\n\t swap(ary, i, j);\n\t }\n\t }\n\t\n\t swap(ary, i + 1, j);\n\t var q = i + 1;\n\t\n\t // (2) Recurse on each half.\n\t\n\t doQuickSort(ary, comparator, p, q - 1);\n\t doQuickSort(ary, comparator, q + 1, r);\n\t }\n\t}\n\t\n\t/**\n\t * Sort the given array in-place with the given comparator function.\n\t *\n\t * @param {Array} ary\n\t * An array to sort.\n\t * @param {function} comparator\n\t * Function to use to compare two items.\n\t */\n\texports.quickSort = function (ary, comparator) {\n\t doQuickSort(ary, comparator, 0, ary.length - 1);\n\t};\n\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\t/* -*- Mode: js; js-indent-level: 2; -*- */\n\t/*\n\t * Copyright 2011 Mozilla Foundation and contributors\n\t * Licensed under the New BSD license. See LICENSE or:\n\t * http://opensource.org/licenses/BSD-3-Clause\n\t */\n\t\n\tvar SourceMapGenerator = __webpack_require__(1).SourceMapGenerator;\n\tvar util = __webpack_require__(4);\n\t\n\t// Matches a Windows-style `\\r\\n` newline or a `\\n` newline used by all other\n\t// operating systems these days (capturing the result).\n\tvar REGEX_NEWLINE = /(\\r?\\n)/;\n\t\n\t// Newline character code for charCodeAt() comparisons\n\tvar NEWLINE_CODE = 10;\n\t\n\t// Private symbol for identifying `SourceNode`s when multiple versions of\n\t// the source-map library are loaded. This MUST NOT CHANGE across\n\t// versions!\n\tvar isSourceNode = \"$$$isSourceNode$$$\";\n\t\n\t/**\n\t * SourceNodes provide a way to abstract over interpolating/concatenating\n\t * snippets of generated JavaScript source code while maintaining the line and\n\t * column information associated with the original source code.\n\t *\n\t * @param aLine The original line number.\n\t * @param aColumn The original column number.\n\t * @param aSource The original source's filename.\n\t * @param aChunks Optional. An array of strings which are snippets of\n\t * generated JS, or other SourceNodes.\n\t * @param aName The original identifier.\n\t */\n\tfunction SourceNode(aLine, aColumn, aSource, aChunks, aName) {\n\t this.children = [];\n\t this.sourceContents = {};\n\t this.line = aLine == null ? null : aLine;\n\t this.column = aColumn == null ? null : aColumn;\n\t this.source = aSource == null ? null : aSource;\n\t this.name = aName == null ? null : aName;\n\t this[isSourceNode] = true;\n\t if (aChunks != null) this.add(aChunks);\n\t}\n\t\n\t/**\n\t * Creates a SourceNode from generated code and a SourceMapConsumer.\n\t *\n\t * @param aGeneratedCode The generated code\n\t * @param aSourceMapConsumer The SourceMap for the generated code\n\t * @param aRelativePath Optional. The path that relative sources in the\n\t * SourceMapConsumer should be relative to.\n\t */\n\tSourceNode.fromStringWithSourceMap =\n\t function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) {\n\t // The SourceNode we want to fill with the generated code\n\t // and the SourceMap\n\t var node = new SourceNode();\n\t\n\t // All even indices of this array are one line of the generated code,\n\t // while all odd indices are the newlines between two adjacent lines\n\t // (since `REGEX_NEWLINE` captures its match).\n\t // Processed fragments are accessed by calling `shiftNextLine`.\n\t var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);\n\t var remainingLinesIndex = 0;\n\t var shiftNextLine = function() {\n\t var lineContents = getNextLine();\n\t // The last line of a file might not have a newline.\n\t var newLine = getNextLine() || \"\";\n\t return lineContents + newLine;\n\t\n\t function getNextLine() {\n\t return remainingLinesIndex < remainingLines.length ?\n\t remainingLines[remainingLinesIndex++] : undefined;\n\t }\n\t };\n\t\n\t // We need to remember the position of \"remainingLines\"\n\t var lastGeneratedLine = 1, lastGeneratedColumn = 0;\n\t\n\t // The generate SourceNodes we need a code range.\n\t // To extract it current and last mapping is used.\n\t // Here we store the last mapping.\n\t var lastMapping = null;\n\t\n\t aSourceMapConsumer.eachMapping(function (mapping) {\n\t if (lastMapping !== null) {\n\t // We add the code from \"lastMapping\" to \"mapping\":\n\t // First check if there is a new line in between.\n\t if (lastGeneratedLine < mapping.generatedLine) {\n\t // Associate first line with \"lastMapping\"\n\t addMappingWithCode(lastMapping, shiftNextLine());\n\t lastGeneratedLine++;\n\t lastGeneratedColumn = 0;\n\t // The remaining code is added without mapping\n\t } else {\n\t // There is no new line in between.\n\t // Associate the code between \"lastGeneratedColumn\" and\n\t // \"mapping.generatedColumn\" with \"lastMapping\"\n\t var nextLine = remainingLines[remainingLinesIndex] || '';\n\t var code = nextLine.substr(0, mapping.generatedColumn -\n\t lastGeneratedColumn);\n\t remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn -\n\t lastGeneratedColumn);\n\t lastGeneratedColumn = mapping.generatedColumn;\n\t addMappingWithCode(lastMapping, code);\n\t // No more remaining code, continue\n\t lastMapping = mapping;\n\t return;\n\t }\n\t }\n\t // We add the generated code until the first mapping\n\t // to the SourceNode without any mapping.\n\t // Each line is added as separate string.\n\t while (lastGeneratedLine < mapping.generatedLine) {\n\t node.add(shiftNextLine());\n\t lastGeneratedLine++;\n\t }\n\t if (lastGeneratedColumn < mapping.generatedColumn) {\n\t var nextLine = remainingLines[remainingLinesIndex] || '';\n\t node.add(nextLine.substr(0, mapping.generatedColumn));\n\t remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);\n\t lastGeneratedColumn = mapping.generatedColumn;\n\t }\n\t lastMapping = mapping;\n\t }, this);\n\t // We have processed all mappings.\n\t if (remainingLinesIndex < remainingLines.length) {\n\t if (lastMapping) {\n\t // Associate the remaining code in the current line with \"lastMapping\"\n\t addMappingWithCode(lastMapping, shiftNextLine());\n\t }\n\t // and add the remaining lines without any mapping\n\t node.add(remainingLines.splice(remainingLinesIndex).join(\"\"));\n\t }\n\t\n\t // Copy sourcesContent into SourceNode\n\t aSourceMapConsumer.sources.forEach(function (sourceFile) {\n\t var content = aSourceMapConsumer.sourceContentFor(sourceFile);\n\t if (content != null) {\n\t if (aRelativePath != null) {\n\t sourceFile = util.join(aRelativePath, sourceFile);\n\t }\n\t node.setSourceContent(sourceFile, content);\n\t }\n\t });\n\t\n\t return node;\n\t\n\t function addMappingWithCode(mapping, code) {\n\t if (mapping === null || mapping.source === undefined) {\n\t node.add(code);\n\t } else {\n\t var source = aRelativePath\n\t ? util.join(aRelativePath, mapping.source)\n\t : mapping.source;\n\t node.add(new SourceNode(mapping.originalLine,\n\t mapping.originalColumn,\n\t source,\n\t code,\n\t mapping.name));\n\t }\n\t }\n\t };\n\t\n\t/**\n\t * Add a chunk of generated JS to this source node.\n\t *\n\t * @param aChunk A string snippet of generated JS code, another instance of\n\t * SourceNode, or an array where each member is one of those things.\n\t */\n\tSourceNode.prototype.add = function SourceNode_add(aChunk) {\n\t if (Array.isArray(aChunk)) {\n\t aChunk.forEach(function (chunk) {\n\t this.add(chunk);\n\t }, this);\n\t }\n\t else if (aChunk[isSourceNode] || typeof aChunk === \"string\") {\n\t if (aChunk) {\n\t this.children.push(aChunk);\n\t }\n\t }\n\t else {\n\t throw new TypeError(\n\t \"Expected a SourceNode, string, or an array of SourceNodes and strings. Got \" + aChunk\n\t );\n\t }\n\t return this;\n\t};\n\t\n\t/**\n\t * Add a chunk of generated JS to the beginning of this source node.\n\t *\n\t * @param aChunk A string snippet of generated JS code, another instance of\n\t * SourceNode, or an array where each member is one of those things.\n\t */\n\tSourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {\n\t if (Array.isArray(aChunk)) {\n\t for (var i = aChunk.length-1; i >= 0; i--) {\n\t this.prepend(aChunk[i]);\n\t }\n\t }\n\t else if (aChunk[isSourceNode] || typeof aChunk === \"string\") {\n\t this.children.unshift(aChunk);\n\t }\n\t else {\n\t throw new TypeError(\n\t \"Expected a SourceNode, string, or an array of SourceNodes and strings. Got \" + aChunk\n\t );\n\t }\n\t return this;\n\t};\n\t\n\t/**\n\t * Walk over the tree of JS snippets in this node and its children. The\n\t * walking function is called once for each snippet of JS and is passed that\n\t * snippet and the its original associated source's line/column location.\n\t *\n\t * @param aFn The traversal function.\n\t */\n\tSourceNode.prototype.walk = function SourceNode_walk(aFn) {\n\t var chunk;\n\t for (var i = 0, len = this.children.length; i < len; i++) {\n\t chunk = this.children[i];\n\t if (chunk[isSourceNode]) {\n\t chunk.walk(aFn);\n\t }\n\t else {\n\t if (chunk !== '') {\n\t aFn(chunk, { source: this.source,\n\t line: this.line,\n\t column: this.column,\n\t name: this.name });\n\t }\n\t }\n\t }\n\t};\n\t\n\t/**\n\t * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between\n\t * each of `this.children`.\n\t *\n\t * @param aSep The separator.\n\t */\n\tSourceNode.prototype.join = function SourceNode_join(aSep) {\n\t var newChildren;\n\t var i;\n\t var len = this.children.length;\n\t if (len > 0) {\n\t newChildren = [];\n\t for (i = 0; i < len-1; i++) {\n\t newChildren.push(this.children[i]);\n\t newChildren.push(aSep);\n\t }\n\t newChildren.push(this.children[i]);\n\t this.children = newChildren;\n\t }\n\t return this;\n\t};\n\t\n\t/**\n\t * Call String.prototype.replace on the very right-most source snippet. Useful\n\t * for trimming whitespace from the end of a source node, etc.\n\t *\n\t * @param aPattern The pattern to replace.\n\t * @param aReplacement The thing to replace the pattern with.\n\t */\n\tSourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {\n\t var lastChild = this.children[this.children.length - 1];\n\t if (lastChild[isSourceNode]) {\n\t lastChild.replaceRight(aPattern, aReplacement);\n\t }\n\t else if (typeof lastChild === 'string') {\n\t this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);\n\t }\n\t else {\n\t this.children.push(''.replace(aPattern, aReplacement));\n\t }\n\t return this;\n\t};\n\t\n\t/**\n\t * Set the source content for a source file. This will be added to the SourceMapGenerator\n\t * in the sourcesContent field.\n\t *\n\t * @param aSourceFile The filename of the source file\n\t * @param aSourceContent The content of the source file\n\t */\n\tSourceNode.prototype.setSourceContent =\n\t function SourceNode_setSourceContent(aSourceFile, aSourceContent) {\n\t this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;\n\t };\n\t\n\t/**\n\t * Walk over the tree of SourceNodes. The walking function is called for each\n\t * source file content and is passed the filename and source content.\n\t *\n\t * @param aFn The traversal function.\n\t */\n\tSourceNode.prototype.walkSourceContents =\n\t function SourceNode_walkSourceContents(aFn) {\n\t for (var i = 0, len = this.children.length; i < len; i++) {\n\t if (this.children[i][isSourceNode]) {\n\t this.children[i].walkSourceContents(aFn);\n\t }\n\t }\n\t\n\t var sources = Object.keys(this.sourceContents);\n\t for (var i = 0, len = sources.length; i < len; i++) {\n\t aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);\n\t }\n\t };\n\t\n\t/**\n\t * Return the string representation of this source node. Walks over the tree\n\t * and concatenates all the various snippets together to one string.\n\t */\n\tSourceNode.prototype.toString = function SourceNode_toString() {\n\t var str = \"\";\n\t this.walk(function (chunk) {\n\t str += chunk;\n\t });\n\t return str;\n\t};\n\t\n\t/**\n\t * Returns the string representation of this source node along with a source\n\t * map.\n\t */\n\tSourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {\n\t var generated = {\n\t code: \"\",\n\t line: 1,\n\t column: 0\n\t };\n\t var map = new SourceMapGenerator(aArgs);\n\t var sourceMappingActive = false;\n\t var lastOriginalSource = null;\n\t var lastOriginalLine = null;\n\t var lastOriginalColumn = null;\n\t var lastOriginalName = null;\n\t this.walk(function (chunk, original) {\n\t generated.code += chunk;\n\t if (original.source !== null\n\t && original.line !== null\n\t && original.column !== null) {\n\t if(lastOriginalSource !== original.source\n\t || lastOriginalLine !== original.line\n\t || lastOriginalColumn !== original.column\n\t || lastOriginalName !== original.name) {\n\t map.addMapping({\n\t source: original.source,\n\t original: {\n\t line: original.line,\n\t column: original.column\n\t },\n\t generated: {\n\t line: generated.line,\n\t column: generated.column\n\t },\n\t name: original.name\n\t });\n\t }\n\t lastOriginalSource = original.source;\n\t lastOriginalLine = original.line;\n\t lastOriginalColumn = original.column;\n\t lastOriginalName = original.name;\n\t sourceMappingActive = true;\n\t } else if (sourceMappingActive) {\n\t map.addMapping({\n\t generated: {\n\t line: generated.line,\n\t column: generated.column\n\t }\n\t });\n\t lastOriginalSource = null;\n\t sourceMappingActive = false;\n\t }\n\t for (var idx = 0, length = chunk.length; idx < length; idx++) {\n\t if (chunk.charCodeAt(idx) === NEWLINE_CODE) {\n\t generated.line++;\n\t generated.column = 0;\n\t // Mappings end at eol\n\t if (idx + 1 === length) {\n\t lastOriginalSource = null;\n\t sourceMappingActive = false;\n\t } else if (sourceMappingActive) {\n\t map.addMapping({\n\t source: original.source,\n\t original: {\n\t line: original.line,\n\t column: original.column\n\t },\n\t generated: {\n\t line: generated.line,\n\t column: generated.column\n\t },\n\t name: original.name\n\t });\n\t }\n\t } else {\n\t generated.column++;\n\t }\n\t }\n\t });\n\t this.walkSourceContents(function (sourceFile, sourceContent) {\n\t map.setSourceContent(sourceFile, sourceContent);\n\t });\n\t\n\t return { code: generated.code, map: map };\n\t};\n\t\n\texports.SourceNode = SourceNode;\n\n\n/***/ })\n/******/ ])\n});\n;\n\n\n// WEBPACK FOOTER //\n// source-map.min.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 0fd5815da764db5fb9fe","/*\n * Copyright 2009-2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE.txt or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\nexports.SourceMapGenerator = require('./lib/source-map-generator').SourceMapGenerator;\nexports.SourceMapConsumer = require('./lib/source-map-consumer').SourceMapConsumer;\nexports.SourceNode = require('./lib/source-node').SourceNode;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./source-map.js\n// module id = 0\n// module chunks = 0","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\nvar base64VLQ = require('./base64-vlq');\nvar util = require('./util');\nvar ArraySet = require('./array-set').ArraySet;\nvar MappingList = require('./mapping-list').MappingList;\n\n/**\n * An instance of the SourceMapGenerator represents a source map which is\n * being built incrementally. You may pass an object with the following\n * properties:\n *\n * - file: The filename of the generated source.\n * - sourceRoot: A root for all relative URLs in this source map.\n */\nfunction SourceMapGenerator(aArgs) {\n if (!aArgs) {\n aArgs = {};\n }\n this._file = util.getArg(aArgs, 'file', null);\n this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);\n this._skipValidation = util.getArg(aArgs, 'skipValidation', false);\n this._sources = new ArraySet();\n this._names = new ArraySet();\n this._mappings = new MappingList();\n this._sourcesContents = null;\n}\n\nSourceMapGenerator.prototype._version = 3;\n\n/**\n * Creates a new SourceMapGenerator based on a SourceMapConsumer\n *\n * @param aSourceMapConsumer The SourceMap.\n */\nSourceMapGenerator.fromSourceMap =\n function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {\n var sourceRoot = aSourceMapConsumer.sourceRoot;\n var generator = new SourceMapGenerator({\n file: aSourceMapConsumer.file,\n sourceRoot: sourceRoot\n });\n aSourceMapConsumer.eachMapping(function (mapping) {\n var newMapping = {\n generated: {\n line: mapping.generatedLine,\n column: mapping.generatedColumn\n }\n };\n\n if (mapping.source != null) {\n newMapping.source = mapping.source;\n if (sourceRoot != null) {\n newMapping.source = util.relative(sourceRoot, newMapping.source);\n }\n\n newMapping.original = {\n line: mapping.originalLine,\n column: mapping.originalColumn\n };\n\n if (mapping.name != null) {\n newMapping.name = mapping.name;\n }\n }\n\n generator.addMapping(newMapping);\n });\n aSourceMapConsumer.sources.forEach(function (sourceFile) {\n var sourceRelative = sourceFile;\n if (sourceRoot !== null) {\n sourceRelative = util.relative(sourceRoot, sourceFile);\n }\n\n if (!generator._sources.has(sourceRelative)) {\n generator._sources.add(sourceRelative);\n }\n\n var content = aSourceMapConsumer.sourceContentFor(sourceFile);\n if (content != null) {\n generator.setSourceContent(sourceFile, content);\n }\n });\n return generator;\n };\n\n/**\n * Add a single mapping from original source line and column to the generated\n * source's line and column for this source map being created. The mapping\n * object should have the following properties:\n *\n * - generated: An object with the generated line and column positions.\n * - original: An object with the original line and column positions.\n * - source: The original source file (relative to the sourceRoot).\n * - name: An optional original token name for this mapping.\n */\nSourceMapGenerator.prototype.addMapping =\n function SourceMapGenerator_addMapping(aArgs) {\n var generated = util.getArg(aArgs, 'generated');\n var original = util.getArg(aArgs, 'original', null);\n var source = util.getArg(aArgs, 'source', null);\n var name = util.getArg(aArgs, 'name', null);\n\n if (!this._skipValidation) {\n this._validateMapping(generated, original, source, name);\n }\n\n if (source != null) {\n source = String(source);\n if (!this._sources.has(source)) {\n this._sources.add(source);\n }\n }\n\n if (name != null) {\n name = String(name);\n if (!this._names.has(name)) {\n this._names.add(name);\n }\n }\n\n this._mappings.add({\n generatedLine: generated.line,\n generatedColumn: generated.column,\n originalLine: original != null && original.line,\n originalColumn: original != null && original.column,\n source: source,\n name: name\n });\n };\n\n/**\n * Set the source content for a source file.\n */\nSourceMapGenerator.prototype.setSourceContent =\n function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {\n var source = aSourceFile;\n if (this._sourceRoot != null) {\n source = util.relative(this._sourceRoot, source);\n }\n\n if (aSourceContent != null) {\n // Add the source content to the _sourcesContents map.\n // Create a new _sourcesContents map if the property is null.\n if (!this._sourcesContents) {\n this._sourcesContents = Object.create(null);\n }\n this._sourcesContents[util.toSetString(source)] = aSourceContent;\n } else if (this._sourcesContents) {\n // Remove the source file from the _sourcesContents map.\n // If the _sourcesContents map is empty, set the property to null.\n delete this._sourcesContents[util.toSetString(source)];\n if (Object.keys(this._sourcesContents).length === 0) {\n this._sourcesContents = null;\n }\n }\n };\n\n/**\n * Applies the mappings of a sub-source-map for a specific source file to the\n * source map being generated. Each mapping to the supplied source file is\n * rewritten using the supplied source map. Note: The resolution for the\n * resulting mappings is the minimium of this map and the supplied map.\n *\n * @param aSourceMapConsumer The source map to be applied.\n * @param aSourceFile Optional. The filename of the source file.\n * If omitted, SourceMapConsumer's file property will be used.\n * @param aSourceMapPath Optional. The dirname of the path to the source map\n * to be applied. If relative, it is relative to the SourceMapConsumer.\n * This parameter is needed when the two source maps aren't in the same\n * directory, and the source map to be applied contains relative source\n * paths. If so, those relative source paths need to be rewritten\n * relative to the SourceMapGenerator.\n */\nSourceMapGenerator.prototype.applySourceMap =\n function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {\n var sourceFile = aSourceFile;\n // If aSourceFile is omitted, we will use the file property of the SourceMap\n if (aSourceFile == null) {\n if (aSourceMapConsumer.file == null) {\n throw new Error(\n 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +\n 'or the source map\\'s \"file\" property. Both were omitted.'\n );\n }\n sourceFile = aSourceMapConsumer.file;\n }\n var sourceRoot = this._sourceRoot;\n // Make \"sourceFile\" relative if an absolute Url is passed.\n if (sourceRoot != null) {\n sourceFile = util.relative(sourceRoot, sourceFile);\n }\n // Applying the SourceMap can add and remove items from the sources and\n // the names array.\n var newSources = new ArraySet();\n var newNames = new ArraySet();\n\n // Find mappings for the \"sourceFile\"\n this._mappings.unsortedForEach(function (mapping) {\n if (mapping.source === sourceFile && mapping.originalLine != null) {\n // Check if it can be mapped by the source map, then update the mapping.\n var original = aSourceMapConsumer.originalPositionFor({\n line: mapping.originalLine,\n column: mapping.originalColumn\n });\n if (original.source != null) {\n // Copy mapping\n mapping.source = original.source;\n if (aSourceMapPath != null) {\n mapping.source = util.join(aSourceMapPath, mapping.source)\n }\n if (sourceRoot != null) {\n mapping.source = util.relative(sourceRoot, mapping.source);\n }\n mapping.originalLine = original.line;\n mapping.originalColumn = original.column;\n if (original.name != null) {\n mapping.name = original.name;\n }\n }\n }\n\n var source = mapping.source;\n if (source != null && !newSources.has(source)) {\n newSources.add(source);\n }\n\n var name = mapping.name;\n if (name != null && !newNames.has(name)) {\n newNames.add(name);\n }\n\n }, this);\n this._sources = newSources;\n this._names = newNames;\n\n // Copy sourcesContents of applied map.\n aSourceMapConsumer.sources.forEach(function (sourceFile) {\n var content = aSourceMapConsumer.sourceContentFor(sourceFile);\n if (content != null) {\n if (aSourceMapPath != null) {\n sourceFile = util.join(aSourceMapPath, sourceFile);\n }\n if (sourceRoot != null) {\n sourceFile = util.relative(sourceRoot, sourceFile);\n }\n this.setSourceContent(sourceFile, content);\n }\n }, this);\n };\n\n/**\n * A mapping can have one of the three levels of data:\n *\n * 1. Just the generated position.\n * 2. The Generated position, original position, and original source.\n * 3. Generated and original position, original source, as well as a name\n * token.\n *\n * To maintain consistency, we validate that any new mapping being added falls\n * in to one of these categories.\n */\nSourceMapGenerator.prototype._validateMapping =\n function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,\n aName) {\n // When aOriginal is truthy but has empty values for .line and .column,\n // it is most likely a programmer error. In this case we throw a very\n // specific error message to try to guide them the right way.\n // For example: https://github.com/Polymer/polymer-bundler/pull/519\n if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {\n throw new Error(\n 'original.line and original.column are not numbers -- you probably meant to omit ' +\n 'the original mapping entirely and only map the generated position. If so, pass ' +\n 'null for the original mapping instead of an object with empty or null values.'\n );\n }\n\n if (aGenerated && 'line' in aGenerated && 'column' in aGenerated\n && aGenerated.line > 0 && aGenerated.column >= 0\n && !aOriginal && !aSource && !aName) {\n // Case 1.\n return;\n }\n else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated\n && aOriginal && 'line' in aOriginal && 'column' in aOriginal\n && aGenerated.line > 0 && aGenerated.column >= 0\n && aOriginal.line > 0 && aOriginal.column >= 0\n && aSource) {\n // Cases 2 and 3.\n return;\n }\n else {\n throw new Error('Invalid mapping: ' + JSON.stringify({\n generated: aGenerated,\n source: aSource,\n original: aOriginal,\n name: aName\n }));\n }\n };\n\n/**\n * Serialize the accumulated mappings in to the stream of base 64 VLQs\n * specified by the source map format.\n */\nSourceMapGenerator.prototype._serializeMappings =\n function SourceMapGenerator_serializeMappings() {\n var previousGeneratedColumn = 0;\n var previousGeneratedLine = 1;\n var previousOriginalColumn = 0;\n var previousOriginalLine = 0;\n var previousName = 0;\n var previousSource = 0;\n var result = '';\n var next;\n var mapping;\n var nameIdx;\n var sourceIdx;\n\n var mappings = this._mappings.toArray();\n for (var i = 0, len = mappings.length; i < len; i++) {\n mapping = mappings[i];\n next = ''\n\n if (mapping.generatedLine !== previousGeneratedLine) {\n previousGeneratedColumn = 0;\n while (mapping.generatedLine !== previousGeneratedLine) {\n next += ';';\n previousGeneratedLine++;\n }\n }\n else {\n if (i > 0) {\n if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {\n continue;\n }\n next += ',';\n }\n }\n\n next += base64VLQ.encode(mapping.generatedColumn\n - previousGeneratedColumn);\n previousGeneratedColumn = mapping.generatedColumn;\n\n if (mapping.source != null) {\n sourceIdx = this._sources.indexOf(mapping.source);\n next += base64VLQ.encode(sourceIdx - previousSource);\n previousSource = sourceIdx;\n\n // lines are stored 0-based in SourceMap spec version 3\n next += base64VLQ.encode(mapping.originalLine - 1\n - previousOriginalLine);\n previousOriginalLine = mapping.originalLine - 1;\n\n next += base64VLQ.encode(mapping.originalColumn\n - previousOriginalColumn);\n previousOriginalColumn = mapping.originalColumn;\n\n if (mapping.name != null) {\n nameIdx = this._names.indexOf(mapping.name);\n next += base64VLQ.encode(nameIdx - previousName);\n previousName = nameIdx;\n }\n }\n\n result += next;\n }\n\n return result;\n };\n\nSourceMapGenerator.prototype._generateSourcesContent =\n function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {\n return aSources.map(function (source) {\n if (!this._sourcesContents) {\n return null;\n }\n if (aSourceRoot != null) {\n source = util.relative(aSourceRoot, source);\n }\n var key = util.toSetString(source);\n return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)\n ? this._sourcesContents[key]\n : null;\n }, this);\n };\n\n/**\n * Externalize the source map.\n */\nSourceMapGenerator.prototype.toJSON =\n function SourceMapGenerator_toJSON() {\n var map = {\n version: this._version,\n sources: this._sources.toArray(),\n names: this._names.toArray(),\n mappings: this._serializeMappings()\n };\n if (this._file != null) {\n map.file = this._file;\n }\n if (this._sourceRoot != null) {\n map.sourceRoot = this._sourceRoot;\n }\n if (this._sourcesContents) {\n map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);\n }\n\n return map;\n };\n\n/**\n * Render the source map being generated to a string.\n */\nSourceMapGenerator.prototype.toString =\n function SourceMapGenerator_toString() {\n return JSON.stringify(this.toJSON());\n };\n\nexports.SourceMapGenerator = SourceMapGenerator;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/source-map-generator.js\n// module id = 1\n// module chunks = 0","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n *\n * Based on the Base 64 VLQ implementation in Closure Compiler:\n * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java\n *\n * Copyright 2011 The Closure Compiler Authors. All rights reserved.\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are\n * met:\n *\n * * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * * Redistributions in binary form must reproduce the above\n * copyright notice, this list of conditions and the following\n * disclaimer in the documentation and/or other materials provided\n * with the distribution.\n * * Neither the name of Google Inc. nor the names of its\n * contributors may be used to endorse or promote products derived\n * from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nvar base64 = require('./base64');\n\n// A single base 64 digit can contain 6 bits of data. For the base 64 variable\n// length quantities we use in the source map spec, the first bit is the sign,\n// the next four bits are the actual value, and the 6th bit is the\n// continuation bit. The continuation bit tells us whether there are more\n// digits in this value following this digit.\n//\n// Continuation\n// | Sign\n// | |\n// V V\n// 101011\n\nvar VLQ_BASE_SHIFT = 5;\n\n// binary: 100000\nvar VLQ_BASE = 1 << VLQ_BASE_SHIFT;\n\n// binary: 011111\nvar VLQ_BASE_MASK = VLQ_BASE - 1;\n\n// binary: 100000\nvar VLQ_CONTINUATION_BIT = VLQ_BASE;\n\n/**\n * Converts from a two-complement value to a value where the sign bit is\n * placed in the least significant bit. For example, as decimals:\n * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)\n * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)\n */\nfunction toVLQSigned(aValue) {\n return aValue < 0\n ? ((-aValue) << 1) + 1\n : (aValue << 1) + 0;\n}\n\n/**\n * Converts to a two-complement value from a value where the sign bit is\n * placed in the least significant bit. For example, as decimals:\n * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1\n * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2\n */\nfunction fromVLQSigned(aValue) {\n var isNegative = (aValue & 1) === 1;\n var shifted = aValue >> 1;\n return isNegative\n ? -shifted\n : shifted;\n}\n\n/**\n * Returns the base 64 VLQ encoded value.\n */\nexports.encode = function base64VLQ_encode(aValue) {\n var encoded = \"\";\n var digit;\n\n var vlq = toVLQSigned(aValue);\n\n do {\n digit = vlq & VLQ_BASE_MASK;\n vlq >>>= VLQ_BASE_SHIFT;\n if (vlq > 0) {\n // There are still more digits in this value, so we must make sure the\n // continuation bit is marked.\n digit |= VLQ_CONTINUATION_BIT;\n }\n encoded += base64.encode(digit);\n } while (vlq > 0);\n\n return encoded;\n};\n\n/**\n * Decodes the next base 64 VLQ value from the given string and returns the\n * value and the rest of the string via the out parameter.\n */\nexports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {\n var strLen = aStr.length;\n var result = 0;\n var shift = 0;\n var continuation, digit;\n\n do {\n if (aIndex >= strLen) {\n throw new Error(\"Expected more digits in base 64 VLQ value.\");\n }\n\n digit = base64.decode(aStr.charCodeAt(aIndex++));\n if (digit === -1) {\n throw new Error(\"Invalid base64 digit: \" + aStr.charAt(aIndex - 1));\n }\n\n continuation = !!(digit & VLQ_CONTINUATION_BIT);\n digit &= VLQ_BASE_MASK;\n result = result + (digit << shift);\n shift += VLQ_BASE_SHIFT;\n } while (continuation);\n\n aOutParam.value = fromVLQSigned(result);\n aOutParam.rest = aIndex;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/base64-vlq.js\n// module id = 2\n// module chunks = 0","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\nvar intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');\n\n/**\n * Encode an integer in the range of 0 to 63 to a single base 64 digit.\n */\nexports.encode = function (number) {\n if (0 <= number && number < intToCharMap.length) {\n return intToCharMap[number];\n }\n throw new TypeError(\"Must be between 0 and 63: \" + number);\n};\n\n/**\n * Decode a single base 64 character code digit to an integer. Returns -1 on\n * failure.\n */\nexports.decode = function (charCode) {\n var bigA = 65; // 'A'\n var bigZ = 90; // 'Z'\n\n var littleA = 97; // 'a'\n var littleZ = 122; // 'z'\n\n var zero = 48; // '0'\n var nine = 57; // '9'\n\n var plus = 43; // '+'\n var slash = 47; // '/'\n\n var littleOffset = 26;\n var numberOffset = 52;\n\n // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ\n if (bigA <= charCode && charCode <= bigZ) {\n return (charCode - bigA);\n }\n\n // 26 - 51: abcdefghijklmnopqrstuvwxyz\n if (littleA <= charCode && charCode <= littleZ) {\n return (charCode - littleA + littleOffset);\n }\n\n // 52 - 61: 0123456789\n if (zero <= charCode && charCode <= nine) {\n return (charCode - zero + numberOffset);\n }\n\n // 62: +\n if (charCode == plus) {\n return 62;\n }\n\n // 63: /\n if (charCode == slash) {\n return 63;\n }\n\n // Invalid base64 digit.\n return -1;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/base64.js\n// module id = 3\n// module chunks = 0","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\n/**\n * This is a helper function for getting values from parameter/options\n * objects.\n *\n * @param args The object we are extracting values from\n * @param name The name of the property we are getting.\n * @param defaultValue An optional value to return if the property is missing\n * from the object. If this is not specified and the property is missing, an\n * error will be thrown.\n */\nfunction getArg(aArgs, aName, aDefaultValue) {\n if (aName in aArgs) {\n return aArgs[aName];\n } else if (arguments.length === 3) {\n return aDefaultValue;\n } else {\n throw new Error('\"' + aName + '\" is a required argument.');\n }\n}\nexports.getArg = getArg;\n\nvar urlRegexp = /^(?:([\\w+\\-.]+):)?\\/\\/(?:(\\w+:\\w+)@)?([\\w.-]*)(?::(\\d+))?(.*)$/;\nvar dataUrlRegexp = /^data:.+\\,.+$/;\n\nfunction urlParse(aUrl) {\n var match = aUrl.match(urlRegexp);\n if (!match) {\n return null;\n }\n return {\n scheme: match[1],\n auth: match[2],\n host: match[3],\n port: match[4],\n path: match[5]\n };\n}\nexports.urlParse = urlParse;\n\nfunction urlGenerate(aParsedUrl) {\n var url = '';\n if (aParsedUrl.scheme) {\n url += aParsedUrl.scheme + ':';\n }\n url += '//';\n if (aParsedUrl.auth) {\n url += aParsedUrl.auth + '@';\n }\n if (aParsedUrl.host) {\n url += aParsedUrl.host;\n }\n if (aParsedUrl.port) {\n url += \":\" + aParsedUrl.port\n }\n if (aParsedUrl.path) {\n url += aParsedUrl.path;\n }\n return url;\n}\nexports.urlGenerate = urlGenerate;\n\n/**\n * Normalizes a path, or the path portion of a URL:\n *\n * - Replaces consecutive slashes with one slash.\n * - Removes unnecessary '.' parts.\n * - Removes unnecessary '/..' parts.\n *\n * Based on code in the Node.js 'path' core module.\n *\n * @param aPath The path or url to normalize.\n */\nfunction normalize(aPath) {\n var path = aPath;\n var url = urlParse(aPath);\n if (url) {\n if (!url.path) {\n return aPath;\n }\n path = url.path;\n }\n var isAbsolute = exports.isAbsolute(path);\n\n var parts = path.split(/\\/+/);\n for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {\n part = parts[i];\n if (part === '.') {\n parts.splice(i, 1);\n } else if (part === '..') {\n up++;\n } else if (up > 0) {\n if (part === '') {\n // The first part is blank if the path is absolute. Trying to go\n // above the root is a no-op. Therefore we can remove all '..' parts\n // directly after the root.\n parts.splice(i + 1, up);\n up = 0;\n } else {\n parts.splice(i, 2);\n up--;\n }\n }\n }\n path = parts.join('/');\n\n if (path === '') {\n path = isAbsolute ? '/' : '.';\n }\n\n if (url) {\n url.path = path;\n return urlGenerate(url);\n }\n return path;\n}\nexports.normalize = normalize;\n\n/**\n * Joins two paths/URLs.\n *\n * @param aRoot The root path or URL.\n * @param aPath The path or URL to be joined with the root.\n *\n * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a\n * scheme-relative URL: Then the scheme of aRoot, if any, is prepended\n * first.\n * - Otherwise aPath is a path. If aRoot is a URL, then its path portion\n * is updated with the result and aRoot is returned. Otherwise the result\n * is returned.\n * - If aPath is absolute, the result is aPath.\n * - Otherwise the two paths are joined with a slash.\n * - Joining for example 'http://' and 'www.example.com' is also supported.\n */\nfunction join(aRoot, aPath) {\n if (aRoot === \"\") {\n aRoot = \".\";\n }\n if (aPath === \"\") {\n aPath = \".\";\n }\n var aPathUrl = urlParse(aPath);\n var aRootUrl = urlParse(aRoot);\n if (aRootUrl) {\n aRoot = aRootUrl.path || '/';\n }\n\n // `join(foo, '//www.example.org')`\n if (aPathUrl && !aPathUrl.scheme) {\n if (aRootUrl) {\n aPathUrl.scheme = aRootUrl.scheme;\n }\n return urlGenerate(aPathUrl);\n }\n\n if (aPathUrl || aPath.match(dataUrlRegexp)) {\n return aPath;\n }\n\n // `join('http://', 'www.example.com')`\n if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {\n aRootUrl.host = aPath;\n return urlGenerate(aRootUrl);\n }\n\n var joined = aPath.charAt(0) === '/'\n ? aPath\n : normalize(aRoot.replace(/\\/+$/, '') + '/' + aPath);\n\n if (aRootUrl) {\n aRootUrl.path = joined;\n return urlGenerate(aRootUrl);\n }\n return joined;\n}\nexports.join = join;\n\nexports.isAbsolute = function (aPath) {\n return aPath.charAt(0) === '/' || urlRegexp.test(aPath);\n};\n\n/**\n * Make a path relative to a URL or another path.\n *\n * @param aRoot The root path or URL.\n * @param aPath The path or URL to be made relative to aRoot.\n */\nfunction relative(aRoot, aPath) {\n if (aRoot === \"\") {\n aRoot = \".\";\n }\n\n aRoot = aRoot.replace(/\\/$/, '');\n\n // It is possible for the path to be above the root. In this case, simply\n // checking whether the root is a prefix of the path won't work. Instead, we\n // need to remove components from the root one by one, until either we find\n // a prefix that fits, or we run out of components to remove.\n var level = 0;\n while (aPath.indexOf(aRoot + '/') !== 0) {\n var index = aRoot.lastIndexOf(\"/\");\n if (index < 0) {\n return aPath;\n }\n\n // If the only part of the root that is left is the scheme (i.e. http://,\n // file:///, etc.), one or more slashes (/), or simply nothing at all, we\n // have exhausted all components, so the path is not relative to the root.\n aRoot = aRoot.slice(0, index);\n if (aRoot.match(/^([^\\/]+:\\/)?\\/*$/)) {\n return aPath;\n }\n\n ++level;\n }\n\n // Make sure we add a \"../\" for each component we removed from the root.\n return Array(level + 1).join(\"../\") + aPath.substr(aRoot.length + 1);\n}\nexports.relative = relative;\n\nvar supportsNullProto = (function () {\n var obj = Object.create(null);\n return !('__proto__' in obj);\n}());\n\nfunction identity (s) {\n return s;\n}\n\n/**\n * Because behavior goes wacky when you set `__proto__` on objects, we\n * have to prefix all the strings in our set with an arbitrary character.\n *\n * See https://github.com/mozilla/source-map/pull/31 and\n * https://github.com/mozilla/source-map/issues/30\n *\n * @param String aStr\n */\nfunction toSetString(aStr) {\n if (isProtoString(aStr)) {\n return '$' + aStr;\n }\n\n return aStr;\n}\nexports.toSetString = supportsNullProto ? identity : toSetString;\n\nfunction fromSetString(aStr) {\n if (isProtoString(aStr)) {\n return aStr.slice(1);\n }\n\n return aStr;\n}\nexports.fromSetString = supportsNullProto ? identity : fromSetString;\n\nfunction isProtoString(s) {\n if (!s) {\n return false;\n }\n\n var length = s.length;\n\n if (length < 9 /* \"__proto__\".length */) {\n return false;\n }\n\n if (s.charCodeAt(length - 1) !== 95 /* '_' */ ||\n s.charCodeAt(length - 2) !== 95 /* '_' */ ||\n s.charCodeAt(length - 3) !== 111 /* 'o' */ ||\n s.charCodeAt(length - 4) !== 116 /* 't' */ ||\n s.charCodeAt(length - 5) !== 111 /* 'o' */ ||\n s.charCodeAt(length - 6) !== 114 /* 'r' */ ||\n s.charCodeAt(length - 7) !== 112 /* 'p' */ ||\n s.charCodeAt(length - 8) !== 95 /* '_' */ ||\n s.charCodeAt(length - 9) !== 95 /* '_' */) {\n return false;\n }\n\n for (var i = length - 10; i >= 0; i--) {\n if (s.charCodeAt(i) !== 36 /* '$' */) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Comparator between two mappings where the original positions are compared.\n *\n * Optionally pass in `true` as `onlyCompareGenerated` to consider two\n * mappings with the same original source/line/column, but different generated\n * line and column the same. Useful when searching for a mapping with a\n * stubbed out mapping.\n */\nfunction compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {\n var cmp = strcmp(mappingA.source, mappingB.source);\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.originalLine - mappingB.originalLine;\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.originalColumn - mappingB.originalColumn;\n if (cmp !== 0 || onlyCompareOriginal) {\n return cmp;\n }\n\n cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.generatedLine - mappingB.generatedLine;\n if (cmp !== 0) {\n return cmp;\n }\n\n return strcmp(mappingA.name, mappingB.name);\n}\nexports.compareByOriginalPositions = compareByOriginalPositions;\n\n/**\n * Comparator between two mappings with deflated source and name indices where\n * the generated positions are compared.\n *\n * Optionally pass in `true` as `onlyCompareGenerated` to consider two\n * mappings with the same generated line and column, but different\n * source/name/original line and column the same. Useful when searching for a\n * mapping with a stubbed out mapping.\n */\nfunction compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {\n var cmp = mappingA.generatedLine - mappingB.generatedLine;\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n if (cmp !== 0 || onlyCompareGenerated) {\n return cmp;\n }\n\n cmp = strcmp(mappingA.source, mappingB.source);\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.originalLine - mappingB.originalLine;\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.originalColumn - mappingB.originalColumn;\n if (cmp !== 0) {\n return cmp;\n }\n\n return strcmp(mappingA.name, mappingB.name);\n}\nexports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;\n\nfunction strcmp(aStr1, aStr2) {\n if (aStr1 === aStr2) {\n return 0;\n }\n\n if (aStr1 === null) {\n return 1; // aStr2 !== null\n }\n\n if (aStr2 === null) {\n return -1; // aStr1 !== null\n }\n\n if (aStr1 > aStr2) {\n return 1;\n }\n\n return -1;\n}\n\n/**\n * Comparator between two mappings with inflated source and name strings where\n * the generated positions are compared.\n */\nfunction compareByGeneratedPositionsInflated(mappingA, mappingB) {\n var cmp = mappingA.generatedLine - mappingB.generatedLine;\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.generatedColumn - mappingB.generatedColumn;\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = strcmp(mappingA.source, mappingB.source);\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.originalLine - mappingB.originalLine;\n if (cmp !== 0) {\n return cmp;\n }\n\n cmp = mappingA.originalColumn - mappingB.originalColumn;\n if (cmp !== 0) {\n return cmp;\n }\n\n return strcmp(mappingA.name, mappingB.name);\n}\nexports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;\n\n/**\n * Strip any JSON XSSI avoidance prefix from the string (as documented\n * in the source maps specification), and then parse the string as\n * JSON.\n */\nfunction parseSourceMapInput(str) {\n return JSON.parse(str.replace(/^\\)]}'[^\\n]*\\n/, ''));\n}\nexports.parseSourceMapInput = parseSourceMapInput;\n\n/**\n * Compute the URL of a source given the the source root, the source's\n * URL, and the source map's URL.\n */\nfunction computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {\n sourceURL = sourceURL || '';\n\n if (sourceRoot) {\n // This follows what Chrome does.\n if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {\n sourceRoot += '/';\n }\n // The spec says:\n // Line 4: An optional source root, useful for relocating source\n // files on a server or removing repeated values in the\n // “sources” entry. This value is prepended to the individual\n // entries in the “source” field.\n sourceURL = sourceRoot + sourceURL;\n }\n\n // Historically, SourceMapConsumer did not take the sourceMapURL as\n // a parameter. This mode is still somewhat supported, which is why\n // this code block is conditional. However, it's preferable to pass\n // the source map URL to SourceMapConsumer, so that this function\n // can implement the source URL resolution algorithm as outlined in\n // the spec. This block is basically the equivalent of:\n // new URL(sourceURL, sourceMapURL).toString()\n // ... except it avoids using URL, which wasn't available in the\n // older releases of node still supported by this library.\n //\n // The spec says:\n // If the sources are not absolute URLs after prepending of the\n // “sourceRoot”, the sources are resolved relative to the\n // SourceMap (like resolving script src in a html document).\n if (sourceMapURL) {\n var parsed = urlParse(sourceMapURL);\n if (!parsed) {\n throw new Error(\"sourceMapURL could not be parsed\");\n }\n if (parsed.path) {\n // Strip the last path component, but keep the \"/\".\n var index = parsed.path.lastIndexOf('/');\n if (index >= 0) {\n parsed.path = parsed.path.substring(0, index + 1);\n }\n }\n sourceURL = join(urlGenerate(parsed), sourceURL);\n }\n\n return normalize(sourceURL);\n}\nexports.computeSourceURL = computeSourceURL;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/util.js\n// module id = 4\n// module chunks = 0","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\nvar util = require('./util');\nvar has = Object.prototype.hasOwnProperty;\nvar hasNativeMap = typeof Map !== \"undefined\";\n\n/**\n * A data structure which is a combination of an array and a set. Adding a new\n * member is O(1), testing for membership is O(1), and finding the index of an\n * element is O(1). Removing elements from the set is not supported. Only\n * strings are supported for membership.\n */\nfunction ArraySet() {\n this._array = [];\n this._set = hasNativeMap ? new Map() : Object.create(null);\n}\n\n/**\n * Static method for creating ArraySet instances from an existing array.\n */\nArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {\n var set = new ArraySet();\n for (var i = 0, len = aArray.length; i < len; i++) {\n set.add(aArray[i], aAllowDuplicates);\n }\n return set;\n};\n\n/**\n * Return how many unique items are in this ArraySet. If duplicates have been\n * added, than those do not count towards the size.\n *\n * @returns Number\n */\nArraySet.prototype.size = function ArraySet_size() {\n return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;\n};\n\n/**\n * Add the given string to this set.\n *\n * @param String aStr\n */\nArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {\n var sStr = hasNativeMap ? aStr : util.toSetString(aStr);\n var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);\n var idx = this._array.length;\n if (!isDuplicate || aAllowDuplicates) {\n this._array.push(aStr);\n }\n if (!isDuplicate) {\n if (hasNativeMap) {\n this._set.set(aStr, idx);\n } else {\n this._set[sStr] = idx;\n }\n }\n};\n\n/**\n * Is the given string a member of this set?\n *\n * @param String aStr\n */\nArraySet.prototype.has = function ArraySet_has(aStr) {\n if (hasNativeMap) {\n return this._set.has(aStr);\n } else {\n var sStr = util.toSetString(aStr);\n return has.call(this._set, sStr);\n }\n};\n\n/**\n * What is the index of the given string in the array?\n *\n * @param String aStr\n */\nArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {\n if (hasNativeMap) {\n var idx = this._set.get(aStr);\n if (idx >= 0) {\n return idx;\n }\n } else {\n var sStr = util.toSetString(aStr);\n if (has.call(this._set, sStr)) {\n return this._set[sStr];\n }\n }\n\n throw new Error('\"' + aStr + '\" is not in the set.');\n};\n\n/**\n * What is the element at the given index?\n *\n * @param Number aIdx\n */\nArraySet.prototype.at = function ArraySet_at(aIdx) {\n if (aIdx >= 0 && aIdx < this._array.length) {\n return this._array[aIdx];\n }\n throw new Error('No element indexed by ' + aIdx);\n};\n\n/**\n * Returns the array representation of this set (which has the proper indices\n * indicated by indexOf). Note that this is a copy of the internal array used\n * for storing the members so that no one can mess with internal state.\n */\nArraySet.prototype.toArray = function ArraySet_toArray() {\n return this._array.slice();\n};\n\nexports.ArraySet = ArraySet;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/array-set.js\n// module id = 5\n// module chunks = 0","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2014 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\nvar util = require('./util');\n\n/**\n * Determine whether mappingB is after mappingA with respect to generated\n * position.\n */\nfunction generatedPositionAfter(mappingA, mappingB) {\n // Optimized for most common case\n var lineA = mappingA.generatedLine;\n var lineB = mappingB.generatedLine;\n var columnA = mappingA.generatedColumn;\n var columnB = mappingB.generatedColumn;\n return lineB > lineA || lineB == lineA && columnB >= columnA ||\n util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;\n}\n\n/**\n * A data structure to provide a sorted view of accumulated mappings in a\n * performance conscious manner. It trades a neglibable overhead in general\n * case for a large speedup in case of mappings being added in order.\n */\nfunction MappingList() {\n this._array = [];\n this._sorted = true;\n // Serves as infimum\n this._last = {generatedLine: -1, generatedColumn: 0};\n}\n\n/**\n * Iterate through internal items. This method takes the same arguments that\n * `Array.prototype.forEach` takes.\n *\n * NOTE: The order of the mappings is NOT guaranteed.\n */\nMappingList.prototype.unsortedForEach =\n function MappingList_forEach(aCallback, aThisArg) {\n this._array.forEach(aCallback, aThisArg);\n };\n\n/**\n * Add the given source mapping.\n *\n * @param Object aMapping\n */\nMappingList.prototype.add = function MappingList_add(aMapping) {\n if (generatedPositionAfter(this._last, aMapping)) {\n this._last = aMapping;\n this._array.push(aMapping);\n } else {\n this._sorted = false;\n this._array.push(aMapping);\n }\n};\n\n/**\n * Returns the flat, sorted array of mappings. The mappings are sorted by\n * generated position.\n *\n * WARNING: This method returns internal data without copying, for\n * performance. The return value must NOT be mutated, and should be treated as\n * an immutable borrow. If you want to take ownership, you must make your own\n * copy.\n */\nMappingList.prototype.toArray = function MappingList_toArray() {\n if (!this._sorted) {\n this._array.sort(util.compareByGeneratedPositionsInflated);\n this._sorted = true;\n }\n return this._array;\n};\n\nexports.MappingList = MappingList;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/mapping-list.js\n// module id = 6\n// module chunks = 0","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\nvar util = require('./util');\nvar binarySearch = require('./binary-search');\nvar ArraySet = require('./array-set').ArraySet;\nvar base64VLQ = require('./base64-vlq');\nvar quickSort = require('./quick-sort').quickSort;\n\nfunction SourceMapConsumer(aSourceMap, aSourceMapURL) {\n var sourceMap = aSourceMap;\n if (typeof aSourceMap === 'string') {\n sourceMap = util.parseSourceMapInput(aSourceMap);\n }\n\n return sourceMap.sections != null\n ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)\n : new BasicSourceMapConsumer(sourceMap, aSourceMapURL);\n}\n\nSourceMapConsumer.fromSourceMap = function(aSourceMap, aSourceMapURL) {\n return BasicSourceMapConsumer.fromSourceMap(aSourceMap, aSourceMapURL);\n}\n\n/**\n * The version of the source mapping spec that we are consuming.\n */\nSourceMapConsumer.prototype._version = 3;\n\n// `__generatedMappings` and `__originalMappings` are arrays that hold the\n// parsed mapping coordinates from the source map's \"mappings\" attribute. They\n// are lazily instantiated, accessed via the `_generatedMappings` and\n// `_originalMappings` getters respectively, and we only parse the mappings\n// and create these arrays once queried for a source location. We jump through\n// these hoops because there can be many thousands of mappings, and parsing\n// them is expensive, so we only want to do it if we must.\n//\n// Each object in the arrays is of the form:\n//\n// {\n// generatedLine: The line number in the generated code,\n// generatedColumn: The column number in the generated code,\n// source: The path to the original source file that generated this\n// chunk of code,\n// originalLine: The line number in the original source that\n// corresponds to this chunk of generated code,\n// originalColumn: The column number in the original source that\n// corresponds to this chunk of generated code,\n// name: The name of the original symbol which generated this chunk of\n// code.\n// }\n//\n// All properties except for `generatedLine` and `generatedColumn` can be\n// `null`.\n//\n// `_generatedMappings` is ordered by the generated positions.\n//\n// `_originalMappings` is ordered by the original positions.\n\nSourceMapConsumer.prototype.__generatedMappings = null;\nObject.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {\n configurable: true,\n enumerable: true,\n get: function () {\n if (!this.__generatedMappings) {\n this._parseMappings(this._mappings, this.sourceRoot);\n }\n\n return this.__generatedMappings;\n }\n});\n\nSourceMapConsumer.prototype.__originalMappings = null;\nObject.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {\n configurable: true,\n enumerable: true,\n get: function () {\n if (!this.__originalMappings) {\n this._parseMappings(this._mappings, this.sourceRoot);\n }\n\n return this.__originalMappings;\n }\n});\n\nSourceMapConsumer.prototype._charIsMappingSeparator =\n function SourceMapConsumer_charIsMappingSeparator(aStr, index) {\n var c = aStr.charAt(index);\n return c === \";\" || c === \",\";\n };\n\n/**\n * Parse the mappings in a string in to a data structure which we can easily\n * query (the ordered arrays in the `this.__generatedMappings` and\n * `this.__originalMappings` properties).\n */\nSourceMapConsumer.prototype._parseMappings =\n function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {\n throw new Error(\"Subclasses must implement _parseMappings\");\n };\n\nSourceMapConsumer.GENERATED_ORDER = 1;\nSourceMapConsumer.ORIGINAL_ORDER = 2;\n\nSourceMapConsumer.GREATEST_LOWER_BOUND = 1;\nSourceMapConsumer.LEAST_UPPER_BOUND = 2;\n\n/**\n * Iterate over each mapping between an original source/line/column and a\n * generated line/column in this source map.\n *\n * @param Function aCallback\n * The function that is called with each mapping.\n * @param Object aContext\n * Optional. If specified, this object will be the value of `this` every\n * time that `aCallback` is called.\n * @param aOrder\n * Either `SourceMapConsumer.GENERATED_ORDER` or\n * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to\n * iterate over the mappings sorted by the generated file's line/column\n * order or the original's source/line/column order, respectively. Defaults to\n * `SourceMapConsumer.GENERATED_ORDER`.\n */\nSourceMapConsumer.prototype.eachMapping =\n function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {\n var context = aContext || null;\n var order = aOrder || SourceMapConsumer.GENERATED_ORDER;\n\n var mappings;\n switch (order) {\n case SourceMapConsumer.GENERATED_ORDER:\n mappings = this._generatedMappings;\n break;\n case SourceMapConsumer.ORIGINAL_ORDER:\n mappings = this._originalMappings;\n break;\n default:\n throw new Error(\"Unknown order of iteration.\");\n }\n\n var sourceRoot = this.sourceRoot;\n mappings.map(function (mapping) {\n var source = mapping.source === null ? null : this._sources.at(mapping.source);\n source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);\n return {\n source: source,\n generatedLine: mapping.generatedLine,\n generatedColumn: mapping.generatedColumn,\n originalLine: mapping.originalLine,\n originalColumn: mapping.originalColumn,\n name: mapping.name === null ? null : this._names.at(mapping.name)\n };\n }, this).forEach(aCallback, context);\n };\n\n/**\n * Returns all generated line and column information for the original source,\n * line, and column provided. If no column is provided, returns all mappings\n * corresponding to a either the line we are searching for or the next\n * closest line that has any mappings. Otherwise, returns all mappings\n * corresponding to the given line and either the column we are searching for\n * or the next closest column that has any offsets.\n *\n * The only argument is an object with the following properties:\n *\n * - source: The filename of the original source.\n * - line: The line number in the original source. The line number is 1-based.\n * - column: Optional. the column number in the original source.\n * The column number is 0-based.\n *\n * and an array of objects is returned, each with the following properties:\n *\n * - line: The line number in the generated source, or null. The\n * line number is 1-based.\n * - column: The column number in the generated source, or null.\n * The column number is 0-based.\n */\nSourceMapConsumer.prototype.allGeneratedPositionsFor =\n function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {\n var line = util.getArg(aArgs, 'line');\n\n // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping\n // returns the index of the closest mapping less than the needle. By\n // setting needle.originalColumn to 0, we thus find the last mapping for\n // the given line, provided such a mapping exists.\n var needle = {\n source: util.getArg(aArgs, 'source'),\n originalLine: line,\n originalColumn: util.getArg(aArgs, 'column', 0)\n };\n\n needle.source = this._findSourceIndex(needle.source);\n if (needle.source < 0) {\n return [];\n }\n\n var mappings = [];\n\n var index = this._findMapping(needle,\n this._originalMappings,\n \"originalLine\",\n \"originalColumn\",\n util.compareByOriginalPositions,\n binarySearch.LEAST_UPPER_BOUND);\n if (index >= 0) {\n var mapping = this._originalMappings[index];\n\n if (aArgs.column === undefined) {\n var originalLine = mapping.originalLine;\n\n // Iterate until either we run out of mappings, or we run into\n // a mapping for a different line than the one we found. Since\n // mappings are sorted, this is guaranteed to find all mappings for\n // the line we found.\n while (mapping && mapping.originalLine === originalLine) {\n mappings.push({\n line: util.getArg(mapping, 'generatedLine', null),\n column: util.getArg(mapping, 'generatedColumn', null),\n lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)\n });\n\n mapping = this._originalMappings[++index];\n }\n } else {\n var originalColumn = mapping.originalColumn;\n\n // Iterate until either we run out of mappings, or we run into\n // a mapping for a different line than the one we were searching for.\n // Since mappings are sorted, this is guaranteed to find all mappings for\n // the line we are searching for.\n while (mapping &&\n mapping.originalLine === line &&\n mapping.originalColumn == originalColumn) {\n mappings.push({\n line: util.getArg(mapping, 'generatedLine', null),\n column: util.getArg(mapping, 'generatedColumn', null),\n lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)\n });\n\n mapping = this._originalMappings[++index];\n }\n }\n }\n\n return mappings;\n };\n\nexports.SourceMapConsumer = SourceMapConsumer;\n\n/**\n * A BasicSourceMapConsumer instance represents a parsed source map which we can\n * query for information about the original file positions by giving it a file\n * position in the generated source.\n *\n * The first parameter is the raw source map (either as a JSON string, or\n * already parsed to an object). According to the spec, source maps have the\n * following attributes:\n *\n * - version: Which version of the source map spec this map is following.\n * - sources: An array of URLs to the original source files.\n * - names: An array of identifiers which can be referrenced by individual mappings.\n * - sourceRoot: Optional. The URL root from which all sources are relative.\n * - sourcesContent: Optional. An array of contents of the original source files.\n * - mappings: A string of base64 VLQs which contain the actual mappings.\n * - file: Optional. The generated file this source map is associated with.\n *\n * Here is an example source map, taken from the source map spec[0]:\n *\n * {\n * version : 3,\n * file: \"out.js\",\n * sourceRoot : \"\",\n * sources: [\"foo.js\", \"bar.js\"],\n * names: [\"src\", \"maps\", \"are\", \"fun\"],\n * mappings: \"AA,AB;;ABCDE;\"\n * }\n *\n * The second parameter, if given, is a string whose value is the URL\n * at which the source map was found. This URL is used to compute the\n * sources array.\n *\n * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#\n */\nfunction BasicSourceMapConsumer(aSourceMap, aSourceMapURL) {\n var sourceMap = aSourceMap;\n if (typeof aSourceMap === 'string') {\n sourceMap = util.parseSourceMapInput(aSourceMap);\n }\n\n var version = util.getArg(sourceMap, 'version');\n var sources = util.getArg(sourceMap, 'sources');\n // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which\n // requires the array) to play nice here.\n var names = util.getArg(sourceMap, 'names', []);\n var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);\n var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);\n var mappings = util.getArg(sourceMap, 'mappings');\n var file = util.getArg(sourceMap, 'file', null);\n\n // Once again, Sass deviates from the spec and supplies the version as a\n // string rather than a number, so we use loose equality checking here.\n if (version != this._version) {\n throw new Error('Unsupported version: ' + version);\n }\n\n if (sourceRoot) {\n sourceRoot = util.normalize(sourceRoot);\n }\n\n sources = sources\n .map(String)\n // Some source maps produce relative source paths like \"./foo.js\" instead of\n // \"foo.js\". Normalize these first so that future comparisons will succeed.\n // See bugzil.la/1090768.\n .map(util.normalize)\n // Always ensure that absolute sources are internally stored relative to\n // the source root, if the source root is absolute. Not doing this would\n // be particularly problematic when the source root is a prefix of the\n // source (valid, but why??). See github issue #199 and bugzil.la/1188982.\n .map(function (source) {\n return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source)\n ? util.relative(sourceRoot, source)\n : source;\n });\n\n // Pass `true` below to allow duplicate names and sources. While source maps\n // are intended to be compressed and deduplicated, the TypeScript compiler\n // sometimes generates source maps with duplicates in them. See Github issue\n // #72 and bugzil.la/889492.\n this._names = ArraySet.fromArray(names.map(String), true);\n this._sources = ArraySet.fromArray(sources, true);\n\n this._absoluteSources = this._sources.toArray().map(function (s) {\n return util.computeSourceURL(sourceRoot, s, aSourceMapURL);\n });\n\n this.sourceRoot = sourceRoot;\n this.sourcesContent = sourcesContent;\n this._mappings = mappings;\n this._sourceMapURL = aSourceMapURL;\n this.file = file;\n}\n\nBasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);\nBasicSourceMapConsumer.prototype.consumer = SourceMapConsumer;\n\n/**\n * Utility function to find the index of a source. Returns -1 if not\n * found.\n */\nBasicSourceMapConsumer.prototype._findSourceIndex = function(aSource) {\n var relativeSource = aSource;\n if (this.sourceRoot != null) {\n relativeSource = util.relative(this.sourceRoot, relativeSource);\n }\n\n if (this._sources.has(relativeSource)) {\n return this._sources.indexOf(relativeSource);\n }\n\n // Maybe aSource is an absolute URL as returned by |sources|. In\n // this case we can't simply undo the transform.\n var i;\n for (i = 0; i < this._absoluteSources.length; ++i) {\n if (this._absoluteSources[i] == aSource) {\n return i;\n }\n }\n\n return -1;\n};\n\n/**\n * Create a BasicSourceMapConsumer from a SourceMapGenerator.\n *\n * @param SourceMapGenerator aSourceMap\n * The source map that will be consumed.\n * @param String aSourceMapURL\n * The URL at which the source map can be found (optional)\n * @returns BasicSourceMapConsumer\n */\nBasicSourceMapConsumer.fromSourceMap =\n function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) {\n var smc = Object.create(BasicSourceMapConsumer.prototype);\n\n var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);\n var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);\n smc.sourceRoot = aSourceMap._sourceRoot;\n smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),\n smc.sourceRoot);\n smc.file = aSourceMap._file;\n smc._sourceMapURL = aSourceMapURL;\n smc._absoluteSources = smc._sources.toArray().map(function (s) {\n return util.computeSourceURL(smc.sourceRoot, s, aSourceMapURL);\n });\n\n // Because we are modifying the entries (by converting string sources and\n // names to indices into the sources and names ArraySets), we have to make\n // a copy of the entry or else bad things happen. Shared mutable state\n // strikes again! See github issue #191.\n\n var generatedMappings = aSourceMap._mappings.toArray().slice();\n var destGeneratedMappings = smc.__generatedMappings = [];\n var destOriginalMappings = smc.__originalMappings = [];\n\n for (var i = 0, length = generatedMappings.length; i < length; i++) {\n var srcMapping = generatedMappings[i];\n var destMapping = new Mapping;\n destMapping.generatedLine = srcMapping.generatedLine;\n destMapping.generatedColumn = srcMapping.generatedColumn;\n\n if (srcMapping.source) {\n destMapping.source = sources.indexOf(srcMapping.source);\n destMapping.originalLine = srcMapping.originalLine;\n destMapping.originalColumn = srcMapping.originalColumn;\n\n if (srcMapping.name) {\n destMapping.name = names.indexOf(srcMapping.name);\n }\n\n destOriginalMappings.push(destMapping);\n }\n\n destGeneratedMappings.push(destMapping);\n }\n\n quickSort(smc.__originalMappings, util.compareByOriginalPositions);\n\n return smc;\n };\n\n/**\n * The version of the source mapping spec that we are consuming.\n */\nBasicSourceMapConsumer.prototype._version = 3;\n\n/**\n * The list of original sources.\n */\nObject.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {\n get: function () {\n return this._absoluteSources.slice();\n }\n});\n\n/**\n * Provide the JIT with a nice shape / hidden class.\n */\nfunction Mapping() {\n this.generatedLine = 0;\n this.generatedColumn = 0;\n this.source = null;\n this.originalLine = null;\n this.originalColumn = null;\n this.name = null;\n}\n\n/**\n * Parse the mappings in a string in to a data structure which we can easily\n * query (the ordered arrays in the `this.__generatedMappings` and\n * `this.__originalMappings` properties).\n */\nBasicSourceMapConsumer.prototype._parseMappings =\n function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {\n var generatedLine = 1;\n var previousGeneratedColumn = 0;\n var previousOriginalLine = 0;\n var previousOriginalColumn = 0;\n var previousSource = 0;\n var previousName = 0;\n var length = aStr.length;\n var index = 0;\n var cachedSegments = {};\n var temp = {};\n var originalMappings = [];\n var generatedMappings = [];\n var mapping, str, segment, end, value;\n\n while (index < length) {\n if (aStr.charAt(index) === ';') {\n generatedLine++;\n index++;\n previousGeneratedColumn = 0;\n }\n else if (aStr.charAt(index) === ',') {\n index++;\n }\n else {\n mapping = new Mapping();\n mapping.generatedLine = generatedLine;\n\n // Because each offset is encoded relative to the previous one,\n // many segments often have the same encoding. We can exploit this\n // fact by caching the parsed variable length fields of each segment,\n // allowing us to avoid a second parse if we encounter the same\n // segment again.\n for (end = index; end < length; end++) {\n if (this._charIsMappingSeparator(aStr, end)) {\n break;\n }\n }\n str = aStr.slice(index, end);\n\n segment = cachedSegments[str];\n if (segment) {\n index += str.length;\n } else {\n segment = [];\n while (index < end) {\n base64VLQ.decode(aStr, index, temp);\n value = temp.value;\n index = temp.rest;\n segment.push(value);\n }\n\n if (segment.length === 2) {\n throw new Error('Found a source, but no line and column');\n }\n\n if (segment.length === 3) {\n throw new Error('Found a source and line, but no column');\n }\n\n cachedSegments[str] = segment;\n }\n\n // Generated column.\n mapping.generatedColumn = previousGeneratedColumn + segment[0];\n previousGeneratedColumn = mapping.generatedColumn;\n\n if (segment.length > 1) {\n // Original source.\n mapping.source = previousSource + segment[1];\n previousSource += segment[1];\n\n // Original line.\n mapping.originalLine = previousOriginalLine + segment[2];\n previousOriginalLine = mapping.originalLine;\n // Lines are stored 0-based\n mapping.originalLine += 1;\n\n // Original column.\n mapping.originalColumn = previousOriginalColumn + segment[3];\n previousOriginalColumn = mapping.originalColumn;\n\n if (segment.length > 4) {\n // Original name.\n mapping.name = previousName + segment[4];\n previousName += segment[4];\n }\n }\n\n generatedMappings.push(mapping);\n if (typeof mapping.originalLine === 'number') {\n originalMappings.push(mapping);\n }\n }\n }\n\n quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated);\n this.__generatedMappings = generatedMappings;\n\n quickSort(originalMappings, util.compareByOriginalPositions);\n this.__originalMappings = originalMappings;\n };\n\n/**\n * Find the mapping that best matches the hypothetical \"needle\" mapping that\n * we are searching for in the given \"haystack\" of mappings.\n */\nBasicSourceMapConsumer.prototype._findMapping =\n function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName,\n aColumnName, aComparator, aBias) {\n // To return the position we are searching for, we must first find the\n // mapping for the given position and then return the opposite position it\n // points to. Because the mappings are sorted, we can use binary search to\n // find the best mapping.\n\n if (aNeedle[aLineName] <= 0) {\n throw new TypeError('Line must be greater than or equal to 1, got '\n + aNeedle[aLineName]);\n }\n if (aNeedle[aColumnName] < 0) {\n throw new TypeError('Column must be greater than or equal to 0, got '\n + aNeedle[aColumnName]);\n }\n\n return binarySearch.search(aNeedle, aMappings, aComparator, aBias);\n };\n\n/**\n * Compute the last column for each generated mapping. The last column is\n * inclusive.\n */\nBasicSourceMapConsumer.prototype.computeColumnSpans =\n function SourceMapConsumer_computeColumnSpans() {\n for (var index = 0; index < this._generatedMappings.length; ++index) {\n var mapping = this._generatedMappings[index];\n\n // Mappings do not contain a field for the last generated columnt. We\n // can come up with an optimistic estimate, however, by assuming that\n // mappings are contiguous (i.e. given two consecutive mappings, the\n // first mapping ends where the second one starts).\n if (index + 1 < this._generatedMappings.length) {\n var nextMapping = this._generatedMappings[index + 1];\n\n if (mapping.generatedLine === nextMapping.generatedLine) {\n mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1;\n continue;\n }\n }\n\n // The last mapping for each line spans the entire line.\n mapping.lastGeneratedColumn = Infinity;\n }\n };\n\n/**\n * Returns the original source, line, and column information for the generated\n * source's line and column positions provided. The only argument is an object\n * with the following properties:\n *\n * - line: The line number in the generated source. The line number\n * is 1-based.\n * - column: The column number in the generated source. The column\n * number is 0-based.\n * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or\n * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the\n * closest element that is smaller than or greater than the one we are\n * searching for, respectively, if the exact element cannot be found.\n * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.\n *\n * and an object is returned with the following properties:\n *\n * - source: The original source file, or null.\n * - line: The line number in the original source, or null. The\n * line number is 1-based.\n * - column: The column number in the original source, or null. The\n * column number is 0-based.\n * - name: The original identifier, or null.\n */\nBasicSourceMapConsumer.prototype.originalPositionFor =\n function SourceMapConsumer_originalPositionFor(aArgs) {\n var needle = {\n generatedLine: util.getArg(aArgs, 'line'),\n generatedColumn: util.getArg(aArgs, 'column')\n };\n\n var index = this._findMapping(\n needle,\n this._generatedMappings,\n \"generatedLine\",\n \"generatedColumn\",\n util.compareByGeneratedPositionsDeflated,\n util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)\n );\n\n if (index >= 0) {\n var mapping = this._generatedMappings[index];\n\n if (mapping.generatedLine === needle.generatedLine) {\n var source = util.getArg(mapping, 'source', null);\n if (source !== null) {\n source = this._sources.at(source);\n source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL);\n }\n var name = util.getArg(mapping, 'name', null);\n if (name !== null) {\n name = this._names.at(name);\n }\n return {\n source: source,\n line: util.getArg(mapping, 'originalLine', null),\n column: util.getArg(mapping, 'originalColumn', null),\n name: name\n };\n }\n }\n\n return {\n source: null,\n line: null,\n column: null,\n name: null\n };\n };\n\n/**\n * Return true if we have the source content for every source in the source\n * map, false otherwise.\n */\nBasicSourceMapConsumer.prototype.hasContentsOfAllSources =\n function BasicSourceMapConsumer_hasContentsOfAllSources() {\n if (!this.sourcesContent) {\n return false;\n }\n return this.sourcesContent.length >= this._sources.size() &&\n !this.sourcesContent.some(function (sc) { return sc == null; });\n };\n\n/**\n * Returns the original source content. The only argument is the url of the\n * original source file. Returns null if no original source content is\n * available.\n */\nBasicSourceMapConsumer.prototype.sourceContentFor =\n function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {\n if (!this.sourcesContent) {\n return null;\n }\n\n var index = this._findSourceIndex(aSource);\n if (index >= 0) {\n return this.sourcesContent[index];\n }\n\n var relativeSource = aSource;\n if (this.sourceRoot != null) {\n relativeSource = util.relative(this.sourceRoot, relativeSource);\n }\n\n var url;\n if (this.sourceRoot != null\n && (url = util.urlParse(this.sourceRoot))) {\n // XXX: file:// URIs and absolute paths lead to unexpected behavior for\n // many users. We can help them out when they expect file:// URIs to\n // behave like it would if they were running a local HTTP server. See\n // https://bugzilla.mozilla.org/show_bug.cgi?id=885597.\n var fileUriAbsPath = relativeSource.replace(/^file:\\/\\//, \"\");\n if (url.scheme == \"file\"\n && this._sources.has(fileUriAbsPath)) {\n return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]\n }\n\n if ((!url.path || url.path == \"/\")\n && this._sources.has(\"/\" + relativeSource)) {\n return this.sourcesContent[this._sources.indexOf(\"/\" + relativeSource)];\n }\n }\n\n // This function is used recursively from\n // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we\n // don't want to throw if we can't find the source - we just want to\n // return null, so we provide a flag to exit gracefully.\n if (nullOnMissing) {\n return null;\n }\n else {\n throw new Error('\"' + relativeSource + '\" is not in the SourceMap.');\n }\n };\n\n/**\n * Returns the generated line and column information for the original source,\n * line, and column positions provided. The only argument is an object with\n * the following properties:\n *\n * - source: The filename of the original source.\n * - line: The line number in the original source. The line number\n * is 1-based.\n * - column: The column number in the original source. The column\n * number is 0-based.\n * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or\n * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the\n * closest element that is smaller than or greater than the one we are\n * searching for, respectively, if the exact element cannot be found.\n * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.\n *\n * and an object is returned with the following properties:\n *\n * - line: The line number in the generated source, or null. The\n * line number is 1-based.\n * - column: The column number in the generated source, or null.\n * The column number is 0-based.\n */\nBasicSourceMapConsumer.prototype.generatedPositionFor =\n function SourceMapConsumer_generatedPositionFor(aArgs) {\n var source = util.getArg(aArgs, 'source');\n source = this._findSourceIndex(source);\n if (source < 0) {\n return {\n line: null,\n column: null,\n lastColumn: null\n };\n }\n\n var needle = {\n source: source,\n originalLine: util.getArg(aArgs, 'line'),\n originalColumn: util.getArg(aArgs, 'column')\n };\n\n var index = this._findMapping(\n needle,\n this._originalMappings,\n \"originalLine\",\n \"originalColumn\",\n util.compareByOriginalPositions,\n util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)\n );\n\n if (index >= 0) {\n var mapping = this._originalMappings[index];\n\n if (mapping.source === needle.source) {\n return {\n line: util.getArg(mapping, 'generatedLine', null),\n column: util.getArg(mapping, 'generatedColumn', null),\n lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)\n };\n }\n }\n\n return {\n line: null,\n column: null,\n lastColumn: null\n };\n };\n\nexports.BasicSourceMapConsumer = BasicSourceMapConsumer;\n\n/**\n * An IndexedSourceMapConsumer instance represents a parsed source map which\n * we can query for information. It differs from BasicSourceMapConsumer in\n * that it takes \"indexed\" source maps (i.e. ones with a \"sections\" field) as\n * input.\n *\n * The first parameter is a raw source map (either as a JSON string, or already\n * parsed to an object). According to the spec for indexed source maps, they\n * have the following attributes:\n *\n * - version: Which version of the source map spec this map is following.\n * - file: Optional. The generated file this source map is associated with.\n * - sections: A list of section definitions.\n *\n * Each value under the \"sections\" field has two fields:\n * - offset: The offset into the original specified at which this section\n * begins to apply, defined as an object with a \"line\" and \"column\"\n * field.\n * - map: A source map definition. This source map could also be indexed,\n * but doesn't have to be.\n *\n * Instead of the \"map\" field, it's also possible to have a \"url\" field\n * specifying a URL to retrieve a source map from, but that's currently\n * unsupported.\n *\n * Here's an example source map, taken from the source map spec[0], but\n * modified to omit a section which uses the \"url\" field.\n *\n * {\n * version : 3,\n * file: \"app.js\",\n * sections: [{\n * offset: {line:100, column:10},\n * map: {\n * version : 3,\n * file: \"section.js\",\n * sources: [\"foo.js\", \"bar.js\"],\n * names: [\"src\", \"maps\", \"are\", \"fun\"],\n * mappings: \"AAAA,E;;ABCDE;\"\n * }\n * }],\n * }\n *\n * The second parameter, if given, is a string whose value is the URL\n * at which the source map was found. This URL is used to compute the\n * sources array.\n *\n * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt\n */\nfunction IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {\n var sourceMap = aSourceMap;\n if (typeof aSourceMap === 'string') {\n sourceMap = util.parseSourceMapInput(aSourceMap);\n }\n\n var version = util.getArg(sourceMap, 'version');\n var sections = util.getArg(sourceMap, 'sections');\n\n if (version != this._version) {\n throw new Error('Unsupported version: ' + version);\n }\n\n this._sources = new ArraySet();\n this._names = new ArraySet();\n\n var lastOffset = {\n line: -1,\n column: 0\n };\n this._sections = sections.map(function (s) {\n if (s.url) {\n // The url field will require support for asynchronicity.\n // See https://github.com/mozilla/source-map/issues/16\n throw new Error('Support for url field in sections not implemented.');\n }\n var offset = util.getArg(s, 'offset');\n var offsetLine = util.getArg(offset, 'line');\n var offsetColumn = util.getArg(offset, 'column');\n\n if (offsetLine < lastOffset.line ||\n (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) {\n throw new Error('Section offsets must be ordered and non-overlapping.');\n }\n lastOffset = offset;\n\n return {\n generatedOffset: {\n // The offset fields are 0-based, but we use 1-based indices when\n // encoding/decoding from VLQ.\n generatedLine: offsetLine + 1,\n generatedColumn: offsetColumn + 1\n },\n consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL)\n }\n });\n}\n\nIndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);\nIndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer;\n\n/**\n * The version of the source mapping spec that we are consuming.\n */\nIndexedSourceMapConsumer.prototype._version = 3;\n\n/**\n * The list of original sources.\n */\nObject.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', {\n get: function () {\n var sources = [];\n for (var i = 0; i < this._sections.length; i++) {\n for (var j = 0; j < this._sections[i].consumer.sources.length; j++) {\n sources.push(this._sections[i].consumer.sources[j]);\n }\n }\n return sources;\n }\n});\n\n/**\n * Returns the original source, line, and column information for the generated\n * source's line and column positions provided. The only argument is an object\n * with the following properties:\n *\n * - line: The line number in the generated source. The line number\n * is 1-based.\n * - column: The column number in the generated source. The column\n * number is 0-based.\n *\n * and an object is returned with the following properties:\n *\n * - source: The original source file, or null.\n * - line: The line number in the original source, or null. The\n * line number is 1-based.\n * - column: The column number in the original source, or null. The\n * column number is 0-based.\n * - name: The original identifier, or null.\n */\nIndexedSourceMapConsumer.prototype.originalPositionFor =\n function IndexedSourceMapConsumer_originalPositionFor(aArgs) {\n var needle = {\n generatedLine: util.getArg(aArgs, 'line'),\n generatedColumn: util.getArg(aArgs, 'column')\n };\n\n // Find the section containing the generated position we're trying to map\n // to an original position.\n var sectionIndex = binarySearch.search(needle, this._sections,\n function(needle, section) {\n var cmp = needle.generatedLine - section.generatedOffset.generatedLine;\n if (cmp) {\n return cmp;\n }\n\n return (needle.generatedColumn -\n section.generatedOffset.generatedColumn);\n });\n var section = this._sections[sectionIndex];\n\n if (!section) {\n return {\n source: null,\n line: null,\n column: null,\n name: null\n };\n }\n\n return section.consumer.originalPositionFor({\n line: needle.generatedLine -\n (section.generatedOffset.generatedLine - 1),\n column: needle.generatedColumn -\n (section.generatedOffset.generatedLine === needle.generatedLine\n ? section.generatedOffset.generatedColumn - 1\n : 0),\n bias: aArgs.bias\n });\n };\n\n/**\n * Return true if we have the source content for every source in the source\n * map, false otherwise.\n */\nIndexedSourceMapConsumer.prototype.hasContentsOfAllSources =\n function IndexedSourceMapConsumer_hasContentsOfAllSources() {\n return this._sections.every(function (s) {\n return s.consumer.hasContentsOfAllSources();\n });\n };\n\n/**\n * Returns the original source content. The only argument is the url of the\n * original source file. Returns null if no original source content is\n * available.\n */\nIndexedSourceMapConsumer.prototype.sourceContentFor =\n function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {\n for (var i = 0; i < this._sections.length; i++) {\n var section = this._sections[i];\n\n var content = section.consumer.sourceContentFor(aSource, true);\n if (content) {\n return content;\n }\n }\n if (nullOnMissing) {\n return null;\n }\n else {\n throw new Error('\"' + aSource + '\" is not in the SourceMap.');\n }\n };\n\n/**\n * Returns the generated line and column information for the original source,\n * line, and column positions provided. The only argument is an object with\n * the following properties:\n *\n * - source: The filename of the original source.\n * - line: The line number in the original source. The line number\n * is 1-based.\n * - column: The column number in the original source. The column\n * number is 0-based.\n *\n * and an object is returned with the following properties:\n *\n * - line: The line number in the generated source, or null. The\n * line number is 1-based. \n * - column: The column number in the generated source, or null.\n * The column number is 0-based.\n */\nIndexedSourceMapConsumer.prototype.generatedPositionFor =\n function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {\n for (var i = 0; i < this._sections.length; i++) {\n var section = this._sections[i];\n\n // Only consider this section if the requested source is in the list of\n // sources of the consumer.\n if (section.consumer._findSourceIndex(util.getArg(aArgs, 'source')) === -1) {\n continue;\n }\n var generatedPosition = section.consumer.generatedPositionFor(aArgs);\n if (generatedPosition) {\n var ret = {\n line: generatedPosition.line +\n (section.generatedOffset.generatedLine - 1),\n column: generatedPosition.column +\n (section.generatedOffset.generatedLine === generatedPosition.line\n ? section.generatedOffset.generatedColumn - 1\n : 0)\n };\n return ret;\n }\n }\n\n return {\n line: null,\n column: null\n };\n };\n\n/**\n * Parse the mappings in a string in to a data structure which we can easily\n * query (the ordered arrays in the `this.__generatedMappings` and\n * `this.__originalMappings` properties).\n */\nIndexedSourceMapConsumer.prototype._parseMappings =\n function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) {\n this.__generatedMappings = [];\n this.__originalMappings = [];\n for (var i = 0; i < this._sections.length; i++) {\n var section = this._sections[i];\n var sectionMappings = section.consumer._generatedMappings;\n for (var j = 0; j < sectionMappings.length; j++) {\n var mapping = sectionMappings[j];\n\n var source = section.consumer._sources.at(mapping.source);\n source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL);\n this._sources.add(source);\n source = this._sources.indexOf(source);\n\n var name = null;\n if (mapping.name) {\n name = section.consumer._names.at(mapping.name);\n this._names.add(name);\n name = this._names.indexOf(name);\n }\n\n // The mappings coming from the consumer for the section have\n // generated positions relative to the start of the section, so we\n // need to offset them to be relative to the start of the concatenated\n // generated file.\n var adjustedMapping = {\n source: source,\n generatedLine: mapping.generatedLine +\n (section.generatedOffset.generatedLine - 1),\n generatedColumn: mapping.generatedColumn +\n (section.generatedOffset.generatedLine === mapping.generatedLine\n ? section.generatedOffset.generatedColumn - 1\n : 0),\n originalLine: mapping.originalLine,\n originalColumn: mapping.originalColumn,\n name: name\n };\n\n this.__generatedMappings.push(adjustedMapping);\n if (typeof adjustedMapping.originalLine === 'number') {\n this.__originalMappings.push(adjustedMapping);\n }\n }\n }\n\n quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated);\n quickSort(this.__originalMappings, util.compareByOriginalPositions);\n };\n\nexports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/source-map-consumer.js\n// module id = 7\n// module chunks = 0","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\nexports.GREATEST_LOWER_BOUND = 1;\nexports.LEAST_UPPER_BOUND = 2;\n\n/**\n * Recursive implementation of binary search.\n *\n * @param aLow Indices here and lower do not contain the needle.\n * @param aHigh Indices here and higher do not contain the needle.\n * @param aNeedle The element being searched for.\n * @param aHaystack The non-empty array being searched.\n * @param aCompare Function which takes two elements and returns -1, 0, or 1.\n * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or\n * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the\n * closest element that is smaller than or greater than the one we are\n * searching for, respectively, if the exact element cannot be found.\n */\nfunction recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) {\n // This function terminates when one of the following is true:\n //\n // 1. We find the exact element we are looking for.\n //\n // 2. We did not find the exact element, but we can return the index of\n // the next-closest element.\n //\n // 3. We did not find the exact element, and there is no next-closest\n // element than the one we are searching for, so we return -1.\n var mid = Math.floor((aHigh - aLow) / 2) + aLow;\n var cmp = aCompare(aNeedle, aHaystack[mid], true);\n if (cmp === 0) {\n // Found the element we are looking for.\n return mid;\n }\n else if (cmp > 0) {\n // Our needle is greater than aHaystack[mid].\n if (aHigh - mid > 1) {\n // The element is in the upper half.\n return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias);\n }\n\n // The exact needle element was not found in this haystack. Determine if\n // we are in termination case (3) or (2) and return the appropriate thing.\n if (aBias == exports.LEAST_UPPER_BOUND) {\n return aHigh < aHaystack.length ? aHigh : -1;\n } else {\n return mid;\n }\n }\n else {\n // Our needle is less than aHaystack[mid].\n if (mid - aLow > 1) {\n // The element is in the lower half.\n return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias);\n }\n\n // we are in termination case (3) or (2) and return the appropriate thing.\n if (aBias == exports.LEAST_UPPER_BOUND) {\n return mid;\n } else {\n return aLow < 0 ? -1 : aLow;\n }\n }\n}\n\n/**\n * This is an implementation of binary search which will always try and return\n * the index of the closest element if there is no exact hit. This is because\n * mappings between original and generated line/col pairs are single points,\n * and there is an implicit region between each of them, so a miss just means\n * that you aren't on the very start of a region.\n *\n * @param aNeedle The element you are looking for.\n * @param aHaystack The array that is being searched.\n * @param aCompare A function which takes the needle and an element in the\n * array and returns -1, 0, or 1 depending on whether the needle is less\n * than, equal to, or greater than the element, respectively.\n * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or\n * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the\n * closest element that is smaller than or greater than the one we are\n * searching for, respectively, if the exact element cannot be found.\n * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'.\n */\nexports.search = function search(aNeedle, aHaystack, aCompare, aBias) {\n if (aHaystack.length === 0) {\n return -1;\n }\n\n var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack,\n aCompare, aBias || exports.GREATEST_LOWER_BOUND);\n if (index < 0) {\n return -1;\n }\n\n // We have found either the exact element, or the next-closest element than\n // the one we are searching for. However, there may be more than one such\n // element. Make sure we always return the smallest of these.\n while (index - 1 >= 0) {\n if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {\n break;\n }\n --index;\n }\n\n return index;\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/binary-search.js\n// module id = 8\n// module chunks = 0","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\n// It turns out that some (most?) JavaScript engines don't self-host\n// `Array.prototype.sort`. This makes sense because C++ will likely remain\n// faster than JS when doing raw CPU-intensive sorting. However, when using a\n// custom comparator function, calling back and forth between the VM's C++ and\n// JIT'd JS is rather slow *and* loses JIT type information, resulting in\n// worse generated code for the comparator function than would be optimal. In\n// fact, when sorting with a comparator, these costs outweigh the benefits of\n// sorting in C++. By using our own JS-implemented Quick Sort (below), we get\n// a ~3500ms mean speed-up in `bench/bench.html`.\n\n/**\n * Swap the elements indexed by `x` and `y` in the array `ary`.\n *\n * @param {Array} ary\n * The array.\n * @param {Number} x\n * The index of the first item.\n * @param {Number} y\n * The index of the second item.\n */\nfunction swap(ary, x, y) {\n var temp = ary[x];\n ary[x] = ary[y];\n ary[y] = temp;\n}\n\n/**\n * Returns a random integer within the range `low .. high` inclusive.\n *\n * @param {Number} low\n * The lower bound on the range.\n * @param {Number} high\n * The upper bound on the range.\n */\nfunction randomIntInRange(low, high) {\n return Math.round(low + (Math.random() * (high - low)));\n}\n\n/**\n * The Quick Sort algorithm.\n *\n * @param {Array} ary\n * An array to sort.\n * @param {function} comparator\n * Function to use to compare two items.\n * @param {Number} p\n * Start index of the array\n * @param {Number} r\n * End index of the array\n */\nfunction doQuickSort(ary, comparator, p, r) {\n // If our lower bound is less than our upper bound, we (1) partition the\n // array into two pieces and (2) recurse on each half. If it is not, this is\n // the empty array and our base case.\n\n if (p < r) {\n // (1) Partitioning.\n //\n // The partitioning chooses a pivot between `p` and `r` and moves all\n // elements that are less than or equal to the pivot to the before it, and\n // all the elements that are greater than it after it. The effect is that\n // once partition is done, the pivot is in the exact place it will be when\n // the array is put in sorted order, and it will not need to be moved\n // again. This runs in O(n) time.\n\n // Always choose a random pivot so that an input array which is reverse\n // sorted does not cause O(n^2) running time.\n var pivotIndex = randomIntInRange(p, r);\n var i = p - 1;\n\n swap(ary, pivotIndex, r);\n var pivot = ary[r];\n\n // Immediately after `j` is incremented in this loop, the following hold\n // true:\n //\n // * Every element in `ary[p .. i]` is less than or equal to the pivot.\n //\n // * Every element in `ary[i+1 .. j-1]` is greater than the pivot.\n for (var j = p; j < r; j++) {\n if (comparator(ary[j], pivot) <= 0) {\n i += 1;\n swap(ary, i, j);\n }\n }\n\n swap(ary, i + 1, j);\n var q = i + 1;\n\n // (2) Recurse on each half.\n\n doQuickSort(ary, comparator, p, q - 1);\n doQuickSort(ary, comparator, q + 1, r);\n }\n}\n\n/**\n * Sort the given array in-place with the given comparator function.\n *\n * @param {Array} ary\n * An array to sort.\n * @param {function} comparator\n * Function to use to compare two items.\n */\nexports.quickSort = function (ary, comparator) {\n doQuickSort(ary, comparator, 0, ary.length - 1);\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/quick-sort.js\n// module id = 9\n// module chunks = 0","/* -*- Mode: js; js-indent-level: 2; -*- */\n/*\n * Copyright 2011 Mozilla Foundation and contributors\n * Licensed under the New BSD license. See LICENSE or:\n * http://opensource.org/licenses/BSD-3-Clause\n */\n\nvar SourceMapGenerator = require('./source-map-generator').SourceMapGenerator;\nvar util = require('./util');\n\n// Matches a Windows-style `\\r\\n` newline or a `\\n` newline used by all other\n// operating systems these days (capturing the result).\nvar REGEX_NEWLINE = /(\\r?\\n)/;\n\n// Newline character code for charCodeAt() comparisons\nvar NEWLINE_CODE = 10;\n\n// Private symbol for identifying `SourceNode`s when multiple versions of\n// the source-map library are loaded. This MUST NOT CHANGE across\n// versions!\nvar isSourceNode = \"$$$isSourceNode$$$\";\n\n/**\n * SourceNodes provide a way to abstract over interpolating/concatenating\n * snippets of generated JavaScript source code while maintaining the line and\n * column information associated with the original source code.\n *\n * @param aLine The original line number.\n * @param aColumn The original column number.\n * @param aSource The original source's filename.\n * @param aChunks Optional. An array of strings which are snippets of\n * generated JS, or other SourceNodes.\n * @param aName The original identifier.\n */\nfunction SourceNode(aLine, aColumn, aSource, aChunks, aName) {\n this.children = [];\n this.sourceContents = {};\n this.line = aLine == null ? null : aLine;\n this.column = aColumn == null ? null : aColumn;\n this.source = aSource == null ? null : aSource;\n this.name = aName == null ? null : aName;\n this[isSourceNode] = true;\n if (aChunks != null) this.add(aChunks);\n}\n\n/**\n * Creates a SourceNode from generated code and a SourceMapConsumer.\n *\n * @param aGeneratedCode The generated code\n * @param aSourceMapConsumer The SourceMap for the generated code\n * @param aRelativePath Optional. The path that relative sources in the\n * SourceMapConsumer should be relative to.\n */\nSourceNode.fromStringWithSourceMap =\n function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) {\n // The SourceNode we want to fill with the generated code\n // and the SourceMap\n var node = new SourceNode();\n\n // All even indices of this array are one line of the generated code,\n // while all odd indices are the newlines between two adjacent lines\n // (since `REGEX_NEWLINE` captures its match).\n // Processed fragments are accessed by calling `shiftNextLine`.\n var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);\n var remainingLinesIndex = 0;\n var shiftNextLine = function() {\n var lineContents = getNextLine();\n // The last line of a file might not have a newline.\n var newLine = getNextLine() || \"\";\n return lineContents + newLine;\n\n function getNextLine() {\n return remainingLinesIndex < remainingLines.length ?\n remainingLines[remainingLinesIndex++] : undefined;\n }\n };\n\n // We need to remember the position of \"remainingLines\"\n var lastGeneratedLine = 1, lastGeneratedColumn = 0;\n\n // The generate SourceNodes we need a code range.\n // To extract it current and last mapping is used.\n // Here we store the last mapping.\n var lastMapping = null;\n\n aSourceMapConsumer.eachMapping(function (mapping) {\n if (lastMapping !== null) {\n // We add the code from \"lastMapping\" to \"mapping\":\n // First check if there is a new line in between.\n if (lastGeneratedLine < mapping.generatedLine) {\n // Associate first line with \"lastMapping\"\n addMappingWithCode(lastMapping, shiftNextLine());\n lastGeneratedLine++;\n lastGeneratedColumn = 0;\n // The remaining code is added without mapping\n } else {\n // There is no new line in between.\n // Associate the code between \"lastGeneratedColumn\" and\n // \"mapping.generatedColumn\" with \"lastMapping\"\n var nextLine = remainingLines[remainingLinesIndex] || '';\n var code = nextLine.substr(0, mapping.generatedColumn -\n lastGeneratedColumn);\n remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn -\n lastGeneratedColumn);\n lastGeneratedColumn = mapping.generatedColumn;\n addMappingWithCode(lastMapping, code);\n // No more remaining code, continue\n lastMapping = mapping;\n return;\n }\n }\n // We add the generated code until the first mapping\n // to the SourceNode without any mapping.\n // Each line is added as separate string.\n while (lastGeneratedLine < mapping.generatedLine) {\n node.add(shiftNextLine());\n lastGeneratedLine++;\n }\n if (lastGeneratedColumn < mapping.generatedColumn) {\n var nextLine = remainingLines[remainingLinesIndex] || '';\n node.add(nextLine.substr(0, mapping.generatedColumn));\n remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);\n lastGeneratedColumn = mapping.generatedColumn;\n }\n lastMapping = mapping;\n }, this);\n // We have processed all mappings.\n if (remainingLinesIndex < remainingLines.length) {\n if (lastMapping) {\n // Associate the remaining code in the current line with \"lastMapping\"\n addMappingWithCode(lastMapping, shiftNextLine());\n }\n // and add the remaining lines without any mapping\n node.add(remainingLines.splice(remainingLinesIndex).join(\"\"));\n }\n\n // Copy sourcesContent into SourceNode\n aSourceMapConsumer.sources.forEach(function (sourceFile) {\n var content = aSourceMapConsumer.sourceContentFor(sourceFile);\n if (content != null) {\n if (aRelativePath != null) {\n sourceFile = util.join(aRelativePath, sourceFile);\n }\n node.setSourceContent(sourceFile, content);\n }\n });\n\n return node;\n\n function addMappingWithCode(mapping, code) {\n if (mapping === null || mapping.source === undefined) {\n node.add(code);\n } else {\n var source = aRelativePath\n ? util.join(aRelativePath, mapping.source)\n : mapping.source;\n node.add(new SourceNode(mapping.originalLine,\n mapping.originalColumn,\n source,\n code,\n mapping.name));\n }\n }\n };\n\n/**\n * Add a chunk of generated JS to this source node.\n *\n * @param aChunk A string snippet of generated JS code, another instance of\n * SourceNode, or an array where each member is one of those things.\n */\nSourceNode.prototype.add = function SourceNode_add(aChunk) {\n if (Array.isArray(aChunk)) {\n aChunk.forEach(function (chunk) {\n this.add(chunk);\n }, this);\n }\n else if (aChunk[isSourceNode] || typeof aChunk === \"string\") {\n if (aChunk) {\n this.children.push(aChunk);\n }\n }\n else {\n throw new TypeError(\n \"Expected a SourceNode, string, or an array of SourceNodes and strings. Got \" + aChunk\n );\n }\n return this;\n};\n\n/**\n * Add a chunk of generated JS to the beginning of this source node.\n *\n * @param aChunk A string snippet of generated JS code, another instance of\n * SourceNode, or an array where each member is one of those things.\n */\nSourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {\n if (Array.isArray(aChunk)) {\n for (var i = aChunk.length-1; i >= 0; i--) {\n this.prepend(aChunk[i]);\n }\n }\n else if (aChunk[isSourceNode] || typeof aChunk === \"string\") {\n this.children.unshift(aChunk);\n }\n else {\n throw new TypeError(\n \"Expected a SourceNode, string, or an array of SourceNodes and strings. Got \" + aChunk\n );\n }\n return this;\n};\n\n/**\n * Walk over the tree of JS snippets in this node and its children. The\n * walking function is called once for each snippet of JS and is passed that\n * snippet and the its original associated source's line/column location.\n *\n * @param aFn The traversal function.\n */\nSourceNode.prototype.walk = function SourceNode_walk(aFn) {\n var chunk;\n for (var i = 0, len = this.children.length; i < len; i++) {\n chunk = this.children[i];\n if (chunk[isSourceNode]) {\n chunk.walk(aFn);\n }\n else {\n if (chunk !== '') {\n aFn(chunk, { source: this.source,\n line: this.line,\n column: this.column,\n name: this.name });\n }\n }\n }\n};\n\n/**\n * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between\n * each of `this.children`.\n *\n * @param aSep The separator.\n */\nSourceNode.prototype.join = function SourceNode_join(aSep) {\n var newChildren;\n var i;\n var len = this.children.length;\n if (len > 0) {\n newChildren = [];\n for (i = 0; i < len-1; i++) {\n newChildren.push(this.children[i]);\n newChildren.push(aSep);\n }\n newChildren.push(this.children[i]);\n this.children = newChildren;\n }\n return this;\n};\n\n/**\n * Call String.prototype.replace on the very right-most source snippet. Useful\n * for trimming whitespace from the end of a source node, etc.\n *\n * @param aPattern The pattern to replace.\n * @param aReplacement The thing to replace the pattern with.\n */\nSourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {\n var lastChild = this.children[this.children.length - 1];\n if (lastChild[isSourceNode]) {\n lastChild.replaceRight(aPattern, aReplacement);\n }\n else if (typeof lastChild === 'string') {\n this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);\n }\n else {\n this.children.push(''.replace(aPattern, aReplacement));\n }\n return this;\n};\n\n/**\n * Set the source content for a source file. This will be added to the SourceMapGenerator\n * in the sourcesContent field.\n *\n * @param aSourceFile The filename of the source file\n * @param aSourceContent The content of the source file\n */\nSourceNode.prototype.setSourceContent =\n function SourceNode_setSourceContent(aSourceFile, aSourceContent) {\n this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;\n };\n\n/**\n * Walk over the tree of SourceNodes. The walking function is called for each\n * source file content and is passed the filename and source content.\n *\n * @param aFn The traversal function.\n */\nSourceNode.prototype.walkSourceContents =\n function SourceNode_walkSourceContents(aFn) {\n for (var i = 0, len = this.children.length; i < len; i++) {\n if (this.children[i][isSourceNode]) {\n this.children[i].walkSourceContents(aFn);\n }\n }\n\n var sources = Object.keys(this.sourceContents);\n for (var i = 0, len = sources.length; i < len; i++) {\n aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);\n }\n };\n\n/**\n * Return the string representation of this source node. Walks over the tree\n * and concatenates all the various snippets together to one string.\n */\nSourceNode.prototype.toString = function SourceNode_toString() {\n var str = \"\";\n this.walk(function (chunk) {\n str += chunk;\n });\n return str;\n};\n\n/**\n * Returns the string representation of this source node along with a source\n * map.\n */\nSourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {\n var generated = {\n code: \"\",\n line: 1,\n column: 0\n };\n var map = new SourceMapGenerator(aArgs);\n var sourceMappingActive = false;\n var lastOriginalSource = null;\n var lastOriginalLine = null;\n var lastOriginalColumn = null;\n var lastOriginalName = null;\n this.walk(function (chunk, original) {\n generated.code += chunk;\n if (original.source !== null\n && original.line !== null\n && original.column !== null) {\n if(lastOriginalSource !== original.source\n || lastOriginalLine !== original.line\n || lastOriginalColumn !== original.column\n || lastOriginalName !== original.name) {\n map.addMapping({\n source: original.source,\n original: {\n line: original.line,\n column: original.column\n },\n generated: {\n line: generated.line,\n column: generated.column\n },\n name: original.name\n });\n }\n lastOriginalSource = original.source;\n lastOriginalLine = original.line;\n lastOriginalColumn = original.column;\n lastOriginalName = original.name;\n sourceMappingActive = true;\n } else if (sourceMappingActive) {\n map.addMapping({\n generated: {\n line: generated.line,\n column: generated.column\n }\n });\n lastOriginalSource = null;\n sourceMappingActive = false;\n }\n for (var idx = 0, length = chunk.length; idx < length; idx++) {\n if (chunk.charCodeAt(idx) === NEWLINE_CODE) {\n generated.line++;\n generated.column = 0;\n // Mappings end at eol\n if (idx + 1 === length) {\n lastOriginalSource = null;\n sourceMappingActive = false;\n } else if (sourceMappingActive) {\n map.addMapping({\n source: original.source,\n original: {\n line: original.line,\n column: original.column\n },\n generated: {\n line: generated.line,\n column: generated.column\n },\n name: original.name\n });\n }\n } else {\n generated.column++;\n }\n }\n });\n this.walkSourceContents(function (sourceFile, sourceContent) {\n map.setSourceContent(sourceFile, sourceContent);\n });\n\n return { code: generated.code, map: map };\n};\n\nexports.SourceNode = SourceNode;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/source-node.js\n// module id = 10\n// module chunks = 0"],"sourceRoot":""} \ No newline at end of file diff --git a/node_modules/source-map/lib/array-set.js b/node_modules/source-map/lib/array-set.js new file mode 100644 index 0000000..fbd5c81 --- /dev/null +++ b/node_modules/source-map/lib/array-set.js @@ -0,0 +1,121 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var util = require('./util'); +var has = Object.prototype.hasOwnProperty; +var hasNativeMap = typeof Map !== "undefined"; + +/** + * A data structure which is a combination of an array and a set. Adding a new + * member is O(1), testing for membership is O(1), and finding the index of an + * element is O(1). Removing elements from the set is not supported. Only + * strings are supported for membership. + */ +function ArraySet() { + this._array = []; + this._set = hasNativeMap ? new Map() : Object.create(null); +} + +/** + * Static method for creating ArraySet instances from an existing array. + */ +ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { + var set = new ArraySet(); + for (var i = 0, len = aArray.length; i < len; i++) { + set.add(aArray[i], aAllowDuplicates); + } + return set; +}; + +/** + * Return how many unique items are in this ArraySet. If duplicates have been + * added, than those do not count towards the size. + * + * @returns Number + */ +ArraySet.prototype.size = function ArraySet_size() { + return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length; +}; + +/** + * Add the given string to this set. + * + * @param String aStr + */ +ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { + var sStr = hasNativeMap ? aStr : util.toSetString(aStr); + var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr); + var idx = this._array.length; + if (!isDuplicate || aAllowDuplicates) { + this._array.push(aStr); + } + if (!isDuplicate) { + if (hasNativeMap) { + this._set.set(aStr, idx); + } else { + this._set[sStr] = idx; + } + } +}; + +/** + * Is the given string a member of this set? + * + * @param String aStr + */ +ArraySet.prototype.has = function ArraySet_has(aStr) { + if (hasNativeMap) { + return this._set.has(aStr); + } else { + var sStr = util.toSetString(aStr); + return has.call(this._set, sStr); + } +}; + +/** + * What is the index of the given string in the array? + * + * @param String aStr + */ +ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) { + if (hasNativeMap) { + var idx = this._set.get(aStr); + if (idx >= 0) { + return idx; + } + } else { + var sStr = util.toSetString(aStr); + if (has.call(this._set, sStr)) { + return this._set[sStr]; + } + } + + throw new Error('"' + aStr + '" is not in the set.'); +}; + +/** + * What is the element at the given index? + * + * @param Number aIdx + */ +ArraySet.prototype.at = function ArraySet_at(aIdx) { + if (aIdx >= 0 && aIdx < this._array.length) { + return this._array[aIdx]; + } + throw new Error('No element indexed by ' + aIdx); +}; + +/** + * Returns the array representation of this set (which has the proper indices + * indicated by indexOf). Note that this is a copy of the internal array used + * for storing the members so that no one can mess with internal state. + */ +ArraySet.prototype.toArray = function ArraySet_toArray() { + return this._array.slice(); +}; + +exports.ArraySet = ArraySet; diff --git a/node_modules/source-map/lib/base64-vlq.js b/node_modules/source-map/lib/base64-vlq.js new file mode 100644 index 0000000..612b404 --- /dev/null +++ b/node_modules/source-map/lib/base64-vlq.js @@ -0,0 +1,140 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + * + * Based on the Base 64 VLQ implementation in Closure Compiler: + * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java + * + * Copyright 2011 The Closure Compiler Authors. All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS 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 THE COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + */ + +var base64 = require('./base64'); + +// A single base 64 digit can contain 6 bits of data. For the base 64 variable +// length quantities we use in the source map spec, the first bit is the sign, +// the next four bits are the actual value, and the 6th bit is the +// continuation bit. The continuation bit tells us whether there are more +// digits in this value following this digit. +// +// Continuation +// | Sign +// | | +// V V +// 101011 + +var VLQ_BASE_SHIFT = 5; + +// binary: 100000 +var VLQ_BASE = 1 << VLQ_BASE_SHIFT; + +// binary: 011111 +var VLQ_BASE_MASK = VLQ_BASE - 1; + +// binary: 100000 +var VLQ_CONTINUATION_BIT = VLQ_BASE; + +/** + * Converts from a two-complement value to a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) + * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) + */ +function toVLQSigned(aValue) { + return aValue < 0 + ? ((-aValue) << 1) + 1 + : (aValue << 1) + 0; +} + +/** + * Converts to a two-complement value from a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 + * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 + */ +function fromVLQSigned(aValue) { + var isNegative = (aValue & 1) === 1; + var shifted = aValue >> 1; + return isNegative + ? -shifted + : shifted; +} + +/** + * Returns the base 64 VLQ encoded value. + */ +exports.encode = function base64VLQ_encode(aValue) { + var encoded = ""; + var digit; + + var vlq = toVLQSigned(aValue); + + do { + digit = vlq & VLQ_BASE_MASK; + vlq >>>= VLQ_BASE_SHIFT; + if (vlq > 0) { + // There are still more digits in this value, so we must make sure the + // continuation bit is marked. + digit |= VLQ_CONTINUATION_BIT; + } + encoded += base64.encode(digit); + } while (vlq > 0); + + return encoded; +}; + +/** + * Decodes the next base 64 VLQ value from the given string and returns the + * value and the rest of the string via the out parameter. + */ +exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { + var strLen = aStr.length; + var result = 0; + var shift = 0; + var continuation, digit; + + do { + if (aIndex >= strLen) { + throw new Error("Expected more digits in base 64 VLQ value."); + } + + digit = base64.decode(aStr.charCodeAt(aIndex++)); + if (digit === -1) { + throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); + } + + continuation = !!(digit & VLQ_CONTINUATION_BIT); + digit &= VLQ_BASE_MASK; + result = result + (digit << shift); + shift += VLQ_BASE_SHIFT; + } while (continuation); + + aOutParam.value = fromVLQSigned(result); + aOutParam.rest = aIndex; +}; diff --git a/node_modules/source-map/lib/base64.js b/node_modules/source-map/lib/base64.js new file mode 100644 index 0000000..8aa86b3 --- /dev/null +++ b/node_modules/source-map/lib/base64.js @@ -0,0 +1,67 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); + +/** + * Encode an integer in the range of 0 to 63 to a single base 64 digit. + */ +exports.encode = function (number) { + if (0 <= number && number < intToCharMap.length) { + return intToCharMap[number]; + } + throw new TypeError("Must be between 0 and 63: " + number); +}; + +/** + * Decode a single base 64 character code digit to an integer. Returns -1 on + * failure. + */ +exports.decode = function (charCode) { + var bigA = 65; // 'A' + var bigZ = 90; // 'Z' + + var littleA = 97; // 'a' + var littleZ = 122; // 'z' + + var zero = 48; // '0' + var nine = 57; // '9' + + var plus = 43; // '+' + var slash = 47; // '/' + + var littleOffset = 26; + var numberOffset = 52; + + // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ + if (bigA <= charCode && charCode <= bigZ) { + return (charCode - bigA); + } + + // 26 - 51: abcdefghijklmnopqrstuvwxyz + if (littleA <= charCode && charCode <= littleZ) { + return (charCode - littleA + littleOffset); + } + + // 52 - 61: 0123456789 + if (zero <= charCode && charCode <= nine) { + return (charCode - zero + numberOffset); + } + + // 62: + + if (charCode == plus) { + return 62; + } + + // 63: / + if (charCode == slash) { + return 63; + } + + // Invalid base64 digit. + return -1; +}; diff --git a/node_modules/source-map/lib/binary-search.js b/node_modules/source-map/lib/binary-search.js new file mode 100644 index 0000000..010ac94 --- /dev/null +++ b/node_modules/source-map/lib/binary-search.js @@ -0,0 +1,111 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +exports.GREATEST_LOWER_BOUND = 1; +exports.LEAST_UPPER_BOUND = 2; + +/** + * Recursive implementation of binary search. + * + * @param aLow Indices here and lower do not contain the needle. + * @param aHigh Indices here and higher do not contain the needle. + * @param aNeedle The element being searched for. + * @param aHaystack The non-empty array being searched. + * @param aCompare Function which takes two elements and returns -1, 0, or 1. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + */ +function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { + // This function terminates when one of the following is true: + // + // 1. We find the exact element we are looking for. + // + // 2. We did not find the exact element, but we can return the index of + // the next-closest element. + // + // 3. We did not find the exact element, and there is no next-closest + // element than the one we are searching for, so we return -1. + var mid = Math.floor((aHigh - aLow) / 2) + aLow; + var cmp = aCompare(aNeedle, aHaystack[mid], true); + if (cmp === 0) { + // Found the element we are looking for. + return mid; + } + else if (cmp > 0) { + // Our needle is greater than aHaystack[mid]. + if (aHigh - mid > 1) { + // The element is in the upper half. + return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias); + } + + // The exact needle element was not found in this haystack. Determine if + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return aHigh < aHaystack.length ? aHigh : -1; + } else { + return mid; + } + } + else { + // Our needle is less than aHaystack[mid]. + if (mid - aLow > 1) { + // The element is in the lower half. + return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias); + } + + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return mid; + } else { + return aLow < 0 ? -1 : aLow; + } + } +} + +/** + * This is an implementation of binary search which will always try and return + * the index of the closest element if there is no exact hit. This is because + * mappings between original and generated line/col pairs are single points, + * and there is an implicit region between each of them, so a miss just means + * that you aren't on the very start of a region. + * + * @param aNeedle The element you are looking for. + * @param aHaystack The array that is being searched. + * @param aCompare A function which takes the needle and an element in the + * array and returns -1, 0, or 1 depending on whether the needle is less + * than, equal to, or greater than the element, respectively. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. + */ +exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { + if (aHaystack.length === 0) { + return -1; + } + + var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, + aCompare, aBias || exports.GREATEST_LOWER_BOUND); + if (index < 0) { + return -1; + } + + // We have found either the exact element, or the next-closest element than + // the one we are searching for. However, there may be more than one such + // element. Make sure we always return the smallest of these. + while (index - 1 >= 0) { + if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { + break; + } + --index; + } + + return index; +}; diff --git a/node_modules/source-map/lib/mapping-list.js b/node_modules/source-map/lib/mapping-list.js new file mode 100644 index 0000000..06d1274 --- /dev/null +++ b/node_modules/source-map/lib/mapping-list.js @@ -0,0 +1,79 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2014 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var util = require('./util'); + +/** + * Determine whether mappingB is after mappingA with respect to generated + * position. + */ +function generatedPositionAfter(mappingA, mappingB) { + // Optimized for most common case + var lineA = mappingA.generatedLine; + var lineB = mappingB.generatedLine; + var columnA = mappingA.generatedColumn; + var columnB = mappingB.generatedColumn; + return lineB > lineA || lineB == lineA && columnB >= columnA || + util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0; +} + +/** + * A data structure to provide a sorted view of accumulated mappings in a + * performance conscious manner. It trades a neglibable overhead in general + * case for a large speedup in case of mappings being added in order. + */ +function MappingList() { + this._array = []; + this._sorted = true; + // Serves as infimum + this._last = {generatedLine: -1, generatedColumn: 0}; +} + +/** + * Iterate through internal items. This method takes the same arguments that + * `Array.prototype.forEach` takes. + * + * NOTE: The order of the mappings is NOT guaranteed. + */ +MappingList.prototype.unsortedForEach = + function MappingList_forEach(aCallback, aThisArg) { + this._array.forEach(aCallback, aThisArg); + }; + +/** + * Add the given source mapping. + * + * @param Object aMapping + */ +MappingList.prototype.add = function MappingList_add(aMapping) { + if (generatedPositionAfter(this._last, aMapping)) { + this._last = aMapping; + this._array.push(aMapping); + } else { + this._sorted = false; + this._array.push(aMapping); + } +}; + +/** + * Returns the flat, sorted array of mappings. The mappings are sorted by + * generated position. + * + * WARNING: This method returns internal data without copying, for + * performance. The return value must NOT be mutated, and should be treated as + * an immutable borrow. If you want to take ownership, you must make your own + * copy. + */ +MappingList.prototype.toArray = function MappingList_toArray() { + if (!this._sorted) { + this._array.sort(util.compareByGeneratedPositionsInflated); + this._sorted = true; + } + return this._array; +}; + +exports.MappingList = MappingList; diff --git a/node_modules/source-map/lib/quick-sort.js b/node_modules/source-map/lib/quick-sort.js new file mode 100644 index 0000000..6a7caad --- /dev/null +++ b/node_modules/source-map/lib/quick-sort.js @@ -0,0 +1,114 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +// It turns out that some (most?) JavaScript engines don't self-host +// `Array.prototype.sort`. This makes sense because C++ will likely remain +// faster than JS when doing raw CPU-intensive sorting. However, when using a +// custom comparator function, calling back and forth between the VM's C++ and +// JIT'd JS is rather slow *and* loses JIT type information, resulting in +// worse generated code for the comparator function than would be optimal. In +// fact, when sorting with a comparator, these costs outweigh the benefits of +// sorting in C++. By using our own JS-implemented Quick Sort (below), we get +// a ~3500ms mean speed-up in `bench/bench.html`. + +/** + * Swap the elements indexed by `x` and `y` in the array `ary`. + * + * @param {Array} ary + * The array. + * @param {Number} x + * The index of the first item. + * @param {Number} y + * The index of the second item. + */ +function swap(ary, x, y) { + var temp = ary[x]; + ary[x] = ary[y]; + ary[y] = temp; +} + +/** + * Returns a random integer within the range `low .. high` inclusive. + * + * @param {Number} low + * The lower bound on the range. + * @param {Number} high + * The upper bound on the range. + */ +function randomIntInRange(low, high) { + return Math.round(low + (Math.random() * (high - low))); +} + +/** + * The Quick Sort algorithm. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + * @param {Number} p + * Start index of the array + * @param {Number} r + * End index of the array + */ +function doQuickSort(ary, comparator, p, r) { + // If our lower bound is less than our upper bound, we (1) partition the + // array into two pieces and (2) recurse on each half. If it is not, this is + // the empty array and our base case. + + if (p < r) { + // (1) Partitioning. + // + // The partitioning chooses a pivot between `p` and `r` and moves all + // elements that are less than or equal to the pivot to the before it, and + // all the elements that are greater than it after it. The effect is that + // once partition is done, the pivot is in the exact place it will be when + // the array is put in sorted order, and it will not need to be moved + // again. This runs in O(n) time. + + // Always choose a random pivot so that an input array which is reverse + // sorted does not cause O(n^2) running time. + var pivotIndex = randomIntInRange(p, r); + var i = p - 1; + + swap(ary, pivotIndex, r); + var pivot = ary[r]; + + // Immediately after `j` is incremented in this loop, the following hold + // true: + // + // * Every element in `ary[p .. i]` is less than or equal to the pivot. + // + // * Every element in `ary[i+1 .. j-1]` is greater than the pivot. + for (var j = p; j < r; j++) { + if (comparator(ary[j], pivot) <= 0) { + i += 1; + swap(ary, i, j); + } + } + + swap(ary, i + 1, j); + var q = i + 1; + + // (2) Recurse on each half. + + doQuickSort(ary, comparator, p, q - 1); + doQuickSort(ary, comparator, q + 1, r); + } +} + +/** + * Sort the given array in-place with the given comparator function. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + */ +exports.quickSort = function (ary, comparator) { + doQuickSort(ary, comparator, 0, ary.length - 1); +}; diff --git a/node_modules/source-map/lib/source-map-consumer.js b/node_modules/source-map/lib/source-map-consumer.js new file mode 100644 index 0000000..7b99d1d --- /dev/null +++ b/node_modules/source-map/lib/source-map-consumer.js @@ -0,0 +1,1145 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var util = require('./util'); +var binarySearch = require('./binary-search'); +var ArraySet = require('./array-set').ArraySet; +var base64VLQ = require('./base64-vlq'); +var quickSort = require('./quick-sort').quickSort; + +function SourceMapConsumer(aSourceMap, aSourceMapURL) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = util.parseSourceMapInput(aSourceMap); + } + + return sourceMap.sections != null + ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL) + : new BasicSourceMapConsumer(sourceMap, aSourceMapURL); +} + +SourceMapConsumer.fromSourceMap = function(aSourceMap, aSourceMapURL) { + return BasicSourceMapConsumer.fromSourceMap(aSourceMap, aSourceMapURL); +} + +/** + * The version of the source mapping spec that we are consuming. + */ +SourceMapConsumer.prototype._version = 3; + +// `__generatedMappings` and `__originalMappings` are arrays that hold the +// parsed mapping coordinates from the source map's "mappings" attribute. They +// are lazily instantiated, accessed via the `_generatedMappings` and +// `_originalMappings` getters respectively, and we only parse the mappings +// and create these arrays once queried for a source location. We jump through +// these hoops because there can be many thousands of mappings, and parsing +// them is expensive, so we only want to do it if we must. +// +// Each object in the arrays is of the form: +// +// { +// generatedLine: The line number in the generated code, +// generatedColumn: The column number in the generated code, +// source: The path to the original source file that generated this +// chunk of code, +// originalLine: The line number in the original source that +// corresponds to this chunk of generated code, +// originalColumn: The column number in the original source that +// corresponds to this chunk of generated code, +// name: The name of the original symbol which generated this chunk of +// code. +// } +// +// All properties except for `generatedLine` and `generatedColumn` can be +// `null`. +// +// `_generatedMappings` is ordered by the generated positions. +// +// `_originalMappings` is ordered by the original positions. + +SourceMapConsumer.prototype.__generatedMappings = null; +Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', { + configurable: true, + enumerable: true, + get: function () { + if (!this.__generatedMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__generatedMappings; + } +}); + +SourceMapConsumer.prototype.__originalMappings = null; +Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { + configurable: true, + enumerable: true, + get: function () { + if (!this.__originalMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__originalMappings; + } +}); + +SourceMapConsumer.prototype._charIsMappingSeparator = + function SourceMapConsumer_charIsMappingSeparator(aStr, index) { + var c = aStr.charAt(index); + return c === ";" || c === ","; + }; + +/** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ +SourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + throw new Error("Subclasses must implement _parseMappings"); + }; + +SourceMapConsumer.GENERATED_ORDER = 1; +SourceMapConsumer.ORIGINAL_ORDER = 2; + +SourceMapConsumer.GREATEST_LOWER_BOUND = 1; +SourceMapConsumer.LEAST_UPPER_BOUND = 2; + +/** + * Iterate over each mapping between an original source/line/column and a + * generated line/column in this source map. + * + * @param Function aCallback + * The function that is called with each mapping. + * @param Object aContext + * Optional. If specified, this object will be the value of `this` every + * time that `aCallback` is called. + * @param aOrder + * Either `SourceMapConsumer.GENERATED_ORDER` or + * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to + * iterate over the mappings sorted by the generated file's line/column + * order or the original's source/line/column order, respectively. Defaults to + * `SourceMapConsumer.GENERATED_ORDER`. + */ +SourceMapConsumer.prototype.eachMapping = + function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { + var context = aContext || null; + var order = aOrder || SourceMapConsumer.GENERATED_ORDER; + + var mappings; + switch (order) { + case SourceMapConsumer.GENERATED_ORDER: + mappings = this._generatedMappings; + break; + case SourceMapConsumer.ORIGINAL_ORDER: + mappings = this._originalMappings; + break; + default: + throw new Error("Unknown order of iteration."); + } + + var sourceRoot = this.sourceRoot; + mappings.map(function (mapping) { + var source = mapping.source === null ? null : this._sources.at(mapping.source); + source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL); + return { + source: source, + generatedLine: mapping.generatedLine, + generatedColumn: mapping.generatedColumn, + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: mapping.name === null ? null : this._names.at(mapping.name) + }; + }, this).forEach(aCallback, context); + }; + +/** + * Returns all generated line and column information for the original source, + * line, and column provided. If no column is provided, returns all mappings + * corresponding to a either the line we are searching for or the next + * closest line that has any mappings. Otherwise, returns all mappings + * corresponding to the given line and either the column we are searching for + * or the next closest column that has any offsets. + * + * The only argument is an object with the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. The line number is 1-based. + * - column: Optional. the column number in the original source. + * The column number is 0-based. + * + * and an array of objects is returned, each with the following properties: + * + * - line: The line number in the generated source, or null. The + * line number is 1-based. + * - column: The column number in the generated source, or null. + * The column number is 0-based. + */ +SourceMapConsumer.prototype.allGeneratedPositionsFor = + function SourceMapConsumer_allGeneratedPositionsFor(aArgs) { + var line = util.getArg(aArgs, 'line'); + + // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping + // returns the index of the closest mapping less than the needle. By + // setting needle.originalColumn to 0, we thus find the last mapping for + // the given line, provided such a mapping exists. + var needle = { + source: util.getArg(aArgs, 'source'), + originalLine: line, + originalColumn: util.getArg(aArgs, 'column', 0) + }; + + needle.source = this._findSourceIndex(needle.source); + if (needle.source < 0) { + return []; + } + + var mappings = []; + + var index = this._findMapping(needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + binarySearch.LEAST_UPPER_BOUND); + if (index >= 0) { + var mapping = this._originalMappings[index]; + + if (aArgs.column === undefined) { + var originalLine = mapping.originalLine; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we found. Since + // mappings are sorted, this is guaranteed to find all mappings for + // the line we found. + while (mapping && mapping.originalLine === originalLine) { + mappings.push({ + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } + } else { + var originalColumn = mapping.originalColumn; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we were searching for. + // Since mappings are sorted, this is guaranteed to find all mappings for + // the line we are searching for. + while (mapping && + mapping.originalLine === line && + mapping.originalColumn == originalColumn) { + mappings.push({ + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } + } + } + + return mappings; + }; + +exports.SourceMapConsumer = SourceMapConsumer; + +/** + * A BasicSourceMapConsumer instance represents a parsed source map which we can + * query for information about the original file positions by giving it a file + * position in the generated source. + * + * The first parameter is the raw source map (either as a JSON string, or + * already parsed to an object). According to the spec, source maps have the + * following attributes: + * + * - version: Which version of the source map spec this map is following. + * - sources: An array of URLs to the original source files. + * - names: An array of identifiers which can be referrenced by individual mappings. + * - sourceRoot: Optional. The URL root from which all sources are relative. + * - sourcesContent: Optional. An array of contents of the original source files. + * - mappings: A string of base64 VLQs which contain the actual mappings. + * - file: Optional. The generated file this source map is associated with. + * + * Here is an example source map, taken from the source map spec[0]: + * + * { + * version : 3, + * file: "out.js", + * sourceRoot : "", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AA,AB;;ABCDE;" + * } + * + * The second parameter, if given, is a string whose value is the URL + * at which the source map was found. This URL is used to compute the + * sources array. + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# + */ +function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = util.parseSourceMapInput(aSourceMap); + } + + var version = util.getArg(sourceMap, 'version'); + var sources = util.getArg(sourceMap, 'sources'); + // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which + // requires the array) to play nice here. + var names = util.getArg(sourceMap, 'names', []); + var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); + var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); + var mappings = util.getArg(sourceMap, 'mappings'); + var file = util.getArg(sourceMap, 'file', null); + + // Once again, Sass deviates from the spec and supplies the version as a + // string rather than a number, so we use loose equality checking here. + if (version != this._version) { + throw new Error('Unsupported version: ' + version); + } + + if (sourceRoot) { + sourceRoot = util.normalize(sourceRoot); + } + + sources = sources + .map(String) + // Some source maps produce relative source paths like "./foo.js" instead of + // "foo.js". Normalize these first so that future comparisons will succeed. + // See bugzil.la/1090768. + .map(util.normalize) + // Always ensure that absolute sources are internally stored relative to + // the source root, if the source root is absolute. Not doing this would + // be particularly problematic when the source root is a prefix of the + // source (valid, but why??). See github issue #199 and bugzil.la/1188982. + .map(function (source) { + return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) + ? util.relative(sourceRoot, source) + : source; + }); + + // Pass `true` below to allow duplicate names and sources. While source maps + // are intended to be compressed and deduplicated, the TypeScript compiler + // sometimes generates source maps with duplicates in them. See Github issue + // #72 and bugzil.la/889492. + this._names = ArraySet.fromArray(names.map(String), true); + this._sources = ArraySet.fromArray(sources, true); + + this._absoluteSources = this._sources.toArray().map(function (s) { + return util.computeSourceURL(sourceRoot, s, aSourceMapURL); + }); + + this.sourceRoot = sourceRoot; + this.sourcesContent = sourcesContent; + this._mappings = mappings; + this._sourceMapURL = aSourceMapURL; + this.file = file; +} + +BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); +BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer; + +/** + * Utility function to find the index of a source. Returns -1 if not + * found. + */ +BasicSourceMapConsumer.prototype._findSourceIndex = function(aSource) { + var relativeSource = aSource; + if (this.sourceRoot != null) { + relativeSource = util.relative(this.sourceRoot, relativeSource); + } + + if (this._sources.has(relativeSource)) { + return this._sources.indexOf(relativeSource); + } + + // Maybe aSource is an absolute URL as returned by |sources|. In + // this case we can't simply undo the transform. + var i; + for (i = 0; i < this._absoluteSources.length; ++i) { + if (this._absoluteSources[i] == aSource) { + return i; + } + } + + return -1; +}; + +/** + * Create a BasicSourceMapConsumer from a SourceMapGenerator. + * + * @param SourceMapGenerator aSourceMap + * The source map that will be consumed. + * @param String aSourceMapURL + * The URL at which the source map can be found (optional) + * @returns BasicSourceMapConsumer + */ +BasicSourceMapConsumer.fromSourceMap = + function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) { + var smc = Object.create(BasicSourceMapConsumer.prototype); + + var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); + var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); + smc.sourceRoot = aSourceMap._sourceRoot; + smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), + smc.sourceRoot); + smc.file = aSourceMap._file; + smc._sourceMapURL = aSourceMapURL; + smc._absoluteSources = smc._sources.toArray().map(function (s) { + return util.computeSourceURL(smc.sourceRoot, s, aSourceMapURL); + }); + + // Because we are modifying the entries (by converting string sources and + // names to indices into the sources and names ArraySets), we have to make + // a copy of the entry or else bad things happen. Shared mutable state + // strikes again! See github issue #191. + + var generatedMappings = aSourceMap._mappings.toArray().slice(); + var destGeneratedMappings = smc.__generatedMappings = []; + var destOriginalMappings = smc.__originalMappings = []; + + for (var i = 0, length = generatedMappings.length; i < length; i++) { + var srcMapping = generatedMappings[i]; + var destMapping = new Mapping; + destMapping.generatedLine = srcMapping.generatedLine; + destMapping.generatedColumn = srcMapping.generatedColumn; + + if (srcMapping.source) { + destMapping.source = sources.indexOf(srcMapping.source); + destMapping.originalLine = srcMapping.originalLine; + destMapping.originalColumn = srcMapping.originalColumn; + + if (srcMapping.name) { + destMapping.name = names.indexOf(srcMapping.name); + } + + destOriginalMappings.push(destMapping); + } + + destGeneratedMappings.push(destMapping); + } + + quickSort(smc.__originalMappings, util.compareByOriginalPositions); + + return smc; + }; + +/** + * The version of the source mapping spec that we are consuming. + */ +BasicSourceMapConsumer.prototype._version = 3; + +/** + * The list of original sources. + */ +Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', { + get: function () { + return this._absoluteSources.slice(); + } +}); + +/** + * Provide the JIT with a nice shape / hidden class. + */ +function Mapping() { + this.generatedLine = 0; + this.generatedColumn = 0; + this.source = null; + this.originalLine = null; + this.originalColumn = null; + this.name = null; +} + +/** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ +BasicSourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + var generatedLine = 1; + var previousGeneratedColumn = 0; + var previousOriginalLine = 0; + var previousOriginalColumn = 0; + var previousSource = 0; + var previousName = 0; + var length = aStr.length; + var index = 0; + var cachedSegments = {}; + var temp = {}; + var originalMappings = []; + var generatedMappings = []; + var mapping, str, segment, end, value; + + while (index < length) { + if (aStr.charAt(index) === ';') { + generatedLine++; + index++; + previousGeneratedColumn = 0; + } + else if (aStr.charAt(index) === ',') { + index++; + } + else { + mapping = new Mapping(); + mapping.generatedLine = generatedLine; + + // Because each offset is encoded relative to the previous one, + // many segments often have the same encoding. We can exploit this + // fact by caching the parsed variable length fields of each segment, + // allowing us to avoid a second parse if we encounter the same + // segment again. + for (end = index; end < length; end++) { + if (this._charIsMappingSeparator(aStr, end)) { + break; + } + } + str = aStr.slice(index, end); + + segment = cachedSegments[str]; + if (segment) { + index += str.length; + } else { + segment = []; + while (index < end) { + base64VLQ.decode(aStr, index, temp); + value = temp.value; + index = temp.rest; + segment.push(value); + } + + if (segment.length === 2) { + throw new Error('Found a source, but no line and column'); + } + + if (segment.length === 3) { + throw new Error('Found a source and line, but no column'); + } + + cachedSegments[str] = segment; + } + + // Generated column. + mapping.generatedColumn = previousGeneratedColumn + segment[0]; + previousGeneratedColumn = mapping.generatedColumn; + + if (segment.length > 1) { + // Original source. + mapping.source = previousSource + segment[1]; + previousSource += segment[1]; + + // Original line. + mapping.originalLine = previousOriginalLine + segment[2]; + previousOriginalLine = mapping.originalLine; + // Lines are stored 0-based + mapping.originalLine += 1; + + // Original column. + mapping.originalColumn = previousOriginalColumn + segment[3]; + previousOriginalColumn = mapping.originalColumn; + + if (segment.length > 4) { + // Original name. + mapping.name = previousName + segment[4]; + previousName += segment[4]; + } + } + + generatedMappings.push(mapping); + if (typeof mapping.originalLine === 'number') { + originalMappings.push(mapping); + } + } + } + + quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated); + this.__generatedMappings = generatedMappings; + + quickSort(originalMappings, util.compareByOriginalPositions); + this.__originalMappings = originalMappings; + }; + +/** + * Find the mapping that best matches the hypothetical "needle" mapping that + * we are searching for in the given "haystack" of mappings. + */ +BasicSourceMapConsumer.prototype._findMapping = + function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, + aColumnName, aComparator, aBias) { + // To return the position we are searching for, we must first find the + // mapping for the given position and then return the opposite position it + // points to. Because the mappings are sorted, we can use binary search to + // find the best mapping. + + if (aNeedle[aLineName] <= 0) { + throw new TypeError('Line must be greater than or equal to 1, got ' + + aNeedle[aLineName]); + } + if (aNeedle[aColumnName] < 0) { + throw new TypeError('Column must be greater than or equal to 0, got ' + + aNeedle[aColumnName]); + } + + return binarySearch.search(aNeedle, aMappings, aComparator, aBias); + }; + +/** + * Compute the last column for each generated mapping. The last column is + * inclusive. + */ +BasicSourceMapConsumer.prototype.computeColumnSpans = + function SourceMapConsumer_computeColumnSpans() { + for (var index = 0; index < this._generatedMappings.length; ++index) { + var mapping = this._generatedMappings[index]; + + // Mappings do not contain a field for the last generated columnt. We + // can come up with an optimistic estimate, however, by assuming that + // mappings are contiguous (i.e. given two consecutive mappings, the + // first mapping ends where the second one starts). + if (index + 1 < this._generatedMappings.length) { + var nextMapping = this._generatedMappings[index + 1]; + + if (mapping.generatedLine === nextMapping.generatedLine) { + mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1; + continue; + } + } + + // The last mapping for each line spans the entire line. + mapping.lastGeneratedColumn = Infinity; + } + }; + +/** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. The line number + * is 1-based. + * - column: The column number in the generated source. The column + * number is 0-based. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. The + * line number is 1-based. + * - column: The column number in the original source, or null. The + * column number is 0-based. + * - name: The original identifier, or null. + */ +BasicSourceMapConsumer.prototype.originalPositionFor = + function SourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; + + var index = this._findMapping( + needle, + this._generatedMappings, + "generatedLine", + "generatedColumn", + util.compareByGeneratedPositionsDeflated, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._generatedMappings[index]; + + if (mapping.generatedLine === needle.generatedLine) { + var source = util.getArg(mapping, 'source', null); + if (source !== null) { + source = this._sources.at(source); + source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL); + } + var name = util.getArg(mapping, 'name', null); + if (name !== null) { + name = this._names.at(name); + } + return { + source: source, + line: util.getArg(mapping, 'originalLine', null), + column: util.getArg(mapping, 'originalColumn', null), + name: name + }; + } + } + + return { + source: null, + line: null, + column: null, + name: null + }; + }; + +/** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ +BasicSourceMapConsumer.prototype.hasContentsOfAllSources = + function BasicSourceMapConsumer_hasContentsOfAllSources() { + if (!this.sourcesContent) { + return false; + } + return this.sourcesContent.length >= this._sources.size() && + !this.sourcesContent.some(function (sc) { return sc == null; }); + }; + +/** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ +BasicSourceMapConsumer.prototype.sourceContentFor = + function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + if (!this.sourcesContent) { + return null; + } + + var index = this._findSourceIndex(aSource); + if (index >= 0) { + return this.sourcesContent[index]; + } + + var relativeSource = aSource; + if (this.sourceRoot != null) { + relativeSource = util.relative(this.sourceRoot, relativeSource); + } + + var url; + if (this.sourceRoot != null + && (url = util.urlParse(this.sourceRoot))) { + // XXX: file:// URIs and absolute paths lead to unexpected behavior for + // many users. We can help them out when they expect file:// URIs to + // behave like it would if they were running a local HTTP server. See + // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. + var fileUriAbsPath = relativeSource.replace(/^file:\/\//, ""); + if (url.scheme == "file" + && this._sources.has(fileUriAbsPath)) { + return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] + } + + if ((!url.path || url.path == "/") + && this._sources.has("/" + relativeSource)) { + return this.sourcesContent[this._sources.indexOf("/" + relativeSource)]; + } + } + + // This function is used recursively from + // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we + // don't want to throw if we can't find the source - we just want to + // return null, so we provide a flag to exit gracefully. + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + relativeSource + '" is not in the SourceMap.'); + } + }; + +/** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. The line number + * is 1-based. + * - column: The column number in the original source. The column + * number is 0-based. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. The + * line number is 1-based. + * - column: The column number in the generated source, or null. + * The column number is 0-based. + */ +BasicSourceMapConsumer.prototype.generatedPositionFor = + function SourceMapConsumer_generatedPositionFor(aArgs) { + var source = util.getArg(aArgs, 'source'); + source = this._findSourceIndex(source); + if (source < 0) { + return { + line: null, + column: null, + lastColumn: null + }; + } + + var needle = { + source: source, + originalLine: util.getArg(aArgs, 'line'), + originalColumn: util.getArg(aArgs, 'column') + }; + + var index = this._findMapping( + needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._originalMappings[index]; + + if (mapping.source === needle.source) { + return { + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }; + } + } + + return { + line: null, + column: null, + lastColumn: null + }; + }; + +exports.BasicSourceMapConsumer = BasicSourceMapConsumer; + +/** + * An IndexedSourceMapConsumer instance represents a parsed source map which + * we can query for information. It differs from BasicSourceMapConsumer in + * that it takes "indexed" source maps (i.e. ones with a "sections" field) as + * input. + * + * The first parameter is a raw source map (either as a JSON string, or already + * parsed to an object). According to the spec for indexed source maps, they + * have the following attributes: + * + * - version: Which version of the source map spec this map is following. + * - file: Optional. The generated file this source map is associated with. + * - sections: A list of section definitions. + * + * Each value under the "sections" field has two fields: + * - offset: The offset into the original specified at which this section + * begins to apply, defined as an object with a "line" and "column" + * field. + * - map: A source map definition. This source map could also be indexed, + * but doesn't have to be. + * + * Instead of the "map" field, it's also possible to have a "url" field + * specifying a URL to retrieve a source map from, but that's currently + * unsupported. + * + * Here's an example source map, taken from the source map spec[0], but + * modified to omit a section which uses the "url" field. + * + * { + * version : 3, + * file: "app.js", + * sections: [{ + * offset: {line:100, column:10}, + * map: { + * version : 3, + * file: "section.js", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AAAA,E;;ABCDE;" + * } + * }], + * } + * + * The second parameter, if given, is a string whose value is the URL + * at which the source map was found. This URL is used to compute the + * sources array. + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt + */ +function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = util.parseSourceMapInput(aSourceMap); + } + + var version = util.getArg(sourceMap, 'version'); + var sections = util.getArg(sourceMap, 'sections'); + + if (version != this._version) { + throw new Error('Unsupported version: ' + version); + } + + this._sources = new ArraySet(); + this._names = new ArraySet(); + + var lastOffset = { + line: -1, + column: 0 + }; + this._sections = sections.map(function (s) { + if (s.url) { + // The url field will require support for asynchronicity. + // See https://github.com/mozilla/source-map/issues/16 + throw new Error('Support for url field in sections not implemented.'); + } + var offset = util.getArg(s, 'offset'); + var offsetLine = util.getArg(offset, 'line'); + var offsetColumn = util.getArg(offset, 'column'); + + if (offsetLine < lastOffset.line || + (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { + throw new Error('Section offsets must be ordered and non-overlapping.'); + } + lastOffset = offset; + + return { + generatedOffset: { + // The offset fields are 0-based, but we use 1-based indices when + // encoding/decoding from VLQ. + generatedLine: offsetLine + 1, + generatedColumn: offsetColumn + 1 + }, + consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL) + } + }); +} + +IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); +IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer; + +/** + * The version of the source mapping spec that we are consuming. + */ +IndexedSourceMapConsumer.prototype._version = 3; + +/** + * The list of original sources. + */ +Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', { + get: function () { + var sources = []; + for (var i = 0; i < this._sections.length; i++) { + for (var j = 0; j < this._sections[i].consumer.sources.length; j++) { + sources.push(this._sections[i].consumer.sources[j]); + } + } + return sources; + } +}); + +/** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. The line number + * is 1-based. + * - column: The column number in the generated source. The column + * number is 0-based. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. The + * line number is 1-based. + * - column: The column number in the original source, or null. The + * column number is 0-based. + * - name: The original identifier, or null. + */ +IndexedSourceMapConsumer.prototype.originalPositionFor = + function IndexedSourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; + + // Find the section containing the generated position we're trying to map + // to an original position. + var sectionIndex = binarySearch.search(needle, this._sections, + function(needle, section) { + var cmp = needle.generatedLine - section.generatedOffset.generatedLine; + if (cmp) { + return cmp; + } + + return (needle.generatedColumn - + section.generatedOffset.generatedColumn); + }); + var section = this._sections[sectionIndex]; + + if (!section) { + return { + source: null, + line: null, + column: null, + name: null + }; + } + + return section.consumer.originalPositionFor({ + line: needle.generatedLine - + (section.generatedOffset.generatedLine - 1), + column: needle.generatedColumn - + (section.generatedOffset.generatedLine === needle.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + bias: aArgs.bias + }); + }; + +/** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ +IndexedSourceMapConsumer.prototype.hasContentsOfAllSources = + function IndexedSourceMapConsumer_hasContentsOfAllSources() { + return this._sections.every(function (s) { + return s.consumer.hasContentsOfAllSources(); + }); + }; + +/** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ +IndexedSourceMapConsumer.prototype.sourceContentFor = + function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + + var content = section.consumer.sourceContentFor(aSource, true); + if (content) { + return content; + } + } + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + aSource + '" is not in the SourceMap.'); + } + }; + +/** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. The line number + * is 1-based. + * - column: The column number in the original source. The column + * number is 0-based. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. The + * line number is 1-based. + * - column: The column number in the generated source, or null. + * The column number is 0-based. + */ +IndexedSourceMapConsumer.prototype.generatedPositionFor = + function IndexedSourceMapConsumer_generatedPositionFor(aArgs) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + + // Only consider this section if the requested source is in the list of + // sources of the consumer. + if (section.consumer._findSourceIndex(util.getArg(aArgs, 'source')) === -1) { + continue; + } + var generatedPosition = section.consumer.generatedPositionFor(aArgs); + if (generatedPosition) { + var ret = { + line: generatedPosition.line + + (section.generatedOffset.generatedLine - 1), + column: generatedPosition.column + + (section.generatedOffset.generatedLine === generatedPosition.line + ? section.generatedOffset.generatedColumn - 1 + : 0) + }; + return ret; + } + } + + return { + line: null, + column: null + }; + }; + +/** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ +IndexedSourceMapConsumer.prototype._parseMappings = + function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) { + this.__generatedMappings = []; + this.__originalMappings = []; + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + var sectionMappings = section.consumer._generatedMappings; + for (var j = 0; j < sectionMappings.length; j++) { + var mapping = sectionMappings[j]; + + var source = section.consumer._sources.at(mapping.source); + source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL); + this._sources.add(source); + source = this._sources.indexOf(source); + + var name = null; + if (mapping.name) { + name = section.consumer._names.at(mapping.name); + this._names.add(name); + name = this._names.indexOf(name); + } + + // The mappings coming from the consumer for the section have + // generated positions relative to the start of the section, so we + // need to offset them to be relative to the start of the concatenated + // generated file. + var adjustedMapping = { + source: source, + generatedLine: mapping.generatedLine + + (section.generatedOffset.generatedLine - 1), + generatedColumn: mapping.generatedColumn + + (section.generatedOffset.generatedLine === mapping.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: name + }; + + this.__generatedMappings.push(adjustedMapping); + if (typeof adjustedMapping.originalLine === 'number') { + this.__originalMappings.push(adjustedMapping); + } + } + } + + quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated); + quickSort(this.__originalMappings, util.compareByOriginalPositions); + }; + +exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; diff --git a/node_modules/source-map/lib/source-map-generator.js b/node_modules/source-map/lib/source-map-generator.js new file mode 100644 index 0000000..508bcfb --- /dev/null +++ b/node_modules/source-map/lib/source-map-generator.js @@ -0,0 +1,425 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var base64VLQ = require('./base64-vlq'); +var util = require('./util'); +var ArraySet = require('./array-set').ArraySet; +var MappingList = require('./mapping-list').MappingList; + +/** + * An instance of the SourceMapGenerator represents a source map which is + * being built incrementally. You may pass an object with the following + * properties: + * + * - file: The filename of the generated source. + * - sourceRoot: A root for all relative URLs in this source map. + */ +function SourceMapGenerator(aArgs) { + if (!aArgs) { + aArgs = {}; + } + this._file = util.getArg(aArgs, 'file', null); + this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); + this._skipValidation = util.getArg(aArgs, 'skipValidation', false); + this._sources = new ArraySet(); + this._names = new ArraySet(); + this._mappings = new MappingList(); + this._sourcesContents = null; +} + +SourceMapGenerator.prototype._version = 3; + +/** + * Creates a new SourceMapGenerator based on a SourceMapConsumer + * + * @param aSourceMapConsumer The SourceMap. + */ +SourceMapGenerator.fromSourceMap = + function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { + var sourceRoot = aSourceMapConsumer.sourceRoot; + var generator = new SourceMapGenerator({ + file: aSourceMapConsumer.file, + sourceRoot: sourceRoot + }); + aSourceMapConsumer.eachMapping(function (mapping) { + var newMapping = { + generated: { + line: mapping.generatedLine, + column: mapping.generatedColumn + } + }; + + if (mapping.source != null) { + newMapping.source = mapping.source; + if (sourceRoot != null) { + newMapping.source = util.relative(sourceRoot, newMapping.source); + } + + newMapping.original = { + line: mapping.originalLine, + column: mapping.originalColumn + }; + + if (mapping.name != null) { + newMapping.name = mapping.name; + } + } + + generator.addMapping(newMapping); + }); + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var sourceRelative = sourceFile; + if (sourceRoot !== null) { + sourceRelative = util.relative(sourceRoot, sourceFile); + } + + if (!generator._sources.has(sourceRelative)) { + generator._sources.add(sourceRelative); + } + + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + generator.setSourceContent(sourceFile, content); + } + }); + return generator; + }; + +/** + * Add a single mapping from original source line and column to the generated + * source's line and column for this source map being created. The mapping + * object should have the following properties: + * + * - generated: An object with the generated line and column positions. + * - original: An object with the original line and column positions. + * - source: The original source file (relative to the sourceRoot). + * - name: An optional original token name for this mapping. + */ +SourceMapGenerator.prototype.addMapping = + function SourceMapGenerator_addMapping(aArgs) { + var generated = util.getArg(aArgs, 'generated'); + var original = util.getArg(aArgs, 'original', null); + var source = util.getArg(aArgs, 'source', null); + var name = util.getArg(aArgs, 'name', null); + + if (!this._skipValidation) { + this._validateMapping(generated, original, source, name); + } + + if (source != null) { + source = String(source); + if (!this._sources.has(source)) { + this._sources.add(source); + } + } + + if (name != null) { + name = String(name); + if (!this._names.has(name)) { + this._names.add(name); + } + } + + this._mappings.add({ + generatedLine: generated.line, + generatedColumn: generated.column, + originalLine: original != null && original.line, + originalColumn: original != null && original.column, + source: source, + name: name + }); + }; + +/** + * Set the source content for a source file. + */ +SourceMapGenerator.prototype.setSourceContent = + function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { + var source = aSourceFile; + if (this._sourceRoot != null) { + source = util.relative(this._sourceRoot, source); + } + + if (aSourceContent != null) { + // Add the source content to the _sourcesContents map. + // Create a new _sourcesContents map if the property is null. + if (!this._sourcesContents) { + this._sourcesContents = Object.create(null); + } + this._sourcesContents[util.toSetString(source)] = aSourceContent; + } else if (this._sourcesContents) { + // Remove the source file from the _sourcesContents map. + // If the _sourcesContents map is empty, set the property to null. + delete this._sourcesContents[util.toSetString(source)]; + if (Object.keys(this._sourcesContents).length === 0) { + this._sourcesContents = null; + } + } + }; + +/** + * Applies the mappings of a sub-source-map for a specific source file to the + * source map being generated. Each mapping to the supplied source file is + * rewritten using the supplied source map. Note: The resolution for the + * resulting mappings is the minimium of this map and the supplied map. + * + * @param aSourceMapConsumer The source map to be applied. + * @param aSourceFile Optional. The filename of the source file. + * If omitted, SourceMapConsumer's file property will be used. + * @param aSourceMapPath Optional. The dirname of the path to the source map + * to be applied. If relative, it is relative to the SourceMapConsumer. + * This parameter is needed when the two source maps aren't in the same + * directory, and the source map to be applied contains relative source + * paths. If so, those relative source paths need to be rewritten + * relative to the SourceMapGenerator. + */ +SourceMapGenerator.prototype.applySourceMap = + function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { + var sourceFile = aSourceFile; + // If aSourceFile is omitted, we will use the file property of the SourceMap + if (aSourceFile == null) { + if (aSourceMapConsumer.file == null) { + throw new Error( + 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + + 'or the source map\'s "file" property. Both were omitted.' + ); + } + sourceFile = aSourceMapConsumer.file; + } + var sourceRoot = this._sourceRoot; + // Make "sourceFile" relative if an absolute Url is passed. + if (sourceRoot != null) { + sourceFile = util.relative(sourceRoot, sourceFile); + } + // Applying the SourceMap can add and remove items from the sources and + // the names array. + var newSources = new ArraySet(); + var newNames = new ArraySet(); + + // Find mappings for the "sourceFile" + this._mappings.unsortedForEach(function (mapping) { + if (mapping.source === sourceFile && mapping.originalLine != null) { + // Check if it can be mapped by the source map, then update the mapping. + var original = aSourceMapConsumer.originalPositionFor({ + line: mapping.originalLine, + column: mapping.originalColumn + }); + if (original.source != null) { + // Copy mapping + mapping.source = original.source; + if (aSourceMapPath != null) { + mapping.source = util.join(aSourceMapPath, mapping.source) + } + if (sourceRoot != null) { + mapping.source = util.relative(sourceRoot, mapping.source); + } + mapping.originalLine = original.line; + mapping.originalColumn = original.column; + if (original.name != null) { + mapping.name = original.name; + } + } + } + + var source = mapping.source; + if (source != null && !newSources.has(source)) { + newSources.add(source); + } + + var name = mapping.name; + if (name != null && !newNames.has(name)) { + newNames.add(name); + } + + }, this); + this._sources = newSources; + this._names = newNames; + + // Copy sourcesContents of applied map. + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aSourceMapPath != null) { + sourceFile = util.join(aSourceMapPath, sourceFile); + } + if (sourceRoot != null) { + sourceFile = util.relative(sourceRoot, sourceFile); + } + this.setSourceContent(sourceFile, content); + } + }, this); + }; + +/** + * A mapping can have one of the three levels of data: + * + * 1. Just the generated position. + * 2. The Generated position, original position, and original source. + * 3. Generated and original position, original source, as well as a name + * token. + * + * To maintain consistency, we validate that any new mapping being added falls + * in to one of these categories. + */ +SourceMapGenerator.prototype._validateMapping = + function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, + aName) { + // When aOriginal is truthy but has empty values for .line and .column, + // it is most likely a programmer error. In this case we throw a very + // specific error message to try to guide them the right way. + // For example: https://github.com/Polymer/polymer-bundler/pull/519 + if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') { + throw new Error( + 'original.line and original.column are not numbers -- you probably meant to omit ' + + 'the original mapping entirely and only map the generated position. If so, pass ' + + 'null for the original mapping instead of an object with empty or null values.' + ); + } + + if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aGenerated.line > 0 && aGenerated.column >= 0 + && !aOriginal && !aSource && !aName) { + // Case 1. + return; + } + else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aOriginal && 'line' in aOriginal && 'column' in aOriginal + && aGenerated.line > 0 && aGenerated.column >= 0 + && aOriginal.line > 0 && aOriginal.column >= 0 + && aSource) { + // Cases 2 and 3. + return; + } + else { + throw new Error('Invalid mapping: ' + JSON.stringify({ + generated: aGenerated, + source: aSource, + original: aOriginal, + name: aName + })); + } + }; + +/** + * Serialize the accumulated mappings in to the stream of base 64 VLQs + * specified by the source map format. + */ +SourceMapGenerator.prototype._serializeMappings = + function SourceMapGenerator_serializeMappings() { + var previousGeneratedColumn = 0; + var previousGeneratedLine = 1; + var previousOriginalColumn = 0; + var previousOriginalLine = 0; + var previousName = 0; + var previousSource = 0; + var result = ''; + var next; + var mapping; + var nameIdx; + var sourceIdx; + + var mappings = this._mappings.toArray(); + for (var i = 0, len = mappings.length; i < len; i++) { + mapping = mappings[i]; + next = '' + + if (mapping.generatedLine !== previousGeneratedLine) { + previousGeneratedColumn = 0; + while (mapping.generatedLine !== previousGeneratedLine) { + next += ';'; + previousGeneratedLine++; + } + } + else { + if (i > 0) { + if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) { + continue; + } + next += ','; + } + } + + next += base64VLQ.encode(mapping.generatedColumn + - previousGeneratedColumn); + previousGeneratedColumn = mapping.generatedColumn; + + if (mapping.source != null) { + sourceIdx = this._sources.indexOf(mapping.source); + next += base64VLQ.encode(sourceIdx - previousSource); + previousSource = sourceIdx; + + // lines are stored 0-based in SourceMap spec version 3 + next += base64VLQ.encode(mapping.originalLine - 1 + - previousOriginalLine); + previousOriginalLine = mapping.originalLine - 1; + + next += base64VLQ.encode(mapping.originalColumn + - previousOriginalColumn); + previousOriginalColumn = mapping.originalColumn; + + if (mapping.name != null) { + nameIdx = this._names.indexOf(mapping.name); + next += base64VLQ.encode(nameIdx - previousName); + previousName = nameIdx; + } + } + + result += next; + } + + return result; + }; + +SourceMapGenerator.prototype._generateSourcesContent = + function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { + return aSources.map(function (source) { + if (!this._sourcesContents) { + return null; + } + if (aSourceRoot != null) { + source = util.relative(aSourceRoot, source); + } + var key = util.toSetString(source); + return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) + ? this._sourcesContents[key] + : null; + }, this); + }; + +/** + * Externalize the source map. + */ +SourceMapGenerator.prototype.toJSON = + function SourceMapGenerator_toJSON() { + var map = { + version: this._version, + sources: this._sources.toArray(), + names: this._names.toArray(), + mappings: this._serializeMappings() + }; + if (this._file != null) { + map.file = this._file; + } + if (this._sourceRoot != null) { + map.sourceRoot = this._sourceRoot; + } + if (this._sourcesContents) { + map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); + } + + return map; + }; + +/** + * Render the source map being generated to a string. + */ +SourceMapGenerator.prototype.toString = + function SourceMapGenerator_toString() { + return JSON.stringify(this.toJSON()); + }; + +exports.SourceMapGenerator = SourceMapGenerator; diff --git a/node_modules/source-map/lib/source-node.js b/node_modules/source-map/lib/source-node.js new file mode 100644 index 0000000..8bcdbe3 --- /dev/null +++ b/node_modules/source-map/lib/source-node.js @@ -0,0 +1,413 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var SourceMapGenerator = require('./source-map-generator').SourceMapGenerator; +var util = require('./util'); + +// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other +// operating systems these days (capturing the result). +var REGEX_NEWLINE = /(\r?\n)/; + +// Newline character code for charCodeAt() comparisons +var NEWLINE_CODE = 10; + +// Private symbol for identifying `SourceNode`s when multiple versions of +// the source-map library are loaded. This MUST NOT CHANGE across +// versions! +var isSourceNode = "$$$isSourceNode$$$"; + +/** + * SourceNodes provide a way to abstract over interpolating/concatenating + * snippets of generated JavaScript source code while maintaining the line and + * column information associated with the original source code. + * + * @param aLine The original line number. + * @param aColumn The original column number. + * @param aSource The original source's filename. + * @param aChunks Optional. An array of strings which are snippets of + * generated JS, or other SourceNodes. + * @param aName The original identifier. + */ +function SourceNode(aLine, aColumn, aSource, aChunks, aName) { + this.children = []; + this.sourceContents = {}; + this.line = aLine == null ? null : aLine; + this.column = aColumn == null ? null : aColumn; + this.source = aSource == null ? null : aSource; + this.name = aName == null ? null : aName; + this[isSourceNode] = true; + if (aChunks != null) this.add(aChunks); +} + +/** + * Creates a SourceNode from generated code and a SourceMapConsumer. + * + * @param aGeneratedCode The generated code + * @param aSourceMapConsumer The SourceMap for the generated code + * @param aRelativePath Optional. The path that relative sources in the + * SourceMapConsumer should be relative to. + */ +SourceNode.fromStringWithSourceMap = + function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) { + // The SourceNode we want to fill with the generated code + // and the SourceMap + var node = new SourceNode(); + + // All even indices of this array are one line of the generated code, + // while all odd indices are the newlines between two adjacent lines + // (since `REGEX_NEWLINE` captures its match). + // Processed fragments are accessed by calling `shiftNextLine`. + var remainingLines = aGeneratedCode.split(REGEX_NEWLINE); + var remainingLinesIndex = 0; + var shiftNextLine = function() { + var lineContents = getNextLine(); + // The last line of a file might not have a newline. + var newLine = getNextLine() || ""; + return lineContents + newLine; + + function getNextLine() { + return remainingLinesIndex < remainingLines.length ? + remainingLines[remainingLinesIndex++] : undefined; + } + }; + + // We need to remember the position of "remainingLines" + var lastGeneratedLine = 1, lastGeneratedColumn = 0; + + // The generate SourceNodes we need a code range. + // To extract it current and last mapping is used. + // Here we store the last mapping. + var lastMapping = null; + + aSourceMapConsumer.eachMapping(function (mapping) { + if (lastMapping !== null) { + // We add the code from "lastMapping" to "mapping": + // First check if there is a new line in between. + if (lastGeneratedLine < mapping.generatedLine) { + // Associate first line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + lastGeneratedLine++; + lastGeneratedColumn = 0; + // The remaining code is added without mapping + } else { + // There is no new line in between. + // Associate the code between "lastGeneratedColumn" and + // "mapping.generatedColumn" with "lastMapping" + var nextLine = remainingLines[remainingLinesIndex] || ''; + var code = nextLine.substr(0, mapping.generatedColumn - + lastGeneratedColumn); + remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn - + lastGeneratedColumn); + lastGeneratedColumn = mapping.generatedColumn; + addMappingWithCode(lastMapping, code); + // No more remaining code, continue + lastMapping = mapping; + return; + } + } + // We add the generated code until the first mapping + // to the SourceNode without any mapping. + // Each line is added as separate string. + while (lastGeneratedLine < mapping.generatedLine) { + node.add(shiftNextLine()); + lastGeneratedLine++; + } + if (lastGeneratedColumn < mapping.generatedColumn) { + var nextLine = remainingLines[remainingLinesIndex] || ''; + node.add(nextLine.substr(0, mapping.generatedColumn)); + remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn); + lastGeneratedColumn = mapping.generatedColumn; + } + lastMapping = mapping; + }, this); + // We have processed all mappings. + if (remainingLinesIndex < remainingLines.length) { + if (lastMapping) { + // Associate the remaining code in the current line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + } + // and add the remaining lines without any mapping + node.add(remainingLines.splice(remainingLinesIndex).join("")); + } + + // Copy sourcesContent into SourceNode + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aRelativePath != null) { + sourceFile = util.join(aRelativePath, sourceFile); + } + node.setSourceContent(sourceFile, content); + } + }); + + return node; + + function addMappingWithCode(mapping, code) { + if (mapping === null || mapping.source === undefined) { + node.add(code); + } else { + var source = aRelativePath + ? util.join(aRelativePath, mapping.source) + : mapping.source; + node.add(new SourceNode(mapping.originalLine, + mapping.originalColumn, + source, + code, + mapping.name)); + } + } + }; + +/** + * Add a chunk of generated JS to this source node. + * + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. + */ +SourceNode.prototype.add = function SourceNode_add(aChunk) { + if (Array.isArray(aChunk)) { + aChunk.forEach(function (chunk) { + this.add(chunk); + }, this); + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + if (aChunk) { + this.children.push(aChunk); + } + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; +}; + +/** + * Add a chunk of generated JS to the beginning of this source node. + * + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. + */ +SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { + if (Array.isArray(aChunk)) { + for (var i = aChunk.length-1; i >= 0; i--) { + this.prepend(aChunk[i]); + } + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + this.children.unshift(aChunk); + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; +}; + +/** + * Walk over the tree of JS snippets in this node and its children. The + * walking function is called once for each snippet of JS and is passed that + * snippet and the its original associated source's line/column location. + * + * @param aFn The traversal function. + */ +SourceNode.prototype.walk = function SourceNode_walk(aFn) { + var chunk; + for (var i = 0, len = this.children.length; i < len; i++) { + chunk = this.children[i]; + if (chunk[isSourceNode]) { + chunk.walk(aFn); + } + else { + if (chunk !== '') { + aFn(chunk, { source: this.source, + line: this.line, + column: this.column, + name: this.name }); + } + } + } +}; + +/** + * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between + * each of `this.children`. + * + * @param aSep The separator. + */ +SourceNode.prototype.join = function SourceNode_join(aSep) { + var newChildren; + var i; + var len = this.children.length; + if (len > 0) { + newChildren = []; + for (i = 0; i < len-1; i++) { + newChildren.push(this.children[i]); + newChildren.push(aSep); + } + newChildren.push(this.children[i]); + this.children = newChildren; + } + return this; +}; + +/** + * Call String.prototype.replace on the very right-most source snippet. Useful + * for trimming whitespace from the end of a source node, etc. + * + * @param aPattern The pattern to replace. + * @param aReplacement The thing to replace the pattern with. + */ +SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { + var lastChild = this.children[this.children.length - 1]; + if (lastChild[isSourceNode]) { + lastChild.replaceRight(aPattern, aReplacement); + } + else if (typeof lastChild === 'string') { + this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); + } + else { + this.children.push(''.replace(aPattern, aReplacement)); + } + return this; +}; + +/** + * Set the source content for a source file. This will be added to the SourceMapGenerator + * in the sourcesContent field. + * + * @param aSourceFile The filename of the source file + * @param aSourceContent The content of the source file + */ +SourceNode.prototype.setSourceContent = + function SourceNode_setSourceContent(aSourceFile, aSourceContent) { + this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; + }; + +/** + * Walk over the tree of SourceNodes. The walking function is called for each + * source file content and is passed the filename and source content. + * + * @param aFn The traversal function. + */ +SourceNode.prototype.walkSourceContents = + function SourceNode_walkSourceContents(aFn) { + for (var i = 0, len = this.children.length; i < len; i++) { + if (this.children[i][isSourceNode]) { + this.children[i].walkSourceContents(aFn); + } + } + + var sources = Object.keys(this.sourceContents); + for (var i = 0, len = sources.length; i < len; i++) { + aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); + } + }; + +/** + * Return the string representation of this source node. Walks over the tree + * and concatenates all the various snippets together to one string. + */ +SourceNode.prototype.toString = function SourceNode_toString() { + var str = ""; + this.walk(function (chunk) { + str += chunk; + }); + return str; +}; + +/** + * Returns the string representation of this source node along with a source + * map. + */ +SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { + var generated = { + code: "", + line: 1, + column: 0 + }; + var map = new SourceMapGenerator(aArgs); + var sourceMappingActive = false; + var lastOriginalSource = null; + var lastOriginalLine = null; + var lastOriginalColumn = null; + var lastOriginalName = null; + this.walk(function (chunk, original) { + generated.code += chunk; + if (original.source !== null + && original.line !== null + && original.column !== null) { + if(lastOriginalSource !== original.source + || lastOriginalLine !== original.line + || lastOriginalColumn !== original.column + || lastOriginalName !== original.name) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + lastOriginalSource = original.source; + lastOriginalLine = original.line; + lastOriginalColumn = original.column; + lastOriginalName = original.name; + sourceMappingActive = true; + } else if (sourceMappingActive) { + map.addMapping({ + generated: { + line: generated.line, + column: generated.column + } + }); + lastOriginalSource = null; + sourceMappingActive = false; + } + for (var idx = 0, length = chunk.length; idx < length; idx++) { + if (chunk.charCodeAt(idx) === NEWLINE_CODE) { + generated.line++; + generated.column = 0; + // Mappings end at eol + if (idx + 1 === length) { + lastOriginalSource = null; + sourceMappingActive = false; + } else if (sourceMappingActive) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + } else { + generated.column++; + } + } + }); + this.walkSourceContents(function (sourceFile, sourceContent) { + map.setSourceContent(sourceFile, sourceContent); + }); + + return { code: generated.code, map: map }; +}; + +exports.SourceNode = SourceNode; diff --git a/node_modules/source-map/lib/util.js b/node_modules/source-map/lib/util.js new file mode 100644 index 0000000..3ca92e5 --- /dev/null +++ b/node_modules/source-map/lib/util.js @@ -0,0 +1,488 @@ +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +/** + * This is a helper function for getting values from parameter/options + * objects. + * + * @param args The object we are extracting values from + * @param name The name of the property we are getting. + * @param defaultValue An optional value to return if the property is missing + * from the object. If this is not specified and the property is missing, an + * error will be thrown. + */ +function getArg(aArgs, aName, aDefaultValue) { + if (aName in aArgs) { + return aArgs[aName]; + } else if (arguments.length === 3) { + return aDefaultValue; + } else { + throw new Error('"' + aName + '" is a required argument.'); + } +} +exports.getArg = getArg; + +var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/; +var dataUrlRegexp = /^data:.+\,.+$/; + +function urlParse(aUrl) { + var match = aUrl.match(urlRegexp); + if (!match) { + return null; + } + return { + scheme: match[1], + auth: match[2], + host: match[3], + port: match[4], + path: match[5] + }; +} +exports.urlParse = urlParse; + +function urlGenerate(aParsedUrl) { + var url = ''; + if (aParsedUrl.scheme) { + url += aParsedUrl.scheme + ':'; + } + url += '//'; + if (aParsedUrl.auth) { + url += aParsedUrl.auth + '@'; + } + if (aParsedUrl.host) { + url += aParsedUrl.host; + } + if (aParsedUrl.port) { + url += ":" + aParsedUrl.port + } + if (aParsedUrl.path) { + url += aParsedUrl.path; + } + return url; +} +exports.urlGenerate = urlGenerate; + +/** + * Normalizes a path, or the path portion of a URL: + * + * - Replaces consecutive slashes with one slash. + * - Removes unnecessary '.' parts. + * - Removes unnecessary '/..' parts. + * + * Based on code in the Node.js 'path' core module. + * + * @param aPath The path or url to normalize. + */ +function normalize(aPath) { + var path = aPath; + var url = urlParse(aPath); + if (url) { + if (!url.path) { + return aPath; + } + path = url.path; + } + var isAbsolute = exports.isAbsolute(path); + + var parts = path.split(/\/+/); + for (var part, up = 0, i = parts.length - 1; i >= 0; i--) { + part = parts[i]; + if (part === '.') { + parts.splice(i, 1); + } else if (part === '..') { + up++; + } else if (up > 0) { + if (part === '') { + // The first part is blank if the path is absolute. Trying to go + // above the root is a no-op. Therefore we can remove all '..' parts + // directly after the root. + parts.splice(i + 1, up); + up = 0; + } else { + parts.splice(i, 2); + up--; + } + } + } + path = parts.join('/'); + + if (path === '') { + path = isAbsolute ? '/' : '.'; + } + + if (url) { + url.path = path; + return urlGenerate(url); + } + return path; +} +exports.normalize = normalize; + +/** + * Joins two paths/URLs. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be joined with the root. + * + * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a + * scheme-relative URL: Then the scheme of aRoot, if any, is prepended + * first. + * - Otherwise aPath is a path. If aRoot is a URL, then its path portion + * is updated with the result and aRoot is returned. Otherwise the result + * is returned. + * - If aPath is absolute, the result is aPath. + * - Otherwise the two paths are joined with a slash. + * - Joining for example 'http://' and 'www.example.com' is also supported. + */ +function join(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + if (aPath === "") { + aPath = "."; + } + var aPathUrl = urlParse(aPath); + var aRootUrl = urlParse(aRoot); + if (aRootUrl) { + aRoot = aRootUrl.path || '/'; + } + + // `join(foo, '//www.example.org')` + if (aPathUrl && !aPathUrl.scheme) { + if (aRootUrl) { + aPathUrl.scheme = aRootUrl.scheme; + } + return urlGenerate(aPathUrl); + } + + if (aPathUrl || aPath.match(dataUrlRegexp)) { + return aPath; + } + + // `join('http://', 'www.example.com')` + if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { + aRootUrl.host = aPath; + return urlGenerate(aRootUrl); + } + + var joined = aPath.charAt(0) === '/' + ? aPath + : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); + + if (aRootUrl) { + aRootUrl.path = joined; + return urlGenerate(aRootUrl); + } + return joined; +} +exports.join = join; + +exports.isAbsolute = function (aPath) { + return aPath.charAt(0) === '/' || urlRegexp.test(aPath); +}; + +/** + * Make a path relative to a URL or another path. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be made relative to aRoot. + */ +function relative(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + + aRoot = aRoot.replace(/\/$/, ''); + + // It is possible for the path to be above the root. In this case, simply + // checking whether the root is a prefix of the path won't work. Instead, we + // need to remove components from the root one by one, until either we find + // a prefix that fits, or we run out of components to remove. + var level = 0; + while (aPath.indexOf(aRoot + '/') !== 0) { + var index = aRoot.lastIndexOf("/"); + if (index < 0) { + return aPath; + } + + // If the only part of the root that is left is the scheme (i.e. http://, + // file:///, etc.), one or more slashes (/), or simply nothing at all, we + // have exhausted all components, so the path is not relative to the root. + aRoot = aRoot.slice(0, index); + if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { + return aPath; + } + + ++level; + } + + // Make sure we add a "../" for each component we removed from the root. + return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); +} +exports.relative = relative; + +var supportsNullProto = (function () { + var obj = Object.create(null); + return !('__proto__' in obj); +}()); + +function identity (s) { + return s; +} + +/** + * Because behavior goes wacky when you set `__proto__` on objects, we + * have to prefix all the strings in our set with an arbitrary character. + * + * See https://github.com/mozilla/source-map/pull/31 and + * https://github.com/mozilla/source-map/issues/30 + * + * @param String aStr + */ +function toSetString(aStr) { + if (isProtoString(aStr)) { + return '$' + aStr; + } + + return aStr; +} +exports.toSetString = supportsNullProto ? identity : toSetString; + +function fromSetString(aStr) { + if (isProtoString(aStr)) { + return aStr.slice(1); + } + + return aStr; +} +exports.fromSetString = supportsNullProto ? identity : fromSetString; + +function isProtoString(s) { + if (!s) { + return false; + } + + var length = s.length; + + if (length < 9 /* "__proto__".length */) { + return false; + } + + if (s.charCodeAt(length - 1) !== 95 /* '_' */ || + s.charCodeAt(length - 2) !== 95 /* '_' */ || + s.charCodeAt(length - 3) !== 111 /* 'o' */ || + s.charCodeAt(length - 4) !== 116 /* 't' */ || + s.charCodeAt(length - 5) !== 111 /* 'o' */ || + s.charCodeAt(length - 6) !== 114 /* 'r' */ || + s.charCodeAt(length - 7) !== 112 /* 'p' */ || + s.charCodeAt(length - 8) !== 95 /* '_' */ || + s.charCodeAt(length - 9) !== 95 /* '_' */) { + return false; + } + + for (var i = length - 10; i >= 0; i--) { + if (s.charCodeAt(i) !== 36 /* '$' */) { + return false; + } + } + + return true; +} + +/** + * Comparator between two mappings where the original positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same original source/line/column, but different generated + * line and column the same. Useful when searching for a mapping with a + * stubbed out mapping. + */ +function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { + var cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0 || onlyCompareOriginal) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + return strcmp(mappingA.name, mappingB.name); +} +exports.compareByOriginalPositions = compareByOriginalPositions; + +/** + * Comparator between two mappings with deflated source and name indices where + * the generated positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same generated line and column, but different + * source/name/original line and column the same. Useful when searching for a + * mapping with a stubbed out mapping. + */ +function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0 || onlyCompareGenerated) { + return cmp; + } + + cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return strcmp(mappingA.name, mappingB.name); +} +exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; + +function strcmp(aStr1, aStr2) { + if (aStr1 === aStr2) { + return 0; + } + + if (aStr1 === null) { + return 1; // aStr2 !== null + } + + if (aStr2 === null) { + return -1; // aStr1 !== null + } + + if (aStr1 > aStr2) { + return 1; + } + + return -1; +} + +/** + * Comparator between two mappings with inflated source and name strings where + * the generated positions are compared. + */ +function compareByGeneratedPositionsInflated(mappingA, mappingB) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return strcmp(mappingA.name, mappingB.name); +} +exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; + +/** + * Strip any JSON XSSI avoidance prefix from the string (as documented + * in the source maps specification), and then parse the string as + * JSON. + */ +function parseSourceMapInput(str) { + return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, '')); +} +exports.parseSourceMapInput = parseSourceMapInput; + +/** + * Compute the URL of a source given the the source root, the source's + * URL, and the source map's URL. + */ +function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) { + sourceURL = sourceURL || ''; + + if (sourceRoot) { + // This follows what Chrome does. + if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') { + sourceRoot += '/'; + } + // The spec says: + // Line 4: An optional source root, useful for relocating source + // files on a server or removing repeated values in the + // “sources” entry. This value is prepended to the individual + // entries in the “source” field. + sourceURL = sourceRoot + sourceURL; + } + + // Historically, SourceMapConsumer did not take the sourceMapURL as + // a parameter. This mode is still somewhat supported, which is why + // this code block is conditional. However, it's preferable to pass + // the source map URL to SourceMapConsumer, so that this function + // can implement the source URL resolution algorithm as outlined in + // the spec. This block is basically the equivalent of: + // new URL(sourceURL, sourceMapURL).toString() + // ... except it avoids using URL, which wasn't available in the + // older releases of node still supported by this library. + // + // The spec says: + // If the sources are not absolute URLs after prepending of the + // “sourceRoot”, the sources are resolved relative to the + // SourceMap (like resolving script src in a html document). + if (sourceMapURL) { + var parsed = urlParse(sourceMapURL); + if (!parsed) { + throw new Error("sourceMapURL could not be parsed"); + } + if (parsed.path) { + // Strip the last path component, but keep the "/". + var index = parsed.path.lastIndexOf('/'); + if (index >= 0) { + parsed.path = parsed.path.substring(0, index + 1); + } + } + sourceURL = join(urlGenerate(parsed), sourceURL); + } + + return normalize(sourceURL); +} +exports.computeSourceURL = computeSourceURL; diff --git a/node_modules/source-map/package.json b/node_modules/source-map/package.json new file mode 100644 index 0000000..2466341 --- /dev/null +++ b/node_modules/source-map/package.json @@ -0,0 +1,73 @@ +{ + "name": "source-map", + "description": "Generates and consumes source maps", + "version": "0.6.1", + "homepage": "https://github.com/mozilla/source-map", + "author": "Nick Fitzgerald ", + "contributors": [ + "Tobias Koppers ", + "Duncan Beevers ", + "Stephen Crane ", + "Ryan Seddon ", + "Miles Elam ", + "Mihai Bazon ", + "Michael Ficarra ", + "Todd Wolfson ", + "Alexander Solovyov ", + "Felix Gnass ", + "Conrad Irwin ", + "usrbincc ", + "David Glasser ", + "Chase Douglas ", + "Evan Wallace ", + "Heather Arthur ", + "Hugh Kennedy ", + "David Glasser ", + "Simon Lydell ", + "Jmeas Smith ", + "Michael Z Goddard ", + "azu ", + "John Gozde ", + "Adam Kirkton ", + "Chris Montgomery ", + "J. Ryan Stinnett ", + "Jack Herrington ", + "Chris Truter ", + "Daniel Espeset ", + "Jamie Wong ", + "Eddy Bruël ", + "Hawken Rives ", + "Gilad Peleg ", + "djchie ", + "Gary Ye ", + "Nicolas Lalevée " + ], + "repository": { + "type": "git", + "url": "http://github.com/mozilla/source-map.git" + }, + "main": "./source-map.js", + "files": [ + "source-map.js", + "source-map.d.ts", + "lib/", + "dist/source-map.debug.js", + "dist/source-map.js", + "dist/source-map.min.js", + "dist/source-map.min.js.map" + ], + "engines": { + "node": ">=0.10.0" + }, + "license": "BSD-3-Clause", + "scripts": { + "test": "npm run build && node test/run-tests.js", + "build": "webpack --color", + "toc": "doctoc --title '## Table of Contents' README.md && doctoc --title '## Table of Contents' CONTRIBUTING.md" + }, + "devDependencies": { + "doctoc": "^0.15.0", + "webpack": "^1.12.0" + }, + "typings": "source-map" +} diff --git a/node_modules/source-map/source-map.d.ts b/node_modules/source-map/source-map.d.ts new file mode 100644 index 0000000..8f972b0 --- /dev/null +++ b/node_modules/source-map/source-map.d.ts @@ -0,0 +1,98 @@ +export interface StartOfSourceMap { + file?: string; + sourceRoot?: string; +} + +export interface RawSourceMap extends StartOfSourceMap { + version: string; + sources: string[]; + names: string[]; + sourcesContent?: string[]; + mappings: string; +} + +export interface Position { + line: number; + column: number; +} + +export interface LineRange extends Position { + lastColumn: number; +} + +export interface FindPosition extends Position { + // SourceMapConsumer.GREATEST_LOWER_BOUND or SourceMapConsumer.LEAST_UPPER_BOUND + bias?: number; +} + +export interface SourceFindPosition extends FindPosition { + source: string; +} + +export interface MappedPosition extends Position { + source: string; + name?: string; +} + +export interface MappingItem { + source: string; + generatedLine: number; + generatedColumn: number; + originalLine: number; + originalColumn: number; + name: string; +} + +export class SourceMapConsumer { + static GENERATED_ORDER: number; + static ORIGINAL_ORDER: number; + + static GREATEST_LOWER_BOUND: number; + static LEAST_UPPER_BOUND: number; + + constructor(rawSourceMap: RawSourceMap); + computeColumnSpans(): void; + originalPositionFor(generatedPosition: FindPosition): MappedPosition; + generatedPositionFor(originalPosition: SourceFindPosition): LineRange; + allGeneratedPositionsFor(originalPosition: MappedPosition): Position[]; + hasContentsOfAllSources(): boolean; + sourceContentFor(source: string, returnNullOnMissing?: boolean): string; + eachMapping(callback: (mapping: MappingItem) => void, context?: any, order?: number): void; +} + +export interface Mapping { + generated: Position; + original: Position; + source: string; + name?: string; +} + +export class SourceMapGenerator { + constructor(startOfSourceMap?: StartOfSourceMap); + static fromSourceMap(sourceMapConsumer: SourceMapConsumer): SourceMapGenerator; + addMapping(mapping: Mapping): void; + setSourceContent(sourceFile: string, sourceContent: string): void; + applySourceMap(sourceMapConsumer: SourceMapConsumer, sourceFile?: string, sourceMapPath?: string): void; + toString(): string; +} + +export interface CodeWithSourceMap { + code: string; + map: SourceMapGenerator; +} + +export class SourceNode { + constructor(); + constructor(line: number, column: number, source: string); + constructor(line: number, column: number, source: string, chunk?: string, name?: string); + static fromStringWithSourceMap(code: string, sourceMapConsumer: SourceMapConsumer, relativePath?: string): SourceNode; + add(chunk: string): void; + prepend(chunk: string): void; + setSourceContent(sourceFile: string, sourceContent: string): void; + walk(fn: (chunk: string, mapping: MappedPosition) => void): void; + walkSourceContents(fn: (file: string, content: string) => void): void; + join(sep: string): SourceNode; + replaceRight(pattern: string, replacement: string): SourceNode; + toString(): string; + toStringWithSourceMap(startOfSourceMap?: StartOfSourceMap): CodeWithSourceMap; +} diff --git a/node_modules/source-map/source-map.js b/node_modules/source-map/source-map.js new file mode 100644 index 0000000..bc88fe8 --- /dev/null +++ b/node_modules/source-map/source-map.js @@ -0,0 +1,8 @@ +/* + * Copyright 2009-2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE.txt or: + * http://opensource.org/licenses/BSD-3-Clause + */ +exports.SourceMapGenerator = require('./lib/source-map-generator').SourceMapGenerator; +exports.SourceMapConsumer = require('./lib/source-map-consumer').SourceMapConsumer; +exports.SourceNode = require('./lib/source-node').SourceNode; diff --git a/node_modules/terser/CHANGELOG.md b/node_modules/terser/CHANGELOG.md new file mode 100644 index 0000000..9270397 --- /dev/null +++ b/node_modules/terser/CHANGELOG.md @@ -0,0 +1,843 @@ +# Changelog + +## v5.44.0 + + - Support `using` and `await using` declarations (#1635) + +## v5.43.1 + + - Prevent niche optimizations that would move around block declarations + - Add `lhs_constants` to `CompressOptions` type (#1621) + +## v5.43.0 + + - Do not wrap callbacks in parentheses (`wrap_func_args` format option is now false by default) + - Do not inline functions into for loops (for performance reasons) + +## v5.42.0 + + - Improved performance in the parse step by adding a fast path for simple identifiers. + - Improved ESTree conversion + +## v5.41.0 + + - fixed semicolon insertion between class fields, when the field names are number literals + - `keep_numbers` format option now works for bigint + - internal: correctly mark accessors' is_generator property + - internal: do not read or assign quote properties without need + - internal: add missing equivalent_to comparison + +## v5.40.0 + + - Fix exporting AssignmentExpression (default assign pattern) to ESTree + - Fix ESTree output of object keys with quotes + - Fix handling of an ESTree empty `export {}` (#1601) + - Fix some `const` and `let` resulting from ESTree input (#1599) + +## v5.39.2 + + - Fix crash when parsing bare `yield` inside a template string. + - Update internally used acorn version requirement + +## v5.39.1 + + - Fix bitwise operations that could mix `BigInt` and `number` + +## v5.39.0 + + - Remove unnecessary `console.assert` calls (#1590) + +## v5.38.2 + + - internal: Flatten inheritance tree for object/class members + +## v5.38.1 + + - Fix inlining non-call expressions into an `optional_call?.()` + +## v5.38.0 + + - Remove `console` method-of-method calls (eg `console.log.apply()`) when `drop_console` option is used (#1585) + - Remove more object spreads, such as `{ ...void !0 }` (#1142) + +## v5.37.0 + + - Reserved object properties from chrome extensions (domprops) + - Fix semicolon insertion between a class property without a semicolon `a` and a computed class property `["prop"]` + +## v5.36.0 + + - Support import attributes `with` syntax + +## v5.35.0 + + - Ensure parent directory exists when using --output on CLI (#1530) + +## v5.34.1 + + - bump the rollup devDependency to disable CVE warnings (Terser was not affected) + +## v5.34.0 + + - internal: stop assigning properties to objects they don't belong in + - internal: run compress tests in parallel + - `drop_console`: emit an empty function if the return value of `console.METHOD(...)` may be called. + +## v5.33.0 + + - `reduce_vars` improved when dealing with hoisted function definitions (#1544) + +## v5.32.0 + + - `import("module")` can now be input and output from ESTree AST (#1557) + - `BigInt` literals can now be input and output from ESTree AST (#1555) + - `typeof` an object or array (`typeof {}` and `typeof []`) can now be statically evaluated. (#1546) + +## v5.31.6 + - Retain side effects in a `case` when the expression is a sequence (comma) expression + +## v5.31.5 + - Revert v5.31.4, which created mysterious issues #1548, #1549 + +## v5.31.4 (reverted) + - drop_unused: drop classes which only have side effects in the `extends` part + +## v5.31.3 + - drop_unused: drop unused parameters from IIFEs in some more situations. + +## v5.31.2 + - drop_unused: scan variables in self-referential class declarations that contain side effects. + - Don't add parens to arrow function when it's the default for an argument (#1540) + - Update domprops (#1538) + +## v5.31.1 + - Allow drop-unused to drop the whole assignment (not just the assigned name) in more situations, in order to avoid duplication of long strings. + +## v5.31.0 + - Sync up property mangler exceptions with current contents of Firefox and Chrome environments + - Add more webcomponent properties to property mangler exceptions (#1525) + - Drop non-nullish constants in `...spreads` in objects (#1141) + +## v5.30.4 + - Fix parsing `#private in ...` when next to other operators + +## v5.30.3 + - Fix precedence of `#private in ...` operator + +## v5.30.2 + - Avoid optimizations inside computed keys, because they can cause js-engine-specific bugs. + +## v5.30.1 + - Removed useless `\` escapes for non-ascii characters + - Make modern identifier characters quoted for older environments (#1512) + +## v5.30.0 + - Improve removal of classes referring to themselves + +## v5.29.2 + - Make sure 'computed_props' creates string keys + - Take into account the evaluated size when inlining + +## v5.29.1 + - fix optimisation of all-bits mask check + +## v5.29.0 + - Re-releases previously reverted 5.28.0 + - Fix crash while optimizing some bitwise ops + - (internal) Remove needless wrapper for from_moz (#1499) + +## v5.28.1 +(hotfix release) + - Reverts v5.28.0 + +## v5.28.0 + - Optimise redundant or shrinkable bitwise operations (`|`, `^`, `&`, `>>`, `<<`) + - Evaluate some `BigInt` math operations + +## v5.27.2 + - Recognise `this` as a reference to the surrounding class in `drop_unused`. Closes #1472 + +## v5.27.1 + - Fixed case where `collapse_vars` inlines `await` expressions into non-async functions. + +## v5.27.0 + - Created `minify_sync()` alternative to `minify()` since there's no async code left. + +## v5.26.0 + - Do not take the `/*#__PURE__*/` annotation into account when the `side_effects` compress option is off. + - The `preserve_annotations` option now automatically opts annotation comments in, instead of requiring the `comments` option to be configured for this. + - Refuse to parse empty parenthesized expressions (`()`) + +## v5.25.0 + - Regex properties added to reserved property mangler (#1471) + - `pure_new` option added to drop unused `new` expressions. + +## v5.24.0 + - Improve formatting performance in V8 by keeping a small work string and a large output string + +## v5.23.0 + - When top_retain will keep a variable assignment around, inline the assignee when it's shorter than the name (#1434) + - Remove empty class `static {}` blocks. + +## v5.22.0 + - Do not `unsafe`ly shorten expressions like a?.toString() when they're conditional. + - Avoid running drop_unused in nodes that aren't scopes. Fixes a rare crash. + - When 'module' is enabled, assume strict mode when figuring out scopes. + +## v5.21.0 + - Do not inline functions that would be retained in the toplevel (as this would cause code duplication). + - Fix precedence of arrow function and ternary operator when formatting output. + +## v5.20.0 + - Passing `minify()` zero files will now throw a clean exception (#1450) + - `drop_console` supports passing in an array of `console.*` method names (#1445) + - New DOM properties from the WebGPU API have been added for use in the property mangler (#1436) + - Internal code simplification (#1437) + +## v5.19.4 + - Prevent creating very deeply nested ternaries from a long list of `if..return` + - Prevent inlining classes into other functions, to avoid constructors being compared. + +## v5.19.3 + - Fix side effect detection of `optional?.chains`. + - Add roundRect to domprops.js (#1426) + +## v5.19.2 + - fix performance hit from avoiding HTML comments in the output + +## v5.19.1 + - Better avoid outputting `` and HTML comments. + - Fix unused variables in class static blocks not being dropped correctly. + - Fix sourcemap names of methods that are `async` or `static` + +## v5.19.0 + - Allow `/*@__MANGLE_PROP__*/` annotation in `object.property`, in addition to property declarations. + +## v5.18.2 + - Stop using recursion in hoisted defuns fix. + +## v5.18.1 + - Fix major performance issue caused by hoisted defuns' scopes bugfix. + +## v5.18.0 + - Add new `/*@__MANGLE_PROP__*/` annotation, to mark properties that should be mangled. + +## v5.17.7 + - Update some dependencies + - Add consistent sorting for `v` RegExp flag + - Add `inert` DOM attribute to domprops + +## v5.17.6 + - Fixes to mozilla AST input and output, for class properties, private properties and static blocks + - Fix outputting a shorthand property in quotes when safari10 and ecma=2015 options are enabled + - `configurable` and `enumerable`, used in Object.defineProperty, added to domprops (#1393) + +## v5.17.5 + - Take into account the non-deferred bits of a class, such as static properties, while dropping unused code. + +## v5.17.4 + + - Fix crash when trying to negate a class (`!class{}`) + - Avoid outputting comments between `yield`/`await` and its argument + - Fix detection of left-hand-side of assignment, to avoid optimizing it like any other expression in some edge cases + +## v5.17.3 + + - Fix issue with trimming a static class property's contents accessing the class as `this`. + +## v5.17.2 + - Be less conservative when detecting use-before-definition of `var` in hoisted functions. + - Support unusual (but perfectly valid) initializers of for-in and for-of loops. + - Fix issue where hoisted function would be dropped if it was after a `continue` statement + +## v5.17.1 + - Fix evaluating `.length` when the source array might've been mutated + +## v5.17.0 + - Drop vestigial `= undefined` default argument in IIFE calls (#1366) + - Evaluate known arrays' `.length` property when statically determinable + - Add `@__KEY__` annotation to mangle string literals (#1365) + +## v5.16.9 + - Fix parentheses in output of optional chains (`a?.b`) (#1374) + - More documentation on source maps (#1368) + - New `lhs_constants` option, allowing to stop Terser from swapping comparison operands (#1361) + +## v5.16.8 + + - Become even less conservative around function definitions for `reduce_vars` + - Fix parsing context of `import.meta` expressions such that method calls are allowed + +## v5.16.6 + + - Become less conservative with analyzing function definitions for `reduce_vars` + - Parse `import.meta` as a real AST node and not an `object.property` + +## v5.16.5 + + - Correctly handle AST transform functions that mutate children arrays + - Don't mutate the options object passed to Terser (#1342) + - Do not treat BigInt like a number + +## v5.16.4 + + - Keep `(defaultArg = undefined) => ...`, because default args don't count for function length + - Prevent inlining variables into `?.` optional chains + - Avoid removing unused arguments while transforming + - Optimize iterating AST node lists + - Make sure `catch` and `finally` aren't children of `try` in the AST + - Use modern unicode property escapes (`\p{...}`) to parse identifiers when available + +## v5.16.3 + + - Ensure function definitions, don't assume the values of variables defined after them. + +## v5.16.2 + + - Fix sourcemaps with non-ascii characters (#1318) + - Support string module name and export * as (#1336) + - Do not move `let` out of `for` initializers, as it can change scoping + - Fix a corner case that would generate the invalid syntax `if (something) let x` ("let" in braceless if body) + - Knowledge of more native object properties (#1330) + - Got rid of Travis (#1323) + - Added semi-secret `asObject` sourcemap option to typescript defs (#1321) + +## v5.16.1 + + - Properly handle references in destructurings (`const { [reference]: val } = ...`) + - Allow parsing of `.#privatefield` in nested classes + - Do not evaluate operations that return large strings if that would make the output code larger + - Make `collapse_vars` handle block scope correctly + - Internal improvements: Typos (#1311), more tests, small-scale refactoring + +## v5.16.0 + + - Disallow private fields in object bodies (#1011) + - Parse `#privatefield in object` (#1279) + - Compress `#privatefield in object` + +## v5.15.1 + + - Fixed missing parentheses around optional chains + - Avoid bare `let` or `const` as the bodies of `if` statements (#1253) + - Small internal fixes (#1271) + - Avoid inlining a class twice and creating two equivalent but `!==` classes. + +## v5.15.0 + - Basic support for ES2022 class static initializer blocks. + - Add `AudioWorkletNode` constructor options to domprops list (#1230) + - Make identity function inliner not inline `id(...expandedArgs)` + +## v5.14.2 + + - Security fix for RegExps that should not be evaluated (regexp DDOS) + - Source maps improvements (#1211) + - Performance improvements in long property access evaluation (#1213) + +## v5.14.1 + - keep_numbers option added to TypeScript defs (#1208) + - Fixed parsing of nested template strings (#1204) + +## v5.14.0 + - Switched to @jridgewell/source-map for sourcemap generation (#1190, #1181) + - Fixed source maps with non-terminated segments (#1106) + - Enabled typescript types to be imported from the package (#1194) + - Extra DOM props have been added (#1191) + - Delete the AST while generating code, as a means to save RAM + +## v5.13.1 + - Removed self-assignments (`varname=varname`) (closes #1081) + - Separated inlining code (for inlining things into references, or removing IIFEs) + - Allow multiple identifiers with the same name in `var` destructuring (eg `var { a, a } = x`) (#1176) + +## v5.13.0 + + - All calls to eval() were removed (#1171, #1184) + - `source-map` was updated to 0.8.0-beta.0 (#1164) + - NavigatorUAData was added to domprops to avoid property mangling (#1166) + +## v5.12.1 + + - Fixed an issue with function definitions inside blocks (#1155) + - Fixed parens of `new` in some situations (closes #1159) + +## v5.12.0 + + - `TERSER_DEBUG_DIR` environment variable + - @copyright comments are now preserved with the comments="some" option (#1153) + +## v5.11.0 + + - Unicode code point escapes (`\u{abcde}`) are not emitted inside RegExp literals anymore (#1147) + - acorn is now a regular dependency + +## v5.10.0 + + - Massive optimization to max_line_len (#1109) + - Basic support for import assertions + - Marked ES2022 Object.hasOwn as a pure function + - Fix `delete optional?.property` + - New CI/CD pipeline with github actions (#1057) + - Fix reordering of switch branches (#1092), (#1084) + - Fix error when creating a class property called `get` + - Acorn dependency is now an optional peerDependency + - Fix mangling collision with exported variables (#1072) + - Fix an issue with `return someVariable = (async () => { ... })()` (#1073) + +## v5.9.0 + + - Collapsing switch cases with the same bodies (even if they're not next to each other) (#1070). + - Fix evaluation of optional chain expressions (#1062) + - Fix mangling collision in ESM exports (#1063) + - Fix issue with mutating function objects after a second pass (#1047) + - Fix for inlining object spread `{ ...obj }` (#1071) + - Typescript typings fix (#1069) + +## v5.8.0 + + - Fixed shadowing variables while moving code in some cases (#1065) + - Stop mangling computed & quoted properties when keep_quoted is enabled. + - Fix for mangling private getter/setter and .#private access (#1060, #1068) + - Array.from has a new optimization when the unsafe option is set (#737) + - Mangle/propmangle let you generate your own identifiers through the nth_identifier option (#1061) + - More optimizations to switch statements (#1044) + +## v5.7.2 + + - Fixed issues with compressing functions defined in `global_defs` option (#1036) + - New recipe for using Terser in gulp was added to RECIPES.md (#1035) + - Fixed issues with `??` and `?.` (#1045) + - Future reserved words such as `package` no longer require you to disable strict mode to be used as names. + - Refactored huge compressor file into multiple more focused files. + - Avoided unparenthesized `in` operator in some for loops (it breaks parsing because of for..in loops) + - Improved documentation (#1021, #1025) + - More type definitions (#1021) + +## v5.7.1 + + - Avoided collapsing assignments together if it would place a chain assignment on the left hand side, which is invalid syntax (`a?.b = c`) + - Removed undefined from object expansions (`{ ...void 0 }` -> `{}`) + - Fix crash when checking if something is nullish or undefined (#1009) + - Fixed comparison of private class properties (#1015) + - Minor performance improvements (#993) + - Fixed scope of function defs in strict mode (they are block scoped) + +## v5.7.0 + + - Several compile-time evaluation and inlining fixes + - Allow `reduce_funcs` to be disabled again. + - Add `spidermonkey` options to parse and format (#974) + - Accept `{get = "default val"}` and `{set = "default val"}` in destructuring arguments. + - Change package.json export map to help require.resolve (#971) + - Improve docs + - Fix `export default` of an anonymous class with `extends` + +## v5.6.1 + + - Mark assignments to the `.prototype` of a class as pure + - Parenthesize `await` on the left of `**` (while accepting legacy non-parenthesised input) + - Avoided outputting NUL bytes in optimized RegExps, to stop the output from breaking other tools + - Added `exports` to domprops (#939) + - Fixed a crash when spreading `...this` + - Fixed the computed size of arrow functions, which improves their inlining + +## v5.6.0 + + - Added top-level await + - Beautify option has been removed in #895 + - Private properties, getters and setters have been added in #913 and some more commits + - Docs improvements: #896, #903, #916 + +## v5.5.1 + + - Fixed object properties with unicode surrogates on safari. + +## v5.5.0 + + - Fixed crash when inlining uninitialized variable into template string. + - The sourcemap for dist was removed for being too large. + +## v5.4.0 + + - Logical assignment + - Change `let x = undefined` to just `let x` + - Removed some optimizations for template strings, placing them behind `unsafe` options. Reason: adding strings is not equivalent to template strings, due to valueOf differences. + - The AST_Token class was slimmed down in order to use less memory. + +## v5.3.8 + + - Restore node 13 support + +## v5.3.7 + +Hotfix release, fixes package.json "engines" syntax + +## v5.3.6 + + - Fixed parentheses when outputting `??` mixed with `||` and `&&` + - Improved hygiene of the symbol generator + +## v5.3.5 + + - Avoid moving named functions into default exports. + - Enabled transform() for chain expressions. This allows AST transformers to reach inside chain expressions. + +## v5.3.4 + + - Fixed a crash when hoisting (with `hoist_vars`) a destructuring variable declaration + +## v5.3.3 + + - `source-map` library has been updated, bringing memory usage and CPU time improvements when reading input source maps (the SourceMapConsumer is now WASM based). + - The `wrap_func_args` option now also wraps arrow functions, as opposed to only function expressions. + +## v5.3.2 + + - Prevented spread operations from being expanded when the expanded array/object contains getters, setters, or array holes. + - Fixed _very_ slow self-recursion in some cases of removing extraneous parentheses from `+` operations. + +## v5.3.1 + + - An issue with destructuring declarations when `pure_getters` is enabled has been fixed + - Fixed a crash when chain expressions need to be shallowly compared + - Made inlining functions more conservative to make sure a function that contains a reference to itself isn't moved into a place that can create multiple instances of itself. + +## v5.3.0 + + - Fixed a crash when compressing object spreads in some cases + - Fixed compiletime evaluation of optional chains (caused typeof a?.b to always return "object") + - domprops has been updated to contain every single possible prop + +## v5.2.1 + + - The parse step now doesn't accept an `ecma` option, so that all ES code is accepted. + - Optional dotted chains now accept keywords, just like dotted expressions (`foo?.default`) + +## v5.2.0 + + - Optional chaining syntax is now supported. + - Consecutive await expressions don't have unnecessary parens + - Taking the variable name's length (after mangling) into consideration when deciding to inline + +## v5.1.0 + + - `import.meta` is now supported + - Typescript typings have been improved + +## v5.0.0 + + - `in` operator now taken into account during property mangle. + - Fixed infinite loop in face of a reference loop in some situations. + - Kept exports and imports around even if there's something which will throw before them. + - The main exported bundle for commonjs, dist/bundle.min.js is no longer minified. + +## v5.0.0-beta.0 + + - BREAKING: `minify()` is now async and rejects a promise instead of returning an error. + - BREAKING: Internal AST is no longer exposed, so that it can be improved without releasing breaking changes. + - BREAKING: Lowest supported node version is 10 + - BREAKING: There are no more warnings being emitted + - Module is now distributed as a dual package - You can `import` and `require()` too. + - Inline improvements were made + + +----- + +## v4.8.1 (backport) + + - Security fix for RegExps that should not be evaluated (regexp DDOS) + +## v4.8.0 + + - Support for numeric separators (`million = 1_000_000`) was added. + - Assigning properties to a class is now assumed to be pure. + - Fixed bug where `yield` wasn't considered a valid property key in generators. + +## v4.7.0 + + - A bug was fixed where an arrow function would have the wrong size + - `arguments` object is now considered safe to retrieve properties from (useful for `length`, or `0`) even when `pure_getters` is not set. + - Fixed erroneous `const` declarations without value (which is invalid) in some corner cases when using `collapse_vars`. + +## v4.6.13 + + - Fixed issue where ES5 object properties were being turned into ES6 object properties due to more lax unicode rules. + - Fixed parsing of BigInt with lowercase `e` in them. + +## v4.6.12 + + - Fixed subtree comparison code, making it see that `[1,[2, 3]]` is different from `[1, 2, [3]]` + - Printing of unicode identifiers has been improved + +## v4.6.11 + + - Read unused classes' properties and method keys, to figure out if they use other variables. + - Prevent inlining into block scopes when there are name collisions + - Functions are no longer inlined into parameter defaults, because they live in their own special scope. + - When inlining identity functions, take into account the fact they may be used to drop `this` in function calls. + - Nullish coalescing operator (`x ?? y`), plus basic optimization for it. + - Template literals in binary expressions such as `+` have been further optimized + +## v4.6.10 + + - Do not use reduce_vars when classes are present + +## v4.6.9 + + - Check if block scopes actually exist in blocks + +## v4.6.8 + + - Take into account "executed bits" of classes like static properties or computed keys, when checking if a class evaluation might throw or have side effects. + +## v4.6.7 + + - Some new performance gains through a `AST_Node.size()` method which measures a node's source code length without printing it to a string first. + - An issue with setting `--comments` to `false` in the CLI has been fixed. + - Fixed some issues with inlining + - `unsafe_symbols` compress option was added, which turns `Symbol("name")` into just `Symbol()` + - Brought back compress performance improvement through the `AST_Node.equivalent_to(other)` method (which was reverted in v4.6.6). + +## v4.6.6 + +(hotfix release) + + - Reverted code to 4.6.4 to allow for more time to investigate an issue. + +## v4.6.5 (REVERTED) + + - Improved compress performance through using a new method to see if two nodes are equivalent, instead of printing them to a string. + +## v4.6.4 + + - The `"some"` value in the `comments` output option now preserves `@lic` and other important comments when using `//` + - `` is now better escaped in regex, and in comments, when using the `inline_script` output option + - Fixed an issue when transforming `new RegExp` into `/.../` when slashes are included in the source + - `AST_Node.prototype.constructor` now exists, allowing for easier debugging of crashes + - Multiple if statements with the same consequents are now collapsed + - Typescript typings improvements + - Optimizations while looking for surrogate pairs in strings + +## v4.6.3 + + - Annotations such as `/*#__NOINLINE__*/` and `/*#__PURE__*/` may now be preserved using the `preserve_annotations` output option + - A TypeScript definition update for the `keep_quoted` output option. + +## v4.6.2 + + - A bug where functions were inlined into other functions with scope conflicts has been fixed. + - `/*#__NOINLINE__*/` annotation fixed for more use cases where inlining happens. + +## v4.6.1 + + - Fixed an issue where a class is duplicated by reduce_vars when there's a recursive reference to the class. + +## v4.6.0 + + - Fixed issues with recursive class references. + - BigInt evaluation has been prevented, stopping Terser from evaluating BigInts like it would do regular numbers. + - Class property support has been added + +## v4.5.1 + +(hotfix release) + + - Fixed issue where `() => ({})[something]` was not parenthesised correctly. + +## v4.5.0 + + - Inlining has been improved + - An issue where keep_fnames combined with functions declared through variables was causing name shadowing has been fixed + - You can now set the ES version through their year + - The output option `keep_numbers` has been added, which prevents Terser from turning `1000` into `1e3` and such + - Internal small optimisations and refactors + +## v4.4.3 + + - Number and BigInt parsing has been fixed + - `/*#__INLINE__*/` annotation fixed for arrow functions with non-block bodies. + - Functional tests have been added, using [this repository](https://github.com/terser/terser-functional-tests). + - A memory leak, where the entire AST lives on after compression, has been plugged. + +## v4.4.2 + + - Fixed a problem with inlining identity functions + +## v4.4.1 + +*note:* This introduced a feature, therefore it should have been a minor release. + + - Fixed a crash when `unsafe` was enabled. + - An issue has been fixed where `let` statements might be collapsed out of their scope. + - Some error messages have been improved by adding quotes around variable names. + +## v4.4.0 + + - Added `/*#__INLINE__*/` and `/*#__NOINLINE__*/` annotations for calls. If a call has one of these, it either forces or forbids inlining. + +## v4.3.11 + + - Fixed a problem where `window` was considered safe to access, even though there are situations where it isn't (Node.js, workers...) + - Fixed an error where `++` and `--` were considered side-effect free + - `Number(x)` now needs both `unsafe` and and `unsafe_math` to be compressed into `+x` because `x` might be a `BigInt` + - `keep_fnames` now correctly supports regexes when the function is in a variable declaration + +## v4.3.10 + + - Fixed syntax error when repeated semicolons were encountered in classes + - Fixed invalid output caused by the creation of empty sequences internally + - Scopes are now updated when scopes are inlined into them + +## v4.3.9 + - Fixed issue with mangle's `keep_fnames` option, introduced when adding code to keep variable names of anonymous functions + +## v4.3.8 + + - Typescript typings fix + +## v4.3.7 + + - Parsing of regex options in the CLI (which broke in v4.3.5) was fixed. + - typescript definition updates + +## v4.3.6 + +(crash hotfix) + +## v4.3.5 + + - Fixed an issue with DOS line endings strings separated by `\` and a new line. + - Improved fix for the output size regression related to unused references within the extends section of a class. + - Variable names of anonymous functions (eg: `const x = () => { ... }` or `var func = function () {...}`) are now preserved when keep_fnames is true. + - Fixed performance degradation introduced for large payloads in v4.2.0 + +## v4.3.4 + + - Fixed a regression where the output size was increased when unused classes were referred to in the extends clause of a class. + - Small typescript typings fixes. + - Comments with `@preserve`, `@license`, `@cc_on` as well as comments starting with `/*!` and `/**!` are now preserved by default. + +## v4.3.3 + + - Fixed a problem where parsing template strings would mix up octal notation and a slash followed by a zero representing a null character. + - Started accepting the name `async` in destructuring arguments with default value. + - Now Terser takes into account side effects inside class `extends` clauses. + - Added parens whenever there's a comment between a return statement and the returned value, to prevent issues with ASI. + - Stopped using raw RegExp objects, since the spec is going to continue to evolve. This ensures Terser is able to process new, unknown RegExp flags and features. This is a breaking change in the AST node AST_RegExp. + +## v4.3.2 + + - Typescript typing fix + - Ensure that functions can't be inlined, by reduce_vars, into places where they're accessing variables with the same name, but from somewhere else. + +## v4.3.1 + + - Fixed an issue from 4.3.0 where any block scope within a for loop erroneously had its parent set to the function scopee + - Fixed an issue where compressing IIFEs with argument expansions would result in some parameters becoming undefined + - addEventListener options argument's properties are now part of the DOM properties list. + +## v4.3.0 + + - Do not drop computed object keys with side effects + - Functions passed to other functions in calls are now wrapped in parentheses by default, which speeds up loading most modules + - Objects with computed properties are now less likely to be hoisted + - Speed and memory efficiency optimizations + - Fixed scoping issues with `try` and `switch` + +## v4.2.1 + + - Minor refactors + - Fixed a bug similar to #369 in collapse_vars + - Functions can no longer be inlined into a place where they're going to be compared with themselves. + - reduce_funcs option is now legacy, as using reduce_vars without reduce_funcs caused some weird corner cases. As a result, it is now implied in reduce_vars and can't be turned off without turning off reduce_vars. + - Bug which would cause a random stack overflow has now been fixed. + +## v4.2.0 + + - When the source map URL is `inline`, don't write it to a file. + - Fixed output parens when a lambda literal is the tag on a tagged template string. + - The `mangle.properties.undeclared` option was added. This enables the property mangler to mangle properties of variables which can be found in the name cache, but whose properties are not known to this Terser run. + - The v8 bug where the toString and source representations of regexes like `RegExp("\\\n")` includes an actual newline is now fixed. + - Now we're guaranteed to not have duplicate comments in the output + - Domprops updates + +## v4.1.4 + + - Fixed a crash when inlining a function into somewhere else when it has interdependent, non-removable variables. + +## v4.1.3 + + - Several issues with the `reduce_vars` option were fixed. + - Starting this version, we only have a dist/bundle.min.js + +## v4.1.2 + + - The hotfix was hotfixed + +## v4.1.1 + + - Fixed a bug where toplevel scopes were being mixed up with lambda scopes + +## v4.1.0 + + - Internal functions were replaced by `Object.assign`, `Array.prototype.some`, `Array.prototype.find` and `Array.prototype.every`. + - A serious issue where some ESM-native code was broken was fixed. + - Performance improvements were made. + - Support for BigInt was added. + - Inline efficiency was improved. Functions are now being inlined more proactively instead of being inlined only after another Compressor pass. + +## v4.0.2 + +(Hotfix release. Reverts unmapped segments PR [#342](https://github.com/terser/terser/pull/342), which will be put back on Terser when the upstream issue is resolved) + +## v4.0.1 + + - Collisions between the arguments of inlined functions and names in the outer scope are now being avoided while inlining + - Unmapped segments are now preserved when compressing a file which has source maps + - Default values of functions are now correctly converted from Mozilla AST to Terser AST + - JSON ⊂ ECMAScript spec (if you don't know what this is you don't need to) + - Export AST_* classes to library users + - Fixed issue with `collapse_vars` when functions are created with the same name as a variable which already exists + - Added `MutationObserverInit` (Object with options for initialising a mutation observer) properties to the DOM property list + - Custom `Error` subclasses are now internally used instead of old-school Error inheritance hacks. + - Documentation fixes + - Performance optimizations + +## v4.0.0 + + - **breaking change**: The `variables` property of all scopes has become a standard JavaScript `Map` as opposed to the old bespoke `Dictionary` object. + - Typescript definitions were fixed + - `terser --help` was fixed + - The public interface was cleaned up + - Fixed optimisation of `Array` and `new Array` + - Added the `keep_quoted=strict` mode to mangle_props, which behaves more like Google Closure Compiler by mangling all unquoted property names, instead of reserving quoted property names automatically. + - Fixed parent functions' parameters being shadowed in some cases + - Allowed Terser to run in a situation where there are custom functions attached to Object.prototype + - And more bug fixes, optimisations and internal changes + +## v3.17.0 + + - More DOM properties added to --mangle-properties's DOM property list + - Closed issue where if 2 functions had the same argument name, Terser would not inline them together properly + - Fixed issue with `hasOwnProperty.call` + - You can now list files to minify in a Terser config file + - Started replacing `new Array()` with an array literal + - Started using ES6 capabilities like `Set` and the `includes` method for strings and arrays + +## v3.16.1 + + - Fixed issue where Terser being imported with `import` would cause it not to work due to the `__esModule` property. (PR #254 was submitted, which was nice, but since it wasn't a pure commonJS approach I decided to go with my own solution) + +## v3.16.0 + + - No longer leaves names like Array or Object or window as a SimpleStatement (statement which is just a single expression). + - Add support for sections sourcemaps (IndexedSourceMapConsumer) + - Drops node.js v4 and starts using commonJS + - Is now built with rollup + +## v3.15.0 + + - Inlined spread syntax (`[...[1, 2, 3], 4, 5] => [1, 2, 3, 4, 5]`) in arrays and objects. + - Fixed typo in compressor warning + - Fixed inline source map input bug + - Fixed parsing of template literals with unnecessary escapes (Like `\\a`) diff --git a/node_modules/terser/LICENSE b/node_modules/terser/LICENSE new file mode 100644 index 0000000..3b07e94 --- /dev/null +++ b/node_modules/terser/LICENSE @@ -0,0 +1,27 @@ +Copyright 2012-2018 (c) Mihai Bazon + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY +EXPRESS 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 THE COPYRIGHT HOLDER 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. diff --git a/node_modules/terser/PATRONS.md b/node_modules/terser/PATRONS.md new file mode 100644 index 0000000..3df7715 --- /dev/null +++ b/node_modules/terser/PATRONS.md @@ -0,0 +1,15 @@ +# Our patrons + +These are the first-tier patrons from Patreon (notice: **The Terser Patreon is shutting down in favor of opencollective**). My appreciation goes to everyone on this list for supporting the project! + + * 38elements + * Alan Orozco + * Aria Buckles + * CKEditor + * Mariusz Nowak + * Nakshatra Mukhopadhyay + * Philippe Léger + * Piotrek Koszuliński + * Serhiy Shyyko + * Viktor Hubert + * 龙腾道 diff --git a/node_modules/terser/README.md b/node_modules/terser/README.md new file mode 100644 index 0000000..27cf463 --- /dev/null +++ b/node_modules/terser/README.md @@ -0,0 +1,1419 @@ +

Terser

+ + [![NPM Version][npm-image]][npm-url] + [![NPM Downloads][downloads-image]][downloads-url] + [![CI pipeline][ci-image]][ci-url] + [![Opencollective financial contributors][opencollective-contributors]][opencollective-url] + +A JavaScript mangler/compressor toolkit for ES6+. + +*note*: You can support this project on patreon: [link] **The Terser Patreon is shutting down in favor of opencollective**. Check out [PATRONS.md](https://github.com/terser/terser/blob/master/PATRONS.md) for our first-tier patrons. + +Terser recommends you use RollupJS to bundle your modules, as that produces smaller code overall. + +*Beautification* has been undocumented and is *being removed* from terser, we recommend you use [prettier](https://npmjs.com/package/prettier). + +Find the changelog in [CHANGELOG.md](https://github.com/terser/terser/blob/master/CHANGELOG.md) + + + +[npm-image]: https://img.shields.io/npm/v/terser.svg +[npm-url]: https://npmjs.org/package/terser +[downloads-image]: https://img.shields.io/npm/dm/terser.svg +[downloads-url]: https://npmjs.org/package/terser +[ci-image]: https://github.com/terser/terser/actions/workflows/ci.yml/badge.svg +[ci-url]: https://github.com/terser/terser/actions/workflows/ci.yml +[opencollective-contributors]: https://opencollective.com/terser/tiers/badge.svg +[opencollective-url]: https://opencollective.com/terser + +Why choose terser? +------------------ + +`uglify-es` is [no longer maintained](https://github.com/mishoo/UglifyJS2/issues/3156#issuecomment-392943058) and `uglify-js` does not support ES6+. + +**`terser`** is a fork of `uglify-es` that mostly retains API and CLI compatibility +with `uglify-es` and `uglify-js@3`. + +Install +------- + +First make sure you have installed the latest version of [node.js](http://nodejs.org/) +(You may need to restart your computer after this step). + +From NPM for use as a command line app: + + npm install terser -g + +From NPM for programmatic use: + + npm install terser + +# Command line usage + + + +``` +terser [input files] [options] +``` + +Terser can take multiple input files. It's recommended that you pass the +input files first, then pass the options. Terser will parse input files +in sequence and apply any compression options. The files are parsed in the +same global scope, that is, a reference from a file to some +variable/function declared in another file will be matched properly. + +Command line arguments that take options (like --parse, --compress, --mangle and +--format) can take in a comma-separated list of default option overrides. For +instance: + + terser input.js --compress ecma=2015,computed_props=false + +If no input file is specified, Terser will read from STDIN. + +If you wish to pass your options before the input files, separate the two with +a double dash to prevent input files being used as option arguments: + + terser --compress --mangle -- input.js + +### Command line options + +``` + -h, --help Print usage information. + `--help options` for details on available options. + -V, --version Print version number. + -p, --parse Specify parser options: + `acorn` Use Acorn for parsing. + `bare_returns` Allow return outside of functions. + Useful when minifying CommonJS + modules and Userscripts that may + be anonymous function wrapped (IIFE) + by the .user.js engine `caller`. + `expression` Parse a single expression, rather than + a program (for parsing JSON). + `spidermonkey` Assume input files are SpiderMonkey + AST format (as JSON). + -c, --compress [options] Enable compressor/specify compressor options: + `pure_funcs` List of functions that can be safely + removed when their return values are + not used. + -m, --mangle [options] Mangle names/specify mangler options: + `reserved` List of names that should not be mangled. + --mangle-props [options] Mangle properties/specify mangler options: + `builtins` Mangle property names that overlaps + with standard JavaScript globals and DOM + API props. + `debug` Add debug prefix and suffix. + `keep_quoted` Only mangle unquoted properties, quoted + properties are automatically reserved. + `strict` disables quoted properties + being automatically reserved. + `regex` Only mangle matched property names. + `only_annotated` Only mangle properties defined with /*@__MANGLE_PROP__*/. + `reserved` List of names that should not be mangled. + -f, --format [options] Specify format options. + `preamble` Preamble to prepend to the output. You + can use this to insert a comment, for + example for licensing information. + This will not be parsed, but the source + map will adjust for its presence. + `quote_style` Quote style: + 0 - auto + 1 - single + 2 - double + 3 - original + `wrap_iife` Wrap IIFEs in parenthesis. Note: you may + want to disable `negate_iife` under + compressor options. + `wrap_func_args` Wrap function arguments in parenthesis. + -o, --output Output file path (default STDOUT). Specify `ast` or + `spidermonkey` to write Terser or SpiderMonkey AST + as JSON to STDOUT respectively. + --comments [filter] Preserve copyright comments in the output. By + default this works like Google Closure, keeping + JSDoc-style comments that contain e.g. "@license", + or start with "!". You can optionally pass one of the + following arguments to this flag: + - "all" to keep all comments + - `false` to omit comments in the output + - a valid JS RegExp like `/foo/` or `/^!/` to + keep only matching comments. + Note that currently not *all* comments can be + kept when compression is on, because of dead + code removal or cascading statements into + sequences. + --config-file Read `minify()` options from JSON file. + -d, --define [=value] Global definitions. + --ecma Specify ECMAScript release: 5, 2015, 2016, etc. + -e, --enclose [arg[:value]] Embed output in a big function with configurable + arguments and values. + --ie8 Support non-standard Internet Explorer 8. + Equivalent to setting `ie8: true` in `minify()` + for `compress`, `mangle` and `format` options. + By default Terser will not try to be IE-proof. + --keep-classnames Do not mangle/drop class names. + --keep-fnames Do not mangle/drop function names. Useful for + code relying on Function.prototype.name. + --module Input is an ES6 module. If `compress` or `mangle` is + enabled then the `toplevel` option, as well as strict mode, + will be enabled. + --name-cache File to hold mangled name mappings. + --safari10 Support non-standard Safari 10/11. + Equivalent to setting `safari10: true` in `minify()` + for `mangle` and `format` options. + By default `terser` will not work around + Safari 10/11 bugs. + --source-map [options] Enable source map/specify source map options: + `base` Path to compute relative paths from input files. + `content` Input source map, useful if you're compressing + JS that was generated from some other original + code. Specify "inline" if the source map is + included within the sources. + `filename` Name and/or location of the output source. + `includeSources` Pass this flag if you want to include + the content of source files in the + source map as sourcesContent property. + `root` Path to the original source to be included in + the source map. + `url` If specified, path to the source map to append in + `//# sourceMappingURL`. + --timings Display operations run time on STDERR. + --toplevel Compress and/or mangle variables in top level scope. + --wrap Embed everything in a big function, making the + “exports” and “global” variables available. You + need to pass an argument to this option to + specify the name that your module will take + when included in, say, a browser. +``` + +Specify `--output` (`-o`) to declare the output file. Otherwise the output +goes to STDOUT. + +## CLI source map options + +Terser can generate a source map file, which is highly useful for +debugging your compressed JavaScript. To get a source map, pass +`--source-map --output output.js` (source map will be written out to +`output.js.map`). + +Additional options: + +- `--source-map "filename=''"` to specify the name of the source map. + +- `--source-map "root=''"` to pass the URL where the original files can be found. + +- `--source-map "url=''"` to specify the URL where the source map can be found. + Otherwise Terser assumes HTTP `X-SourceMap` is being used and will omit the + `//# sourceMappingURL=` directive. + +For example: + + terser js/file1.js js/file2.js \ + -o foo.min.js -c -m \ + --source-map "root='http://foo.com/src',url='foo.min.js.map'" + +The above will compress and mangle `file1.js` and `file2.js`, will drop the +output in `foo.min.js` and the source map in `foo.min.js.map`. The source +mapping will refer to `http://foo.com/src/js/file1.js` and +`http://foo.com/src/js/file2.js` (in fact it will list `http://foo.com/src` +as the source map root, and the original files as `js/file1.js` and +`js/file2.js`). + +### Composed source map + +When you're compressing JS code that was output by a compiler such as +CoffeeScript, mapping to the JS code won't be too helpful. Instead, you'd +like to map back to the original code (i.e. CoffeeScript). Terser has an +option to take an input source map. Assuming you have a mapping from +CoffeeScript → compiled JS, Terser can generate a map from CoffeeScript → +compressed JS by mapping every token in the compiled JS to its original +location. + +To use this feature pass `--source-map "content='/path/to/input/source.map'"` +or `--source-map "content=inline"` if the source map is included inline with +the sources. + +## CLI compress options + +You need to pass `--compress` (`-c`) to enable the compressor. Optionally +you can pass a comma-separated list of [compress options](#compress-options). + +Options are in the form `foo=bar`, or just `foo` (the latter implies +a boolean option that you want to set `true`; it's effectively a +shortcut for `foo=true`). + +Example: + + terser file.js -c toplevel,sequences=false + +## CLI mangle options + +To enable the mangler you need to pass `--mangle` (`-m`). The following +(comma-separated) options are supported: + +- `toplevel` (default `false`) -- mangle names declared in the top level scope. + +- `eval` (default `false`) -- mangle names visible in scopes where `eval` or `with` are used. + +When mangling is enabled but you want to prevent certain names from being +mangled, you can declare those names with `--mangle reserved` — pass a +comma-separated list of names. For example: + + terser ... -m reserved=['$','require','exports'] + +to prevent the `require`, `exports` and `$` names from being changed. + +### CLI mangling property names (`--mangle-props`) + +**Note:** THIS **WILL** BREAK YOUR CODE. A good rule of thumb is not to use this unless you know exactly what you're doing and how this works and read this section until the end. + +Mangling property names is a separate step, different from variable name mangling. Pass +`--mangle-props` to enable it. The least dangerous +way to use this is to use the `regex` option like so: + +``` +terser example.js -c -m --mangle-props regex=/_$/ +``` + +This will mangle all properties that end with an +underscore. So you can use it to mangle internal methods. + +By default, it will mangle all properties in the +input code with the exception of built in DOM properties and properties +in core JavaScript classes, which is what will break your code if you don't: + +1. Control all the code you're mangling +2. Avoid using a module bundler, as they usually will call Terser on each file individually, making it impossible to pass mangled objects between modules. +3. Avoid calling functions like `defineProperty` or `hasOwnProperty`, because they refer to object properties using strings and will break your code if you don't know what you are doing. + +An example: + +```javascript +// example.js +var x = { + baz_: 0, + foo_: 1, + calc: function() { + return this.foo_ + this.baz_; + } +}; +x.bar_ = 2; +x["baz_"] = 3; +console.log(x.calc()); +``` +Mangle all properties (except for JavaScript `builtins`) (**very** unsafe): +```bash +$ terser example.js -c passes=2 -m --mangle-props +``` +```javascript +var x={o:3,t:1,i:function(){return this.t+this.o},s:2};console.log(x.i()); +``` +Mangle all properties except for `reserved` properties (still very unsafe): +```bash +$ terser example.js -c passes=2 -m --mangle-props reserved=[foo_,bar_] +``` +```javascript +var x={o:3,foo_:1,t:function(){return this.foo_+this.o},bar_:2};console.log(x.t()); +``` +Mangle all properties matching a `regex` (not as unsafe but still unsafe): +```bash +$ terser example.js -c passes=2 -m --mangle-props regex=/_$/ +``` +```javascript +var x={o:3,t:1,calc:function(){return this.t+this.o},i:2};console.log(x.calc()); +``` + +Combining mangle properties options: +```bash +$ terser example.js -c passes=2 -m --mangle-props regex=/_$/,reserved=[bar_] +``` +```javascript +var x={o:3,t:1,calc:function(){return this.t+this.o},bar_:2};console.log(x.calc()); +``` + +In order for this to be of any use, we avoid mangling standard JS names and DOM +API properties by default (`--mangle-props builtins` to override). + +A regular expression can be used to define which property names should be +mangled. For example, `--mangle-props regex=/^_/` will only mangle property +names that start with an underscore. + +When you compress multiple files using this option, in order for them to +work together in the end we need to ensure somehow that one property gets +mangled to the same name in all of them. For this, pass `--name-cache filename.json` +and Terser will maintain these mappings in a file which can then be reused. +It should be initially empty. Example: + +```bash +$ rm -f /tmp/cache.json # start fresh +$ terser file1.js file2.js --mangle-props --name-cache /tmp/cache.json -o part1.js +$ terser file3.js file4.js --mangle-props --name-cache /tmp/cache.json -o part2.js +``` + +Now, `part1.js` and `part2.js` will be consistent with each other in terms +of mangled property names. + +Using the name cache is not necessary if you compress all your files in a +single call to Terser. + +### Mangling unquoted names (`--mangle-props keep_quoted`) + +Using quoted property name (`o["foo"]`) reserves the property name (`foo`) +so that it is not mangled throughout the entire script even when used in an +unquoted style (`o.foo`). Example: + +```javascript +// stuff.js +var o = { + "foo": 1, + bar: 3 +}; +o.foo += o.bar; +console.log(o.foo); +``` +```bash +$ terser stuff.js --mangle-props keep_quoted -c -m +``` +```javascript +var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo); +``` + +### Debugging property name mangling + +You can also pass `--mangle-props debug` in order to mangle property names +without completely obscuring them. For example the property `o.foo` +would mangle to `o._$foo$_` with this option. This allows property mangling +of a large codebase while still being able to debug the code and identify +where mangling is breaking things. + +```bash +$ terser stuff.js --mangle-props debug -c -m +``` +```javascript +var o={_$foo$_:1,_$bar$_:3};o._$foo$_+=o._$bar$_,console.log(o._$foo$_); +``` + +You can also pass a custom suffix using `--mangle-props debug=XYZ`. This would then +mangle `o.foo` to `o._$foo$XYZ_`. You can change this each time you compile a +script to identify how a property got mangled. One technique is to pass a +random number on every compile to simulate mangling changing with different +inputs (e.g. as you update the input script with new properties), and to help +identify mistakes like writing mangled keys to storage. + + + +# API Reference + + + +Assuming installation via NPM, you can load Terser in your application +like this: + +```javascript +const { minify } = require("terser"); +``` + +Or, + +```javascript +import { minify } from "terser"; +``` + +Browser loading is also supported. It exposes a global variable `Terser` containing a `.minify` property: +```html + + +``` + +There is an async high level function, **`async minify(code, options)`**, +which will perform all minification [phases](#minify-options) in a configurable +manner. By default `minify()` will enable [`compress`](#compress-options) +and [`mangle`](#mangle-options). Example: +```javascript +var code = "function add(first, second) { return first + second; }"; +var result = await minify(code, { sourceMap: true }); +console.log(result.code); // minified output: function add(n,d){return n+d} +console.log(result.map); // source map +``` + +There is also a `minify_sync()` alternative version of it, which returns instantly. + +You can `minify` more than one JavaScript file at a time by using an object +for the first argument where the keys are file names and the values are source +code: +```javascript +var code = { + "file1.js": "function add(first, second) { return first + second; }", + "file2.js": "console.log(add(1 + 2, 3 + 4));" +}; +var result = await minify(code); +console.log(result.code); +// function add(d,n){return d+n}console.log(add(3,7)); +``` + +The `toplevel` option: +```javascript +var code = { + "file1.js": "function add(first, second) { return first + second; }", + "file2.js": "console.log(add(1 + 2, 3 + 4));" +}; +var options = { toplevel: true }; +var result = await minify(code, options); +console.log(result.code); +// console.log(3+7); +``` + +The `nameCache` option: +```javascript +var options = { + mangle: { + toplevel: true, + }, + nameCache: {} +}; +var result1 = await minify({ + "file1.js": "function add(first, second) { return first + second; }" +}, options); +var result2 = await minify({ + "file2.js": "console.log(add(1 + 2, 3 + 4));" +}, options); +console.log(result1.code); +// function n(n,r){return n+r} +console.log(result2.code); +// console.log(n(3,7)); +``` + +You may persist the name cache to the file system in the following way: +```javascript +var cacheFileName = "/tmp/cache.json"; +var options = { + mangle: { + properties: true, + }, + nameCache: JSON.parse(fs.readFileSync(cacheFileName, "utf8")) +}; +fs.writeFileSync("part1.js", await minify({ + "file1.js": fs.readFileSync("file1.js", "utf8"), + "file2.js": fs.readFileSync("file2.js", "utf8") +}, options).code, "utf8"); +fs.writeFileSync("part2.js", await minify({ + "file3.js": fs.readFileSync("file3.js", "utf8"), + "file4.js": fs.readFileSync("file4.js", "utf8") +}, options).code, "utf8"); +fs.writeFileSync(cacheFileName, JSON.stringify(options.nameCache), "utf8"); +``` + +An example of a combination of `minify()` options: +```javascript +var code = { + "file1.js": "function add(first, second) { return first + second; }", + "file2.js": "console.log(add(1 + 2, 3 + 4));" +}; +var options = { + toplevel: true, + compress: { + global_defs: { + "@console.log": "alert" + }, + passes: 2 + }, + format: { + preamble: "/* minified */" + } +}; +var result = await minify(code, options); +console.log(result.code); +// /* minified */ +// alert(10);" +``` + +An error example: +```javascript +try { + const result = await minify({"foo.js" : "if (0) else console.log(1);"}); + // Do something with result +} catch (error) { + const { message, filename, line, col, pos } = error; + // Do something with error +} +``` + +## Minify options + +- `ecma` (default `undefined`) - pass `5`, `2015`, `2016`, etc to override + `compress` and `format`'s `ecma` options. + +- `enclose` (default `false`) - pass `true`, or a string in the format + of `"args[:values]"`, where `args` and `values` are comma-separated + argument names and values, respectively, to embed the output in a big + function with the configurable arguments and values. + +- `parse` (default `{}`) — pass an object if you wish to specify some + additional [parse options](#parse-options). + +- `compress` (default `{}`) — pass `false` to skip compressing entirely. + Pass an object to specify custom [compress options](#compress-options). + +- `mangle` (default `true`) — pass `false` to skip mangling names, or pass + an object to specify [mangle options](#mangle-options) (see below). + + - `mangle.properties` (default `false`) — a subcategory of the mangle option. + Pass an object to specify custom [mangle property options](#mangle-properties-options). + +- `module` (default `false`) — Use when minifying an ES6 module. "use strict" + is implied and names can be mangled on the top scope. If `compress` or + `mangle` is enabled then the `toplevel` option will be enabled. + +- `format` or `output` (default `null`) — pass an object if you wish to specify + additional [format options](#format-options). The defaults are optimized + for best compression. + +- `sourceMap` (default `false`) - pass an object if you wish to specify + [source map options](#source-map-options). + +- `toplevel` (default `false`) - set to `true` if you wish to enable top level + variable and function name mangling and to drop unused variables and functions. + +- `nameCache` (default `null`) - pass an empty object `{}` or a previously + used `nameCache` object if you wish to cache mangled variable and + property names across multiple invocations of `minify()`. Note: this is + a read/write property. `minify()` will read the name cache state of this + object and update it during minification so that it may be + reused or externally persisted by the user. + +- `ie8` (default `false`) - set to `true` to support IE8. + +- `keep_classnames` (default: `undefined`) - pass `true` to prevent discarding or mangling + of class names. Pass a regular expression to only keep class names matching that regex. + +- `keep_fnames` (default: `false`) - pass `true` to prevent discarding or mangling + of function names. Pass a regular expression to only keep function names matching that regex. + Useful for code relying on `Function.prototype.name`. If the top level minify option + `keep_classnames` is `undefined` it will be overridden with the value of the top level + minify option `keep_fnames`. + +- `safari10` (default: `false`) - pass `true` to work around Safari 10/11 bugs in + loop scoping and `await`. See `safari10` options in [`mangle`](#mangle-options) + and [`format`](#format-options) for details. + +## Minify options structure + +```javascript +{ + parse: { + // parse options + }, + compress: { + // compress options + }, + mangle: { + // mangle options + + properties: { + // mangle property options + } + }, + format: { + // format options (can also use `output` for backwards compatibility) + }, + sourceMap: { + // source map options + }, + ecma: 5, // specify one of: 5, 2015, 2016, etc. + enclose: false, // or specify true, or "args:values" + keep_classnames: false, + keep_fnames: false, + ie8: false, + module: false, + nameCache: null, // or specify a name cache object + safari10: false, + toplevel: false +} +``` + +### Source map options + +To generate a source map: +```javascript +var result = await minify({"file1.js": "var a = function() {};"}, { + sourceMap: { + filename: "out.js", + url: "out.js.map" + } +}); +console.log(result.code); // minified output +console.log(result.map); // source map +``` + +Note that the source map is not saved in a file, it's just returned in +`result.map`. The value passed for `sourceMap.url` is only used to set +`//# sourceMappingURL=out.js.map` in `result.code`. The value of +`filename` is only used to set `file` attribute (see [the spec](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k)) +in source map file. + +You can set option `sourceMap.url` to be `"inline"` and source map will +be appended to code. + +You can also specify sourceRoot property to be included in source map: +```javascript +var result = await minify({"file1.js": "var a = function() {};"}, { + sourceMap: { + root: "http://example.com/src", + url: "out.js.map" + } +}); +``` + +If you're compressing compiled JavaScript and have a source map for it, you +can use `sourceMap.content`: +```javascript +var result = await minify({"compiled.js": "compiled code"}, { + sourceMap: { + content: "content from compiled.js.map", + url: "minified.js.map" + } +}); +// same as before, it returns `code` and `map` +``` + +If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.url`. + +If you happen to need the source map as a raw object, set `sourceMap.asObject` to `true`. + + + + + +## Parse options + +- `bare_returns` (default `false`) -- support top level `return` statements + +- `html5_comments` (default `true`) + +- `shebang` (default `true`) -- support `#!command` as the first line + +- `spidermonkey` (default `false`) -- accept a Spidermonkey (Mozilla) AST + +## Compress options + +- `defaults` (default: `true`) -- Pass `false` to disable most default + enabled `compress` transforms. Useful when you only want to enable a few + `compress` options while disabling the rest. + +- `arrows` (default: `true`) -- Class and object literal methods are converted + will also be converted to arrow expressions if the resultant code is shorter: + `m(){return x}` becomes `m:()=>x`. To do this to regular ES5 functions which + don't use `this` or `arguments`, see `unsafe_arrows`. + +- `arguments` (default: `false`) -- replace `arguments[index]` with function + parameter name whenever possible. + +- `booleans` (default: `true`) -- various optimizations for boolean context, + for example `!!a ? b : c → a ? b : c` + +- `booleans_as_integers` (default: `false`) -- Turn booleans into 0 and 1, also + makes comparisons with booleans use `==` and `!=` instead of `===` and `!==`. + +- `collapse_vars` (default: `true`) -- Collapse single-use non-constant variables, + side effects permitting. + +- `comparisons` (default: `true`) -- apply certain optimizations to binary nodes, + e.g. `!(a <= b) → a > b` (only when `unsafe_comps`), attempts to negate binary + nodes, e.g. `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc. Note: `comparisons` + works best with `lhs_constants` enabled. + +- `computed_props` (default: `true`) -- Transforms constant computed properties + into regular ones: `{["computed"]: 1}` is converted to `{computed: 1}`. + +- `conditionals` (default: `true`) -- apply optimizations for `if`-s and conditional + expressions + +- `dead_code` (default: `true`) -- remove unreachable code + +- `directives` (default: `true`) -- remove redundant or non-standard directives + +- `drop_console` (default: `false`) -- Pass `true` to discard calls to + `console.*` functions. If you only want to discard a portion of console, + you can pass an array like this `['log', 'info']`, which will only discard `console.log`、 `console.info`. + +- `drop_debugger` (default: `true`) -- remove `debugger;` statements + +- `ecma` (default: `5`) -- Pass `2015` or greater to enable `compress` options that + will transform ES5 code into smaller ES6+ equivalent forms. + +- `evaluate` (default: `true`) -- attempt to evaluate constant expressions + +- `expression` (default: `false`) -- Pass `true` to preserve completion values + from terminal statements without `return`, e.g. in bookmarklets. + +- `global_defs` (default: `{}`) -- see [conditional compilation](#conditional-compilation) + +- `hoist_funs` (default: `false`) -- hoist function declarations + +- `hoist_props` (default: `true`) -- hoist properties from constant object and + array literals into regular variables subject to a set of constraints. For example: + `var o={p:1, q:2}; f(o.p, o.q);` is converted to `f(1, 2);`. Note: `hoist_props` + works best with `mangle` enabled, the `compress` option `passes` set to `2` or higher, + and the `compress` option `toplevel` enabled. + +- `hoist_vars` (default: `false`) -- hoist `var` declarations (this is `false` + by default because it seems to increase the size of the output in general) + +- `if_return` (default: `true`) -- optimizations for if/return and if/continue + +- `inline` (default: `true`) -- inline calls to function with simple/`return` statement: + - `false` -- same as `0` + - `0` -- disabled inlining + - `1` -- inline simple functions + - `2` -- inline functions with arguments + - `3` -- inline functions with arguments and variables + - `true` -- same as `3` + +- `join_vars` (default: `true`) -- join consecutive `var`, `let` and `const` statements + +- `keep_classnames` (default: `false`) -- Pass `true` to prevent the compressor from + discarding class names. Pass a regular expression to only keep class names matching + that regex. See also: the `keep_classnames` [mangle option](#mangle-options). + +- `keep_fargs` (default: `true`) -- Prevents the compressor from discarding unused + function arguments. You need this for code which relies on `Function.length`. + +- `keep_fnames` (default: `false`) -- Pass `true` to prevent the + compressor from discarding function names. Pass a regular expression to only keep + function names matching that regex. Useful for code relying on `Function.prototype.name`. + See also: the `keep_fnames` [mangle option](#mangle-options). + +- `keep_infinity` (default: `false`) -- Pass `true` to prevent `Infinity` from + being compressed into `1/0`, which may cause performance issues on Chrome. + +- `lhs_constants` (default: `true`) -- Moves constant values to the left-hand side + of binary nodes. `foo == 42 → 42 == foo` + +- `loops` (default: `true`) -- optimizations for `do`, `while` and `for` loops + when we can statically determine the condition. + +- `module` (default `false`) -- Pass `true` when compressing an ES6 module. Strict + mode is implied and the `toplevel` option as well. + +- `negate_iife` (default: `true`) -- negate "Immediately-Called Function Expressions" + where the return value is discarded, to avoid the parens that the + code generator would insert. + +- `passes` (default: `1`) -- The maximum number of times to run compress. + In some cases more than one pass leads to further compressed code. Keep in + mind more passes will take more time. + +- `properties` (default: `true`) -- rewrite property access using the dot notation, for + example `foo["bar"] → foo.bar` + +- `pure_funcs` (default: `null`) -- You can pass an array of names and + Terser will assume that those functions do not produce side + effects. DANGER: will not check if the name is redefined in scope. + An example case here, for instance `var q = Math.floor(a/b)`. If + variable `q` is not used elsewhere, Terser will drop it, but will + still keep the `Math.floor(a/b)`, not knowing what it does. You can + pass `pure_funcs: [ 'Math.floor' ]` to let it know that this + function won't produce any side effect, in which case the whole + statement would get discarded. The current implementation adds some + overhead (compression will be slower). + +- `pure_getters` (default: `"strict"`) -- If you pass `true` for + this, Terser will assume that object property access + (e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects. + Specify `"strict"` to treat `foo.bar` as side-effect-free only when + `foo` is certain to not throw, i.e. not `null` or `undefined`. + +- `pure_new` (default: `false`) -- Set to `true` to assume `new X()` never has + side effects. + +- `reduce_vars` (default: `true`) -- Improve optimization on variables assigned with and + used as constant values. + +- `reduce_funcs` (default: `true`) -- Inline single-use functions when + possible. Depends on `reduce_vars` being enabled. Disabling this option + sometimes improves performance of the output code. + +- `sequences` (default: `true`) -- join consecutive simple statements using the + comma operator. May be set to a positive integer to specify the maximum number + of consecutive comma sequences that will be generated. If this option is set to + `true` then the default `sequences` limit is `200`. Set option to `false` or `0` + to disable. The smallest `sequences` length is `2`. A `sequences` value of `1` + is grandfathered to be equivalent to `true` and as such means `200`. On rare + occasions the default sequences limit leads to very slow compress times in which + case a value of `20` or less is recommended. + +- `side_effects` (default: `true`) -- Remove expressions which have no side effects + and whose results aren't used. + +- `switches` (default: `true`) -- de-duplicate and remove unreachable `switch` branches + +- `toplevel` (default: `false`) -- drop unreferenced functions (`"funcs"`) and/or + variables (`"vars"`) in the top level scope (`false` by default, `true` to drop + both unreferenced functions and variables) + +- `top_retain` (default: `null`) -- prevent specific toplevel functions and + variables from `unused` removal (can be array, comma-separated, RegExp or + function. Implies `toplevel`) + +- `typeofs` (default: `true`) -- Transforms `typeof foo == "undefined"` into + `foo === void 0`. Note: recommend to set this value to `false` for IE10 and + earlier versions due to known issues. + +- `unsafe` (default: `false`) -- apply "unsafe" transformations + ([details](#the-unsafe-compress-option)). + +- `unsafe_arrows` (default: `false`) -- Convert ES5 style anonymous function + expressions to arrow functions if the function body does not reference `this`. + Note: it is not always safe to perform this conversion if code relies on the + the function having a `prototype`, which arrow functions lack. + This transform requires that the `ecma` compress option is set to `2015` or greater. + +- `unsafe_comps` (default: `false`) -- Reverse `<` and `<=` to `>` and `>=` to + allow improved compression. This might be unsafe when an at least one of two + operands is an object with computed values due the use of methods like `get`, + or `valueOf`. This could cause change in execution order after operands in the + comparison are switching. Or if one of two operands is `NaN`, the result is always + `false`. Compression only works if both `comparisons` and + `unsafe_comps` are both set to true. + +- `unsafe_Function` (default: `false`) -- compress and mangle `Function(args, code)` + when both `args` and `code` are string literals. + +- `unsafe_math` (default: `false`) -- optimize numerical expressions like + `2 * x * 3` into `6 * x`, which may give imprecise floating point results. + +- `unsafe_symbols` (default: `false`) -- removes keys from native Symbol + declarations, e.g `Symbol("kDog")` becomes `Symbol()`. + +- `unsafe_methods` (default: false) -- Converts `{ m: function(){} }` to + `{ m(){} }`. `ecma` must be set to `6` or greater to enable this transform. + If `unsafe_methods` is a RegExp then key/value pairs with keys matching the + RegExp will be converted to concise methods. + Note: if enabled there is a risk of getting a "`` is not a + constructor" TypeError should any code try to `new` the former function. + +- `unsafe_proto` (default: `false`) -- optimize expressions like + `Array.prototype.slice.call(a)` into `[].slice.call(a)` + +- `unsafe_regexp` (default: `false`) -- enable substitutions of variables with + `RegExp` values the same way as if they are constants. + +- `unsafe_undefined` (default: `false`) -- substitute `void 0` if there is a + variable named `undefined` in scope (variable name will be mangled, typically + reduced to a single character) + +- `unused` (default: `true`) -- drop unreferenced functions and variables (simple + direct variable assignments do not count as references unless set to `"keep_assign"`) + +## Mangle options + +- `eval` (default `false`) -- Pass `true` to mangle names visible in scopes + where `eval` or `with` are used. + +- `keep_classnames` (default `false`) -- Pass `true` to not mangle class names. + Pass a regular expression to only keep class names matching that regex. + See also: the `keep_classnames` [compress option](#compress-options). + +- `keep_fnames` (default `false`) -- Pass `true` to not mangle function names. + Pass a regular expression to only keep function names matching that regex. + Useful for code relying on `Function.prototype.name`. See also: the `keep_fnames` + [compress option](#compress-options). + +- `module` (default `false`) -- Pass `true` an ES6 modules, where the toplevel + scope is not the global scope. Implies `toplevel` and assumes input code is strict mode JS. + +- `nth_identifier` (default: an internal mangler that weights based on character + frequency analysis) -- Pass an object with a `get(n)` function that converts an + ordinal into the nth most favored (usually shortest) identifier. + Optionally also provide `reset()`, `sort()`, and `consider(chars, delta)` to + use character frequency analysis of the source code. + +- `reserved` (default `[]`) -- Pass an array of identifiers that should be + excluded from mangling. Example: `["foo", "bar"]`. + +- `toplevel` (default `false`) -- Pass `true` to mangle names declared in the + top level scope. + +- `safari10` (default `false`) -- Pass `true` to work around the Safari 10 loop + iterator [bug](https://bugs.webkit.org/show_bug.cgi?id=171041) + "Cannot declare a let variable twice". + See also: the `safari10` [format option](#format-options). + +Examples: + +```javascript +// test.js +var globalVar; +function funcName(firstLongName, anotherLongName) { + var myVariable = firstLongName + anotherLongName; +} +``` +```javascript +var code = fs.readFileSync("test.js", "utf8"); + +await minify(code).code; +// 'function funcName(a,n){}var globalVar;' + +await minify(code, { mangle: { reserved: ['firstLongName'] } }).code; +// 'function funcName(firstLongName,a){}var globalVar;' + +await minify(code, { mangle: { toplevel: true } }).code; +// 'function n(n,a){}var a;' +``` + +### Mangle properties options + +- `builtins` (default: `false`) — Use `true` to allow the mangling of builtin + DOM properties. Not recommended to override this setting. + +- `debug` (default: `false`) — Mangle names with the original name still present. + Pass an empty string `""` to enable, or a non-empty string to set the debug suffix. + +- `keep_quoted` (default: `false`) — How quoting properties (`{"prop": ...}` and `obj["prop"]`) controls what gets mangled. + - `"strict"` (recommended) -- `obj.prop` is mangled. + - `false` -- `obj["prop"]` is mangled. + - `true` -- `obj.prop` is mangled unless there is `obj["prop"]` elsewhere in the code. + +- `nth_identifier` (default: an internal mangler that weights based on character + frequency analysis) -- Pass an object with a `get(n)` function that converts an + ordinal into the nth most favored (usually shortest) identifier. + Optionally also provide `reset()`, `sort()`, and `consider(chars, delta)` to + use character frequency analysis of the source code. + +- `regex` (default: `null`) — Pass a [RegExp literal or pattern string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) to only mangle property matching the regular expression. + +- `reserved` (default: `[]`) — Do not mangle property names listed in the + `reserved` array. + +- `undeclared` (default: `false`) - Mangle those names when they are accessed + as properties of known top level variables but their declarations are never + found in input code. May be useful when only minifying parts of a project. + See [#397](https://github.com/terser/terser/issues/397) for more details. + + +## Format options + +These options control the format of Terser's output code. Previously known +as "output options". + +- `ascii_only` (default `false`) -- escape Unicode characters in strings and + regexps (affects directives with non-ascii characters becoming invalid) + +- `beautify` (default `false`) -- (DEPRECATED) whether to beautify the output. + When using the legacy `-b` CLI flag, this is set to true by default. + +- `braces` (default `false`) -- always insert braces in `if`, `for`, + `do`, `while` or `with` statements, even if their body is a single + statement. + +- `comments` (default `"some"`) -- by default it keeps JSDoc-style comments + that contain "@license", "@copyright", "@preserve" or start with `!`, pass `true` + or `"all"` to preserve all comments, `false` to omit comments in the output, + a regular expression string (e.g. `/^!/`) or a function. + +- `ecma` (default `5`) -- set desired EcmaScript standard version for output. + Set `ecma` to `2015` or greater to emit shorthand object properties - i.e.: + `{a}` instead of `{a: a}`. The `ecma` option will only change the output in + direct control of the beautifier. Non-compatible features in your input will + still be output as is. For example: an `ecma` setting of `5` will **not** + convert modern code to ES5. + +- `indent_level` (default `4`) + +- `indent_start` (default `0`) -- prefix all lines by that many spaces + +- `inline_script` (default `true`) -- escape HTML comments and the slash in + occurrences of `` in strings + +- `keep_numbers` (default `false`) -- keep number literals as it was in original code + (disables optimizations like converting `1000000` into `1e6`) + +- `keep_quoted_props` (default `false`) -- when turned on, prevents stripping + quotes from property names in object literals. + +- `max_line_len` (default `false`) -- maximum line length (for minified code) + +- `preamble` (default `null`) -- when passed it must be a string and + it will be prepended to the output literally. The source map will + adjust for this text. Can be used to insert a comment containing + licensing information, for example. + +- `quote_keys` (default `false`) -- pass `true` to quote all keys in literal + objects + +- `quote_style` (default `0`) -- preferred quote style for strings (affects + quoted property names and directives as well): + - `0` -- prefers double quotes, switches to single quotes when there are + more double quotes in the string itself. `0` is best for gzip size. + - `1` -- always use single quotes + - `2` -- always use double quotes + - `3` -- always use the original quotes + +- `preserve_annotations` -- (default `false`) -- Preserve [Terser annotations](#annotations) in the output. + +- `safari10` (default `false`) -- set this option to `true` to work around + the [Safari 10/11 await bug](https://bugs.webkit.org/show_bug.cgi?id=176685). + See also: the `safari10` [mangle option](#mangle-options). + +- `semicolons` (default `true`) -- separate statements with semicolons. If + you pass `false` then whenever possible we will use a newline instead of a + semicolon, leading to more readable output of minified code (size before + gzip could be smaller; size after gzip insignificantly larger). + +- `shebang` (default `true`) -- preserve shebang `#!` in preamble (bash scripts) + +- `spidermonkey` (default `false`) -- produce a Spidermonkey (Mozilla) AST + +- `webkit` (default `false`) -- enable workarounds for WebKit bugs. + PhantomJS users should set this option to `true`. + +- `wrap_iife` (default `false`) -- pass `true` to wrap immediately invoked + function expressions. See + [#640](https://github.com/mishoo/UglifyJS2/issues/640) for more details. + +- `wrap_func_args` (default `false`) -- pass `true` in order to wrap + function expressions that are passed as arguments, in parenthesis. See + [OptimizeJS](https://github.com/nolanlawson/optimize-js) for more details. + + + + + +# Miscellaneous + + + +### Keeping copyright notices or other comments + +You can pass `--comments` to retain certain comments in the output. By +default it will keep comments starting with "!" and JSDoc-style comments that +contain "@preserve", "@copyright", "@license" or "@cc_on" (conditional compilation for IE). +You can pass `--comments all` to keep all the comments, or a valid JavaScript regexp to +keep only comments that match this regexp. For example `--comments /^!/` +will keep comments like `/*! Copyright Notice */`. + +Note, however, that there might be situations where comments are lost. For +example: +```javascript +function f() { + /** @preserve Foo Bar */ + function g() { + // this function is never called + } + return something(); +} +``` + +Even though it has "@preserve", the comment will be lost because the inner +function `g` (which is the AST node to which the comment is attached to) is +discarded by the compressor as not referenced. + +The safest comments where to place copyright information (or other info that +needs to be kept in the output) are comments attached to toplevel nodes. + +### The `unsafe` `compress` option + +It enables some transformations that *might* break code logic in certain +contrived cases, but should be fine for most code. It assumes that standard +built-in ECMAScript functions and classes have not been altered or replaced. +You might want to try it on your own code; it should reduce the minified size. +Some examples of the optimizations made when this option is enabled: + +- `new Array(1, 2, 3)` or `Array(1, 2, 3)` → `[ 1, 2, 3 ]` +- `Array.from([1, 2, 3])` → `[1, 2, 3]` +- `new Object()` → `{}` +- `String(exp)` or `exp.toString()` → `"" + exp` +- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new` +- `"foo bar".substr(4)` → `"bar"` + +### Conditional compilation + +You can use the `--define` (`-d`) switch in order to declare global +variables that Terser will assume to be constants (unless defined in +scope). For example if you pass `--define DEBUG=false` then, coupled with +dead code removal Terser will discard the following from the output: +```javascript +if (DEBUG) { + console.log("debug stuff"); +} +``` + +You can specify nested constants in the form of `--define env.DEBUG=false`. + +Another way of doing that is to declare your globals as constants in a +separate file and include it into the build. For example you can have a +`build/defines.js` file with the following: +```javascript +var DEBUG = false; +var PRODUCTION = true; +// etc. +``` + +and build your code like this: + + terser build/defines.js js/foo.js js/bar.js... -c + +Terser will notice the constants and, since they cannot be altered, it +will evaluate references to them to the value itself and drop unreachable +code as usual. The build will contain the `const` declarations if you use +them. If you are targeting < ES6 environments which does not support `const`, +using `var` with `reduce_vars` (enabled by default) should suffice. + +### Conditional compilation API + +You can also use conditional compilation via the programmatic API. With the difference that the +property name is `global_defs` and is a compressor property: + +```javascript +var result = await minify(fs.readFileSync("input.js", "utf8"), { + compress: { + dead_code: true, + global_defs: { + DEBUG: false + } + } +}); +``` + +To replace an identifier with an arbitrary non-constant expression it is +necessary to prefix the `global_defs` key with `"@"` to instruct Terser +to parse the value as an expression: +```javascript +await minify("alert('hello');", { + compress: { + global_defs: { + "@alert": "console.log" + } + } +}).code; +// returns: 'console.log("hello");' +``` + +Otherwise it would be replaced as string literal: +```javascript +await minify("alert('hello');", { + compress: { + global_defs: { + "alert": "console.log" + } + } +}).code; +// returns: '"console.log"("hello");' +``` + +### Annotations + +Annotations in Terser are a way to tell it to treat a certain function call differently. The following annotations are available: + + * `/*@__INLINE__*/` - forces a function to be inlined somewhere. + * `/*@__NOINLINE__*/` - Makes sure the called function is not inlined into the call site. + * `/*@__PURE__*/` - Marks a function call as pure. That means, it can safely be dropped. + * `/*@__KEY__*/` - Marks a string literal as a property to also mangle it when mangling properties. + * `/*@__MANGLE_PROP__*/` - Opts-in an object property (or class field) for mangling, when the property mangler is enabled. + +You can use either a `@` sign at the start, or a `#`. + +Here are some examples on how to use them: + +```javascript +/*@__INLINE__*/ +function_always_inlined_here() + +/*#__NOINLINE__*/ +function_cant_be_inlined_into_here() + +const x = /*#__PURE__*/i_am_dropped_if_x_is_not_used() + +function lookup(object, key) { return object[key]; } +lookup({ i_will_be_mangled_too: "bar" }, /*@__KEY__*/ "i_will_be_mangled_too"); +``` + +### ESTree / SpiderMonkey AST + +Terser has its own abstract syntax tree format; for +[practical reasons](http://lisperator.net/blog/uglifyjs-why-not-switching-to-spidermonkey-ast/) +we can't easily change to using the SpiderMonkey AST internally. However, +Terser now has a converter which can import a SpiderMonkey AST. + +For example [Acorn](https://github.com/acornjs/acorn) is a super-fast parser that produces a +SpiderMonkey AST. It has a small CLI utility that parses one file and dumps +the AST in JSON on the standard output. To use Terser to mangle and +compress that: + + acorn file.js | terser -p spidermonkey -m -c + +The `-p spidermonkey` option tells Terser that all input files are not +JavaScript, but JS code described in SpiderMonkey AST in JSON. Therefore we +don't use our own parser in this case, but just transform that AST into our +internal AST. + +`spidermonkey` is also available in `minify` as `parse` and `format` options to +accept and/or produce a spidermonkey AST. + +### Use Acorn for parsing + +More for fun, I added the `-p acorn` option which will use Acorn to do all +the parsing. If you pass this option, Terser will `require("acorn")`. + +Acorn is really fast (e.g. 250ms instead of 380ms on some 650K code), but +converting the SpiderMonkey tree that Acorn produces takes another 150ms so +in total it's a bit more than just using Terser's own parser. + +### Terser Fast Minify Mode + +It's not well known, but whitespace removal and symbol mangling accounts +for 95% of the size reduction in minified code for most JavaScript - not +elaborate code transforms. One can simply disable `compress` to speed up +Terser builds by 3 to 4 times. + +| d3.js | size | gzip size | time (s) | +| --- | ---: | ---: | ---: | +| original | 451,131 | 108,733 | - | +| terser@3.7.5 mangle=false, compress=false | 316,600 | 85,245 | 0.82 | +| terser@3.7.5 mangle=true, compress=false | 220,216 | 72,730 | 1.45 | +| terser@3.7.5 mangle=true, compress=true | 212,046 | 70,954 | 5.87 | +| babili@0.1.4 | 210,713 | 72,140 | 12.64 | +| babel-minify@0.4.3 | 210,321 | 72,242 | 48.67 | +| babel-minify@0.5.0-alpha.01eac1c3 | 210,421 | 72,238 | 14.17 | + +To enable fast minify mode from the CLI use: +``` +terser file.js -m +``` +To enable fast minify mode with the API use: +```js +await minify(code, { compress: false, mangle: true }); +``` + +#### Source maps and debugging + +Various `compress` transforms that simplify, rearrange, inline and remove code +are known to have an adverse effect on debugging with source maps. This is +expected as code is optimized and mappings are often simply not possible as +some code no longer exists. For highest fidelity in source map debugging +disable the `compress` option and just use `mangle`. + +When debugging, make sure you enable the **"map scopes"** feature to map mangled variable names back to their original names. +Without this, all variable values will be `undefined`. See https://github.com/terser/terser/issues/1367 for more details. +

+ +![image](https://user-images.githubusercontent.com/27283110/230441652-ac5cf6b0-5dc5-4ffc-9d8b-bd02875484f4.png) + +### Compiler assumptions + +To allow for better optimizations, the compiler makes various assumptions: + +- `.toString()` and `.valueOf()` don't have side effects, and for built-in + objects they have not been overridden. +- `undefined`, `NaN` and `Infinity` have not been externally redefined. +- `arguments.callee`, `arguments.caller` and `Function.prototype.caller` are not used. +- The code doesn't expect the contents of `Function.prototype.toString()` or + `Error.prototype.stack` to be anything in particular. +- Getting and setting properties on a plain object does not cause other side effects + (using `.watch()` or `Proxy`). +- Object properties can be added, removed and modified (not prevented with + `Object.defineProperty()`, `Object.defineProperties()`, `Object.freeze()`, + `Object.preventExtensions()` or `Object.seal()`). +- `document.all` is not `== null` +- Assigning properties to a class doesn't have side effects and does not throw. + +### Build Tools and Adaptors using Terser + +https://www.npmjs.com/browse/depended/terser + +### Replacing `uglify-es` with `terser` in a project using `yarn` + +A number of JS bundlers and uglify wrappers are still using buggy versions +of `uglify-es` and have not yet upgraded to `terser`. If you are using `yarn` +you can add the following alias to your project's `package.json` file: + +```js + "resolutions": { + "uglify-es": "npm:terser" + } +``` + +to use `terser` instead of `uglify-es` in all deeply nested dependencies +without changing any code. + +Note: for this change to take effect you must run the following commands +to remove the existing `yarn` lock file and reinstall all packages: + +``` +$ rm -rf node_modules yarn.lock +$ yarn +``` + + + +# Reporting issues + + + +## A minimal, reproducible example + +You're expected to provide a [minimal reproducible example] of input code that will demonstrate your issue. + +To get to this example, you can remove bits of your code and stop if your issue ceases to reproduce. + +## Obtaining the source code given to Terser + +Because users often don't control the call to `await minify()` or its arguments, Terser provides a `TERSER_DEBUG_DIR` environment variable to make terser output some debug logs. + +These logs will contain the input code and options of each `minify()` call. + +```bash +TERSER_DEBUG_DIR=/tmp/terser-log-dir command-that-uses-terser +ls /tmp/terser-log-dir +terser-debug-123456.log +``` + +If you're not sure how to set an environment variable on your shell (the above example works in bash), you can try using cross-env: + +``` +> npx cross-env TERSER_DEBUG_DIR=/path/to/logs command-that-uses-terser +``` + +## Stack traces + +In the terser CLI we use [source-map-support](https://npmjs.com/source-map-support) to produce good error stacks. In your own app, you're expected to enable source-map-support (read their docs) to have nice stack traces that will help you write good issues. + + + +# README.md Patrons: + +*note*: You can support this project on patreon: [link] **The Terser Patreon is shutting down in favor of opencollective**. Check out [PATRONS.md](https://github.com/terser/terser/blob/master/PATRONS.md) for our first-tier patrons. + +These are the second-tier patrons. Great thanks for your support! + + * CKEditor ![](https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/15452278/f8548dcf48d740619071e8d614459280/1?token-time=2145916800&token-hash=SIQ54PhIPHv3M7CVz9LxS8_8v4sOw4H304HaXsXj8MM%3D) + * 38elements ![](https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/12501844/88e7fc5dd62d45c6a5626533bbd48cfb/1?token-time=2145916800&token-hash=c3AsQ5T0IQWic0zKxFHu-bGGQJkXQFvafvJ4bPerFR4%3D) + +## Contributors + +### Code Contributors + +This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. + + +### Financial Contributors + +Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/terser/contribute)] + +#### Individuals + + + +#### Organizations + +Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/terser/contribute)] + + + + + + + + + + + diff --git a/node_modules/terser/bin/package.json b/node_modules/terser/bin/package.json new file mode 100644 index 0000000..d937a6f --- /dev/null +++ b/node_modules/terser/bin/package.json @@ -0,0 +1,10 @@ +{ + "name": "bin", + "private": true, + "version": "1.0.0", + "main": "terser", + "type": "commonjs", + "author": "", + "license": "BSD-2-Clause", + "description": "A package to hold the Terser bin bundle as commonjs while keeping the rest of it ESM." +} diff --git a/node_modules/terser/bin/terser b/node_modules/terser/bin/terser new file mode 100755 index 0000000..b0cdc7c --- /dev/null +++ b/node_modules/terser/bin/terser @@ -0,0 +1,21 @@ +#!/usr/bin/env node + +"use strict"; + +require("../tools/exit.cjs"); + +try { + require("source-map-support").install(); +} catch (err) {} + +const fs = require("fs"); +const path = require("path"); +const program = require("commander"); + +const packageJson = require("../package.json"); +const { _run_cli: run_cli } = require(".."); + +run_cli({ program, packageJson, fs, path }).catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/node_modules/terser/bin/uglifyjs b/node_modules/terser/bin/uglifyjs new file mode 100755 index 0000000..f193025 --- /dev/null +++ b/node_modules/terser/bin/uglifyjs @@ -0,0 +1,10 @@ +#!/usr/bin/env node +// -*- js -*- +/* eslint-env node */ + +"use strict"; + +process.stderr.write( "DEPRECATION WARNING: uglifyjs binary will soon be discontinued!\n"); +process.stderr.write("Please use \"terser\" instead.\n\n"); + +require("./terser"); diff --git a/node_modules/terser/dist/.gitkeep b/node_modules/terser/dist/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/node_modules/terser/dist/bundle.min.js b/node_modules/terser/dist/bundle.min.js new file mode 100644 index 0000000..96579c7 --- /dev/null +++ b/node_modules/terser/dist/bundle.min.js @@ -0,0 +1,33578 @@ +(function (global, factory) { +typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@jridgewell/source-map')) : +typeof define === 'function' && define.amd ? define(['exports', '@jridgewell/source-map'], factory) : +(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Terser = {}, global.sourceMap)); +})(this, (function (exports, sourceMap) { 'use strict'; + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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 characters(str) { + return str.split(""); +} + +function member(name, array) { + return array.includes(name); +} + +class DefaultsError extends Error { + constructor(msg, defs) { + super(); + + this.name = "DefaultsError"; + this.message = msg; + this.defs = defs; + } +} + +function defaults(args, defs, croak) { + if (args === true) { + args = {}; + } else if (args != null && typeof args === "object") { + args = {...args}; + } + + const ret = args || {}; + + if (croak) for (const i in ret) if (HOP(ret, i) && !HOP(defs, i)) { + throw new DefaultsError("`" + i + "` is not a supported option", defs); + } + + for (const i in defs) if (HOP(defs, i)) { + if (!args || !HOP(args, i)) { + ret[i] = defs[i]; + } else if (i === "ecma") { + let ecma = args[i] | 0; + if (ecma > 5 && ecma < 2015) ecma += 2009; + ret[i] = ecma; + } else { + ret[i] = (args && HOP(args, i)) ? args[i] : defs[i]; + } + } + + return ret; +} + +function noop() {} +function return_false() { return false; } +function return_true() { return true; } +function return_this() { return this; } +function return_null() { return null; } + +var MAP = (function() { + function MAP(a, tw, allow_splicing = true) { + const new_a = []; + + for (let i = 0; i < a.length; ++i) { + let item = a[i]; + let ret = item.transform(tw, allow_splicing); + + if (ret instanceof AST_Node) { + new_a.push(ret); + } else if (ret instanceof Splice) { + new_a.push(...ret.v); + } + } + + return new_a; + } + + MAP.splice = function(val) { return new Splice(val); }; + MAP.skip = {}; + function Splice(val) { this.v = val; } + return MAP; +})(); + +function make_node(ctor, orig, props) { + if (!props) props = {}; + if (orig) { + if (!props.start) props.start = orig.start; + if (!props.end) props.end = orig.end; + } + return new ctor(props); +} + +function push_uniq(array, el) { + if (!array.includes(el)) + array.push(el); +} + +function string_template(text, props) { + return text.replace(/{(.+?)}/g, function(str, p) { + return props && props[p]; + }); +} + +function remove(array, el) { + for (var i = array.length; --i >= 0;) { + if (array[i] === el) array.splice(i, 1); + } +} + +function mergeSort(array, cmp) { + if (array.length < 2) return array.slice(); + function merge(a, b) { + var r = [], ai = 0, bi = 0, i = 0; + while (ai < a.length && bi < b.length) { + cmp(a[ai], b[bi]) <= 0 + ? r[i++] = a[ai++] + : r[i++] = b[bi++]; + } + if (ai < a.length) r.push.apply(r, a.slice(ai)); + if (bi < b.length) r.push.apply(r, b.slice(bi)); + return r; + } + function _ms(a) { + if (a.length <= 1) + return a; + var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m); + left = _ms(left); + right = _ms(right); + return merge(left, right); + } + return _ms(array); +} + +function makePredicate(words) { + if (!Array.isArray(words)) words = words.split(" "); + + return new Set(words.sort()); +} + +function map_add(map, key, value) { + if (map.has(key)) { + map.get(key).push(value); + } else { + map.set(key, [ value ]); + } +} + +function map_from_object(obj) { + var map = new Map(); + for (var key in obj) { + if (HOP(obj, key) && key.charAt(0) === "$") { + map.set(key.substr(1), obj[key]); + } + } + return map; +} + +function map_to_object(map) { + var obj = Object.create(null); + map.forEach(function (value, key) { + obj["$" + key] = value; + }); + return obj; +} + +function HOP(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +function keep_name(keep_setting, name) { + return keep_setting === true + || (keep_setting instanceof RegExp && keep_setting.test(name)); +} + +var lineTerminatorEscape = { + "\0": "0", + "\n": "n", + "\r": "r", + "\u2028": "u2028", + "\u2029": "u2029", +}; +function regexp_source_fix(source) { + // V8 does not escape line terminators in regexp patterns in node 12 + // We'll also remove literal \0 + return source.replace(/[\0\n\r\u2028\u2029]/g, function (match, offset) { + var escaped = source[offset - 1] == "\\" + && (source[offset - 2] != "\\" + || /(?:^|[^\\])(?:\\{2})*$/.test(source.slice(0, offset - 1))); + return (escaped ? "" : "\\") + lineTerminatorEscape[match]; + }); +} + +// Subset of regexps that is not going to cause regexp based DDOS +// https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS +const re_safe_regexp = /^[\\/|\0\s\w^$.[\]()]*$/; + +/** Check if the regexp is safe for Terser to create without risking a RegExp DOS */ +const regexp_is_safe = (source) => re_safe_regexp.test(source); + +const all_flags = "dgimsuyv"; +function sort_regexp_flags(flags) { + const existing_flags = new Set(flags.split("")); + let out = ""; + for (const flag of all_flags) { + if (existing_flags.has(flag)) { + out += flag; + existing_flags.delete(flag); + } + } + if (existing_flags.size) { + // Flags Terser doesn't know about + existing_flags.forEach(flag => { out += flag; }); + } + return out; +} + +function has_annotation(node, annotation) { + return node._annotations & annotation; +} + +function set_annotation(node, annotation) { + node._annotations |= annotation; +} + +function clear_annotation(node, annotation) { + node._annotations &= ~annotation; +} + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + Parser based on parse-js (http://marijn.haverbeke.nl/parse-js/). + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +var LATEST_RAW = ""; // Only used for numbers and template strings +var TEMPLATE_RAWS = new Map(); // Raw template strings + +var KEYWORDS = "break case catch class const continue debugger default delete do else export extends finally for function if in instanceof let new return switch throw try typeof var void while with"; +var KEYWORDS_ATOM = "false null true"; +var RESERVED_WORDS = "enum import super this " + KEYWORDS_ATOM + " " + KEYWORDS; +var ALL_RESERVED_WORDS = "implements interface package private protected public static " + RESERVED_WORDS; +var KEYWORDS_BEFORE_EXPRESSION = "return new delete throw else case yield await"; + +KEYWORDS = makePredicate(KEYWORDS); +RESERVED_WORDS = makePredicate(RESERVED_WORDS); +KEYWORDS_BEFORE_EXPRESSION = makePredicate(KEYWORDS_BEFORE_EXPRESSION); +KEYWORDS_ATOM = makePredicate(KEYWORDS_ATOM); +ALL_RESERVED_WORDS = makePredicate(ALL_RESERVED_WORDS); + +var OPERATOR_CHARS = makePredicate(characters("+-*&%=<>!?|~^")); + +var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i; +var RE_OCT_NUMBER = /^0[0-7]+$/; +var RE_ES6_OCT_NUMBER = /^0o[0-7]+$/i; +var RE_BIN_NUMBER = /^0b[01]+$/i; +var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i; +var RE_BIG_INT = /^(0[xob])?[0-9a-f]+n$/i; + +var RE_KEYWORD_RELATIONAL_OPERATORS = /in(?:stanceof)?/y; + +var OPERATORS = makePredicate([ + "in", + "instanceof", + "typeof", + "new", + "void", + "delete", + "++", + "--", + "+", + "-", + "!", + "~", + "&", + "|", + "^", + "*", + "**", + "/", + "%", + ">>", + "<<", + ">>>", + "<", + ">", + "<=", + ">=", + "==", + "===", + "!=", + "!==", + "?", + "=", + "+=", + "-=", + "||=", + "&&=", + "??=", + "/=", + "*=", + "**=", + "%=", + ">>=", + "<<=", + ">>>=", + "|=", + "^=", + "&=", + "&&", + "??", + "||", +]); + +var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000\uFEFF")); + +var NEWLINE_CHARS = makePredicate(characters("\n\r\u2028\u2029")); + +var PUNC_AFTER_EXPRESSION = makePredicate(characters(";]),:")); + +var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,;:")); + +var PUNC_CHARS = makePredicate(characters("[]{}(),;:")); + +/* -----[ Tokenizer ]----- */ + +// surrogate safe regexps adapted from https://github.com/mathiasbynens/unicode-8.0.0/tree/89b412d8a71ecca9ed593d9e9fa073ab64acfebe/Binary_Property +var UNICODE = { + ID_Start: /[$A-Z_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]/, + ID_Continue: /(?:[$0-9A-Z_a-z\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B4\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF])+/, +}; + +function get_full_char(str, pos) { + if (is_surrogate_pair_head(str.charCodeAt(pos))) { + if (is_surrogate_pair_tail(str.charCodeAt(pos + 1))) { + return str.charAt(pos) + str.charAt(pos + 1); + } + } else if (is_surrogate_pair_tail(str.charCodeAt(pos))) { + if (is_surrogate_pair_head(str.charCodeAt(pos - 1))) { + return str.charAt(pos - 1) + str.charAt(pos); + } + } + return str.charAt(pos); +} + +function get_full_char_code(str, pos) { + // https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates + if (is_surrogate_pair_head(str.charCodeAt(pos))) { + return 0x10000 + (str.charCodeAt(pos) - 0xd800 << 10) + str.charCodeAt(pos + 1) - 0xdc00; + } + return str.charCodeAt(pos); +} + +function get_full_char_length(str) { + var surrogates = 0; + + for (var i = 0; i < str.length; i++) { + if (is_surrogate_pair_head(str.charCodeAt(i)) && is_surrogate_pair_tail(str.charCodeAt(i + 1))) { + surrogates++; + i++; + } + } + + return str.length - surrogates; +} + +function from_char_code(code) { + // Based on https://github.com/mathiasbynens/String.fromCodePoint/blob/master/fromcodepoint.js + if (code > 0xFFFF) { + code -= 0x10000; + return (String.fromCharCode((code >> 10) + 0xD800) + + String.fromCharCode((code % 0x400) + 0xDC00)); + } + return String.fromCharCode(code); +} + +function is_surrogate_pair_head(code) { + return code >= 0xd800 && code <= 0xdbff; +} + +function is_surrogate_pair_tail(code) { + return code >= 0xdc00 && code <= 0xdfff; +} + +function is_digit(code) { + return code >= 48 && code <= 57; +} + +function is_identifier_start(ch) { + return UNICODE.ID_Start.test(ch); +} + +function is_identifier_char(ch) { + return UNICODE.ID_Continue.test(ch); +} + +const BASIC_IDENT = /^[a-z_$][a-z0-9_$]*$/i; + +function is_basic_identifier_string(str) { + return BASIC_IDENT.test(str); +} + +function is_identifier_string(str, allow_surrogates) { + if (BASIC_IDENT.test(str)) { + return true; + } + if (!allow_surrogates && /[\ud800-\udfff]/.test(str)) { + return false; + } + var match = UNICODE.ID_Start.exec(str); + if (!match || match.index !== 0) { + return false; + } + + str = str.slice(match[0].length); + if (!str) { + return true; + } + + match = UNICODE.ID_Continue.exec(str); + return !!match && match[0].length === str.length; +} + +function parse_js_number(num, allow_e = true) { + if (!allow_e && num.includes("e")) { + return NaN; + } + if (RE_HEX_NUMBER.test(num)) { + return parseInt(num.substr(2), 16); + } else if (RE_OCT_NUMBER.test(num)) { + return parseInt(num.substr(1), 8); + } else if (RE_ES6_OCT_NUMBER.test(num)) { + return parseInt(num.substr(2), 8); + } else if (RE_BIN_NUMBER.test(num)) { + return parseInt(num.substr(2), 2); + } else if (RE_DEC_NUMBER.test(num)) { + return parseFloat(num); + } else { + var val = parseFloat(num); + if (val == num) return val; + } +} + +class JS_Parse_Error extends Error { + constructor(message, filename, line, col, pos) { + super(); + + this.name = "SyntaxError"; + this.message = message; + this.filename = filename; + this.line = line; + this.col = col; + this.pos = pos; + } +} + +function js_error(message, filename, line, col, pos) { + throw new JS_Parse_Error(message, filename, line, col, pos); +} + +function is_token(token, type, val) { + return token.type == type && (val == null || token.value == val); +} + +var EX_EOF = {}; + +function tokenizer($TEXT, filename, html5_comments, shebang) { + var S = { + text : $TEXT, + filename : filename, + pos : 0, + tokpos : 0, + line : 1, + tokline : 0, + col : 0, + tokcol : 0, + newline_before : false, + regex_allowed : false, + brace_counter : 0, + template_braces : [], + comments_before : [], + directives : {}, + directive_stack : [] + }; + + function peek() { return get_full_char(S.text, S.pos); } + + // Used because parsing ?. involves a lookahead for a digit + function is_option_chain_op() { + const must_be_dot = S.text.charCodeAt(S.pos + 1) === 46; + if (!must_be_dot) return false; + + const cannot_be_digit = S.text.charCodeAt(S.pos + 2); + return cannot_be_digit < 48 || cannot_be_digit > 57; + } + + function next(signal_eof, in_string) { + var ch = get_full_char(S.text, S.pos++); + if (signal_eof && !ch) + throw EX_EOF; + if (NEWLINE_CHARS.has(ch)) { + S.newline_before = S.newline_before || !in_string; + ++S.line; + S.col = 0; + if (ch == "\r" && peek() == "\n") { + // treat a \r\n sequence as a single \n + ++S.pos; + ch = "\n"; + } + } else { + if (ch.length > 1) { + ++S.pos; + ++S.col; + } + ++S.col; + } + return ch; + } + + function forward(i) { + while (i--) next(); + } + + function looking_at(str) { + return S.text.substr(S.pos, str.length) == str; + } + + function find_eol() { + var text = S.text; + for (var i = S.pos, n = S.text.length; i < n; ++i) { + var ch = text[i]; + if (NEWLINE_CHARS.has(ch)) + return i; + } + return -1; + } + + function find(what, signal_eof) { + var pos = S.text.indexOf(what, S.pos); + if (signal_eof && pos == -1) throw EX_EOF; + return pos; + } + + function start_token() { + S.tokline = S.line; + S.tokcol = S.col; + S.tokpos = S.pos; + } + + var prev_was_dot = false; + var previous_token = null; + function token(type, value, is_comment) { + S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX.has(value)) || + (type == "keyword" && KEYWORDS_BEFORE_EXPRESSION.has(value)) || + (type == "punc" && PUNC_BEFORE_EXPRESSION.has(value))) || + (type == "arrow"); + if (type == "punc" && (value == "." || value == "?.")) { + prev_was_dot = true; + } else if (!is_comment) { + prev_was_dot = false; + } + const line = S.tokline; + const col = S.tokcol; + const pos = S.tokpos; + const nlb = S.newline_before; + const file = filename; + let comments_before = []; + let comments_after = []; + + if (!is_comment) { + comments_before = S.comments_before; + comments_after = S.comments_before = []; + } + S.newline_before = false; + const tok = new AST_Token(type, value, line, col, pos, nlb, comments_before, comments_after, file); + + if (!is_comment) previous_token = tok; + return tok; + } + + function skip_whitespace() { + while (WHITESPACE_CHARS.has(peek())) + next(); + } + + function peek_next_token_start_or_newline() { + var pos = S.pos; + for (var in_multiline_comment = false; pos < S.text.length; ) { + var ch = get_full_char(S.text, pos); + if (NEWLINE_CHARS.has(ch)) { + return { char: ch, pos: pos }; + } else if (in_multiline_comment) { + if (ch == "*" && get_full_char(S.text, pos + 1) == "/") { + pos += 2; + in_multiline_comment = false; + } else { + pos++; + } + } else if (!WHITESPACE_CHARS.has(ch)) { + if (ch == "/") { + var next_ch = get_full_char(S.text, pos + 1); + if (next_ch == "/") { + pos = find_eol(); + return { char: get_full_char(S.text, pos), pos: pos }; + } else if (next_ch == "*") { + in_multiline_comment = true; + pos += 2; + continue; + } + } + return { char: ch, pos: pos }; + } else { + pos++; + } + } + return { char: null, pos: pos }; + } + + function ch_starts_binding_identifier(ch, pos) { + if (ch == "\\") { + return true; + } else if (is_identifier_start(ch)) { + RE_KEYWORD_RELATIONAL_OPERATORS.lastIndex = pos; + if (RE_KEYWORD_RELATIONAL_OPERATORS.test(S.text)) { + var after = get_full_char(S.text, RE_KEYWORD_RELATIONAL_OPERATORS.lastIndex); + if (!is_identifier_char(after) && after != "\\") { + // "in" or "instanceof" are keywords, not binding identifiers + return false; + } + } + return true; + } + return false; + } + + function read_while(pred) { + var ret = "", ch, i = 0; + while ((ch = peek()) && pred(ch, i++)) + ret += next(); + return ret; + } + + function parse_error(err) { + js_error(err, filename, S.tokline, S.tokcol, S.tokpos); + } + + function read_num(prefix) { + var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".", is_big_int = false, numeric_separator = false; + var num = read_while(function(ch, i) { + if (is_big_int) return false; + + var code = ch.charCodeAt(0); + switch (code) { + case 95: // _ + return (numeric_separator = true); + case 98: case 66: // bB + return (has_x = true); // Can occur in hex sequence, don't return false yet + case 111: case 79: // oO + case 120: case 88: // xX + return has_x ? false : (has_x = true); + case 101: case 69: // eE + return has_x ? true : has_e ? false : (has_e = after_e = true); + case 45: // - + return after_e || (i == 0 && !prefix); + case 43: // + + return after_e; + case (after_e = false, 46): // . + return (!has_dot && !has_x && !has_e) ? (has_dot = true) : false; + case 110: // n + is_big_int = true; + return true; + } + + return ( + code >= 48 && code <= 57 // 0-9 + || code >= 97 && code <= 102 // a-f + || code >= 65 && code <= 70 // A-F + ); + }); + if (prefix) num = prefix + num; + + LATEST_RAW = num; + + if (RE_OCT_NUMBER.test(num) && next_token.has_directive("use strict")) { + parse_error("Legacy octal literals are not allowed in strict mode"); + } + if (numeric_separator) { + if (num.endsWith("_")) { + parse_error("Numeric separators are not allowed at the end of numeric literals"); + } else if (num.includes("__")) { + parse_error("Only one underscore is allowed as numeric separator"); + } + num = num.replace(/_/g, ""); + } + if (is_big_int) { + const without_n = num.slice(0, -1); + const allow_e = RE_HEX_NUMBER.test(without_n); + const valid = parse_js_number(without_n, allow_e); + if (!has_dot && RE_BIG_INT.test(num) && !isNaN(valid)) + return token("big_int", without_n); + parse_error("Invalid or unexpected token"); + } + var valid = parse_js_number(num); + if (!isNaN(valid)) { + return token("num", valid); + } else { + parse_error("Invalid syntax: " + num); + } + } + + function is_octal(ch) { + return ch >= "0" && ch <= "7"; + } + + function read_escaped_char(in_string, strict_hex, template_string) { + var ch = next(true, in_string); + switch (ch.charCodeAt(0)) { + case 110 : return "\n"; + case 114 : return "\r"; + case 116 : return "\t"; + case 98 : return "\b"; + case 118 : return "\u000b"; // \v + case 102 : return "\f"; + case 120 : return String.fromCharCode(hex_bytes(2, strict_hex)); // \x + case 117 : // \u + if (peek() == "{") { + next(true); + if (peek() === "}") + parse_error("Expecting hex-character between {}"); + while (peek() == "0") next(true); // No significance + var result, length = find("}", true) - S.pos; + // Avoid 32 bit integer overflow (1 << 32 === 1) + // We know first character isn't 0 and thus out of range anyway + if (length > 6 || (result = hex_bytes(length, strict_hex)) > 0x10FFFF) { + parse_error("Unicode reference out of bounds"); + } + next(true); + return from_char_code(result); + } + return String.fromCharCode(hex_bytes(4, strict_hex)); + case 10 : return ""; // newline + case 13 : // \r + if (peek() == "\n") { // DOS newline + next(true, in_string); + return ""; + } + } + if (is_octal(ch)) { + if (template_string && strict_hex) { + const represents_null_character = ch === "0" && !is_octal(peek()); + if (!represents_null_character) { + parse_error("Octal escape sequences are not allowed in template strings"); + } + } + return read_octal_escape_sequence(ch, strict_hex); + } + return ch; + } + + function read_octal_escape_sequence(ch, strict_octal) { + // Read + var p = peek(); + if (p >= "0" && p <= "7") { + ch += next(true); + if (ch[0] <= "3" && (p = peek()) >= "0" && p <= "7") + ch += next(true); + } + + // Parse + if (ch === "0") return "\0"; + if (ch.length > 0 && next_token.has_directive("use strict") && strict_octal) + parse_error("Legacy octal escape sequences are not allowed in strict mode"); + return String.fromCharCode(parseInt(ch, 8)); + } + + function hex_bytes(n, strict_hex) { + var num = 0; + for (; n > 0; --n) { + if (!strict_hex && isNaN(parseInt(peek(), 16))) { + return parseInt(num, 16) || ""; + } + var digit = next(true); + if (isNaN(parseInt(digit, 16))) + parse_error("Invalid hex-character pattern in string"); + num += digit; + } + return parseInt(num, 16); + } + + var read_string = with_eof_error("Unterminated string constant", function() { + const start_pos = S.pos; + var quote = next(), ret = []; + for (;;) { + var ch = next(true, true); + if (ch == "\\") ch = read_escaped_char(true, true); + else if (ch == "\r" || ch == "\n") parse_error("Unterminated string constant"); + else if (ch == quote) break; + ret.push(ch); + } + var tok = token("string", ret.join("")); + LATEST_RAW = S.text.slice(start_pos, S.pos); + tok.quote = quote; + return tok; + }); + + var read_template_characters = with_eof_error("Unterminated template", function(begin) { + if (begin) { + S.template_braces.push(S.brace_counter); + } + var content = "", raw = "", ch, tok; + next(true, true); + while ((ch = next(true, true)) != "`") { + if (ch == "\r") { + if (peek() == "\n") ++S.pos; + ch = "\n"; + } else if (ch == "$" && peek() == "{") { + next(true, true); + S.brace_counter++; + tok = token(begin ? "template_head" : "template_cont", content); + TEMPLATE_RAWS.set(tok, raw); + tok.template_end = false; + return tok; + } + + raw += ch; + if (ch == "\\") { + var tmp = S.pos; + var prev_is_tag = previous_token && (previous_token.type === "name" || previous_token.type === "punc" && (previous_token.value === ")" || previous_token.value === "]")); + ch = read_escaped_char(true, !prev_is_tag, true); + raw += S.text.substr(tmp, S.pos - tmp); + } + + content += ch; + } + S.template_braces.pop(); + tok = token(begin ? "template_head" : "template_cont", content); + TEMPLATE_RAWS.set(tok, raw); + tok.template_end = true; + return tok; + }); + + function skip_line_comment(type) { + var regex_allowed = S.regex_allowed; + var i = find_eol(), ret; + if (i == -1) { + ret = S.text.substr(S.pos); + S.pos = S.text.length; + } else { + ret = S.text.substring(S.pos, i); + S.pos = i; + } + S.col = S.tokcol + (S.pos - S.tokpos); + S.comments_before.push(token(type, ret, true)); + S.regex_allowed = regex_allowed; + return next_token; + } + + var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function() { + var regex_allowed = S.regex_allowed; + var i = find("*/", true); + var text = S.text.substring(S.pos, i).replace(/\r\n|\r|\u2028|\u2029/g, "\n"); + // update stream position + forward(get_full_char_length(text) /* text length doesn't count \r\n as 2 char while S.pos - i does */ + 2); + S.comments_before.push(token("comment2", text, true)); + S.newline_before = S.newline_before || text.includes("\n"); + S.regex_allowed = regex_allowed; + return next_token; + }); + + var read_name = function () { + let start = S.pos, end = start - 1, ch = "c"; + + while ( + (ch = S.text.charAt(++end)) + && (ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z") + ); + + // 0x7F is very rare in actual code, so we compare it to "~" (0x7E) + if (end > start + 1 && ch && ch !== "\\" && !is_identifier_char(ch) && ch <= "~") { + S.pos += end - start; + S.col += end - start; + return S.text.slice(start, S.pos); + } + + return read_name_hard(); + }; + + var read_name_hard = with_eof_error("Unterminated identifier name", function() { + var name = [], ch, escaped = false; + var read_escaped_identifier_char = function() { + escaped = true; + next(); + if (peek() !== "u") { + parse_error("Expecting UnicodeEscapeSequence -- uXXXX or u{XXXX}"); + } + return read_escaped_char(false, true); + }; + + // Read first character (ID_Start) + if ((ch = peek()) === "\\") { + ch = read_escaped_identifier_char(); + if (!is_identifier_start(ch)) { + parse_error("First identifier char is an invalid identifier char"); + } + } else if (is_identifier_start(ch)) { + next(); + } else { + return ""; + } + + name.push(ch); + + // Read ID_Continue + while ((ch = peek()) != null) { + if ((ch = peek()) === "\\") { + ch = read_escaped_identifier_char(); + if (!is_identifier_char(ch)) { + parse_error("Invalid escaped identifier char"); + } + } else { + if (!is_identifier_char(ch)) { + break; + } + next(); + } + name.push(ch); + } + const name_str = name.join(""); + if (RESERVED_WORDS.has(name_str) && escaped) { + parse_error("Escaped characters are not allowed in keywords"); + } + return name_str; + }); + + var read_regexp = with_eof_error("Unterminated regular expression", function(source) { + var prev_backslash = false, ch, in_class = false; + while ((ch = next(true))) if (NEWLINE_CHARS.has(ch)) { + parse_error("Unexpected line terminator"); + } else if (prev_backslash) { + if (/^[\u0000-\u007F]$/.test(ch)) { + source += "\\" + ch; + } else { + // Remove the useless slash before the escape, but only for characters that won't be added to regexp syntax + source += ch; + } + prev_backslash = false; + } else if (ch == "[") { + in_class = true; + source += ch; + } else if (ch == "]" && in_class) { + in_class = false; + source += ch; + } else if (ch == "/" && !in_class) { + break; + } else if (ch == "\\") { + prev_backslash = true; + } else { + source += ch; + } + const flags = read_name(); + return token("regexp", "/" + source + "/" + flags); + }); + + function read_operator(prefix) { + function grow(op) { + if (!peek()) return op; + var bigger = op + peek(); + if (OPERATORS.has(bigger)) { + next(); + return grow(bigger); + } else { + return op; + } + } + return token("operator", grow(prefix || next())); + } + + function handle_slash() { + next(); + switch (peek()) { + case "/": + next(); + return skip_line_comment("comment1"); + case "*": + next(); + return skip_multiline_comment(); + } + return S.regex_allowed ? read_regexp("") : read_operator("/"); + } + + function handle_eq_sign() { + next(); + if (peek() === ">") { + next(); + return token("arrow", "=>"); + } else { + return read_operator("="); + } + } + + function handle_dot() { + next(); + if (is_digit(peek().charCodeAt(0))) { + return read_num("."); + } + if (peek() === ".") { + next(); // Consume second dot + next(); // Consume third dot + return token("expand", "..."); + } + + return token("punc", "."); + } + + function read_word() { + var word = read_name(); + if (prev_was_dot) return token("name", word); + return KEYWORDS_ATOM.has(word) ? token("atom", word) + : !KEYWORDS.has(word) ? token("name", word) + : OPERATORS.has(word) ? token("operator", word) + : token("keyword", word); + } + + function read_private_word() { + next(); + return token("privatename", read_name()); + } + + function with_eof_error(eof_error, cont) { + return function(x) { + try { + return cont(x); + } catch(ex) { + if (ex === EX_EOF) parse_error(eof_error); + else throw ex; + } + }; + } + + function next_token(force_regexp) { + if (force_regexp != null) + return read_regexp(force_regexp); + if (shebang && S.pos == 0 && looking_at("#!")) { + start_token(); + forward(2); + skip_line_comment("comment5"); + } + for (;;) { + skip_whitespace(); + start_token(); + if (html5_comments) { + if (looking_at("") && S.newline_before) { + forward(3); + skip_line_comment("comment4"); + continue; + } + } + var ch = peek(); + if (!ch) return token("eof"); + var code = ch.charCodeAt(0); + switch (code) { + case 34: case 39: return read_string(); + case 46: return handle_dot(); + case 47: { + var tok = handle_slash(); + if (tok === next_token) continue; + return tok; + } + case 61: return handle_eq_sign(); + case 63: { + if (!is_option_chain_op()) break; // Handled below + + next(); // ? + next(); // . + + return token("punc", "?."); + } + case 96: return read_template_characters(true); + case 123: + S.brace_counter++; + break; + case 125: + S.brace_counter--; + if (S.template_braces.length > 0 + && S.template_braces[S.template_braces.length - 1] === S.brace_counter) + return read_template_characters(false); + break; + } + if (is_digit(code)) return read_num(); + if (PUNC_CHARS.has(ch)) return token("punc", next()); + if (OPERATOR_CHARS.has(ch)) return read_operator(); + if (code == 92 || is_identifier_start(ch)) return read_word(); + if (code == 35) return read_private_word(); + break; + } + parse_error("Unexpected character '" + ch + "'"); + } + + next_token.next = next; + next_token.peek = peek; + + next_token.context = function(nc) { + if (nc) S = nc; + return S; + }; + + next_token.add_directive = function(directive) { + S.directive_stack[S.directive_stack.length - 1].push(directive); + + if (S.directives[directive] === undefined) { + S.directives[directive] = 1; + } else { + S.directives[directive]++; + } + }; + + next_token.push_directives_stack = function() { + S.directive_stack.push([]); + }; + + next_token.pop_directives_stack = function() { + var directives = S.directive_stack[S.directive_stack.length - 1]; + + for (var i = 0; i < directives.length; i++) { + S.directives[directives[i]]--; + } + + S.directive_stack.pop(); + }; + + next_token.has_directive = function(directive) { + return S.directives[directive] > 0; + }; + + next_token.peek_next_token_start_or_newline = peek_next_token_start_or_newline; + next_token.ch_starts_binding_identifier = ch_starts_binding_identifier; + + return next_token; + +} + +/* -----[ Parser (constants) ]----- */ + +var UNARY_PREFIX = makePredicate([ + "typeof", + "void", + "delete", + "--", + "++", + "!", + "~", + "-", + "+" +]); + +var UNARY_POSTFIX = makePredicate([ "--", "++" ]); + +var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "??=", "&&=", "||=", "/=", "*=", "**=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]); + +var LOGICAL_ASSIGNMENT = makePredicate([ "??=", "&&=", "||=" ]); + +var PRECEDENCE = (function(a, ret) { + for (var i = 0; i < a.length; ++i) { + for (const op of a[i]) { + ret[op] = i + 1; + } + } + return ret; +})( + [ + ["||"], + ["??"], + ["&&"], + ["|"], + ["^"], + ["&"], + ["==", "===", "!=", "!=="], + ["<", ">", "<=", ">=", "in", "instanceof"], + [">>", "<<", ">>>"], + ["+", "-"], + ["*", "/", "%"], + ["**"] + ], + {} +); + +var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "big_int", "string", "regexp", "name"]); + +/* -----[ Parser ]----- */ + +function parse($TEXT, options) { + // maps start tokens to count of comments found outside of their parens + // Example: /* I count */ ( /* I don't */ foo() ) + // Useful because comments_before property of call with parens outside + // contains both comments inside and outside these parens. Used to find the + + const outer_comments_before_counts = new WeakMap(); + + options = defaults(options, { + bare_returns : false, + ecma : null, // Legacy + expression : false, + filename : null, + html5_comments : true, + module : false, + shebang : true, + strict : false, + toplevel : null, + }, true); + + var S = { + input : (typeof $TEXT == "string" + ? tokenizer($TEXT, options.filename, + options.html5_comments, options.shebang) + : $TEXT), + token : null, + prev : null, + peeked : null, + in_function : 0, + in_async : -1, + in_generator : -1, + in_directives : true, + in_loop : 0, + labels : [] + }; + + S.token = next(); + + function is(type, value) { + return is_token(S.token, type, value); + } + + function peek() { return S.peeked || (S.peeked = S.input()); } + + function next() { + S.prev = S.token; + + if (!S.peeked) peek(); + S.token = S.peeked; + S.peeked = null; + S.in_directives = S.in_directives && ( + S.token.type == "string" || is("punc", ";") + ); + return S.token; + } + + function prev() { + return S.prev; + } + + function croak(msg, line, col, pos) { + var ctx = S.input.context(); + js_error(msg, + ctx.filename, + line != null ? line : ctx.tokline, + col != null ? col : ctx.tokcol, + pos != null ? pos : ctx.tokpos); + } + + function token_error(token, msg) { + croak(msg, token.line, token.col); + } + + function unexpected(token) { + if (token == null) + token = S.token; + token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")"); + } + + function expect_token(type, val) { + if (is(type, val)) { + return next(); + } + token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»"); + } + + function expect(punc) { return expect_token("punc", punc); } + + function has_newline_before(token) { + return token.nlb || !token.comments_before.every((comment) => !comment.nlb); + } + + function can_insert_semicolon() { + return !options.strict + && (is("eof") || is("punc", "}") || has_newline_before(S.token)); + } + + function is_in_generator() { + return S.in_generator === S.in_function; + } + + function is_in_async() { + return S.in_async === S.in_function; + } + + function can_await() { + return ( + S.in_async === S.in_function + || S.in_function === 0 && S.input.has_directive("use strict") + ); + } + + function semicolon(optional) { + if (is("punc", ";")) next(); + else if (!optional && !can_insert_semicolon()) unexpected(); + } + + function parenthesised() { + expect("("); + var exp = expression(true); + expect(")"); + return exp; + } + + function embed_tokens(parser) { + return function _embed_tokens_wrapper(...args) { + const start = S.token; + const expr = parser(...args); + expr.start = start; + expr.end = prev(); + return expr; + }; + } + + function handle_regexp() { + if (is("operator", "/") || is("operator", "/=")) { + S.peeked = null; + S.token = S.input(S.token.value.substr(1)); // force regexp + } + } + + var statement = embed_tokens(function statement(is_export_default, is_for_body, is_if_body) { + handle_regexp(); + switch (S.token.type) { + case "string": + if (S.in_directives) { + var token = peek(); + if (!LATEST_RAW.includes("\\") + && (is_token(token, "punc", ";") + || is_token(token, "punc", "}") + || has_newline_before(token) + || is_token(token, "eof"))) { + S.input.add_directive(S.token.value); + } else { + S.in_directives = false; + } + } + var dir = S.in_directives, stat = simple_statement(); + return dir && stat.body instanceof AST_String ? new AST_Directive(stat.body) : stat; + case "template_head": + case "num": + case "big_int": + case "regexp": + case "operator": + case "atom": + return simple_statement(); + + case "name": + if (S.token.value == "async" && is_token(peek(), "keyword", "function")) { + next(); + next(); + if (is_for_body) { + croak("functions are not allowed as the body of a loop"); + } + return function_(AST_Defun, false, true, is_export_default); + } + if (S.token.value == "import" && !is_token(peek(), "punc", "(") && !is_token(peek(), "punc", ".")) { + next(); + var node = import_statement(); + semicolon(); + return node; + } + if (S.token.value == "using" && is_token(peek(), "name") && !has_newline_before(peek())) { + next(); + var node = using_(); + semicolon(); + return node; + } + if (S.token.value == "await" && can_await() && is_token(peek(), "name", "using") && !has_newline_before(peek())) { + var next_next = S.input.peek_next_token_start_or_newline(); + if (S.input.ch_starts_binding_identifier(next_next.char, next_next.pos)) { + next(); + // The "using" token will be consumed by the await_using_ function. + var node = await_using_(); + semicolon(); + return node; + } + } + return is_token(peek(), "punc", ":") + ? labeled_statement() + : simple_statement(); + + case "privatename": + if(!S.in_class) + croak("Private field must be used in an enclosing class"); + return simple_statement(); + + case "punc": + switch (S.token.value) { + case "{": + return new AST_BlockStatement({ + start : S.token, + body : block_(), + end : prev() + }); + case "[": + case "(": + return simple_statement(); + case ";": + S.in_directives = false; + next(); + return new AST_EmptyStatement(); + default: + unexpected(); + } + + case "keyword": + switch (S.token.value) { + case "break": + next(); + return break_cont(AST_Break); + + case "continue": + next(); + return break_cont(AST_Continue); + + case "debugger": + next(); + semicolon(); + return new AST_Debugger(); + + case "do": + next(); + var body = in_loop(statement); + expect_token("keyword", "while"); + var condition = parenthesised(); + semicolon(true); + return new AST_Do({ + body : body, + condition : condition + }); + + case "while": + next(); + return new AST_While({ + condition : parenthesised(), + body : in_loop(function() { return statement(false, true); }) + }); + + case "for": + next(); + return for_(); + + case "class": + next(); + if (is_for_body) { + croak("classes are not allowed as the body of a loop"); + } + if (is_if_body) { + croak("classes are not allowed as the body of an if"); + } + return class_(AST_DefClass, is_export_default); + + case "function": + next(); + if (is_for_body) { + croak("functions are not allowed as the body of a loop"); + } + return function_(AST_Defun, false, false, is_export_default); + + case "if": + next(); + return if_(); + + case "return": + if (S.in_function == 0 && !options.bare_returns) + croak("'return' outside of function"); + next(); + var value = null; + if (is("punc", ";")) { + next(); + } else if (!can_insert_semicolon()) { + value = expression(true); + semicolon(); + } + return new AST_Return({ + value: value + }); + + case "switch": + next(); + return new AST_Switch({ + expression : parenthesised(), + body : in_loop(switch_body_) + }); + + case "throw": + next(); + if (has_newline_before(S.token)) + croak("Illegal newline after 'throw'"); + var value = expression(true); + semicolon(); + return new AST_Throw({ + value: value + }); + + case "try": + next(); + return try_(); + + case "var": + next(); + var node = var_(); + semicolon(); + return node; + + case "let": + next(); + var node = let_(); + semicolon(); + return node; + + case "const": + next(); + var node = const_(); + semicolon(); + return node; + + case "with": + if (S.input.has_directive("use strict")) { + croak("Strict mode may not include a with statement"); + } + next(); + return new AST_With({ + expression : parenthesised(), + body : statement() + }); + + case "export": + if (!is_token(peek(), "punc", "(")) { + next(); + var node = export_statement(); + if (is("punc", ";")) semicolon(); + return node; + } + } + } + unexpected(); + }); + + function labeled_statement() { + var label = as_symbol(AST_Label); + if (label.name === "await" && is_in_async()) { + token_error(S.prev, "await cannot be used as label inside async function"); + } + if (S.labels.some((l) => l.name === label.name)) { + // ECMA-262, 12.12: An ECMAScript program is considered + // syntactically incorrect if it contains a + // LabelledStatement that is enclosed by a + // LabelledStatement with the same Identifier as label. + croak("Label " + label.name + " defined twice"); + } + expect(":"); + S.labels.push(label); + var stat = statement(); + S.labels.pop(); + if (!(stat instanceof AST_IterationStatement)) { + // check for `continue` that refers to this label. + // those should be reported as syntax errors. + // https://github.com/mishoo/UglifyJS2/issues/287 + label.references.forEach(function(ref) { + if (ref instanceof AST_Continue) { + ref = ref.label.start; + croak("Continue label `" + label.name + "` refers to non-IterationStatement.", + ref.line, ref.col, ref.pos); + } + }); + } + return new AST_LabeledStatement({ body: stat, label: label }); + } + + function simple_statement(tmp) { + return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) }); + } + + function break_cont(type) { + var label = null, ldef; + if (!can_insert_semicolon()) { + label = as_symbol(AST_LabelRef, true); + } + if (label != null) { + ldef = S.labels.find((l) => l.name === label.name); + if (!ldef) + croak("Undefined label " + label.name); + label.thedef = ldef; + } else if (S.in_loop == 0) + croak(type.TYPE + " not inside a loop or switch"); + semicolon(); + var stat = new type({ label: label }); + if (ldef) ldef.references.push(stat); + return stat; + } + + function for_() { + var for_await_error = "`for await` invalid in this context"; + var await_tok = S.token; + if (await_tok.type == "name" && await_tok.value == "await") { + if (!can_await()) { + token_error(await_tok, for_await_error); + } + next(); + } else { + await_tok = false; + } + expect("("); + var init = null; + if (!is("punc", ";")) { + init = + is("keyword", "var") ? (next(), var_(true)) : + is("keyword", "let") ? (next(), let_(true)) : + is("keyword", "const") ? (next(), const_(true)) : + is("name", "using") && is_token(peek(), "name") && (peek().value != "of" || S.input.peek_next_token_start_or_newline().char == "=") ? (next(), using_(true)) : + is("name", "await") && can_await() && is_token(peek(), "name", "using") ? (next(), await_using_(true)) : + expression(true, true); + var is_in = is("operator", "in"); + var is_of = is("name", "of"); + if (await_tok && !is_of) { + token_error(await_tok, for_await_error); + } + if (is_in || is_of) { + if (init instanceof AST_DefinitionsLike) { + if (init.definitions.length > 1) + token_error(init.start, "Only one variable declaration allowed in for..in loop"); + if (is_in && init instanceof AST_Using) { + token_error(init.start, "Invalid using declaration in for..in loop"); + } + } else if (!(is_assignable(init) || (init = to_destructuring(init)) instanceof AST_Destructuring)) { + token_error(init.start, "Invalid left-hand side in for..in loop"); + } + next(); + if (is_in) { + return for_in(init); + } else { + return for_of(init, !!await_tok); + } + } + } else if (await_tok) { + token_error(await_tok, for_await_error); + } + return regular_for(init); + } + + function regular_for(init) { + expect(";"); + var test = is("punc", ";") ? null : expression(true); + expect(";"); + var step = is("punc", ")") ? null : expression(true); + expect(")"); + return new AST_For({ + init : init, + condition : test, + step : step, + body : in_loop(function() { return statement(false, true); }) + }); + } + + function for_of(init, is_await) { + var lhs = init instanceof AST_DefinitionsLike ? init.definitions[0].name : null; + var obj = expression(true); + expect(")"); + return new AST_ForOf({ + await : is_await, + init : init, + name : lhs, + object : obj, + body : in_loop(function() { return statement(false, true); }) + }); + } + + function for_in(init) { + var obj = expression(true); + expect(")"); + return new AST_ForIn({ + init : init, + object : obj, + body : in_loop(function() { return statement(false, true); }) + }); + } + + var arrow_function = function(start, argnames, is_async) { + if (has_newline_before(S.token)) { + croak("Unexpected newline before arrow (=>)"); + } + + expect_token("arrow", "=>"); + + var body = _function_body(is("punc", "{"), false, is_async); + + return new AST_Arrow({ + start : start, + end : body.end, + async : is_async, + argnames : argnames, + body : body + }); + }; + + var function_ = function(ctor, is_generator, is_async, is_export_default) { + var in_statement = ctor === AST_Defun; + if (is("operator", "*")) { + is_generator = true; + next(); + } + + var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null; + if (in_statement && !name) { + if (is_export_default) { + ctor = AST_Function; + } else { + unexpected(); + } + } + + if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration)) + unexpected(prev()); + + var args = []; + var body = _function_body(true, is_generator, is_async, name, args); + return new ctor({ + start : args.start, + end : body.end, + is_generator: is_generator, + async : is_async, + name : name, + argnames: args, + body : body + }); + }; + + class UsedParametersTracker { + constructor(is_parameter, strict, duplicates_ok = false) { + this.is_parameter = is_parameter; + this.duplicates_ok = duplicates_ok; + this.parameters = new Set(); + this.duplicate = null; + this.default_assignment = false; + this.spread = false; + this.strict_mode = !!strict; + } + add_parameter(token) { + if (this.parameters.has(token.value)) { + if (this.duplicate === null) { + this.duplicate = token; + } + this.check_strict(); + } else { + this.parameters.add(token.value); + if (this.is_parameter) { + switch (token.value) { + case "arguments": + case "eval": + case "yield": + if (this.strict_mode) { + token_error(token, "Unexpected " + token.value + " identifier as parameter inside strict mode"); + } + break; + default: + if (RESERVED_WORDS.has(token.value)) { + unexpected(); + } + } + } + } + } + mark_default_assignment(token) { + if (this.default_assignment === false) { + this.default_assignment = token; + } + } + mark_spread(token) { + if (this.spread === false) { + this.spread = token; + } + } + mark_strict_mode() { + this.strict_mode = true; + } + is_strict() { + return this.default_assignment !== false || this.spread !== false || this.strict_mode; + } + check_strict() { + if (this.is_strict() && this.duplicate !== null && !this.duplicates_ok) { + token_error(this.duplicate, "Parameter " + this.duplicate.value + " was used already"); + } + } + } + + function parameters(params) { + var used_parameters = new UsedParametersTracker(true, S.input.has_directive("use strict")); + + expect("("); + + while (!is("punc", ")")) { + var param = parameter(used_parameters); + params.push(param); + + if (!is("punc", ")")) { + expect(","); + } + + if (param instanceof AST_Expansion) { + break; + } + } + + next(); + } + + function parameter(used_parameters, symbol_type) { + var param; + var expand = false; + if (used_parameters === undefined) { + used_parameters = new UsedParametersTracker(true, S.input.has_directive("use strict")); + } + if (is("expand", "...")) { + expand = S.token; + used_parameters.mark_spread(S.token); + next(); + } + param = binding_element(used_parameters, symbol_type); + + if (is("operator", "=") && expand === false) { + used_parameters.mark_default_assignment(S.token); + next(); + param = new AST_DefaultAssign({ + start: param.start, + left: param, + operator: "=", + right: expression(false), + end: S.token + }); + } + + if (expand !== false) { + if (!is("punc", ")")) { + unexpected(); + } + param = new AST_Expansion({ + start: expand, + expression: param, + end: expand + }); + } + used_parameters.check_strict(); + + return param; + } + + function binding_element(used_parameters, symbol_type) { + var elements = []; + var first = true; + var is_expand = false; + var expand_token; + var first_token = S.token; + if (used_parameters === undefined) { + const strict = S.input.has_directive("use strict"); + const duplicates_ok = symbol_type === AST_SymbolVar; + used_parameters = new UsedParametersTracker(false, strict, duplicates_ok); + } + symbol_type = symbol_type === undefined ? AST_SymbolFunarg : symbol_type; + if (is("punc", "[")) { + next(); + while (!is("punc", "]")) { + if (first) { + first = false; + } else { + expect(","); + } + + if (is("expand", "...")) { + is_expand = true; + expand_token = S.token; + used_parameters.mark_spread(S.token); + next(); + } + if (is("punc")) { + switch (S.token.value) { + case ",": + elements.push(new AST_Hole({ + start: S.token, + end: S.token + })); + continue; + case "]": // Trailing comma after last element + break; + case "[": + case "{": + elements.push(binding_element(used_parameters, symbol_type)); + break; + default: + unexpected(); + } + } else if (is("name")) { + used_parameters.add_parameter(S.token); + elements.push(as_symbol(symbol_type)); + } else { + croak("Invalid function parameter"); + } + if (is("operator", "=") && is_expand === false) { + used_parameters.mark_default_assignment(S.token); + next(); + elements[elements.length - 1] = new AST_DefaultAssign({ + start: elements[elements.length - 1].start, + left: elements[elements.length - 1], + operator: "=", + right: expression(false), + end: S.token + }); + } + if (is_expand) { + if (!is("punc", "]")) { + croak("Rest element must be last element"); + } + elements[elements.length - 1] = new AST_Expansion({ + start: expand_token, + expression: elements[elements.length - 1], + end: expand_token + }); + } + } + expect("]"); + used_parameters.check_strict(); + return new AST_Destructuring({ + start: first_token, + names: elements, + is_array: true, + end: prev() + }); + } else if (is("punc", "{")) { + next(); + while (!is("punc", "}")) { + if (first) { + first = false; + } else { + expect(","); + } + if (is("expand", "...")) { + is_expand = true; + expand_token = S.token; + used_parameters.mark_spread(S.token); + next(); + } + if (is("name") && (is_token(peek(), "punc") || is_token(peek(), "operator")) && [",", "}", "="].includes(peek().value)) { + used_parameters.add_parameter(S.token); + var start = prev(); + var value = as_symbol(symbol_type); + if (is_expand) { + elements.push(new AST_Expansion({ + start: expand_token, + expression: value, + end: value.end, + })); + } else { + elements.push(new AST_ObjectKeyVal({ + start: start, + key: value.name, + value: value, + end: value.end, + })); + } + } else if (is("punc", "}")) { + continue; // Allow trailing hole + } else { + var property_token = S.token; + var property = as_property_name(); + if (property === null) { + unexpected(prev()); + } else if (prev().type === "name" && !is("punc", ":")) { + elements.push(new AST_ObjectKeyVal({ + start: prev(), + key: property, + value: new symbol_type({ + start: prev(), + name: property, + end: prev() + }), + end: prev() + })); + } else { + expect(":"); + elements.push(new AST_ObjectKeyVal({ + start: property_token, + quote: property_token.quote, + key: property, + value: binding_element(used_parameters, symbol_type), + end: prev() + })); + } + } + if (is_expand) { + if (!is("punc", "}")) { + croak("Rest element must be last element"); + } + } else if (is("operator", "=")) { + used_parameters.mark_default_assignment(S.token); + next(); + elements[elements.length - 1].value = new AST_DefaultAssign({ + start: elements[elements.length - 1].value.start, + left: elements[elements.length - 1].value, + operator: "=", + right: expression(false), + end: S.token + }); + } + } + expect("}"); + used_parameters.check_strict(); + return new AST_Destructuring({ + start: first_token, + names: elements, + is_array: false, + end: prev() + }); + } else if (is("name")) { + used_parameters.add_parameter(S.token); + return as_symbol(symbol_type); + } else { + croak("Invalid function parameter"); + } + } + + function params_or_seq_(allow_arrows, maybe_sequence) { + var spread_token; + var invalid_sequence; + var trailing_comma; + var a = []; + expect("("); + while (!is("punc", ")")) { + if (spread_token) unexpected(spread_token); + if (is("expand", "...")) { + spread_token = S.token; + if (maybe_sequence) invalid_sequence = S.token; + next(); + a.push(new AST_Expansion({ + start: prev(), + expression: expression(), + end: S.token, + })); + } else { + a.push(expression()); + } + if (!is("punc", ")")) { + expect(","); + if (is("punc", ")")) { + trailing_comma = prev(); + if (maybe_sequence) invalid_sequence = trailing_comma; + } + } + } + expect(")"); + if (allow_arrows && is("arrow", "=>")) { + if (spread_token && trailing_comma) unexpected(trailing_comma); + } else if (invalid_sequence) { + unexpected(invalid_sequence); + } + return a; + } + + function _function_body(block, generator, is_async, name, args) { + var loop = S.in_loop; + var labels = S.labels; + var current_generator = S.in_generator; + var current_async = S.in_async; + ++S.in_function; + if (generator) + S.in_generator = S.in_function; + if (is_async) + S.in_async = S.in_function; + if (args) parameters(args); + if (block) + S.in_directives = true; + S.in_loop = 0; + S.labels = []; + if (block) { + S.input.push_directives_stack(); + var a = block_(); + if (name) _verify_symbol(name); + if (args) args.forEach(_verify_symbol); + S.input.pop_directives_stack(); + } else { + var a = [new AST_Return({ + start: S.token, + value: expression(false), + end: S.token + })]; + } + --S.in_function; + S.in_loop = loop; + S.labels = labels; + S.in_generator = current_generator; + S.in_async = current_async; + return a; + } + + function _await_expression() { + // Previous token must be "await" and not be interpreted as an identifier + if (!can_await()) { + croak("Unexpected await expression outside async function", + S.prev.line, S.prev.col, S.prev.pos); + } + // the await expression is parsed as a unary expression in Babel + return new AST_Await({ + start: prev(), + end: S.token, + expression : maybe_unary(true), + }); + } + + function _yield_expression() { + var start = S.token; + var star = false; + var has_expression = true; + + // Attempt to get expression or star (and then the mandatory expression) + // behind yield on the same line. + // + // If nothing follows on the same line of the yieldExpression, + // it should default to the value `undefined` for yield to return. + // In that case, the `undefined` stored as `null` in ast. + // + // Note 1: It isn't allowed for yield* to close without an expression + // Note 2: If there is a nlb between yield and star, it is interpret as + // yield * + if ( + can_insert_semicolon() + || is("punc") && PUNC_AFTER_EXPRESSION.has(S.token.value) + || is("template_cont") + ) { + has_expression = false; + } else if (is("operator", "*")) { + star = true; + next(); + } + + return new AST_Yield({ + start : start, + is_star : star, + expression : has_expression ? expression() : null, + end : prev() + }); + } + + function if_() { + var cond = parenthesised(), body = statement(false, false, true), belse = null; + if (is("keyword", "else")) { + next(); + belse = statement(false, false, true); + } + return new AST_If({ + condition : cond, + body : body, + alternative : belse + }); + } + + function block_() { + expect("{"); + var a = []; + while (!is("punc", "}")) { + if (is("eof")) unexpected(); + a.push(statement()); + } + next(); + return a; + } + + function switch_body_() { + expect("{"); + var a = [], cur = null, branch = null, tmp; + while (!is("punc", "}")) { + if (is("eof")) unexpected(); + if (is("keyword", "case")) { + if (branch) branch.end = prev(); + cur = []; + branch = new AST_Case({ + start : (tmp = S.token, next(), tmp), + expression : expression(true), + body : cur + }); + a.push(branch); + expect(":"); + } else if (is("keyword", "default")) { + if (branch) branch.end = prev(); + cur = []; + branch = new AST_Default({ + start : (tmp = S.token, next(), expect(":"), tmp), + body : cur + }); + a.push(branch); + } else { + if (!cur) unexpected(); + cur.push(statement()); + } + } + if (branch) branch.end = prev(); + next(); + return a; + } + + function try_() { + var body, bcatch = null, bfinally = null; + body = new AST_TryBlock({ + start : S.token, + body : block_(), + end : prev(), + }); + if (is("keyword", "catch")) { + var start = S.token; + next(); + if (is("punc", "{")) { + var name = null; + } else { + expect("("); + var name = parameter(undefined, AST_SymbolCatch); + expect(")"); + } + bcatch = new AST_Catch({ + start : start, + argname : name, + body : block_(), + end : prev() + }); + } + if (is("keyword", "finally")) { + var start = S.token; + next(); + bfinally = new AST_Finally({ + start : start, + body : block_(), + end : prev() + }); + } + if (!bcatch && !bfinally) + croak("Missing catch/finally blocks"); + return new AST_Try({ + body : body, + bcatch : bcatch, + bfinally : bfinally + }); + } + + /** + * var + * vardef1 = 2, + * vardef2 = 3; + */ + function vardefs(no_in, kind) { + var var_defs = []; + var def; + for (;;) { + var sym_type = + kind === "var" ? AST_SymbolVar : + kind === "const" ? AST_SymbolConst : + kind === "let" ? AST_SymbolLet : + kind === "using" ? AST_SymbolUsing : + kind === "await using" ? AST_SymbolUsing : null; + var def_type = kind === "using" || kind === "await using" ? AST_UsingDef : AST_VarDef; + // var { a } = b + if (is("punc", "{") || is("punc", "[")) { + def = new def_type({ + start: S.token, + name: binding_element(undefined, sym_type), + value: is("operator", "=") ? (expect_token("operator", "="), expression(false, no_in)) : null, + end: prev() + }); + } else { + def = new def_type({ + start : S.token, + name : as_symbol(sym_type), + value : is("operator", "=") + ? (next(), expression(false, no_in)) + : !no_in && (kind === "const" || kind === "using" || kind === "await using") + ? croak("Missing initializer in " + kind + " declaration") : null, + end : prev() + }); + if (def.name.name == "import") croak("Unexpected token: import"); + } + var_defs.push(def); + if (!is("punc", ",")) + break; + next(); + } + return var_defs; + } + + var var_ = function(no_in) { + return new AST_Var({ + start : prev(), + definitions : vardefs(no_in, "var"), + end : prev() + }); + }; + + var let_ = function(no_in) { + return new AST_Let({ + start : prev(), + definitions : vardefs(no_in, "let"), + end : prev() + }); + }; + + var const_ = function(no_in) { + return new AST_Const({ + start : prev(), + definitions : vardefs(no_in, "const"), + end : prev() + }); + }; + + var using_ = function(no_in) { + return new AST_Using({ + start : prev(), + await : false, + definitions : vardefs(no_in, "using"), + end : prev() + }); + }; + + var await_using_ = function(no_in) { + // Assumption: When await_using_ is called, only the `await` token has been consumed. + return new AST_Using({ + start : prev(), + await : true, + definitions : (next(), vardefs(no_in, "await using")), + end : prev() + }); + }; + + var new_ = function(allow_calls) { + var start = S.token; + expect_token("operator", "new"); + if (is("punc", ".")) { + next(); + expect_token("name", "target"); + return subscripts(new AST_NewTarget({ + start : start, + end : prev() + }), allow_calls); + } + var newexp = expr_atom(false), args; + if (is("punc", "(")) { + next(); + args = expr_list(")", true); + } else { + args = []; + } + var call = new AST_New({ + start : start, + expression : newexp, + args : args, + end : prev() + }); + annotate(call); + return subscripts(call, allow_calls); + }; + + function as_atom_node() { + var tok = S.token, ret; + switch (tok.type) { + case "name": + ret = _make_symbol(AST_SymbolRef); + break; + case "num": + ret = new AST_Number({ + start: tok, + end: tok, + value: tok.value, + raw: LATEST_RAW + }); + break; + case "big_int": + ret = new AST_BigInt({ + start: tok, + end: tok, + value: tok.value, + raw: LATEST_RAW, + }); + break; + case "string": + ret = new AST_String({ + start : tok, + end : tok, + value : tok.value, + quote : tok.quote + }); + annotate(ret); + break; + case "regexp": + const [_, source, flags] = tok.value.match(/^\/(.*)\/(\w*)$/); + + ret = new AST_RegExp({ start: tok, end: tok, value: { source, flags } }); + break; + case "atom": + switch (tok.value) { + case "false": + ret = new AST_False({ start: tok, end: tok }); + break; + case "true": + ret = new AST_True({ start: tok, end: tok }); + break; + case "null": + ret = new AST_Null({ start: tok, end: tok }); + break; + } + break; + } + next(); + return ret; + } + + function to_fun_args(ex, default_seen_above) { + var insert_default = function(ex, default_value) { + if (default_value) { + return new AST_DefaultAssign({ + start: ex.start, + left: ex, + operator: "=", + right: default_value, + end: default_value.end + }); + } + return ex; + }; + if (ex instanceof AST_Object) { + return insert_default(new AST_Destructuring({ + start: ex.start, + end: ex.end, + is_array: false, + names: ex.properties.map(prop => to_fun_args(prop)) + }), default_seen_above); + } else if (ex instanceof AST_ObjectKeyVal) { + ex.value = to_fun_args(ex.value); + return insert_default(ex, default_seen_above); + } else if (ex instanceof AST_Hole) { + return ex; + } else if (ex instanceof AST_Destructuring) { + ex.names = ex.names.map(name => to_fun_args(name)); + return insert_default(ex, default_seen_above); + } else if (ex instanceof AST_SymbolRef) { + return insert_default(new AST_SymbolFunarg({ + name: ex.name, + start: ex.start, + end: ex.end + }), default_seen_above); + } else if (ex instanceof AST_Expansion) { + ex.expression = to_fun_args(ex.expression); + return insert_default(ex, default_seen_above); + } else if (ex instanceof AST_Array) { + return insert_default(new AST_Destructuring({ + start: ex.start, + end: ex.end, + is_array: true, + names: ex.elements.map(elm => to_fun_args(elm)) + }), default_seen_above); + } else if (ex instanceof AST_Assign) { + return insert_default(to_fun_args(ex.left, ex.right), default_seen_above); + } else if (ex instanceof AST_DefaultAssign) { + ex.left = to_fun_args(ex.left); + return ex; + } else { + croak("Invalid function parameter", ex.start.line, ex.start.col); + } + } + + var expr_atom = function(allow_calls, allow_arrows) { + if (is("operator", "new")) { + return new_(allow_calls); + } + if (is("name", "import") && is_token(peek(), "punc", ".")) { + return import_meta(allow_calls); + } + var start = S.token; + var peeked; + var async = is("name", "async") + && (peeked = peek()).value != "[" + && peeked.type != "arrow" + && as_atom_node(); + if (is("punc")) { + switch (S.token.value) { + case "(": + if (async && !allow_calls) break; + var exprs = params_or_seq_(allow_arrows, !async); + if (allow_arrows && is("arrow", "=>")) { + return arrow_function(start, exprs.map(e => to_fun_args(e)), !!async); + } + var ex = async ? new AST_Call({ + expression: async, + args: exprs + }) : to_expr_or_sequence(start, exprs); + if (ex.start) { + const outer_comments_before = start.comments_before.length; + outer_comments_before_counts.set(start, outer_comments_before); + ex.start.comments_before.unshift(...start.comments_before); + start.comments_before = ex.start.comments_before; + if (outer_comments_before == 0 && start.comments_before.length > 0) { + var comment = start.comments_before[0]; + if (!comment.nlb) { + comment.nlb = start.nlb; + start.nlb = false; + } + } + start.comments_after = ex.start.comments_after; + } + ex.start = start; + var end = prev(); + if (ex.end) { + end.comments_before = ex.end.comments_before; + ex.end.comments_after.push(...end.comments_after); + end.comments_after = ex.end.comments_after; + } + ex.end = end; + if (ex instanceof AST_Call) annotate(ex); + return subscripts(ex, allow_calls); + case "[": + return subscripts(array_(), allow_calls); + case "{": + return subscripts(object_or_destructuring_(), allow_calls); + } + if (!async) unexpected(); + } + if (allow_arrows && is("name") && is_token(peek(), "arrow")) { + var param = new AST_SymbolFunarg({ + name: S.token.value, + start: start, + end: start, + }); + next(); + return arrow_function(start, [param], !!async); + } + if (is("keyword", "function")) { + next(); + var func = function_(AST_Function, false, !!async); + func.start = start; + func.end = prev(); + return subscripts(func, allow_calls); + } + if (async) return subscripts(async, allow_calls); + if (is("keyword", "class")) { + next(); + var cls = class_(AST_ClassExpression); + cls.start = start; + cls.end = prev(); + return subscripts(cls, allow_calls); + } + if (is("template_head")) { + return subscripts(template_string(), allow_calls); + } + if (ATOMIC_START_TOKEN.has(S.token.type)) { + return subscripts(as_atom_node(), allow_calls); + } + unexpected(); + }; + + function template_string() { + var segments = [], start = S.token; + + segments.push(new AST_TemplateSegment({ + start: S.token, + raw: TEMPLATE_RAWS.get(S.token), + value: S.token.value, + end: S.token + })); + + while (!S.token.template_end) { + next(); + handle_regexp(); + segments.push(expression(true)); + + segments.push(new AST_TemplateSegment({ + start: S.token, + raw: TEMPLATE_RAWS.get(S.token), + value: S.token.value, + end: S.token + })); + } + next(); + + return new AST_TemplateString({ + start: start, + segments: segments, + end: S.token + }); + } + + function expr_list(closing, allow_trailing_comma, allow_empty) { + var first = true, a = []; + while (!is("punc", closing)) { + if (first) first = false; else expect(","); + if (allow_trailing_comma && is("punc", closing)) break; + if (is("punc", ",") && allow_empty) { + a.push(new AST_Hole({ start: S.token, end: S.token })); + } else if (is("expand", "...")) { + next(); + a.push(new AST_Expansion({start: prev(), expression: expression(),end: S.token})); + } else { + a.push(expression(false)); + } + } + next(); + return a; + } + + var array_ = embed_tokens(function() { + expect("["); + return new AST_Array({ + elements: expr_list("]", !options.strict, true) + }); + }); + + var create_accessor = embed_tokens((is_generator, is_async) => { + return function_(AST_Accessor, is_generator, is_async); + }); + + var object_or_destructuring_ = embed_tokens(function object_or_destructuring_() { + var start = S.token, first = true, a = []; + expect("{"); + while (!is("punc", "}")) { + if (first) first = false; else expect(","); + if (!options.strict && is("punc", "}")) + // allow trailing comma + break; + + start = S.token; + if (start.type == "expand") { + next(); + a.push(new AST_Expansion({ + start: start, + expression: expression(false), + end: prev(), + })); + continue; + } + if(is("privatename")) { + croak("private fields are not allowed in an object"); + } + var name = as_property_name(); + var value; + + // Check property and fetch value + if (!is("punc", ":")) { + var concise = object_or_class_property(name, start); + if (concise) { + a.push(concise); + continue; + } + + value = new AST_SymbolRef({ + start: prev(), + name: name, + end: prev() + }); + } else if (name === null) { + unexpected(prev()); + } else { + next(); // `:` - see first condition + value = expression(false); + } + + // Check for default value and alter value accordingly if necessary + if (is("operator", "=")) { + next(); + value = new AST_Assign({ + start: start, + left: value, + operator: "=", + right: expression(false), + logical: false, + end: prev() + }); + } + + // Create property + const kv = new AST_ObjectKeyVal({ + start: start, + quote: start.quote, + key: name, + value: value, + end: prev() + }); + a.push(annotate(kv)); + } + next(); + return new AST_Object({ properties: a }); + }); + + function class_(KindOfClass, is_export_default) { + var start, method, class_name, extends_, properties = []; + + S.input.push_directives_stack(); // Push directive stack, but not scope stack + S.input.add_directive("use strict"); + + if (S.token.type == "name" && S.token.value != "extends") { + class_name = as_symbol(KindOfClass === AST_DefClass ? AST_SymbolDefClass : AST_SymbolClass); + } + + if (KindOfClass === AST_DefClass && !class_name) { + if (is_export_default) { + KindOfClass = AST_ClassExpression; + } else { + unexpected(); + } + } + + if (S.token.value == "extends") { + next(); + extends_ = expression(true); + } + + expect("{"); + // mark in class feild, + const save_in_class = S.in_class; + S.in_class = true; + while (is("punc", ";")) { next(); } // Leading semicolons are okay in class bodies. + while (!is("punc", "}")) { + start = S.token; + method = object_or_class_property(as_property_name(), start, true); + if (!method) { unexpected(); } + properties.push(method); + while (is("punc", ";")) { next(); } + } + // mark in class feild, + S.in_class = save_in_class; + + S.input.pop_directives_stack(); + + next(); + + return new KindOfClass({ + start: start, + name: class_name, + extends: extends_, + properties: properties, + end: prev(), + }); + } + + function object_or_class_property(name, start, is_class) { + const get_symbol_ast = (name, SymbolClass) => { + if (typeof name === "string") { + return new SymbolClass({ start, name, end: prev() }); + } else if (name === null) { + unexpected(); + } + return name; + }; + + var is_private = prev().type === "privatename"; + const is_not_method_start = () => + !is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("punc", ";") && !is("operator", "=") && !is_private; + + var is_async = false; + var is_static = false; + var is_generator = false; + var accessor_type = null; + + if (is_class && name === "static" && is_not_method_start()) { + const static_block = class_static_block(); + if (static_block != null) { + return static_block; + } + is_static = true; + name = as_property_name(); + } + if (name === "async" && is_not_method_start()) { + is_async = true; + name = as_property_name(); + } + if (prev().type === "operator" && prev().value === "*") { + is_generator = true; + name = as_property_name(); + } + if ((name === "get" || name === "set") && is_not_method_start()) { + accessor_type = name; + name = as_property_name(); + } + if (!is_private && prev().type === "privatename") { + is_private = true; + } + + const property_token = prev(); + + if (accessor_type != null) { + if (!is_private) { + const AccessorClass = accessor_type === "get" + ? AST_ObjectGetter + : AST_ObjectSetter; + + name = get_symbol_ast(name, AST_SymbolMethod); + return annotate(new AccessorClass({ + start, + static: is_static, + key: name, + quote: name instanceof AST_SymbolMethod ? property_token.quote : undefined, + value: create_accessor(), + end: prev() + })); + } else { + const AccessorClass = accessor_type === "get" + ? AST_PrivateGetter + : AST_PrivateSetter; + + return annotate(new AccessorClass({ + start, + static: is_static, + key: get_symbol_ast(name, AST_SymbolMethod), + value: create_accessor(), + end: prev(), + })); + } + } + + if (is("punc", "(")) { + name = get_symbol_ast(name, AST_SymbolMethod); + const AST_MethodVariant = is_private + ? AST_PrivateMethod + : AST_ConciseMethod; + var node = new AST_MethodVariant({ + start : start, + static : is_static, + key : name, + quote : name instanceof AST_SymbolMethod ? + property_token.quote : undefined, + value : create_accessor(is_generator, is_async), + end : prev() + }); + return annotate(node); + } + + if (is_class) { + const AST_SymbolVariant = is_private + ? AST_SymbolPrivateProperty + : AST_SymbolClassProperty; + const AST_ClassPropertyVariant = is_private + ? AST_ClassPrivateProperty + : AST_ClassProperty; + + const key = get_symbol_ast(name, AST_SymbolVariant); + const quote = key instanceof AST_SymbolClassProperty + ? property_token.quote + : undefined; + if (is("operator", "=")) { + next(); + return annotate( + new AST_ClassPropertyVariant({ + start, + static: is_static, + quote, + key, + value: expression(false), + end: prev() + }) + ); + } else if ( + is("name") + || is("privatename") + || is("punc", "[") + || is("operator", "*") + || is("punc", ";") + || is("punc", "}") + || is("string") + || is("num") + || is("big_int") + ) { + return annotate( + new AST_ClassPropertyVariant({ + start, + static: is_static, + quote, + key, + end: prev() + }) + ); + } + } + } + + function class_static_block() { + if (!is("punc", "{")) { + return null; + } + + const start = S.token; + const body = []; + + next(); + + while (!is("punc", "}")) { + body.push(statement()); + } + + next(); + + return new AST_ClassStaticBlock({ start, body, end: prev() }); + } + + function maybe_import_attributes() { + if ( + (is("keyword", "with") || is("name", "assert")) + && !has_newline_before(S.token) + ) { + next(); + return object_or_destructuring_(); + } + return null; + } + + function import_statement() { + var start = prev(); + + var imported_name; + var imported_names; + if (is("name")) { + imported_name = as_symbol(AST_SymbolImport); + } + + if (is("punc", ",")) { + next(); + } + + imported_names = map_names(true); + + if (imported_names || imported_name) { + expect_token("name", "from"); + } + var mod_str = S.token; + if (mod_str.type !== "string") { + unexpected(); + } + next(); + + const attributes = maybe_import_attributes(); + + return new AST_Import({ + start, + imported_name, + imported_names, + module_name: new AST_String({ + start: mod_str, + value: mod_str.value, + quote: mod_str.quote, + end: mod_str, + }), + attributes, + end: S.token, + }); + } + + function import_meta(allow_calls) { + var start = S.token; + expect_token("name", "import"); + expect_token("punc", "."); + expect_token("name", "meta"); + return subscripts(new AST_ImportMeta({ + start: start, + end: prev() + }), allow_calls); + } + + function map_name(is_import) { + function make_symbol(type, quote) { + return new type({ + name: as_property_name(), + quote: quote || undefined, + start: prev(), + end: prev() + }); + } + + var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign; + var type = is_import ? AST_SymbolImport : AST_SymbolExport; + var start = S.token; + var foreign_name; + var name; + + if (is_import) { + foreign_name = make_symbol(foreign_type, start.quote); + } else { + name = make_symbol(type, start.quote); + } + if (is("name", "as")) { + next(); // The "as" word + if (is_import) { + name = make_symbol(type); + } else { + foreign_name = make_symbol(foreign_type, S.token.quote); + } + } else { + if (is_import) { + name = new type(foreign_name); + } else { + foreign_name = new foreign_type(name); + } + } + + return new AST_NameMapping({ + start: start, + foreign_name: foreign_name, + name: name, + end: prev(), + }); + } + + function map_nameAsterisk(is_import, import_or_export_foreign_name) { + var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign; + var type = is_import ? AST_SymbolImport : AST_SymbolExport; + var start = S.token; + var name, foreign_name; + var end = prev(); + + if (is_import) { + name = import_or_export_foreign_name; + } else { + foreign_name = import_or_export_foreign_name; + } + + name = name || new type({ + start: start, + name: "*", + end: end, + }); + + foreign_name = foreign_name || new foreign_type({ + start: start, + name: "*", + end: end, + }); + + return new AST_NameMapping({ + start: start, + foreign_name: foreign_name, + name: name, + end: end, + }); + } + + function map_names(is_import) { + var names; + if (is("punc", "{")) { + next(); + names = []; + while (!is("punc", "}")) { + names.push(map_name(is_import)); + if (is("punc", ",")) { + next(); + } + } + next(); + } else if (is("operator", "*")) { + var name; + next(); + if (is("name", "as")) { + next(); // The "as" word + name = is_import ? as_symbol(AST_SymbolImport) : as_symbol_or_string(AST_SymbolExportForeign); + } + names = [map_nameAsterisk(is_import, name)]; + } + return names; + } + + function export_statement() { + var start = S.token; + var is_default; + var exported_names; + + if (is("keyword", "default")) { + is_default = true; + next(); + } else if (exported_names = map_names(false)) { + if (is("name", "from")) { + next(); + + var mod_str = S.token; + if (mod_str.type !== "string") { + unexpected(); + } + next(); + + const attributes = maybe_import_attributes(); + + return new AST_Export({ + start: start, + is_default: is_default, + exported_names: exported_names, + module_name: new AST_String({ + start: mod_str, + value: mod_str.value, + quote: mod_str.quote, + end: mod_str, + }), + end: prev(), + attributes + }); + } else { + return new AST_Export({ + start: start, + is_default: is_default, + exported_names: exported_names, + end: prev(), + }); + } + } + + var node; + var exported_value; + var exported_definition; + if (is("punc", "{") + || is_default + && (is("keyword", "class") || is("keyword", "function")) + && is_token(peek(), "punc")) { + exported_value = expression(false); + semicolon(); + } else if ((node = statement(is_default)) instanceof AST_Definitions && is_default) { + unexpected(node.start); + } else if ( + node instanceof AST_Definitions + || node instanceof AST_Defun + || node instanceof AST_DefClass + ) { + exported_definition = node; + } else if ( + node instanceof AST_ClassExpression + || node instanceof AST_Function + ) { + exported_value = node; + } else if (node instanceof AST_SimpleStatement) { + exported_value = node.body; + } else { + unexpected(node.start); + } + + return new AST_Export({ + start: start, + is_default: is_default, + exported_value: exported_value, + exported_definition: exported_definition, + end: prev(), + attributes: null + }); + } + + function as_property_name() { + var tmp = S.token; + switch (tmp.type) { + case "punc": + if (tmp.value === "[") { + next(); + var ex = expression(false); + expect("]"); + return ex; + } else unexpected(tmp); + case "operator": + if (tmp.value === "*") { + next(); + return null; + } + if (!["delete", "in", "instanceof", "new", "typeof", "void"].includes(tmp.value)) { + unexpected(tmp); + } + /* falls through */ + case "name": + case "privatename": + case "string": + case "keyword": + case "atom": + next(); + return tmp.value; + case "num": + case "big_int": + next(); + return "" + tmp.value; + default: + unexpected(tmp); + } + } + + function as_name() { + var tmp = S.token; + if (tmp.type != "name" && tmp.type != "privatename") unexpected(); + next(); + return tmp.value; + } + + function _make_symbol(type) { + var name = S.token.value; + return new (name == "this" ? AST_This : + name == "super" ? AST_Super : + type)({ + name : String(name), + start : S.token, + end : S.token + }); + } + + function _verify_symbol(sym) { + var name = sym.name; + if (is_in_generator() && name == "yield") { + token_error(sym.start, "Yield cannot be used as identifier inside generators"); + } + if (S.input.has_directive("use strict")) { + if (name == "yield") { + token_error(sym.start, "Unexpected yield identifier inside strict mode"); + } + if (sym instanceof AST_SymbolDeclaration && (name == "arguments" || name == "eval")) { + token_error(sym.start, "Unexpected " + name + " in strict mode"); + } + } + } + + function as_symbol(type, noerror) { + if (!is("name")) { + if (!noerror) croak("Name expected"); + return null; + } + var sym = _make_symbol(type); + _verify_symbol(sym); + next(); + return sym; + } + + function as_symbol_or_string(type) { + if (!is("name")) { + if (!is("string")) { + croak("Name or string expected"); + } + var tok = S.token; + var ret = new type({ + start : tok, + end : tok, + name : tok.value, + quote : tok.quote + }); + next(); + return ret; + } + var sym = _make_symbol(type); + _verify_symbol(sym); + next(); + return sym; + } + + // Annotate AST_Call, AST_Lambda or AST_New with the special comments + function annotate(node, before_token = node.start) { + var comments = before_token.comments_before; + const comments_outside_parens = outer_comments_before_counts.get(before_token); + var i = comments_outside_parens != null ? comments_outside_parens : comments.length; + while (--i >= 0) { + var comment = comments[i]; + if (/[@#]__/.test(comment.value)) { + if (/[@#]__PURE__/.test(comment.value)) { + set_annotation(node, _PURE); + break; + } + if (/[@#]__INLINE__/.test(comment.value)) { + set_annotation(node, _INLINE); + break; + } + if (/[@#]__NOINLINE__/.test(comment.value)) { + set_annotation(node, _NOINLINE); + break; + } + if (/[@#]__KEY__/.test(comment.value)) { + set_annotation(node, _KEY); + break; + } + if (/[@#]__MANGLE_PROP__/.test(comment.value)) { + set_annotation(node, _MANGLEPROP); + break; + } + } + } + return node; + } + + var subscripts = function(expr, allow_calls, is_chain) { + var start = expr.start; + if (is("punc", ".")) { + next(); + if(is("privatename") && !S.in_class) + croak("Private field must be used in an enclosing class"); + const AST_DotVariant = is("privatename") ? AST_DotHash : AST_Dot; + return annotate(subscripts(new AST_DotVariant({ + start : start, + expression : expr, + optional : false, + property : as_name(), + end : prev() + }), allow_calls, is_chain)); + } + if (is("punc", "[")) { + next(); + var prop = expression(true); + expect("]"); + return annotate(subscripts(new AST_Sub({ + start : start, + expression : expr, + optional : false, + property : prop, + end : prev() + }), allow_calls, is_chain)); + } + if (allow_calls && is("punc", "(")) { + next(); + var call = new AST_Call({ + start : start, + expression : expr, + optional : false, + args : call_args(), + end : prev() + }); + annotate(call); + return subscripts(call, true, is_chain); + } + + // Optional chain + if (is("punc", "?.")) { + next(); + + let chain_contents; + + if (allow_calls && is("punc", "(")) { + next(); + + const call = new AST_Call({ + start, + optional: true, + expression: expr, + args: call_args(), + end: prev() + }); + annotate(call); + + chain_contents = subscripts(call, true, true); + } else if (is("name") || is("privatename")) { + if(is("privatename") && !S.in_class) + croak("Private field must be used in an enclosing class"); + const AST_DotVariant = is("privatename") ? AST_DotHash : AST_Dot; + chain_contents = annotate(subscripts(new AST_DotVariant({ + start, + expression: expr, + optional: true, + property: as_name(), + end: prev() + }), allow_calls, true)); + } else if (is("punc", "[")) { + next(); + const property = expression(true); + expect("]"); + chain_contents = annotate(subscripts(new AST_Sub({ + start, + expression: expr, + optional: true, + property, + end: prev() + }), allow_calls, true)); + } + + if (!chain_contents) unexpected(); + + if (chain_contents instanceof AST_Chain) return chain_contents; + + return new AST_Chain({ + start, + expression: chain_contents, + end: prev() + }); + } + + if (is("template_head")) { + if (is_chain) { + // a?.b`c` is a syntax error + unexpected(); + } + + return subscripts(new AST_PrefixedTemplateString({ + start: start, + prefix: expr, + template_string: template_string(), + end: prev() + }), allow_calls); + } + return expr; + }; + + function call_args() { + var args = []; + while (!is("punc", ")")) { + if (is("expand", "...")) { + next(); + args.push(new AST_Expansion({ + start: prev(), + expression: expression(false), + end: prev() + })); + } else { + args.push(expression(false)); + } + if (!is("punc", ")")) { + expect(","); + } + } + next(); + return args; + } + + var maybe_unary = function(allow_calls, allow_arrows) { + var start = S.token; + if (start.type == "name" && start.value == "await" && can_await()) { + next(); + return _await_expression(); + } + if (is("operator") && UNARY_PREFIX.has(start.value)) { + next(); + handle_regexp(); + var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls)); + ex.start = start; + ex.end = prev(); + return ex; + } + var val = expr_atom(allow_calls, allow_arrows); + while (is("operator") && UNARY_POSTFIX.has(S.token.value) && !has_newline_before(S.token)) { + if (val instanceof AST_Arrow) unexpected(); + val = make_unary(AST_UnaryPostfix, S.token, val); + val.start = start; + val.end = S.token; + next(); + } + return val; + }; + + function make_unary(ctor, token, expr) { + var op = token.value; + switch (op) { + case "++": + case "--": + if (!is_assignable(expr)) + croak("Invalid use of " + op + " operator", token.line, token.col, token.pos); + break; + case "delete": + if (expr instanceof AST_SymbolRef && S.input.has_directive("use strict")) + croak("Calling delete on expression not allowed in strict mode", expr.start.line, expr.start.col, expr.start.pos); + break; + } + return new ctor({ operator: op, expression: expr }); + } + + var expr_op = function(left, min_prec, no_in) { + var op = is("operator") ? S.token.value : null; + if (op == "in" && no_in) op = null; + if (op == "**" && left instanceof AST_UnaryPrefix + /* unary token in front not allowed - parenthesis required */ + && !is_token(left.start, "punc", "(") + && left.operator !== "--" && left.operator !== "++") + unexpected(left.start); + var prec = op != null ? PRECEDENCE[op] : null; + if (prec != null && (prec > min_prec || (op === "**" && min_prec === prec))) { + next(); + var right = expr_ops(no_in, prec, true); + return expr_op(new AST_Binary({ + start : left.start, + left : left, + operator : op, + right : right, + end : right.end + }), min_prec, no_in); + } + return left; + }; + + function expr_ops(no_in, min_prec, allow_calls, allow_arrows) { + // maybe_unary won't return us a AST_SymbolPrivateProperty + if (!no_in && min_prec < PRECEDENCE["in"] && is("privatename")) { + if(!S.in_class) { + croak("Private field must be used in an enclosing class"); + } + + const start = S.token; + const key = new AST_SymbolPrivateProperty({ + start, + name: start.value, + end: start + }); + next(); + expect_token("operator", "in"); + + const private_in = new AST_PrivateIn({ + start, + key, + value: expr_ops(no_in, PRECEDENCE["in"], true), + end: prev() + }); + + return expr_op(private_in, 0, no_in); + } else { + return expr_op(maybe_unary(allow_calls, allow_arrows), min_prec, no_in); + } + } + + var maybe_conditional = function(no_in) { + var start = S.token; + var expr = expr_ops(no_in, 0, true, true); + if (is("operator", "?")) { + next(); + var yes = expression(false); + expect(":"); + return new AST_Conditional({ + start : start, + condition : expr, + consequent : yes, + alternative : expression(false, no_in), + end : prev() + }); + } + return expr; + }; + + function is_assignable(expr) { + return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef; + } + + function to_destructuring(node) { + if (node instanceof AST_Object) { + node = new AST_Destructuring({ + start: node.start, + names: node.properties.map(to_destructuring), + is_array: false, + end: node.end + }); + } else if (node instanceof AST_Array) { + var names = []; + + for (var i = 0; i < node.elements.length; i++) { + // Only allow expansion as last element + if (node.elements[i] instanceof AST_Expansion) { + if (i + 1 !== node.elements.length) { + token_error(node.elements[i].start, "Spread must the be last element in destructuring array"); + } + node.elements[i].expression = to_destructuring(node.elements[i].expression); + } + + names.push(to_destructuring(node.elements[i])); + } + + node = new AST_Destructuring({ + start: node.start, + names: names, + is_array: true, + end: node.end + }); + } else if (node instanceof AST_ObjectProperty) { + node.value = to_destructuring(node.value); + } else if (node instanceof AST_Assign) { + node = new AST_DefaultAssign({ + start: node.start, + left: node.left, + operator: "=", + right: node.right, + end: node.end + }); + } + return node; + } + + // In ES6, AssignmentExpression can also be an ArrowFunction + var maybe_assign = function(no_in) { + handle_regexp(); + var start = S.token; + + if (start.type == "name" && start.value == "yield") { + if (is_in_generator()) { + next(); + return _yield_expression(); + } else if (S.input.has_directive("use strict")) { + token_error(S.token, "Unexpected yield identifier inside strict mode"); + } + } + + var left = maybe_conditional(no_in); + var val = S.token.value; + + if (is("operator") && ASSIGNMENT.has(val)) { + if (is_assignable(left) || (left = to_destructuring(left)) instanceof AST_Destructuring) { + next(); + + return new AST_Assign({ + start : start, + left : left, + operator : val, + right : maybe_assign(no_in), + logical : LOGICAL_ASSIGNMENT.has(val), + end : prev() + }); + } + croak("Invalid assignment"); + } + return left; + }; + + var to_expr_or_sequence = function(start, exprs) { + if (exprs.length === 1) { + return exprs[0]; + } else if (exprs.length > 1) { + return new AST_Sequence({ start, expressions: exprs, end: peek() }); + } else { + croak("Invalid parenthesized expression"); + } + }; + + var expression = function(commas, no_in) { + var start = S.token; + var exprs = []; + while (true) { + exprs.push(maybe_assign(no_in)); + if (!commas || !is("punc", ",")) break; + next(); + commas = true; + } + return to_expr_or_sequence(start, exprs); + }; + + function in_loop(cont) { + ++S.in_loop; + var ret = cont(); + --S.in_loop; + return ret; + } + + if (options.expression) { + return expression(true); + } + + return (function parse_toplevel() { + var start = S.token; + var body = []; + S.input.push_directives_stack(); + if (options.module) S.input.add_directive("use strict"); + while (!is("eof")) { + body.push(statement()); + } + S.input.pop_directives_stack(); + var end = prev(); + var toplevel = options.toplevel; + if (toplevel) { + toplevel.body = toplevel.body.concat(body); + toplevel.end = end; + } else { + toplevel = new AST_Toplevel({ start: start, body: body, end: end }); + } + TEMPLATE_RAWS = new Map(); + return toplevel; + })(); + +} + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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 DEFNODE(type, props, ctor, methods, base = AST_Node) { + if (!props) props = []; + else props = props.split(/\s+/); + var self_props = props; + if (base && base.PROPS) + props = props.concat(base.PROPS); + const proto = base && Object.create(base.prototype); + if (proto) { + ctor.prototype = proto; + ctor.BASE = base; + } + if (base) base.SUBCLASSES.push(ctor); + ctor.prototype.CTOR = ctor; + ctor.prototype.constructor = ctor; + ctor.PROPS = props || null; + ctor.SELF_PROPS = self_props; + ctor.SUBCLASSES = []; + if (type) { + ctor.prototype.TYPE = ctor.TYPE = type; + } + if (methods) for (let i in methods) if (HOP(methods, i)) { + if (i[0] === "$") { + ctor[i.substr(1)] = methods[i]; + } else { + ctor.prototype[i] = methods[i]; + } + } + ctor.DEFMETHOD = function(name, method) { + this.prototype[name] = method; + }; + return ctor; +} + +const has_tok_flag = (tok, flag) => Boolean(tok.flags & flag); +const set_tok_flag = (tok, flag, truth) => { + if (truth) { + tok.flags |= flag; + } else { + tok.flags &= ~flag; + } +}; + +const TOK_FLAG_NLB = 0b0001; +const TOK_FLAG_QUOTE_SINGLE = 0b0010; +const TOK_FLAG_QUOTE_EXISTS = 0b0100; +const TOK_FLAG_TEMPLATE_END = 0b1000; + +class AST_Token { + constructor(type, value, line, col, pos, nlb, comments_before, comments_after, file) { + this.flags = (nlb ? 1 : 0); + + this.type = type; + this.value = value; + this.line = line; + this.col = col; + this.pos = pos; + this.comments_before = comments_before; + this.comments_after = comments_after; + this.file = file; + + Object.seal(this); + } + + // Return a string summary of the token for node.js console.log + [Symbol.for("nodejs.util.inspect.custom")](_depth, options) { + const special = str => options.stylize(str, "special"); + const quote = typeof this.value === "string" && this.value.includes("`") ? "'" : "`"; + const value = `${quote}${this.value}${quote}`; + return `${special("[AST_Token")} ${value} at ${this.line}:${this.col}${special("]")}`; + } + + get nlb() { + return has_tok_flag(this, TOK_FLAG_NLB); + } + + set nlb(new_nlb) { + set_tok_flag(this, TOK_FLAG_NLB, new_nlb); + } + + get quote() { + return !has_tok_flag(this, TOK_FLAG_QUOTE_EXISTS) + ? "" + : (has_tok_flag(this, TOK_FLAG_QUOTE_SINGLE) ? "'" : '"'); + } + + set quote(quote_type) { + set_tok_flag(this, TOK_FLAG_QUOTE_SINGLE, quote_type === "'"); + set_tok_flag(this, TOK_FLAG_QUOTE_EXISTS, !!quote_type); + } + + get template_end() { + return has_tok_flag(this, TOK_FLAG_TEMPLATE_END); + } + + set template_end(new_template_end) { + set_tok_flag(this, TOK_FLAG_TEMPLATE_END, new_template_end); + } +} + +var AST_Node = DEFNODE("Node", "start end", function AST_Node(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + _clone: function(deep) { + if (deep) { + var self = this.clone(); + return self.transform(new TreeTransformer(function(node) { + if (node !== self) { + return node.clone(true); + } + })); + } + return new this.CTOR(this); + }, + clone: function(deep) { + return this._clone(deep); + }, + $documentation: "Base class of all AST nodes", + $propdoc: { + start: "[AST_Token] The first token of this node", + end: "[AST_Token] The last token of this node" + }, + _walk: function(visitor) { + return visitor._visit(this); + }, + walk: function(visitor) { + return this._walk(visitor); // not sure the indirection will be any help + }, + _children_backwards: () => {} +}, null); + +/* -----[ statements ]----- */ + +var AST_Statement = DEFNODE("Statement", null, function AST_Statement(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class of all statements", +}); + +var AST_Debugger = DEFNODE("Debugger", null, function AST_Debugger(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Represents a debugger statement", +}, AST_Statement); + +var AST_Directive = DEFNODE("Directive", "value quote", function AST_Directive(props) { + if (props) { + this.value = props.value; + this.quote = props.quote; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Represents a directive, like \"use strict\";", + $propdoc: { + value: "[string] The value of this directive as a plain string (it's not an AST_String!)", + quote: "[string] the original quote character" + }, +}, AST_Statement); + +var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", function AST_SimpleStatement(props) { + if (props) { + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A statement consisting of an expression, i.e. a = 1 + 2", + $propdoc: { + body: "[AST_Node] an expression node (should not be instanceof AST_Statement)" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.body._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.body); + } +}, AST_Statement); + +function walk_body(node, visitor) { + const body = node.body; + for (var i = 0, len = body.length; i < len; i++) { + body[i]._walk(visitor); + } +} + +function clone_block_scope(deep) { + var clone = this._clone(deep); + if (this.block_scope) { + clone.block_scope = this.block_scope.clone(); + } + return clone; +} + +var AST_Block = DEFNODE("Block", "body block_scope", function AST_Block(props) { + if (props) { + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A body of statements (usually braced)", + $propdoc: { + body: "[AST_Statement*] an array of statements", + block_scope: "[AST_Scope] the block scope" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + walk_body(this, visitor); + }); + }, + _children_backwards(push) { + let i = this.body.length; + while (i--) push(this.body[i]); + }, + clone: clone_block_scope +}, AST_Statement); + +var AST_BlockStatement = DEFNODE("BlockStatement", null, function AST_BlockStatement(props) { + if (props) { + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A block statement", +}, AST_Block); + +var AST_EmptyStatement = DEFNODE("EmptyStatement", null, function AST_EmptyStatement(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The empty statement (empty block or simply a semicolon)" +}, AST_Statement); + +var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", function AST_StatementWithBody(props) { + if (props) { + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`", + $propdoc: { + body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement" + } +}, AST_Statement); + +var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", function AST_LabeledStatement(props) { + if (props) { + this.label = props.label; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Statement with a label", + $propdoc: { + label: "[AST_Label] a label definition" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.label._walk(visitor); + this.body._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.body); + push(this.label); + }, + clone: function(deep) { + var node = this._clone(deep); + if (deep) { + var label = node.label; + var def = this.label; + node.walk(new TreeWalker(function(node) { + if (node instanceof AST_LoopControl + && node.label && node.label.thedef === def) { + node.label.thedef = label; + label.references.push(node); + } + })); + } + return node; + } +}, AST_StatementWithBody); + +var AST_IterationStatement = DEFNODE( + "IterationStatement", + "block_scope", + function AST_IterationStatement(props) { + if (props) { + this.block_scope = props.block_scope; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "Internal class. All loops inherit from it.", + $propdoc: { + block_scope: "[AST_Scope] the block scope for this iteration statement." + }, + clone: clone_block_scope + }, + AST_StatementWithBody +); + +var AST_DWLoop = DEFNODE("DWLoop", "condition", function AST_DWLoop(props) { + if (props) { + this.condition = props.condition; + this.block_scope = props.block_scope; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for do/while statements", + $propdoc: { + condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement" + } +}, AST_IterationStatement); + +var AST_Do = DEFNODE("Do", null, function AST_Do(props) { + if (props) { + this.condition = props.condition; + this.block_scope = props.block_scope; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `do` statement", + _walk: function(visitor) { + return visitor._visit(this, function() { + this.body._walk(visitor); + this.condition._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.condition); + push(this.body); + } +}, AST_DWLoop); + +var AST_While = DEFNODE("While", null, function AST_While(props) { + if (props) { + this.condition = props.condition; + this.block_scope = props.block_scope; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `while` statement", + _walk: function(visitor) { + return visitor._visit(this, function() { + this.condition._walk(visitor); + this.body._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.body); + push(this.condition); + }, +}, AST_DWLoop); + +var AST_For = DEFNODE("For", "init condition step", function AST_For(props) { + if (props) { + this.init = props.init; + this.condition = props.condition; + this.step = props.step; + this.block_scope = props.block_scope; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `for` statement", + $propdoc: { + init: "[AST_Node?] the `for` initialization code, or null if empty", + condition: "[AST_Node?] the `for` termination clause, or null if empty", + step: "[AST_Node?] the `for` update clause, or null if empty" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + if (this.init) this.init._walk(visitor); + if (this.condition) this.condition._walk(visitor); + if (this.step) this.step._walk(visitor); + this.body._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.body); + if (this.step) push(this.step); + if (this.condition) push(this.condition); + if (this.init) push(this.init); + }, +}, AST_IterationStatement); + +var AST_ForIn = DEFNODE("ForIn", "init object", function AST_ForIn(props) { + if (props) { + this.init = props.init; + this.object = props.object; + this.block_scope = props.block_scope; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `for ... in` statement", + $propdoc: { + init: "[AST_Node] the `for/in` initialization code", + object: "[AST_Node] the object that we're looping through" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.init._walk(visitor); + this.object._walk(visitor); + this.body._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.body); + if (this.object) push(this.object); + if (this.init) push(this.init); + }, +}, AST_IterationStatement); + +var AST_ForOf = DEFNODE("ForOf", "await", function AST_ForOf(props) { + if (props) { + this.await = props.await; + this.init = props.init; + this.object = props.object; + this.block_scope = props.block_scope; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `for ... of` statement", +}, AST_ForIn); + +var AST_With = DEFNODE("With", "expression", function AST_With(props) { + if (props) { + this.expression = props.expression; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `with` statement", + $propdoc: { + expression: "[AST_Node] the `with` expression" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + this.body._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.body); + push(this.expression); + }, +}, AST_StatementWithBody); + +/* -----[ scope and functions ]----- */ + +var AST_Scope = DEFNODE( + "Scope", + "variables uses_with uses_eval parent_scope enclosed cname", + function AST_Scope(props) { + if (props) { + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "Base class for all statements introducing a lexical scope", + $propdoc: { + variables: "[Map/S] a map of name -> SymbolDef for all variables/functions defined in this scope", + uses_with: "[boolean/S] tells whether this scope uses the `with` statement", + uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`", + parent_scope: "[AST_Scope?/S] link to the parent scope", + enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes", + cname: "[integer/S] current index for mangling variables (used internally by the mangler)", + }, + get_defun_scope: function() { + var self = this; + while (self.is_block_scope()) { + self = self.parent_scope; + } + return self; + }, + clone: function(deep, toplevel) { + var node = this._clone(deep); + if (deep && this.variables && toplevel && !this._block_scope) { + node.figure_out_scope({}, { + toplevel: toplevel, + parent_scope: this.parent_scope + }); + } else { + if (this.variables) node.variables = new Map(this.variables); + if (this.enclosed) node.enclosed = this.enclosed.slice(); + if (this._block_scope) node._block_scope = this._block_scope; + } + return node; + }, + pinned: function() { + return this.uses_eval || this.uses_with; + } + }, + AST_Block +); + +var AST_Toplevel = DEFNODE("Toplevel", "globals", function AST_Toplevel(props) { + if (props) { + this.globals = props.globals; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The toplevel scope", + $propdoc: { + globals: "[Map/S] a map of name -> SymbolDef for all undeclared names", + }, + wrap_commonjs: function(name) { + var body = this.body; + var wrapped_tl = "(function(exports){'$ORIG';})(typeof " + name + "=='undefined'?(" + name + "={}):" + name + ");"; + wrapped_tl = parse(wrapped_tl); + wrapped_tl = wrapped_tl.transform(new TreeTransformer(function(node) { + if (node instanceof AST_Directive && node.value == "$ORIG") { + return MAP.splice(body); + } + })); + return wrapped_tl; + }, + wrap_enclose: function(args_values) { + if (typeof args_values != "string") args_values = ""; + var index = args_values.indexOf(":"); + if (index < 0) index = args_values.length; + var body = this.body; + return parse([ + "(function(", + args_values.slice(0, index), + '){"$ORIG"})(', + args_values.slice(index + 1), + ")" + ].join("")).transform(new TreeTransformer(function(node) { + if (node instanceof AST_Directive && node.value == "$ORIG") { + return MAP.splice(body); + } + })); + } +}, AST_Scope); + +var AST_Expansion = DEFNODE("Expansion", "expression", function AST_Expansion(props) { + if (props) { + this.expression = props.expression; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "An expandible argument, such as ...rest, a splat, such as [1,2,...all], or an expansion in a variable declaration, such as var [first, ...rest] = list", + $propdoc: { + expression: "[AST_Node] the thing to be expanded" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression.walk(visitor); + }); + }, + _children_backwards(push) { + push(this.expression); + }, +}); + +var AST_Lambda = DEFNODE( + "Lambda", + "name argnames uses_arguments is_generator async", + function AST_Lambda(props) { + if (props) { + this.name = props.name; + this.argnames = props.argnames; + this.uses_arguments = props.uses_arguments; + this.is_generator = props.is_generator; + this.async = props.async; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "Base class for functions", + $propdoc: { + name: "[AST_SymbolDeclaration?] the name of this function", + argnames: "[AST_SymbolFunarg|AST_Destructuring|AST_Expansion|AST_DefaultAssign*] array of function arguments, destructurings, or expanding arguments", + uses_arguments: "[boolean/S] tells whether this function accesses the arguments array", + is_generator: "[boolean] is this a generator method", + async: "[boolean] is this method async", + }, + args_as_names: function () { + var out = []; + for (var i = 0; i < this.argnames.length; i++) { + if (this.argnames[i] instanceof AST_Destructuring) { + out.push(...this.argnames[i].all_symbols()); + } else { + out.push(this.argnames[i]); + } + } + return out; + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + if (this.name) this.name._walk(visitor); + var argnames = this.argnames; + for (var i = 0, len = argnames.length; i < len; i++) { + argnames[i]._walk(visitor); + } + walk_body(this, visitor); + }); + }, + _children_backwards(push) { + let i = this.body.length; + while (i--) push(this.body[i]); + + i = this.argnames.length; + while (i--) push(this.argnames[i]); + + if (this.name) push(this.name); + }, + is_braceless() { + return this.body[0] instanceof AST_Return && this.body[0].value; + }, + // Default args and expansion don't count, so .argnames.length doesn't cut it + length_property() { + let length = 0; + + for (const arg of this.argnames) { + if (arg instanceof AST_SymbolFunarg || arg instanceof AST_Destructuring) { + length++; + } + } + + return length; + } + }, + AST_Scope +); + +var AST_Accessor = DEFNODE("Accessor", null, function AST_Accessor(props) { + if (props) { + this.name = props.name; + this.argnames = props.argnames; + this.uses_arguments = props.uses_arguments; + this.is_generator = props.is_generator; + this.async = props.async; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A setter/getter function. The `name` property is always null." +}, AST_Lambda); + +var AST_Function = DEFNODE("Function", null, function AST_Function(props) { + if (props) { + this.name = props.name; + this.argnames = props.argnames; + this.uses_arguments = props.uses_arguments; + this.is_generator = props.is_generator; + this.async = props.async; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A function expression" +}, AST_Lambda); + +var AST_Arrow = DEFNODE("Arrow", null, function AST_Arrow(props) { + if (props) { + this.name = props.name; + this.argnames = props.argnames; + this.uses_arguments = props.uses_arguments; + this.is_generator = props.is_generator; + this.async = props.async; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "An ES6 Arrow function ((a) => b)" +}, AST_Lambda); + +var AST_Defun = DEFNODE("Defun", null, function AST_Defun(props) { + if (props) { + this.name = props.name; + this.argnames = props.argnames; + this.uses_arguments = props.uses_arguments; + this.is_generator = props.is_generator; + this.async = props.async; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A function definition" +}, AST_Lambda); + +/* -----[ DESTRUCTURING ]----- */ +var AST_Destructuring = DEFNODE("Destructuring", "names is_array", function AST_Destructuring(props) { + if (props) { + this.names = props.names; + this.is_array = props.is_array; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A destructuring of several names. Used in destructuring assignment and with destructuring function argument names", + $propdoc: { + "names": "[AST_Node*] Array of properties or elements", + "is_array": "[Boolean] Whether the destructuring represents an object or array" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.names.forEach(function(name) { + name._walk(visitor); + }); + }); + }, + _children_backwards(push) { + let i = this.names.length; + while (i--) push(this.names[i]); + }, + all_symbols: function() { + var out = []; + walk(this, node => { + if (node instanceof AST_SymbolDeclaration) { + out.push(node); + } + if (node instanceof AST_Lambda) { + return true; + } + }); + return out; + } +}); + +var AST_PrefixedTemplateString = DEFNODE( + "PrefixedTemplateString", + "template_string prefix", + function AST_PrefixedTemplateString(props) { + if (props) { + this.template_string = props.template_string; + this.prefix = props.prefix; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "A templatestring with a prefix, such as String.raw`foobarbaz`", + $propdoc: { + template_string: "[AST_TemplateString] The template string", + prefix: "[AST_Node] The prefix, which will get called." + }, + _walk: function(visitor) { + return visitor._visit(this, function () { + this.prefix._walk(visitor); + this.template_string._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.template_string); + push(this.prefix); + }, + } +); + +var AST_TemplateString = DEFNODE("TemplateString", "segments", function AST_TemplateString(props) { + if (props) { + this.segments = props.segments; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A template string literal", + $propdoc: { + segments: "[AST_Node*] One or more segments, starting with AST_TemplateSegment. AST_Node may follow AST_TemplateSegment, but each AST_Node must be followed by AST_TemplateSegment." + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.segments.forEach(function(seg) { + seg._walk(visitor); + }); + }); + }, + _children_backwards(push) { + let i = this.segments.length; + while (i--) push(this.segments[i]); + } +}); + +var AST_TemplateSegment = DEFNODE("TemplateSegment", "value raw", function AST_TemplateSegment(props) { + if (props) { + this.value = props.value; + this.raw = props.raw; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A segment of a template string literal", + $propdoc: { + value: "Content of the segment", + raw: "Raw source of the segment", + } +}); + +/* -----[ JUMPS ]----- */ + +var AST_Jump = DEFNODE("Jump", null, function AST_Jump(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)" +}, AST_Statement); + +/** Base class for “exits” (`return` and `throw`) */ +var AST_Exit = DEFNODE("Exit", "value", function AST_Exit(props) { + if (props) { + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for “exits” (`return` and `throw`)", + $propdoc: { + value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return" + }, + _walk: function(visitor) { + return visitor._visit(this, this.value && function() { + this.value._walk(visitor); + }); + }, + _children_backwards(push) { + if (this.value) push(this.value); + }, +}, AST_Jump); + +var AST_Return = DEFNODE("Return", null, function AST_Return(props) { + if (props) { + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `return` statement" +}, AST_Exit); + +var AST_Throw = DEFNODE("Throw", null, function AST_Throw(props) { + if (props) { + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `throw` statement" +}, AST_Exit); + +var AST_LoopControl = DEFNODE("LoopControl", "label", function AST_LoopControl(props) { + if (props) { + this.label = props.label; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for loop control statements (`break` and `continue`)", + $propdoc: { + label: "[AST_LabelRef?] the label, or null if none", + }, + _walk: function(visitor) { + return visitor._visit(this, this.label && function() { + this.label._walk(visitor); + }); + }, + _children_backwards(push) { + if (this.label) push(this.label); + }, +}, AST_Jump); + +var AST_Break = DEFNODE("Break", null, function AST_Break(props) { + if (props) { + this.label = props.label; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `break` statement" +}, AST_LoopControl); + +var AST_Continue = DEFNODE("Continue", null, function AST_Continue(props) { + if (props) { + this.label = props.label; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `continue` statement" +}, AST_LoopControl); + +var AST_Await = DEFNODE("Await", "expression", function AST_Await(props) { + if (props) { + this.expression = props.expression; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "An `await` statement", + $propdoc: { + expression: "[AST_Node] the mandatory expression being awaited", + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.expression); + }, +}); + +var AST_Yield = DEFNODE("Yield", "expression is_star", function AST_Yield(props) { + if (props) { + this.expression = props.expression; + this.is_star = props.is_star; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `yield` statement", + $propdoc: { + expression: "[AST_Node?] the value returned or thrown by this statement; could be null (representing undefined) but only when is_star is set to false", + is_star: "[Boolean] Whether this is a yield or yield* statement" + }, + _walk: function(visitor) { + return visitor._visit(this, this.expression && function() { + this.expression._walk(visitor); + }); + }, + _children_backwards(push) { + if (this.expression) push(this.expression); + } +}); + +/* -----[ IF ]----- */ + +var AST_If = DEFNODE("If", "condition alternative", function AST_If(props) { + if (props) { + this.condition = props.condition; + this.alternative = props.alternative; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `if` statement", + $propdoc: { + condition: "[AST_Node] the `if` condition", + alternative: "[AST_Statement?] the `else` part, or null if not present" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.condition._walk(visitor); + this.body._walk(visitor); + if (this.alternative) this.alternative._walk(visitor); + }); + }, + _children_backwards(push) { + if (this.alternative) { + push(this.alternative); + } + push(this.body); + push(this.condition); + } +}, AST_StatementWithBody); + +/* -----[ SWITCH ]----- */ + +var AST_Switch = DEFNODE("Switch", "expression", function AST_Switch(props) { + if (props) { + this.expression = props.expression; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `switch` statement", + $propdoc: { + expression: "[AST_Node] the `switch` “discriminant”" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + walk_body(this, visitor); + }); + }, + _children_backwards(push) { + let i = this.body.length; + while (i--) push(this.body[i]); + push(this.expression); + } +}, AST_Block); + +var AST_SwitchBranch = DEFNODE("SwitchBranch", null, function AST_SwitchBranch(props) { + if (props) { + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for `switch` branches", +}, AST_Block); + +var AST_Default = DEFNODE("Default", null, function AST_Default(props) { + if (props) { + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `default` switch branch", +}, AST_SwitchBranch); + +var AST_Case = DEFNODE("Case", "expression", function AST_Case(props) { + if (props) { + this.expression = props.expression; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `case` switch branch", + $propdoc: { + expression: "[AST_Node] the `case` expression" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + walk_body(this, visitor); + }); + }, + _children_backwards(push) { + let i = this.body.length; + while (i--) push(this.body[i]); + push(this.expression); + }, +}, AST_SwitchBranch); + +/* -----[ EXCEPTIONS ]----- */ + +var AST_Try = DEFNODE("Try", "body bcatch bfinally", function AST_Try(props) { + if (props) { + this.body = props.body; + this.bcatch = props.bcatch; + this.bfinally = props.bfinally; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `try` statement", + $propdoc: { + body: "[AST_TryBlock] the try block", + bcatch: "[AST_Catch?] the catch block, or null if not present", + bfinally: "[AST_Finally?] the finally block, or null if not present" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.body._walk(visitor); + if (this.bcatch) this.bcatch._walk(visitor); + if (this.bfinally) this.bfinally._walk(visitor); + }); + }, + _children_backwards(push) { + if (this.bfinally) push(this.bfinally); + if (this.bcatch) push(this.bcatch); + push(this.body); + }, +}, AST_Statement); + +var AST_TryBlock = DEFNODE("TryBlock", null, function AST_TryBlock(props) { + if (props) { + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The `try` block of a try statement" +}, AST_Block); + +var AST_Catch = DEFNODE("Catch", "argname", function AST_Catch(props) { + if (props) { + this.argname = props.argname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `catch` node; only makes sense as part of a `try` statement", + $propdoc: { + argname: "[AST_SymbolCatch|AST_Destructuring|AST_Expansion|AST_DefaultAssign] symbol for the exception" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + if (this.argname) this.argname._walk(visitor); + walk_body(this, visitor); + }); + }, + _children_backwards(push) { + let i = this.body.length; + while (i--) push(this.body[i]); + if (this.argname) push(this.argname); + }, +}, AST_Block); + +var AST_Finally = DEFNODE("Finally", null, function AST_Finally(props) { + if (props) { + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `finally` node; only makes sense as part of a `try` statement" +}, AST_Block); + +/* -----[ VAR/CONST ]----- */ + +var AST_DefinitionsLike = DEFNODE("DefinitionsLike", "definitions", function AST_DefinitionsLike(props) { + if (props) { + this.definitions = props.definitions; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for variable definitions and `using`", + $propdoc: { + definitions: "[AST_VarDef*|AST_UsingDef*] array of variable definitions" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + var definitions = this.definitions; + for (var i = 0, len = definitions.length; i < len; i++) { + definitions[i]._walk(visitor); + } + }); + }, + _children_backwards(push) { + let i = this.definitions.length; + while (i--) push(this.definitions[i]); + }, +}, AST_Statement); + +var AST_Definitions = DEFNODE("Definitions", null, function AST_Definitions(props) { + if (props) { + this.definitions = props.definitions; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)", +}, AST_DefinitionsLike); + +var AST_Var = DEFNODE("Var", null, function AST_Var(props) { + if (props) { + this.definitions = props.definitions; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `var` statement" +}, AST_Definitions); + +var AST_Let = DEFNODE("Let", null, function AST_Let(props) { + if (props) { + this.definitions = props.definitions; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `let` statement" +}, AST_Definitions); + +var AST_Const = DEFNODE("Const", null, function AST_Const(props) { + if (props) { + this.definitions = props.definitions; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `const` statement" +}, AST_Definitions); + +var AST_Using = DEFNODE("Using", "await", function AST_Using(props) { + if (props) { + this.await = props.await; + this.definitions = props.definitions; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `using` statement", + $propdoc: { + await: "[boolean] Whether it's `await using`" + }, +}, AST_DefinitionsLike); + +var AST_VarDefLike = DEFNODE("VarDefLike", "name value", function AST_VarDefLike(props) { + if (props) { + this.name = props.name; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A name=value pair in a variable definition statement or `using`", + $propdoc: { + name: "[AST_Destructuring|AST_SymbolDeclaration] name of the variable", + value: "[AST_Node?] initializer, or null of there's no initializer" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.name._walk(visitor); + if (this.value) this.value._walk(visitor); + }); + }, + _children_backwards(push) { + if (this.value) push(this.value); + push(this.name); + }, + declarations_as_names() { + if (this.name instanceof AST_SymbolDeclaration) { + return [this.name]; + } else { + return this.name.all_symbols(); + } + } +}); + +var AST_VarDef = DEFNODE("VarDef", null, function AST_VarDef(props) { + if (props) { + this.name = props.name; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A variable declaration; only appears in a AST_Definitions node", +}, AST_VarDefLike); + +var AST_UsingDef = DEFNODE("UsingDef", null, function AST_UsingDef(props) { + if (props) { + this.name = props.name; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Like VarDef but specific to AST_Using", +}, AST_VarDefLike); + +var AST_NameMapping = DEFNODE("NameMapping", "foreign_name name", function AST_NameMapping(props) { + if (props) { + this.foreign_name = props.foreign_name; + this.name = props.name; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The part of the export/import statement that declare names from a module.", + $propdoc: { + foreign_name: "[AST_SymbolExportForeign|AST_SymbolImportForeign] The name being exported/imported (as specified in the module)", + name: "[AST_SymbolExport|AST_SymbolImport] The name as it is visible to this module." + }, + _walk: function (visitor) { + return visitor._visit(this, function() { + this.foreign_name._walk(visitor); + this.name._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.name); + push(this.foreign_name); + }, +}); + +var AST_Import = DEFNODE( + "Import", + "imported_name imported_names module_name attributes", + function AST_Import(props) { + if (props) { + this.imported_name = props.imported_name; + this.imported_names = props.imported_names; + this.module_name = props.module_name; + this.attributes = props.attributes; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "An `import` statement", + $propdoc: { + imported_name: "[AST_SymbolImport] The name of the variable holding the module's default export.", + imported_names: "[AST_NameMapping*] The names of non-default imported variables", + module_name: "[AST_String] String literal describing where this module came from", + attributes: "[AST_Object?] The import attributes (with {...})" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + if (this.imported_name) { + this.imported_name._walk(visitor); + } + if (this.imported_names) { + this.imported_names.forEach(function(name_import) { + name_import._walk(visitor); + }); + } + this.module_name._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.module_name); + if (this.imported_names) { + let i = this.imported_names.length; + while (i--) push(this.imported_names[i]); + } + if (this.imported_name) push(this.imported_name); + }, + } +); + +var AST_ImportMeta = DEFNODE("ImportMeta", null, function AST_ImportMeta(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A reference to import.meta", +}); + +var AST_Export = DEFNODE( + "Export", + "exported_definition exported_value is_default exported_names module_name attributes", + function AST_Export(props) { + if (props) { + this.exported_definition = props.exported_definition; + this.exported_value = props.exported_value; + this.is_default = props.is_default; + this.exported_names = props.exported_names; + this.module_name = props.module_name; + this.attributes = props.attributes; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "An `export` statement", + $propdoc: { + exported_definition: "[AST_Defun|AST_Definitions|AST_DefClass?] An exported definition", + exported_value: "[AST_Node?] An exported value", + exported_names: "[AST_NameMapping*?] List of exported names", + module_name: "[AST_String?] Name of the file to load exports from", + is_default: "[Boolean] Whether this is the default exported value of this module", + attributes: "[AST_Object?] The import attributes" + }, + _walk: function (visitor) { + return visitor._visit(this, function () { + if (this.exported_definition) { + this.exported_definition._walk(visitor); + } + if (this.exported_value) { + this.exported_value._walk(visitor); + } + if (this.exported_names) { + this.exported_names.forEach(function(name_export) { + name_export._walk(visitor); + }); + } + if (this.module_name) { + this.module_name._walk(visitor); + } + }); + }, + _children_backwards(push) { + if (this.module_name) push(this.module_name); + if (this.exported_names) { + let i = this.exported_names.length; + while (i--) push(this.exported_names[i]); + } + if (this.exported_value) push(this.exported_value); + if (this.exported_definition) push(this.exported_definition); + } + }, + AST_Statement +); + +/* -----[ OTHER ]----- */ + +var AST_Call = DEFNODE( + "Call", + "expression args optional _annotations", + function AST_Call(props) { + if (props) { + this.expression = props.expression; + this.args = props.args; + this.optional = props.optional; + this._annotations = props._annotations; + this.start = props.start; + this.end = props.end; + this.initialize(); + } + + this.flags = 0; + }, + { + $documentation: "A function call expression", + $propdoc: { + expression: "[AST_Node] expression to invoke as function", + args: "[AST_Node*] array of arguments", + optional: "[boolean] whether this is an optional call (IE ?.() )", + _annotations: "[number] bitfield containing information about the call" + }, + initialize() { + if (this._annotations == null) this._annotations = 0; + }, + _walk(visitor) { + return visitor._visit(this, function() { + var args = this.args; + for (var i = 0, len = args.length; i < len; i++) { + args[i]._walk(visitor); + } + this.expression._walk(visitor); // TODO why do we need to crawl this last? + }); + }, + _children_backwards(push) { + let i = this.args.length; + while (i--) push(this.args[i]); + push(this.expression); + }, + } +); + +var AST_New = DEFNODE("New", null, function AST_New(props) { + if (props) { + this.expression = props.expression; + this.args = props.args; + this.optional = props.optional; + this._annotations = props._annotations; + this.start = props.start; + this.end = props.end; + this.initialize(); + } + + this.flags = 0; +}, { + $documentation: "An object instantiation. Derives from a function call since it has exactly the same properties" +}, AST_Call); + +var AST_Sequence = DEFNODE("Sequence", "expressions", function AST_Sequence(props) { + if (props) { + this.expressions = props.expressions; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A sequence expression (comma-separated expressions)", + $propdoc: { + expressions: "[AST_Node*] array of expressions (at least two)" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expressions.forEach(function(node) { + node._walk(visitor); + }); + }); + }, + _children_backwards(push) { + let i = this.expressions.length; + while (i--) push(this.expressions[i]); + }, +}); + +var AST_PropAccess = DEFNODE( + "PropAccess", + "expression property optional", + function AST_PropAccess(props) { + if (props) { + this.expression = props.expression; + this.property = props.property; + this.optional = props.optional; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`", + $propdoc: { + expression: "[AST_Node] the “container” expression", + property: "[AST_Node|string] the property to access. For AST_Dot & AST_DotHash this is always a plain string, while for AST_Sub it's an arbitrary AST_Node", + + optional: "[boolean] whether this is an optional property access (IE ?.)" + } + } +); + +var AST_Dot = DEFNODE("Dot", "quote", function AST_Dot(props) { + if (props) { + this.quote = props.quote; + this.expression = props.expression; + this.property = props.property; + this.optional = props.optional; + this._annotations = props._annotations; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A dotted property access expression", + $propdoc: { + quote: "[string] the original quote character when transformed from AST_Sub", + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.expression); + }, +}, AST_PropAccess); + +var AST_DotHash = DEFNODE("DotHash", "", function AST_DotHash(props) { + if (props) { + this.expression = props.expression; + this.property = props.property; + this.optional = props.optional; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A dotted property access to a private property", + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.expression); + }, +}, AST_PropAccess); + +var AST_Sub = DEFNODE("Sub", null, function AST_Sub(props) { + if (props) { + this.expression = props.expression; + this.property = props.property; + this.optional = props.optional; + this._annotations = props._annotations; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Index-style property access, i.e. `a[\"foo\"]`", + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + this.property._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.property); + push(this.expression); + }, +}, AST_PropAccess); + +var AST_Chain = DEFNODE("Chain", "expression", function AST_Chain(props) { + if (props) { + this.expression = props.expression; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A chain expression like a?.b?.(c)?.[d]", + $propdoc: { + expression: "[AST_Call|AST_Dot|AST_DotHash|AST_Sub] chain element." + }, + _walk: function (visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.expression); + }, +}); + +var AST_Unary = DEFNODE("Unary", "operator expression", function AST_Unary(props) { + if (props) { + this.operator = props.operator; + this.expression = props.expression; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for unary expressions", + $propdoc: { + operator: "[string] the operator", + expression: "[AST_Node] expression that this unary operator applies to" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.expression); + }, +}); + +var AST_UnaryPrefix = DEFNODE("UnaryPrefix", null, function AST_UnaryPrefix(props) { + if (props) { + this.operator = props.operator; + this.expression = props.expression; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Unary prefix expression, i.e. `typeof i` or `++i`" +}, AST_Unary); + +var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, function AST_UnaryPostfix(props) { + if (props) { + this.operator = props.operator; + this.expression = props.expression; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Unary postfix expression, i.e. `i++`" +}, AST_Unary); + +var AST_Binary = DEFNODE("Binary", "operator left right", function AST_Binary(props) { + if (props) { + this.operator = props.operator; + this.left = props.left; + this.right = props.right; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Binary expression, i.e. `a + b`", + $propdoc: { + left: "[AST_Node] left-hand side expression", + operator: "[string] the operator", + right: "[AST_Node] right-hand side expression" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.left._walk(visitor); + this.right._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.right); + push(this.left); + }, +}); + +var AST_Conditional = DEFNODE( + "Conditional", + "condition consequent alternative", + function AST_Conditional(props) { + if (props) { + this.condition = props.condition; + this.consequent = props.consequent; + this.alternative = props.alternative; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "Conditional expression using the ternary operator, i.e. `a ? b : c`", + $propdoc: { + condition: "[AST_Node]", + consequent: "[AST_Node]", + alternative: "[AST_Node]" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.condition._walk(visitor); + this.consequent._walk(visitor); + this.alternative._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.alternative); + push(this.consequent); + push(this.condition); + }, + } +); + +var AST_Assign = DEFNODE("Assign", "logical", function AST_Assign(props) { + if (props) { + this.logical = props.logical; + this.operator = props.operator; + this.left = props.left; + this.right = props.right; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "An assignment expression — `a = b + 5`", + $propdoc: { + logical: "Whether it's a logical assignment" + } +}, AST_Binary); + +var AST_DefaultAssign = DEFNODE("DefaultAssign", null, function AST_DefaultAssign(props) { + if (props) { + this.operator = props.operator; + this.left = props.left; + this.right = props.right; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A default assignment expression like in `(a = 3) => a`" +}, AST_Binary); + +/* -----[ LITERALS ]----- */ + +var AST_Array = DEFNODE("Array", "elements", function AST_Array(props) { + if (props) { + this.elements = props.elements; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "An array literal", + $propdoc: { + elements: "[AST_Node*] array of elements" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + var elements = this.elements; + for (var i = 0, len = elements.length; i < len; i++) { + elements[i]._walk(visitor); + } + }); + }, + _children_backwards(push) { + let i = this.elements.length; + while (i--) push(this.elements[i]); + }, +}); + +var AST_Object = DEFNODE("Object", "properties", function AST_Object(props) { + if (props) { + this.properties = props.properties; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "An object literal", + $propdoc: { + properties: "[AST_ObjectProperty*] array of properties" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + var properties = this.properties; + for (var i = 0, len = properties.length; i < len; i++) { + properties[i]._walk(visitor); + } + }); + }, + _children_backwards(push) { + let i = this.properties.length; + while (i--) push(this.properties[i]); + }, +}); + +/* -----[ OBJECT/CLASS PROPERTIES ]----- */ + +/** + * Everything inside the curly braces of an object/class is a subclass of AST_ObjectProperty, except for AST_ClassStaticBlock. + **/ +var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", function AST_ObjectProperty(props) { + if (props) { + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + this._annotations = props._annotations; + } + + this.flags = 0; +}, { + $documentation: "Base class for literal object properties", + $propdoc: { + key: "[string|AST_Node] property name. For ObjectKeyVal this is a string. For getters, setters and computed property this is an AST_Node.", + value: "[AST_Node] property value. For getters, setters and methods this is an AST_Accessor." + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + if (this.key instanceof AST_Node) + this.key._walk(visitor); + this.value._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.value); + if (this.key instanceof AST_Node) push(this.key); + }, +}); + +var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", "quote", function AST_ObjectKeyVal(props) { + if (props) { + this.quote = props.quote; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + this._annotations = props._annotations; + } + + this.flags = 0; +}, { + $documentation: "A key: value object property", + $propdoc: { + quote: "[string] the original quote character" + }, + computed_key() { + return this.key instanceof AST_Node; + } +}, AST_ObjectProperty); + +var AST_PrivateSetter = DEFNODE("PrivateSetter", "static", function AST_PrivateSetter(props) { + if (props) { + this.static = props.static; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $propdoc: { + static: "[boolean] whether this is a static private setter" + }, + $documentation: "A private setter property", + computed_key() { + return false; + } +}, AST_ObjectProperty); + +var AST_PrivateGetter = DEFNODE("PrivateGetter", "static", function AST_PrivateGetter(props) { + if (props) { + this.static = props.static; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $propdoc: { + static: "[boolean] whether this is a static private getter" + }, + $documentation: "A private getter property", + computed_key() { + return false; + } +}, AST_ObjectProperty); + +var AST_ObjectSetter = DEFNODE("ObjectSetter", "quote static", function AST_ObjectSetter(props) { + if (props) { + this.quote = props.quote; + this.static = props.static; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + this._annotations = props._annotations; + } + + this.flags = 0; +}, { + $propdoc: { + quote: "[string|undefined] the original quote character, if any", + static: "[boolean] whether this is a static setter (classes only)" + }, + $documentation: "An object setter property", + computed_key() { + return !(this.key instanceof AST_SymbolMethod); + } +}, AST_ObjectProperty); + +var AST_ObjectGetter = DEFNODE("ObjectGetter", "quote static", function AST_ObjectGetter(props) { + if (props) { + this.quote = props.quote; + this.static = props.static; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + this._annotations = props._annotations; + } + + this.flags = 0; +}, { + $propdoc: { + quote: "[string|undefined] the original quote character, if any", + static: "[boolean] whether this is a static getter (classes only)" + }, + $documentation: "An object getter property", + computed_key() { + return !(this.key instanceof AST_SymbolMethod); + } +}, AST_ObjectProperty); + +var AST_ConciseMethod = DEFNODE("ConciseMethod", "quote static", function AST_ConciseMethod(props) { + if (props) { + this.quote = props.quote; + this.static = props.static; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + this._annotations = props._annotations; + } + + this.flags = 0; +}, { + $propdoc: { + quote: "[string|undefined] the original quote character, if any", + static: "[boolean] is this method static (classes only)", + }, + $documentation: "An ES6 concise method inside an object or class", + computed_key() { + return !(this.key instanceof AST_SymbolMethod); + } +}, AST_ObjectProperty); + +var AST_PrivateMethod = DEFNODE("PrivateMethod", "static", function AST_PrivateMethod(props) { + if (props) { + this.static = props.static; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A private class method inside a class", + $propdoc: { + static: "[boolean] is this a static private method", + }, + computed_key() { + return false; + }, +}, AST_ObjectProperty); + +var AST_Class = DEFNODE("Class", "name extends properties", function AST_Class(props) { + if (props) { + this.name = props.name; + this.extends = props.extends; + this.properties = props.properties; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $propdoc: { + name: "[AST_SymbolClass|AST_SymbolDefClass?] optional class name.", + extends: "[AST_Node]? optional parent class", + properties: "[AST_ObjectProperty|AST_ClassStaticBlock]* array of properties or static blocks" + }, + $documentation: "An ES6 class", + _walk: function(visitor) { + return visitor._visit(this, function() { + if (this.name) { + this.name._walk(visitor); + } + if (this.extends) { + this.extends._walk(visitor); + } + this.properties.forEach((prop) => prop._walk(visitor)); + }); + }, + _children_backwards(push) { + let i = this.properties.length; + while (i--) push(this.properties[i]); + if (this.extends) push(this.extends); + if (this.name) push(this.name); + }, + /** go through the bits that are executed instantly, not when the class is `new`'d. Doesn't walk the name. */ + visit_nondeferred_class_parts(visitor) { + if (this.extends) { + this.extends._walk(visitor); + } + this.properties.forEach((prop) => { + if (prop instanceof AST_ClassStaticBlock) { + prop._walk(visitor); + return; + } + if (prop.computed_key()) { + visitor.push(prop); + prop.key._walk(visitor); + visitor.pop(); + } + if ( + prop instanceof AST_ClassPrivateProperty && prop.static && prop.value + || prop instanceof AST_ClassProperty && prop.static && prop.value + ) { + visitor.push(prop); + prop.value._walk(visitor); + visitor.pop(); + } + }); + }, + /** go through the bits that are executed later, when the class is `new`'d or a static method is called */ + visit_deferred_class_parts(visitor) { + this.properties.forEach((prop) => { + if ( + prop instanceof AST_ConciseMethod + || prop instanceof AST_PrivateMethod + ) { + prop.walk(visitor); + } else if ( + prop instanceof AST_ClassProperty && !prop.static && prop.value + || prop instanceof AST_ClassPrivateProperty && !prop.static && prop.value + ) { + visitor.push(prop); + prop.value._walk(visitor); + visitor.pop(); + } + }); + }, + is_self_referential: function() { + const this_id = this.name && this.name.definition().id; + let found = false; + let class_this = true; + this.visit_nondeferred_class_parts(new TreeWalker((node, descend) => { + if (found) return true; + if (node instanceof AST_This) return (found = class_this); + if (node instanceof AST_SymbolRef) return (found = node.definition().id === this_id); + if (node instanceof AST_Lambda && !(node instanceof AST_Arrow)) { + const class_this_save = class_this; + class_this = false; + descend(); + class_this = class_this_save; + return true; + } + })); + return found; + }, +}, AST_Scope /* TODO a class might have a scope but it's not a scope */); + +var AST_ClassProperty = DEFNODE("ClassProperty", "static quote", function AST_ClassProperty(props) { + if (props) { + this.static = props.static; + this.quote = props.quote; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + this._annotations = props._annotations; + } + + this.flags = 0; +}, { + $documentation: "A class property", + $propdoc: { + static: "[boolean] whether this is a static key", + quote: "[string] which quote is being used" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + if (this.key instanceof AST_Node) + this.key._walk(visitor); + if (this.value instanceof AST_Node) + this.value._walk(visitor); + }); + }, + _children_backwards(push) { + if (this.value instanceof AST_Node) push(this.value); + if (this.key instanceof AST_Node) push(this.key); + }, + computed_key() { + return !(this.key instanceof AST_SymbolClassProperty); + } +}, AST_ObjectProperty); + +var AST_ClassPrivateProperty = DEFNODE("ClassPrivateProperty", "", function AST_ClassPrivateProperty(props) { + if (props) { + this.static = props.static; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A class property for a private property", + _walk: function(visitor) { + return visitor._visit(this, function() { + if (this.value instanceof AST_Node) + this.value._walk(visitor); + }); + }, + _children_backwards(push) { + if (this.value instanceof AST_Node) push(this.value); + }, + computed_key() { + return false; + }, +}, AST_ObjectProperty); + +var AST_PrivateIn = DEFNODE("PrivateIn", "key value", function AST_PrivateIn(props) { + if (props) { + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "An `in` binop when the key is private, eg #x in this", + _walk: function(visitor) { + return visitor._visit(this, function() { + this.key._walk(visitor); + this.value._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.value); + push(this.key); + }, +}); + +var AST_DefClass = DEFNODE("DefClass", null, function AST_DefClass(props) { + if (props) { + this.name = props.name; + this.extends = props.extends; + this.properties = props.properties; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A class definition", +}, AST_Class); + +var AST_ClassStaticBlock = DEFNODE("ClassStaticBlock", "body block_scope", function AST_ClassStaticBlock (props) { + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; +}, { + $documentation: "A block containing statements to be executed in the context of the class", + $propdoc: { + body: "[AST_Statement*] an array of statements", + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + walk_body(this, visitor); + }); + }, + _children_backwards(push) { + let i = this.body.length; + while (i--) push(this.body[i]); + }, + clone: clone_block_scope, + computed_key() { + return false; + }, +}, AST_Scope); + +var AST_ClassExpression = DEFNODE("ClassExpression", null, function AST_ClassExpression(props) { + if (props) { + this.name = props.name; + this.extends = props.extends; + this.properties = props.properties; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A class expression." +}, AST_Class); + +var AST_Symbol = DEFNODE("Symbol", "scope name thedef", function AST_Symbol(props) { + if (props) { + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $propdoc: { + name: "[string] name of this symbol", + scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)", + thedef: "[SymbolDef/S] the definition of this symbol" + }, + $documentation: "Base class for all symbols" +}); + +var AST_NewTarget = DEFNODE("NewTarget", null, function AST_NewTarget(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A reference to new.target" +}); + +var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", function AST_SymbolDeclaration(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)", +}, AST_Symbol); + +var AST_SymbolVar = DEFNODE("SymbolVar", null, function AST_SymbolVar(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol defining a variable", +}, AST_SymbolDeclaration); + +var AST_SymbolBlockDeclaration = DEFNODE( + "SymbolBlockDeclaration", + null, + function AST_SymbolBlockDeclaration(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "Base class for block-scoped declaration symbols" + }, + AST_SymbolDeclaration +); + +var AST_SymbolConst = DEFNODE("SymbolConst", null, function AST_SymbolConst(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A constant declaration" +}, AST_SymbolBlockDeclaration); + +var AST_SymbolUsing = DEFNODE("SymbolUsing", null, function AST_SymbolUsing(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `using` declaration" +}, AST_SymbolBlockDeclaration); + +var AST_SymbolLet = DEFNODE("SymbolLet", null, function AST_SymbolLet(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A block-scoped `let` declaration" +}, AST_SymbolBlockDeclaration); + +var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, function AST_SymbolFunarg(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol naming a function argument", +}, AST_SymbolVar); + +var AST_SymbolDefun = DEFNODE("SymbolDefun", null, function AST_SymbolDefun(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol defining a function", +}, AST_SymbolDeclaration); + +var AST_SymbolMethod = DEFNODE("SymbolMethod", null, function AST_SymbolMethod(props) { + if (props) { + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol in an object defining a method", +}, AST_Symbol); + +var AST_SymbolClassProperty = DEFNODE("SymbolClassProperty", null, function AST_SymbolClassProperty(props) { + if (props) { + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol for a class property", +}, AST_Symbol); + +var AST_SymbolLambda = DEFNODE("SymbolLambda", null, function AST_SymbolLambda(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol naming a function expression", +}, AST_SymbolDeclaration); + +var AST_SymbolDefClass = DEFNODE("SymbolDefClass", null, function AST_SymbolDefClass(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol naming a class's name in a class declaration. Lexically scoped to its containing scope, and accessible within the class." +}, AST_SymbolBlockDeclaration); + +var AST_SymbolClass = DEFNODE("SymbolClass", null, function AST_SymbolClass(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol naming a class's name. Lexically scoped to the class." +}, AST_SymbolDeclaration); + +var AST_SymbolCatch = DEFNODE("SymbolCatch", null, function AST_SymbolCatch(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol naming the exception in catch", +}, AST_SymbolBlockDeclaration); + +var AST_SymbolImport = DEFNODE("SymbolImport", null, function AST_SymbolImport(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol referring to an imported name", +}, AST_SymbolBlockDeclaration); + +var AST_SymbolImportForeign = DEFNODE("SymbolImportForeign", "quote", function AST_SymbolImportForeign(props) { + if (props) { + this.quote = props.quote; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A symbol imported from a module, but it is defined in the other module, and its real name is irrelevant for this module's purposes", +}, AST_Symbol); + +var AST_Label = DEFNODE("Label", "references", function AST_Label(props) { + if (props) { + this.references = props.references; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + this.initialize(); + } + + this.flags = 0; +}, { + $documentation: "Symbol naming a label (declaration)", + $propdoc: { + references: "[AST_LoopControl*] a list of nodes referring to this label" + }, + initialize: function() { + this.references = []; + this.thedef = this; + } +}, AST_Symbol); + +var AST_SymbolRef = DEFNODE("SymbolRef", null, function AST_SymbolRef(props) { + if (props) { + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Reference to some symbol (not definition/declaration)", +}, AST_Symbol); + +var AST_SymbolExport = DEFNODE("SymbolExport", "quote", function AST_SymbolExport(props) { + if (props) { + this.quote = props.quote; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol referring to a name to export", +}, AST_SymbolRef); + +var AST_SymbolExportForeign = DEFNODE("SymbolExportForeign", "quote", function AST_SymbolExportForeign(props) { + if (props) { + this.quote = props.quote; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A symbol exported from this module, but it is used in the other module, and its real name is irrelevant for this module's purposes", +}, AST_Symbol); + +var AST_LabelRef = DEFNODE("LabelRef", null, function AST_LabelRef(props) { + if (props) { + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Reference to a label symbol", +}, AST_Symbol); + +var AST_SymbolPrivateProperty = DEFNODE("SymbolPrivateProperty", null, function AST_SymbolPrivateProperty(props) { + if (props) { + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A symbol that refers to a private property", +}, AST_Symbol); + +var AST_This = DEFNODE("This", null, function AST_This(props) { + if (props) { + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The `this` symbol", +}, AST_Symbol); + +var AST_Super = DEFNODE("Super", null, function AST_Super(props) { + if (props) { + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The `super` symbol", +}, AST_This); + +var AST_Constant = DEFNODE("Constant", null, function AST_Constant(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for all constants", + getValue: function() { + return this.value; + } +}); + +var AST_String = DEFNODE("String", "value quote", function AST_String(props) { + if (props) { + this.value = props.value; + this.quote = props.quote; + this.start = props.start; + this.end = props.end; + this._annotations = props._annotations; + } + + this.flags = 0; +}, { + $documentation: "A string literal", + $propdoc: { + value: "[string] the contents of this string", + quote: "[string] the original quote character" + } +}, AST_Constant); + +var AST_Number = DEFNODE("Number", "value raw", function AST_Number(props) { + if (props) { + this.value = props.value; + this.raw = props.raw; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A number literal", + $propdoc: { + value: "[number] the numeric value", + raw: "[string] numeric value as string" + } +}, AST_Constant); + +var AST_BigInt = DEFNODE("BigInt", "value raw", function AST_BigInt(props) { + if (props) { + this.value = props.value; + this.raw = props.raw; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A big int literal", + $propdoc: { + value: "[string] big int value, represented as a string", + raw: "[string] the original format preserved" + } +}, AST_Constant); + +var AST_RegExp = DEFNODE("RegExp", "value", function AST_RegExp(props) { + if (props) { + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A regexp literal", + $propdoc: { + value: "[RegExp] the actual regexp", + } +}, AST_Constant); + +var AST_Atom = DEFNODE("Atom", null, function AST_Atom(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for atoms", +}, AST_Constant); + +var AST_Null = DEFNODE("Null", null, function AST_Null(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The `null` atom", + value: null +}, AST_Atom); + +var AST_NaN = DEFNODE("NaN", null, function AST_NaN(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The impossible value", + value: 0/0 +}, AST_Atom); + +var AST_Undefined = DEFNODE("Undefined", null, function AST_Undefined(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The `undefined` value", + value: (function() {}()) +}, AST_Atom); + +var AST_Hole = DEFNODE("Hole", null, function AST_Hole(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A hole in an array", + value: (function() {}()) +}, AST_Atom); + +var AST_Infinity = DEFNODE("Infinity", null, function AST_Infinity(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The `Infinity` value", + value: 1/0 +}, AST_Atom); + +var AST_Boolean = DEFNODE("Boolean", null, function AST_Boolean(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for booleans", +}, AST_Atom); + +var AST_False = DEFNODE("False", null, function AST_False(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The `false` atom", + value: false +}, AST_Boolean); + +var AST_True = DEFNODE("True", null, function AST_True(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The `true` atom", + value: true +}, AST_Boolean); + +/* -----[ Walk function ]---- */ + +/** + * Walk nodes in depth-first search fashion. + * Callback can return `walk_abort` symbol to stop iteration. + * It can also return `true` to stop iteration just for child nodes. + * Iteration can be stopped and continued by passing the `to_visit` argument, + * which is given to the callback in the second argument. + **/ +function walk(node, cb, to_visit = [node]) { + const push = to_visit.push.bind(to_visit); + while (to_visit.length) { + const node = to_visit.pop(); + const ret = cb(node, to_visit); + + if (ret) { + if (ret === walk_abort) return true; + continue; + } + + node._children_backwards(push); + } + return false; +} + +/** + * Walks an AST node and its children. + * + * {cb} can return `walk_abort` to interrupt the walk. + * + * @param node + * @param cb {(node, info: { parent: (nth) => any }) => (boolean | undefined)} + * + * @returns {boolean} whether the walk was aborted + * + * @example + * const found_some_cond = walk_parent(my_ast_node, (node, { parent }) => { + * if (some_cond(node, parent())) return walk_abort + * }); + */ +function walk_parent(node, cb, initial_stack) { + const to_visit = [node]; + const push = to_visit.push.bind(to_visit); + const stack = initial_stack ? initial_stack.slice() : []; + const parent_pop_indices = []; + + let current; + + const info = { + parent: (n = 0) => { + if (n === -1) { + return current; + } + + // [ p1 p0 ] [ 1 0 ] + if (initial_stack && n >= stack.length) { + n -= stack.length; + return initial_stack[ + initial_stack.length - (n + 1) + ]; + } + + return stack[stack.length - (1 + n)]; + }, + }; + + while (to_visit.length) { + current = to_visit.pop(); + + while ( + parent_pop_indices.length && + to_visit.length == parent_pop_indices[parent_pop_indices.length - 1] + ) { + stack.pop(); + parent_pop_indices.pop(); + } + + const ret = cb(current, info); + + if (ret) { + if (ret === walk_abort) return true; + continue; + } + + const visit_length = to_visit.length; + + current._children_backwards(push); + + // Push only if we're going to traverse the children + if (to_visit.length > visit_length) { + stack.push(current); + parent_pop_indices.push(visit_length - 1); + } + } + + return false; +} + +const walk_abort = Symbol("abort walk"); + +/* -----[ TreeWalker ]----- */ + +class TreeWalker { + constructor(callback) { + this.visit = callback; + this.stack = []; + this.directives = Object.create(null); + } + + _visit(node, descend) { + this.push(node); + var ret = this.visit(node, descend ? function() { + descend.call(node); + } : noop); + if (!ret && descend) { + descend.call(node); + } + this.pop(); + return ret; + } + + parent(n) { + return this.stack[this.stack.length - 2 - (n || 0)]; + } + + push(node) { + if (node instanceof AST_Lambda) { + this.directives = Object.create(this.directives); + } else if (node instanceof AST_Directive && !this.directives[node.value]) { + this.directives[node.value] = node; + } else if (node instanceof AST_Class) { + this.directives = Object.create(this.directives); + if (!this.directives["use strict"]) { + this.directives["use strict"] = node; + } + } + this.stack.push(node); + } + + pop() { + var node = this.stack.pop(); + if (node instanceof AST_Lambda || node instanceof AST_Class) { + this.directives = Object.getPrototypeOf(this.directives); + } + } + + self() { + return this.stack[this.stack.length - 1]; + } + + find_parent(type) { + var stack = this.stack; + for (var i = stack.length; --i >= 0;) { + var x = stack[i]; + if (x instanceof type) return x; + } + } + + is_within_loop() { + let i = this.stack.length - 1; + let child = this.stack[i]; + while (i--) { + const node = this.stack[i]; + + if (node instanceof AST_Lambda) return false; + if ( + node instanceof AST_IterationStatement + // exclude for-loop bits that only run once + && !((node instanceof AST_For) && child === node.init) + && !((node instanceof AST_ForIn || node instanceof AST_ForOf) && child === node.object) + ) { + return true; + } + + child = node; + } + + return false; + } + + find_scope() { + var stack = this.stack; + for (var i = stack.length; --i >= 0;) { + const p = stack[i]; + if (p instanceof AST_Toplevel) return p; + if (p instanceof AST_Lambda) return p; + if (p.block_scope) return p.block_scope; + } + } + + has_directive(type) { + var dir = this.directives[type]; + if (dir) return dir; + var node = this.stack[this.stack.length - 1]; + if (node instanceof AST_Scope && node.body) { + for (var i = 0; i < node.body.length; ++i) { + var st = node.body[i]; + if (!(st instanceof AST_Directive)) break; + if (st.value == type) return st; + } + } + } + + loopcontrol_target(node) { + var stack = this.stack; + if (node.label) for (var i = stack.length; --i >= 0;) { + var x = stack[i]; + if (x instanceof AST_LabeledStatement && x.label.name == node.label.name) + return x.body; + } else for (var i = stack.length; --i >= 0;) { + var x = stack[i]; + if (x instanceof AST_IterationStatement + || node instanceof AST_Break && x instanceof AST_Switch) + return x; + } + } +} + +// Tree transformer helpers. +class TreeTransformer extends TreeWalker { + constructor(before, after) { + super(); + this.before = before; + this.after = after; + } +} + +const _PURE = 0b00000001; +const _INLINE = 0b00000010; +const _NOINLINE = 0b00000100; +const _KEY = 0b00001000; +const _MANGLEPROP = 0b00010000; + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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 def_transform(node, descend) { + node.DEFMETHOD("transform", function(tw, in_list) { + let transformed = undefined; + tw.push(this); + if (tw.before) transformed = tw.before(this, descend, in_list); + if (transformed === undefined) { + transformed = this; + descend(transformed, tw); + if (tw.after) { + const after_ret = tw.after(transformed, in_list); + if (after_ret !== undefined) transformed = after_ret; + } + } + tw.pop(); + return transformed; + }); +} + +def_transform(AST_Node, noop); + +def_transform(AST_LabeledStatement, function(self, tw) { + self.label = self.label.transform(tw); + self.body = self.body.transform(tw); +}); + +def_transform(AST_SimpleStatement, function(self, tw) { + self.body = self.body.transform(tw); +}); + +def_transform(AST_Block, function(self, tw) { + self.body = MAP(self.body, tw); +}); + +def_transform(AST_Do, function(self, tw) { + self.body = self.body.transform(tw); + self.condition = self.condition.transform(tw); +}); + +def_transform(AST_While, function(self, tw) { + self.condition = self.condition.transform(tw); + self.body = self.body.transform(tw); +}); + +def_transform(AST_For, function(self, tw) { + if (self.init) self.init = self.init.transform(tw); + if (self.condition) self.condition = self.condition.transform(tw); + if (self.step) self.step = self.step.transform(tw); + self.body = self.body.transform(tw); +}); + +def_transform(AST_ForIn, function(self, tw) { + self.init = self.init.transform(tw); + self.object = self.object.transform(tw); + self.body = self.body.transform(tw); +}); + +def_transform(AST_With, function(self, tw) { + self.expression = self.expression.transform(tw); + self.body = self.body.transform(tw); +}); + +def_transform(AST_Exit, function(self, tw) { + if (self.value) self.value = self.value.transform(tw); +}); + +def_transform(AST_LoopControl, function(self, tw) { + if (self.label) self.label = self.label.transform(tw); +}); + +def_transform(AST_If, function(self, tw) { + self.condition = self.condition.transform(tw); + self.body = self.body.transform(tw); + if (self.alternative) self.alternative = self.alternative.transform(tw); +}); + +def_transform(AST_Switch, function(self, tw) { + self.expression = self.expression.transform(tw); + self.body = MAP(self.body, tw); +}); + +def_transform(AST_Case, function(self, tw) { + self.expression = self.expression.transform(tw); + self.body = MAP(self.body, tw); +}); + +def_transform(AST_Try, function(self, tw) { + self.body = self.body.transform(tw); + if (self.bcatch) self.bcatch = self.bcatch.transform(tw); + if (self.bfinally) self.bfinally = self.bfinally.transform(tw); +}); + +def_transform(AST_Catch, function(self, tw) { + if (self.argname) self.argname = self.argname.transform(tw); + self.body = MAP(self.body, tw); +}); + +def_transform(AST_DefinitionsLike, function(self, tw) { + self.definitions = MAP(self.definitions, tw); +}); + +def_transform(AST_VarDefLike, function(self, tw) { + self.name = self.name.transform(tw); + if (self.value) self.value = self.value.transform(tw); +}); + +def_transform(AST_Destructuring, function(self, tw) { + self.names = MAP(self.names, tw); +}); + +def_transform(AST_Lambda, function(self, tw) { + if (self.name) self.name = self.name.transform(tw); + self.argnames = MAP(self.argnames, tw, /* allow_splicing */ false); + if (self.body instanceof AST_Node) { + self.body = self.body.transform(tw); + } else { + self.body = MAP(self.body, tw); + } +}); + +def_transform(AST_Call, function(self, tw) { + self.expression = self.expression.transform(tw); + self.args = MAP(self.args, tw, /* allow_splicing */ false); +}); + +def_transform(AST_Sequence, function(self, tw) { + const result = MAP(self.expressions, tw); + self.expressions = result.length + ? result + : [new AST_Number({ value: 0 })]; +}); + +def_transform(AST_PropAccess, function(self, tw) { + self.expression = self.expression.transform(tw); +}); + +def_transform(AST_Sub, function(self, tw) { + self.expression = self.expression.transform(tw); + self.property = self.property.transform(tw); +}); + +def_transform(AST_Chain, function(self, tw) { + self.expression = self.expression.transform(tw); +}); + +def_transform(AST_Yield, function(self, tw) { + if (self.expression) self.expression = self.expression.transform(tw); +}); + +def_transform(AST_Await, function(self, tw) { + self.expression = self.expression.transform(tw); +}); + +def_transform(AST_Unary, function(self, tw) { + self.expression = self.expression.transform(tw); +}); + +def_transform(AST_Binary, function(self, tw) { + self.left = self.left.transform(tw); + self.right = self.right.transform(tw); +}); + +def_transform(AST_PrivateIn, function(self, tw) { + self.key = self.key.transform(tw); + self.value = self.value.transform(tw); +}); + +def_transform(AST_Conditional, function(self, tw) { + self.condition = self.condition.transform(tw); + self.consequent = self.consequent.transform(tw); + self.alternative = self.alternative.transform(tw); +}); + +def_transform(AST_Array, function(self, tw) { + self.elements = MAP(self.elements, tw); +}); + +def_transform(AST_Object, function(self, tw) { + self.properties = MAP(self.properties, tw); +}); + +def_transform(AST_ObjectProperty, function(self, tw) { + if (self.key instanceof AST_Node) { + self.key = self.key.transform(tw); + } + if (self.value) self.value = self.value.transform(tw); +}); + +def_transform(AST_Class, function(self, tw) { + if (self.name) self.name = self.name.transform(tw); + if (self.extends) self.extends = self.extends.transform(tw); + self.properties = MAP(self.properties, tw); +}); + +def_transform(AST_ClassStaticBlock, function(self, tw) { + self.body = MAP(self.body, tw); +}); + +def_transform(AST_Expansion, function(self, tw) { + self.expression = self.expression.transform(tw); +}); + +def_transform(AST_NameMapping, function(self, tw) { + self.foreign_name = self.foreign_name.transform(tw); + self.name = self.name.transform(tw); +}); + +def_transform(AST_Import, function(self, tw) { + if (self.imported_name) self.imported_name = self.imported_name.transform(tw); + if (self.imported_names) MAP(self.imported_names, tw); + self.module_name = self.module_name.transform(tw); +}); + +def_transform(AST_Export, function(self, tw) { + if (self.exported_definition) self.exported_definition = self.exported_definition.transform(tw); + if (self.exported_value) self.exported_value = self.exported_value.transform(tw); + if (self.exported_names) MAP(self.exported_names, tw); + if (self.module_name) self.module_name = self.module_name.transform(tw); +}); + +def_transform(AST_TemplateString, function(self, tw) { + self.segments = MAP(self.segments, tw); +}); + +def_transform(AST_PrefixedTemplateString, function(self, tw) { + self.prefix = self.prefix.transform(tw); + self.template_string = self.template_string.transform(tw); +}); + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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() { + + var normalize_directives = function(body) { + for (var i = 0; i < body.length; i++) { + if (body[i] instanceof AST_Statement && body[i].body instanceof AST_String) { + body[i] = new AST_Directive({ + start: body[i].start, + end: body[i].end, + quote: '"', + value: body[i].body.value + }); + } else { + return body; + } + } + + return body; + }; + + function import_attributes_from_moz(attributes) { + if (attributes && attributes.length > 0) { + return new AST_Object({ + start: my_start_token(attributes), + end: my_end_token(attributes), + properties: attributes.map((attr) => + new AST_ObjectKeyVal({ + start: my_start_token(attr), + end: my_end_token(attr), + key: attr.key.name || attr.key.value, + value: from_moz(attr.value) + }) + ) + }); + } + return null; + } + + var MOZ_TO_ME = { + Program: function(M) { + return new AST_Toplevel({ + start: my_start_token(M), + end: my_end_token(M), + body: normalize_directives(M.body.map(from_moz)) + }); + }, + + ArrayPattern: function(M) { + return new AST_Destructuring({ + start: my_start_token(M), + end: my_end_token(M), + names: M.elements.map(function(elm) { + if (elm === null) { + return new AST_Hole(); + } + return from_moz(elm); + }), + is_array: true + }); + }, + + ObjectPattern: function(M) { + return new AST_Destructuring({ + start: my_start_token(M), + end: my_end_token(M), + names: M.properties.map(from_moz), + is_array: false + }); + }, + + AssignmentPattern: function(M) { + return new AST_DefaultAssign({ + start: my_start_token(M), + end: my_end_token(M), + left: from_moz(M.left), + operator: "=", + right: from_moz(M.right) + }); + }, + + SpreadElement: function(M) { + return new AST_Expansion({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz(M.argument) + }); + }, + + RestElement: function(M) { + return new AST_Expansion({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz(M.argument) + }); + }, + + TemplateElement: function(M) { + return new AST_TemplateSegment({ + start: my_start_token(M), + end: my_end_token(M), + value: M.value.cooked, + raw: M.value.raw + }); + }, + + TemplateLiteral: function(M) { + var segments = []; + for (var i = 0; i < M.quasis.length; i++) { + segments.push(from_moz(M.quasis[i])); + if (M.expressions[i]) { + segments.push(from_moz(M.expressions[i])); + } + } + return new AST_TemplateString({ + start: my_start_token(M), + end: my_end_token(M), + segments: segments + }); + }, + + TaggedTemplateExpression: function(M) { + return new AST_PrefixedTemplateString({ + start: my_start_token(M), + end: my_end_token(M), + template_string: from_moz(M.quasi), + prefix: from_moz(M.tag) + }); + }, + + FunctionDeclaration: function(M) { + return new AST_Defun({ + start: my_start_token(M), + end: my_end_token(M), + name: M.id && from_moz_symbol(AST_SymbolDefun, M.id), + argnames: M.params.map(M => from_moz_pattern(M, AST_SymbolFunarg)), + is_generator: M.generator, + async: M.async, + body: normalize_directives(from_moz(M.body).body) + }); + }, + + FunctionExpression: function(M) { + return from_moz_lambda(M, /*is_method=*/false); + }, + + ArrowFunctionExpression: function(M) { + const body = M.body.type === "BlockStatement" + ? from_moz(M.body).body + : [make_node(AST_Return, {}, { value: from_moz(M.body) })]; + return new AST_Arrow({ + start: my_start_token(M), + end: my_end_token(M), + argnames: M.params.map(p => from_moz_pattern(p, AST_SymbolFunarg)), + body, + async: M.async, + }); + }, + + ExpressionStatement: function(M) { + return new AST_SimpleStatement({ + start: my_start_token(M), + end: my_end_token(M), + body: from_moz(M.expression) + }); + }, + + TryStatement: function(M) { + var handlers = M.handlers || [M.handler]; + if (handlers.length > 1 || M.guardedHandlers && M.guardedHandlers.length) { + throw new Error("Multiple catch clauses are not supported."); + } + return new AST_Try({ + start : my_start_token(M), + end : my_end_token(M), + body : new AST_TryBlock(from_moz(M.block)), + bcatch : from_moz(handlers[0]), + bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null + }); + }, + + Property: function(M) { + if (M.kind == "init" && !M.method) { + var args = { + start : my_start_token(M.key || M.value), + end : my_end_token(M.value), + key : M.computed + ? from_moz(M.key) + : M.key.name || String(M.key.value), + quote : from_moz_quote(M.key, M.computed), + static : false, // always an object + value : from_moz(M.value) + }; + + return new AST_ObjectKeyVal(args); + } else { + var value = from_moz_lambda(M.value, /*is_method=*/true); + var args = { + start : my_start_token(M.key || M.value), + end : my_end_token(M.value), + key : M.computed + ? from_moz(M.key) + : from_moz_symbol(AST_SymbolMethod, M.key), + quote : from_moz_quote(M.key, M.computed), + static : false, // always an object + value, + }; + + if (M.kind == "get") return new AST_ObjectGetter(args); + if (M.kind == "set") return new AST_ObjectSetter(args); + if (M.method) return new AST_ConciseMethod(args); + } + }, + + MethodDefinition: function(M) { + const is_private = M.key.type === "PrivateIdentifier"; + const key = M.computed ? from_moz(M.key) : new AST_SymbolMethod({ name: M.key.name || String(M.key.value) }); + + var args = { + start : my_start_token(M), + end : my_end_token(M), + key, + quote : from_moz_quote(M.key, M.computed), + value : from_moz_lambda(M.value, /*is_method=*/true), + static : M.static, + }; + if (M.kind == "get") { + return new (is_private ? AST_PrivateGetter : AST_ObjectGetter)(args); + } + if (M.kind == "set") { + return new (is_private ? AST_PrivateSetter : AST_ObjectSetter)(args); + } + return new (is_private ? AST_PrivateMethod : AST_ConciseMethod)(args); + }, + + FieldDefinition: function(M) { + let key; + if (M.computed) { + key = from_moz(M.key); + } else { + if (M.key.type !== "Identifier") throw new Error("Non-Identifier key in FieldDefinition"); + key = from_moz(M.key); + } + return new AST_ClassProperty({ + start : my_start_token(M), + end : my_end_token(M), + quote : from_moz_quote(M.key, M.computed), + key, + value : from_moz(M.value), + static : M.static, + }); + }, + + PropertyDefinition: function(M) { + let key; + if (M.computed) { + key = from_moz(M.key); + } else if (M.key.type === "PrivateIdentifier") { + return new AST_ClassPrivateProperty({ + start : my_start_token(M), + end : my_end_token(M), + key : from_moz(M.key), + value : from_moz(M.value), + static : M.static, + }); + } else { + key = from_moz_symbol(AST_SymbolClassProperty, M.key); + } + + return new AST_ClassProperty({ + start : my_start_token(M), + end : my_end_token(M), + quote : from_moz_quote(M.key, M.computed), + key, + value : from_moz(M.value), + static : M.static, + }); + }, + + PrivateIdentifier: function (M) { + return new AST_SymbolPrivateProperty({ + start: my_start_token(M), + end: my_end_token(M), + name: M.name + }); + }, + + StaticBlock: function(M) { + return new AST_ClassStaticBlock({ + start : my_start_token(M), + end : my_end_token(M), + body : M.body.map(from_moz), + }); + }, + + ArrayExpression: function(M) { + return new AST_Array({ + start : my_start_token(M), + end : my_end_token(M), + elements : M.elements.map(function(elem) { + return elem === null ? new AST_Hole() : from_moz(elem); + }) + }); + }, + + ObjectExpression: function(M) { + return new AST_Object({ + start : my_start_token(M), + end : my_end_token(M), + properties : M.properties.map(function(prop) { + if (prop.type === "SpreadElement") { + return from_moz(prop); + } + prop.type = "Property"; + return from_moz(prop); + }) + }); + }, + + SequenceExpression: function(M) { + return new AST_Sequence({ + start : my_start_token(M), + end : my_end_token(M), + expressions: M.expressions.map(from_moz) + }); + }, + + MemberExpression: function(M) { + if (M.property.type === "PrivateIdentifier") { + return new AST_DotHash({ + start : my_start_token(M), + end : my_end_token(M), + property : M.property.name, + expression : from_moz(M.object), + optional : M.optional || false + }); + } + return new (M.computed ? AST_Sub : AST_Dot)({ + start : my_start_token(M), + end : my_end_token(M), + property : M.computed ? from_moz(M.property) : M.property.name, + expression : from_moz(M.object), + optional : M.optional || false + }); + }, + + ChainExpression: function(M) { + return new AST_Chain({ + start : my_start_token(M), + end : my_end_token(M), + expression : from_moz(M.expression) + }); + }, + + SwitchCase: function(M) { + return new (M.test ? AST_Case : AST_Default)({ + start : my_start_token(M), + end : my_end_token(M), + expression : from_moz(M.test), + body : M.consequent.map(from_moz) + }); + }, + + VariableDeclaration: function(M) { + let decl_type; + let defs_type = AST_VarDef; + let sym_type; + let await_using = false; + if (M.kind === "const") { + decl_type = AST_Const; + sym_type = AST_SymbolConst; + } else if (M.kind === "let") { + decl_type = AST_Let; + sym_type = AST_SymbolLet; + } else if (M.kind === "using") { + decl_type = AST_Using; + defs_type = AST_UsingDef; + sym_type = AST_SymbolUsing; + } else if (M.kind === "await using") { + decl_type = AST_Using; + defs_type = AST_UsingDef; + sym_type = AST_SymbolUsing; + await_using = true; + } else { + decl_type = AST_Var; + sym_type = AST_SymbolVar; + } + const definitions = M.declarations.map(M => { + return new defs_type({ + start: my_start_token(M), + end: my_end_token(M), + name: from_moz_pattern(M.id, sym_type), + value: from_moz(M.init), + }); + }); + return new decl_type({ + start : my_start_token(M), + end : my_end_token(M), + definitions : definitions, + await : await_using, + }); + }, + + ImportDeclaration: function(M) { + var imported_name = null; + var imported_names = null; + M.specifiers.forEach(function (specifier) { + if (specifier.type === "ImportSpecifier" || specifier.type === "ImportNamespaceSpecifier") { + if (!imported_names) { imported_names = []; } + imported_names.push(from_moz(specifier)); + } else if (specifier.type === "ImportDefaultSpecifier") { + imported_name = from_moz(specifier); + } + }); + return new AST_Import({ + start : my_start_token(M), + end : my_end_token(M), + imported_name: imported_name, + imported_names : imported_names, + module_name : from_moz(M.source), + attributes: import_attributes_from_moz(M.attributes || M.assertions) + }); + }, + + ImportSpecifier: function(M) { + return new AST_NameMapping({ + start: my_start_token(M), + end: my_end_token(M), + foreign_name: from_moz_symbol(AST_SymbolImportForeign, M.imported, M.imported.type === "Literal"), + name: from_moz_symbol(AST_SymbolImport, M.local) + }); + }, + + ImportDefaultSpecifier: function(M) { + return from_moz_symbol(AST_SymbolImport, M.local); + }, + + ImportNamespaceSpecifier: function(M) { + return new AST_NameMapping({ + start: my_start_token(M), + end: my_end_token(M), + foreign_name: new AST_SymbolImportForeign({ name: "*" }), + name: from_moz_symbol(AST_SymbolImport, M.local) + }); + }, + + ImportExpression: function(M) { + const args = [from_moz(M.source)]; + if (M.options) { + args.push(from_moz(M.options)); + } + return new AST_Call({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz({ + type: "Identifier", + name: "import" + }), + optional: false, + args + }); + }, + + ExportAllDeclaration: function(M) { + var foreign_name = M.exported == null ? + new AST_SymbolExportForeign({ name: "*" }) : + from_moz_symbol(AST_SymbolExportForeign, M.exported, M.exported.type === "Literal"); + return new AST_Export({ + start: my_start_token(M), + end: my_end_token(M), + exported_names: [ + new AST_NameMapping({ + start: my_start_token(M), + end: my_end_token(M), + name: new AST_SymbolExport({ name: "*" }), + foreign_name: foreign_name + }) + ], + module_name: from_moz(M.source), + attributes: import_attributes_from_moz(M.attributes || M.assertions) + }); + }, + + ExportNamedDeclaration: function(M) { + if (M.declaration) { + // export const, export function, ... + return new AST_Export({ + start: my_start_token(M), + end: my_end_token(M), + exported_definition: from_moz(M.declaration), + exported_names: null, + module_name: null, + attributes: null, + }); + } else { + return new AST_Export({ + start: my_start_token(M), + end: my_end_token(M), + exported_definition: null, + exported_names: M.specifiers && M.specifiers.length ? M.specifiers.map(from_moz) : [], + module_name: from_moz(M.source), + attributes: import_attributes_from_moz(M.attributes || M.assertions), + }); + } + }, + + ExportDefaultDeclaration: function(M) { + return new AST_Export({ + start: my_start_token(M), + end: my_end_token(M), + exported_value: from_moz(M.declaration), + is_default: true + }); + }, + + ExportSpecifier: function(M) { + return new AST_NameMapping({ + start: my_start_token(M), + end: my_end_token(M), + foreign_name: from_moz_symbol(AST_SymbolExportForeign, M.exported, M.exported.type === "Literal"), + name: from_moz_symbol(AST_SymbolExport, M.local, M.local.type === "Literal"), + }); + }, + + Literal: function(M) { + var val = M.value, args = { + start : my_start_token(M), + end : my_end_token(M) + }; + var rx = M.regex; + if (rx && rx.pattern) { + // RegExpLiteral as per ESTree AST spec + args.value = { + source: rx.pattern, + flags: rx.flags + }; + return new AST_RegExp(args); + } else if (rx) { + // support legacy RegExp + const rx_source = M.raw || val; + const match = rx_source.match(/^\/(.*)\/(\w*)$/); + if (!match) throw new Error("Invalid regex source " + rx_source); + const [_, source, flags] = match; + args.value = { source, flags }; + return new AST_RegExp(args); + } + const bi = typeof M.value === "bigint" ? M.value.toString() : M.bigint; + if (typeof bi === "string") { + args.value = bi; + args.raw = M.raw; + return new AST_BigInt(args); + } + if (val === null) return new AST_Null(args); + switch (typeof val) { + case "string": + args.quote = "\""; + args.value = val; + return new AST_String(args); + case "number": + args.value = val; + args.raw = M.raw || val.toString(); + return new AST_Number(args); + case "boolean": + return new (val ? AST_True : AST_False)(args); + } + }, + + MetaProperty: function(M) { + if (M.meta.name === "new" && M.property.name === "target") { + return new AST_NewTarget({ + start: my_start_token(M), + end: my_end_token(M) + }); + } else if (M.meta.name === "import" && M.property.name === "meta") { + return new AST_ImportMeta({ + start: my_start_token(M), + end: my_end_token(M) + }); + } + }, + + Identifier: function(M) { + return new AST_SymbolRef({ + start : my_start_token(M), + end : my_end_token(M), + name : M.name + }); + }, + + EmptyStatement: function(M) { + return new AST_EmptyStatement({ + start: my_start_token(M), + end: my_end_token(M) + }); + }, + + BlockStatement: function(M) { + return new AST_BlockStatement({ + start: my_start_token(M), + end: my_end_token(M), + body: M.body.map(from_moz) + }); + }, + + IfStatement: function(M) { + return new AST_If({ + start: my_start_token(M), + end: my_end_token(M), + condition: from_moz(M.test), + body: from_moz(M.consequent), + alternative: from_moz(M.alternate) + }); + }, + + LabeledStatement: function(M) { + try { + const label = from_moz_symbol(AST_Label, M.label); + FROM_MOZ_LABELS.push(label); + + const stat = new AST_LabeledStatement({ + start: my_start_token(M), + end: my_end_token(M), + label, + body: from_moz(M.body) + }); + + return stat; + } finally { + FROM_MOZ_LABELS.pop(); + } + }, + + BreakStatement: function(M) { + return new AST_Break({ + start: my_start_token(M), + end: my_end_token(M), + label: from_moz_label_ref(M.label), + }); + }, + + ContinueStatement: function(M) { + return new AST_Continue({ + start: my_start_token(M), + end: my_end_token(M), + label: from_moz_label_ref(M.label), + }); + }, + + WithStatement: function(M) { + return new AST_With({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz(M.object), + body: from_moz(M.body) + }); + }, + + SwitchStatement: function(M) { + return new AST_Switch({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz(M.discriminant), + body: M.cases.map(from_moz) + }); + }, + + ReturnStatement: function(M) { + return new AST_Return({ + start: my_start_token(M), + end: my_end_token(M), + value: from_moz(M.argument) + }); + }, + + ThrowStatement: function(M) { + return new AST_Throw({ + start: my_start_token(M), + end: my_end_token(M), + value: from_moz(M.argument) + }); + }, + + WhileStatement: function(M) { + return new AST_While({ + start: my_start_token(M), + end: my_end_token(M), + condition: from_moz(M.test), + body: from_moz(M.body) + }); + }, + + DoWhileStatement: function(M) { + return new AST_Do({ + start: my_start_token(M), + end: my_end_token(M), + condition: from_moz(M.test), + body: from_moz(M.body) + }); + }, + + ForStatement: function(M) { + return new AST_For({ + start: my_start_token(M), + end: my_end_token(M), + init: from_moz(M.init), + condition: from_moz(M.test), + step: from_moz(M.update), + body: from_moz(M.body) + }); + }, + + ForInStatement: function(M) { + return new AST_ForIn({ + start: my_start_token(M), + end: my_end_token(M), + init: from_moz(M.left), + object: from_moz(M.right), + body: from_moz(M.body) + }); + }, + + ForOfStatement: function(M) { + return new AST_ForOf({ + start: my_start_token(M), + end: my_end_token(M), + init: from_moz(M.left), + object: from_moz(M.right), + body: from_moz(M.body), + await: M.await + }); + }, + + AwaitExpression: function(M) { + return new AST_Await({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz(M.argument) + }); + }, + + YieldExpression: function(M) { + return new AST_Yield({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz(M.argument), + is_star: M.delegate + }); + }, + + DebuggerStatement: function(M) { + return new AST_Debugger({ + start: my_start_token(M), + end: my_end_token(M) + }); + }, + + CatchClause: function(M) { + return new AST_Catch({ + start: my_start_token(M), + end: my_end_token(M), + argname: M.param ? from_moz_pattern(M.param, AST_SymbolCatch) : null, + body: from_moz(M.body).body + }); + }, + + ThisExpression: function(M) { + return new AST_This({ + start: my_start_token(M), + name: "this", + end: my_end_token(M) + }); + }, + + Super: function(M) { + return new AST_Super({ + start: my_start_token(M), + end: my_end_token(M), + name: "super", + }); + }, + + BinaryExpression: function(M) { + if (M.left.type === "PrivateIdentifier") { + return new AST_PrivateIn({ + start: my_start_token(M), + end: my_end_token(M), + key: new AST_SymbolPrivateProperty({ + start: my_start_token(M.left), + end: my_end_token(M.left), + name: M.left.name + }), + value: from_moz(M.right), + }); + } + return new AST_Binary({ + start: my_start_token(M), + end: my_end_token(M), + operator: M.operator, + left: from_moz(M.left), + right: from_moz(M.right) + }); + }, + + LogicalExpression: function(M) { + return new AST_Binary({ + start: my_start_token(M), + end: my_end_token(M), + operator: M.operator, + left: from_moz(M.left), + right: from_moz(M.right) + }); + }, + + AssignmentExpression: function(M) { + return new AST_Assign({ + start: my_start_token(M), + end: my_end_token(M), + operator: M.operator, + logical: M.operator === "??=" || M.operator === "&&=" || M.operator === "||=", + left: from_moz(M.left), + right: from_moz(M.right) + }); + }, + + ConditionalExpression: function(M) { + return new AST_Conditional({ + start: my_start_token(M), + end: my_end_token(M), + condition: from_moz(M.test), + consequent: from_moz(M.consequent), + alternative: from_moz(M.alternate) + }); + }, + + NewExpression: function(M) { + return new AST_New({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz(M.callee), + args: M.arguments.map(from_moz) + }); + }, + + CallExpression: function(M) { + return new AST_Call({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz(M.callee), + optional: M.optional, + args: M.arguments.map(from_moz) + }); + } + }; + + MOZ_TO_ME.UpdateExpression = + MOZ_TO_ME.UnaryExpression = function To_Moz_Unary(M) { + var prefix = "prefix" in M ? M.prefix + : M.type == "UnaryExpression" ? true : false; + return new (prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({ + start : my_start_token(M), + end : my_end_token(M), + operator : M.operator, + expression : from_moz(M.argument) + }); + }; + + MOZ_TO_ME.ClassDeclaration = + MOZ_TO_ME.ClassExpression = function From_Moz_Class(M) { + return new (M.type === "ClassDeclaration" ? AST_DefClass : AST_ClassExpression)({ + start : my_start_token(M), + end : my_end_token(M), + name : M.id && from_moz_symbol(M.type === "ClassDeclaration" ? AST_SymbolDefClass : AST_SymbolClass, M.id), + extends : from_moz(M.superClass), + properties: M.body.body.map(from_moz) + }); + }; + + def_to_moz(AST_EmptyStatement, function To_Moz_EmptyStatement() { + return { + type: "EmptyStatement" + }; + }); + def_to_moz(AST_BlockStatement, function To_Moz_BlockStatement(M) { + return { + type: "BlockStatement", + body: M.body.map(to_moz) + }; + }); + def_to_moz(AST_If, function To_Moz_IfStatement(M) { + return { + type: "IfStatement", + test: to_moz(M.condition), + consequent: to_moz(M.body), + alternate: to_moz(M.alternative) + }; + }); + def_to_moz(AST_LabeledStatement, function To_Moz_LabeledStatement(M) { + return { + type: "LabeledStatement", + label: to_moz(M.label), + body: to_moz(M.body) + }; + }); + def_to_moz(AST_Break, function To_Moz_BreakStatement(M) { + return { + type: "BreakStatement", + label: to_moz(M.label) + }; + }); + def_to_moz(AST_Continue, function To_Moz_ContinueStatement(M) { + return { + type: "ContinueStatement", + label: to_moz(M.label) + }; + }); + def_to_moz(AST_With, function To_Moz_WithStatement(M) { + return { + type: "WithStatement", + object: to_moz(M.expression), + body: to_moz(M.body) + }; + }); + def_to_moz(AST_Switch, function To_Moz_SwitchStatement(M) { + return { + type: "SwitchStatement", + discriminant: to_moz(M.expression), + cases: M.body.map(to_moz) + }; + }); + def_to_moz(AST_Return, function To_Moz_ReturnStatement(M) { + return { + type: "ReturnStatement", + argument: to_moz(M.value) + }; + }); + def_to_moz(AST_Throw, function To_Moz_ThrowStatement(M) { + return { + type: "ThrowStatement", + argument: to_moz(M.value) + }; + }); + def_to_moz(AST_While, function To_Moz_WhileStatement(M) { + return { + type: "WhileStatement", + test: to_moz(M.condition), + body: to_moz(M.body) + }; + }); + def_to_moz(AST_Do, function To_Moz_DoWhileStatement(M) { + return { + type: "DoWhileStatement", + test: to_moz(M.condition), + body: to_moz(M.body) + }; + }); + def_to_moz(AST_For, function To_Moz_ForStatement(M) { + return { + type: "ForStatement", + init: to_moz(M.init), + test: to_moz(M.condition), + update: to_moz(M.step), + body: to_moz(M.body) + }; + }); + def_to_moz(AST_ForIn, function To_Moz_ForInStatement(M) { + return { + type: "ForInStatement", + left: to_moz(M.init), + right: to_moz(M.object), + body: to_moz(M.body) + }; + }); + def_to_moz(AST_ForOf, function To_Moz_ForOfStatement(M) { + return { + type: "ForOfStatement", + left: to_moz(M.init), + right: to_moz(M.object), + body: to_moz(M.body), + await: M.await + }; + }); + def_to_moz(AST_Await, function To_Moz_AwaitExpression(M) { + return { + type: "AwaitExpression", + argument: to_moz(M.expression) + }; + }); + def_to_moz(AST_Yield, function To_Moz_YieldExpression(M) { + return { + type: "YieldExpression", + argument: to_moz(M.expression), + delegate: M.is_star + }; + }); + def_to_moz(AST_Debugger, function To_Moz_DebuggerStatement() { + return { + type: "DebuggerStatement" + }; + }); + def_to_moz(AST_VarDefLike, function To_Moz_VariableDeclarator(M) { + return { + type: "VariableDeclarator", + id: to_moz(M.name), + init: to_moz(M.value) + }; + }); + + def_to_moz(AST_This, function To_Moz_ThisExpression() { + return { + type: "ThisExpression" + }; + }); + def_to_moz(AST_Super, function To_Moz_Super() { + return { + type: "Super" + }; + }); + def_to_moz(AST_Conditional, function To_Moz_ConditionalExpression(M) { + return { + type: "ConditionalExpression", + test: to_moz(M.condition), + consequent: to_moz(M.consequent), + alternate: to_moz(M.alternative) + }; + }); + def_to_moz(AST_New, function To_Moz_NewExpression(M) { + return { + type: "NewExpression", + callee: to_moz(M.expression), + arguments: M.args.map(to_moz) + }; + }); + def_to_moz(AST_Call, function To_Moz_CallExpression(M) { + if (M.expression instanceof AST_SymbolRef && M.expression.name === "import") { + const [source, options] = M.args.map(to_moz); + return { + type: "ImportExpression", + source, + options: options || null + }; + } + + return { + type: "CallExpression", + callee: to_moz(M.expression), + optional: M.optional, + arguments: M.args.map(to_moz) + }; + }); + + def_to_moz(AST_Toplevel, function To_Moz_Program(M) { + return to_moz_scope("Program", M); + }); + + def_to_moz(AST_Expansion, function To_Moz_Spread(M) { + return { + type: to_moz_in_destructuring() ? "RestElement" : "SpreadElement", + argument: to_moz(M.expression) + }; + }); + + def_to_moz(AST_PrefixedTemplateString, function To_Moz_TaggedTemplateExpression(M) { + return { + type: "TaggedTemplateExpression", + tag: to_moz(M.prefix), + quasi: to_moz(M.template_string) + }; + }); + + def_to_moz(AST_TemplateString, function To_Moz_TemplateLiteral(M) { + var quasis = []; + var expressions = []; + for (var i = 0; i < M.segments.length; i++) { + if (i % 2 !== 0) { + expressions.push(to_moz(M.segments[i])); + } else { + quasis.push({ + type: "TemplateElement", + value: { + raw: M.segments[i].raw, + cooked: M.segments[i].value + }, + tail: i === M.segments.length - 1 + }); + } + } + return { + type: "TemplateLiteral", + quasis: quasis, + expressions: expressions + }; + }); + + def_to_moz(AST_Defun, function To_Moz_FunctionDeclaration(M) { + return { + type: "FunctionDeclaration", + id: to_moz(M.name), + params: M.argnames.map(to_moz_pattern), + generator: M.is_generator, + async: M.async, + body: to_moz_scope("BlockStatement", M) + }; + }); + + def_to_moz(AST_Function, function To_Moz_FunctionExpression(M) { + return { + type: "FunctionExpression", + id: to_moz(M.name), + params: M.argnames.map(to_moz_pattern), + generator: M.is_generator || false, + async: M.async || false, + body: to_moz_scope("BlockStatement", M) + }; + }); + + def_to_moz(AST_Arrow, function To_Moz_ArrowFunctionExpression(M) { + var body = M.body.length === 1 && M.body[0] instanceof AST_Return && M.body[0].value + ? to_moz(M.body[0].value) + : { + type: "BlockStatement", + body: M.body.map(to_moz) + }; + return { + type: "ArrowFunctionExpression", + params: M.argnames.map(to_moz_pattern), + async: M.async, + body: body, + }; + }); + + def_to_moz(AST_Destructuring, function To_Moz_ObjectPattern(M) { + if (M.is_array) { + return { + type: "ArrayPattern", + elements: M.names.map( + M => M instanceof AST_Hole ? null : to_moz_pattern(M) + ), + }; + } + return { + type: "ObjectPattern", + properties: M.names.map(M => { + if (M instanceof AST_ObjectKeyVal) { + var computed = M.computed_key(); + const [shorthand, key] = to_moz_property_key(M.key, computed, M.quote, M.value); + + return { + type: "Property", + computed, + kind: "init", + key: key, + method: false, + shorthand, + value: to_moz_pattern(M.value) + }; + } else { + return to_moz_pattern(M); + } + }), + }; + }); + + def_to_moz(AST_DefaultAssign, function To_Moz_AssignmentExpression(M) { + return { + type: "AssignmentPattern", + left: to_moz_pattern(M.left), + right: to_moz(M.right), + }; + }); + + def_to_moz(AST_Directive, function To_Moz_Directive(M) { + return { + type: "ExpressionStatement", + expression: { + type: "Literal", + value: M.value, + raw: M.print_to_string() + }, + directive: M.value + }; + }); + + def_to_moz(AST_SimpleStatement, function To_Moz_ExpressionStatement(M) { + return { + type: "ExpressionStatement", + expression: to_moz(M.body) + }; + }); + + def_to_moz(AST_SwitchBranch, function To_Moz_SwitchCase(M) { + return { + type: "SwitchCase", + test: to_moz(M.expression), + consequent: M.body.map(to_moz) + }; + }); + + def_to_moz(AST_Try, function To_Moz_TryStatement(M) { + return { + type: "TryStatement", + block: to_moz_block(M.body), + handler: to_moz(M.bcatch), + guardedHandlers: [], + finalizer: to_moz(M.bfinally) + }; + }); + + def_to_moz(AST_Catch, function To_Moz_CatchClause(M) { + return { + type: "CatchClause", + param: M.argname != null ? to_moz_pattern(M.argname) : null, + body: to_moz_block(M) + }; + }); + + def_to_moz(AST_DefinitionsLike, function To_Moz_VariableDeclaration(M) { + return { + type: "VariableDeclaration", + kind: + M instanceof AST_Const ? "const" : + M instanceof AST_Let ? "let" : + M instanceof AST_Using ? (M.await ? "await using" : "using") : + "var", + declarations: M.definitions.map(to_moz) + }; + }); + + function import_attributes_to_moz(attribute) { + const import_attributes = []; + if (attribute) { + for (const { key, value } of attribute.properties) { + const key_moz = is_basic_identifier_string(key) + ? { type: "Identifier", name: key } + : { type: "Literal", value: key, raw: JSON.stringify(key) }; + import_attributes.push({ + type: "ImportAttribute", + key: key_moz, + value: to_moz(value) + }); + } + } + return import_attributes; + } + + def_to_moz(AST_Export, function To_Moz_ExportDeclaration(M) { + if (M.exported_names) { + var first_exported = M.exported_names[0]; + if (first_exported && first_exported.name.name === "*" && !first_exported.name.quote) { + var foreign_name = first_exported.foreign_name; + var exported = foreign_name.name === "*" && !foreign_name.quote + ? null + : to_moz(foreign_name); + return { + type: "ExportAllDeclaration", + source: to_moz(M.module_name), + exported: exported, + attributes: import_attributes_to_moz(M.attributes) + }; + } + return { + type: "ExportNamedDeclaration", + specifiers: M.exported_names.map(function (name_mapping) { + return { + type: "ExportSpecifier", + exported: to_moz(name_mapping.foreign_name), + local: to_moz(name_mapping.name) + }; + }), + declaration: to_moz(M.exported_definition), + source: to_moz(M.module_name), + attributes: import_attributes_to_moz(M.attributes) + }; + } + + if (M.is_default) { + return { + type: "ExportDefaultDeclaration", + declaration: to_moz(M.exported_value || M.exported_definition), + }; + } else { + return { + type: "ExportNamedDeclaration", + declaration: to_moz(M.exported_value || M.exported_definition), + specifiers: [], + source: null, + }; + } + }); + + def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) { + var specifiers = []; + if (M.imported_name) { + specifiers.push({ + type: "ImportDefaultSpecifier", + local: to_moz(M.imported_name) + }); + } + if (M.imported_names) { + var first_imported_foreign_name = M.imported_names[0].foreign_name; + if (first_imported_foreign_name.name === "*" && !first_imported_foreign_name.quote) { + specifiers.push({ + type: "ImportNamespaceSpecifier", + local: to_moz(M.imported_names[0].name) + }); + } else { + M.imported_names.forEach(function(name_mapping) { + specifiers.push({ + type: "ImportSpecifier", + local: to_moz(name_mapping.name), + imported: to_moz(name_mapping.foreign_name) + }); + }); + } + } + return { + type: "ImportDeclaration", + specifiers: specifiers, + source: to_moz(M.module_name), + attributes: import_attributes_to_moz(M.attributes) + }; + }); + + def_to_moz(AST_ImportMeta, function To_Moz_MetaProperty() { + return { + type: "MetaProperty", + meta: { + type: "Identifier", + name: "import" + }, + property: { + type: "Identifier", + name: "meta" + } + }; + }); + + def_to_moz(AST_Sequence, function To_Moz_SequenceExpression(M) { + return { + type: "SequenceExpression", + expressions: M.expressions.map(to_moz) + }; + }); + + def_to_moz(AST_DotHash, function To_Moz_PrivateMemberExpression(M) { + return { + type: "MemberExpression", + object: to_moz(M.expression), + computed: false, + property: { + type: "PrivateIdentifier", + name: M.property + }, + optional: M.optional + }; + }); + + def_to_moz(AST_PropAccess, function To_Moz_MemberExpression(M) { + var isComputed = M instanceof AST_Sub; + return { + type: "MemberExpression", + object: to_moz(M.expression), + computed: isComputed, + property: isComputed ? to_moz(M.property) : {type: "Identifier", name: M.property}, + optional: M.optional + }; + }); + + def_to_moz(AST_Chain, function To_Moz_ChainExpression(M) { + return { + type: "ChainExpression", + expression: to_moz(M.expression) + }; + }); + + def_to_moz(AST_Unary, function To_Moz_Unary(M) { + return { + type: M.operator == "++" || M.operator == "--" ? "UpdateExpression" : "UnaryExpression", + operator: M.operator, + prefix: M instanceof AST_UnaryPrefix, + argument: to_moz(M.expression) + }; + }); + + def_to_moz(AST_Binary, function To_Moz_BinaryExpression(M) { + if (M.operator == "=" && to_moz_in_destructuring()) { + return { + type: "AssignmentPattern", + left: to_moz(M.left), + right: to_moz(M.right) + }; + } + + const type = M.operator == "&&" || M.operator == "||" || M.operator === "??" + ? "LogicalExpression" + : "BinaryExpression"; + + return { + type, + left: to_moz(M.left), + operator: M.operator, + right: to_moz(M.right) + }; + }); + + def_to_moz(AST_Assign, function To_Moz_AssignmentExpression(M) { + return { + type: "AssignmentExpression", + operator: M.operator, + left: to_moz(M.left), + right: to_moz(M.right) + }; + }); + + def_to_moz(AST_PrivateIn, function To_Moz_BinaryExpression_PrivateIn(M) { + return { + type: "BinaryExpression", + left: { type: "PrivateIdentifier", name: M.key.name }, + operator: "in", + right: to_moz(M.value), + }; + }); + + def_to_moz(AST_Array, function To_Moz_ArrayExpression(M) { + return { + type: "ArrayExpression", + elements: M.elements.map(to_moz) + }; + }); + + def_to_moz(AST_Object, function To_Moz_ObjectExpression(M) { + return { + type: "ObjectExpression", + properties: M.properties.map(to_moz) + }; + }); + + def_to_moz(AST_ObjectProperty, function To_Moz_Property(M, parent) { + var computed = M.computed_key(); + const [shorthand, key] = to_moz_property_key(M.key, computed, M.quote, M.value); + + var kind; + if (M instanceof AST_ObjectGetter) { + kind = "get"; + } else + if (M instanceof AST_ObjectSetter) { + kind = "set"; + } + if (M instanceof AST_PrivateGetter || M instanceof AST_PrivateSetter) { + const kind = M instanceof AST_PrivateGetter ? "get" : "set"; + return { + type: "MethodDefinition", + computed: false, + kind: kind, + static: M.static, + key: { + type: "PrivateIdentifier", + name: M.key.name + }, + value: to_moz(M.value) + }; + } + if (M instanceof AST_ClassPrivateProperty) { + return { + type: "PropertyDefinition", + key: { + type: "PrivateIdentifier", + name: M.key.name + }, + value: to_moz(M.value), + computed: false, + static: M.static + }; + } + if (M instanceof AST_ClassProperty) { + return { + type: "PropertyDefinition", + key, + value: to_moz(M.value), + computed, + static: M.static + }; + } + if (parent instanceof AST_Class) { + return { + type: "MethodDefinition", + computed: computed, + kind: kind, + static: M.static, + key: to_moz(M.key), + value: to_moz(M.value) + }; + } + return { + type: "Property", + computed: computed, + method: false, + shorthand, + kind: kind, + key: key, + value: to_moz(M.value) + }; + }); + + def_to_moz(AST_ObjectKeyVal, function To_Moz_Property(M) { + var computed = M.computed_key(); + const [shorthand, key] = to_moz_property_key(M.key, computed, M.quote, M.value); + + return { + type: "Property", + computed: computed, + shorthand: shorthand, + method: false, + kind: "init", + key: key, + value: to_moz(M.value) + }; + }); + + def_to_moz(AST_ConciseMethod, function To_Moz_MethodDefinition(M, parent) { + const computed = M.computed_key(); + const [_always_false, key] = to_moz_property_key(M.key, computed, M.quote, M.value); + + if (parent instanceof AST_Object) { + return { + type: "Property", + kind: "init", + computed, + method: true, + shorthand: false, + key, + value: to_moz(M.value), + }; + } + + return { + type: "MethodDefinition", + kind: !computed && M.key.name === "constructor" ? "constructor" : "method", + computed, + key, + value: to_moz(M.value), + static: M.static, + }; + }); + + def_to_moz(AST_PrivateMethod, function To_Moz_MethodDefinition(M) { + return { + type: "MethodDefinition", + kind: "method", + key: { type: "PrivateIdentifier", name: M.key.name }, + value: to_moz(M.value), + computed: false, + static: M.static, + }; + }); + + def_to_moz(AST_Class, function To_Moz_Class(M) { + var type = M instanceof AST_ClassExpression ? "ClassExpression" : "ClassDeclaration"; + return { + type: type, + superClass: to_moz(M.extends), + id: M.name ? to_moz(M.name) : null, + body: { + type: "ClassBody", + body: M.properties.map(to_moz) + } + }; + }); + + def_to_moz(AST_ClassStaticBlock, function To_Moz_StaticBlock(M) { + return { + type: "StaticBlock", + body: M.body.map(to_moz), + }; + }); + + def_to_moz(AST_NewTarget, function To_Moz_MetaProperty() { + return { + type: "MetaProperty", + meta: { + type: "Identifier", + name: "new" + }, + property: { + type: "Identifier", + name: "target" + } + }; + }); + + def_to_moz(AST_Symbol, function To_Moz_Identifier(M, parent) { + if ( + (M instanceof AST_SymbolMethod && parent.quote) || + (( + M instanceof AST_SymbolImportForeign || + M instanceof AST_SymbolExportForeign || + M instanceof AST_SymbolExport + ) && M.quote) + ) { + return { + type: "Literal", + value: M.name + }; + } + var def = M.definition(); + return { + type: "Identifier", + name: def ? def.mangled_name || def.name : M.name + }; + }); + + def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) { + const pattern = M.value.source; + const flags = M.value.flags; + return { + type: "Literal", + value: null, + raw: M.print_to_string(), + regex: { pattern, flags } + }; + }); + + def_to_moz(AST_Constant, function To_Moz_Literal(M) { + var value = M.value; + return { + type: "Literal", + value: value, + raw: M.raw || M.print_to_string() + }; + }); + + def_to_moz(AST_Atom, function To_Moz_Atom(M) { + return { + type: "Identifier", + name: String(M.value) + }; + }); + + def_to_moz(AST_BigInt, M => ({ + type: "Literal", + // value cannot be represented natively + // see: https://github.com/estree/estree/blob/master/es2020.md#bigintliteral + value: null, + // `M.value` is a string that may be a hex number representation. + // but "bigint" property should have only decimal digits + bigint: typeof BigInt === "function" ? BigInt(M.value).toString() : M.value, + raw: M.raw, + })); + + AST_Boolean.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast); + AST_Null.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast); + AST_Hole.DEFMETHOD("to_mozilla_ast", function To_Moz_ArrayHole() { return null; }); + + AST_Block.DEFMETHOD("to_mozilla_ast", AST_BlockStatement.prototype.to_mozilla_ast); + AST_Lambda.DEFMETHOD("to_mozilla_ast", AST_Function.prototype.to_mozilla_ast); + + /* -----[ tools ]----- */ + + function my_start_token(moznode) { + var loc = moznode.loc, start = loc && loc.start; + var range = moznode.range; + return new AST_Token( + "", + "", + start && start.line || 0, + start && start.column || 0, + range ? range [0] : moznode.start, + false, + [], + [], + loc && loc.source, + ); + } + + function my_end_token(moznode) { + var loc = moznode.loc, end = loc && loc.end; + var range = moznode.range; + return new AST_Token( + "", + "", + end && end.line || 0, + end && end.column || 0, + range ? range [0] : moznode.end, + false, + [], + [], + loc && loc.source, + ); + } + + var FROM_MOZ_LABELS = null; + + function from_moz(node) { + if (node == null) return null; + return MOZ_TO_ME[node.type](node); + } + + function from_moz_quote(moz_key, computed) { + if (!computed && moz_key.type === "Literal" && typeof moz_key.value === "string") { + return '"'; + } else { + return ""; + } + } + + function from_moz_symbol(symbol_type, M, has_quote) { + return new symbol_type({ + start: my_start_token(M), + quote: has_quote ? '"' : undefined, + name: M.type === "Identifier" ? M.name : String(M.value), + end: my_end_token(M), + }); + } + + function from_moz_lambda(M, is_method) { + return new (is_method ? AST_Accessor : AST_Function)({ + start: my_start_token(M), + end: my_end_token(M), + name: M.id && from_moz_symbol(is_method ? AST_SymbolMethod : AST_SymbolLambda, M.id), + argnames: M.params.map(M => from_moz_pattern(M, AST_SymbolFunarg)), + is_generator: M.generator, + async: M.async, + body: normalize_directives(from_moz(M.body).body) + }); + } + + function from_moz_pattern(M, sym_type) { + switch (M.type) { + case "ObjectPattern": + return new AST_Destructuring({ + start: my_start_token(M), + end: my_end_token(M), + names: M.properties.map(p => from_moz_pattern(p, sym_type)), + is_array: false + }); + + case "Property": + var key = M.key; + var args = { + start : my_start_token(key || M.value), + end : my_end_token(M.value), + key : key.type == "Identifier" ? key.name : String(key.value), + quote : !M.computed && key.type === "Literal" && typeof key.value === "string" + ? '"' + : "", + value : from_moz_pattern(M.value, sym_type) + }; + if (M.computed) { + args.key = from_moz(M.key); + } + return new AST_ObjectKeyVal(args); + + case "ArrayPattern": + return new AST_Destructuring({ + start: my_start_token(M), + end: my_end_token(M), + names: M.elements.map(function(elm) { + if (elm === null) { + return new AST_Hole(); + } + return from_moz_pattern(elm, sym_type); + }), + is_array: true + }); + + case "SpreadElement": + case "RestElement": + return new AST_Expansion({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz_pattern(M.argument, sym_type), + }); + + case "AssignmentPattern": + return new AST_DefaultAssign({ + start : my_start_token(M), + end : my_end_token(M), + left : from_moz_pattern(M.left, sym_type), + operator: "=", + right : from_moz(M.right), + }); + + case "Identifier": + return new sym_type({ + start : my_start_token(M), + end : my_end_token(M), + name : M.name, + }); + + default: + throw new Error("Invalid node type for destructuring: " + M.type); + } + } + + function from_moz_label_ref(m_label) { + if (!m_label) return null; + + const label = from_moz_symbol(AST_LabelRef, m_label); + + let i = FROM_MOZ_LABELS.length; + while (i--) { + const label_origin = FROM_MOZ_LABELS[i]; + + if (label.name === label_origin.name) { + label.thedef = label_origin; + break; + } + } + + return label; + } + + AST_Node.from_mozilla_ast = function(node) { + var save_labels = FROM_MOZ_LABELS; + FROM_MOZ_LABELS = []; + var ast = from_moz(node); + FROM_MOZ_LABELS = save_labels; + return ast; + }; + + function set_moz_loc(mynode, moznode) { + var start = mynode.start; + var end = mynode.end; + if (!(start && end)) { + return moznode; + } + if (start.pos != null && end.endpos != null) { + moznode.range = [start.pos, end.endpos]; + } + if (start.line) { + moznode.loc = { + start: {line: start.line, column: start.col}, + end: end.endline ? {line: end.endline, column: end.endcol} : null + }; + if (start.file) { + moznode.loc.source = start.file; + } + } + return moznode; + } + + function def_to_moz(mytype, handler) { + mytype.DEFMETHOD("to_mozilla_ast", function(parent) { + return set_moz_loc(this, handler(this, parent)); + }); + } + + var TO_MOZ_STACK = null; + + function to_moz(node) { + if (TO_MOZ_STACK === null) { TO_MOZ_STACK = []; } + TO_MOZ_STACK.push(node); + var ast = node != null ? node.to_mozilla_ast(TO_MOZ_STACK[TO_MOZ_STACK.length - 2]) : null; + TO_MOZ_STACK.pop(); + if (TO_MOZ_STACK.length === 0) { TO_MOZ_STACK = null; } + return ast; + } + + /** Object property keys can be number literals, string literals, or raw names. Additionally they can be shorthand. We decide that here. */ + function to_moz_property_key(key, computed = false, quote = false, value = null) { + if (computed) { + return [false, to_moz(key)]; + } + + const key_name = typeof key === "string" ? key : key.name; + let moz_key; + if (quote) { + moz_key = { type: "Literal", value: key_name, raw: JSON.stringify(key_name) }; + } else if ("" + +key_name === key_name && +key_name >= 0) { + // representable as a number + moz_key = { type: "Literal", value: +key_name, raw: JSON.stringify(+key_name) }; + } else { + moz_key = { type: "Identifier", name: key_name }; + } + + const shorthand = + moz_key.type === "Identifier" + && moz_key.name === key_name + && (value instanceof AST_Symbol && value.name === key_name + || value instanceof AST_DefaultAssign && value.left.name === key_name); + return [shorthand, moz_key]; + } + + function to_moz_pattern(node) { + if (node instanceof AST_Expansion) { + return { + type: "RestElement", + argument: to_moz_pattern(node.expression), + }; + } + + if (( + node instanceof AST_Symbol + || node instanceof AST_Destructuring + || node instanceof AST_DefaultAssign + || node instanceof AST_PropAccess + )) { + // Plain translation + return to_moz(node); + } + + throw new Error(node.TYPE); + } + + function to_moz_in_destructuring() { + var i = TO_MOZ_STACK.length; + while (i--) { + if (TO_MOZ_STACK[i] instanceof AST_Destructuring) { + return true; + } + } + return false; + } + + function to_moz_block(node) { + return { + type: "BlockStatement", + body: node.body.map(to_moz) + }; + } + + function to_moz_scope(type, node) { + var body = node.body.map(to_moz); + if (node.body[0] instanceof AST_SimpleStatement && node.body[0].body instanceof AST_String) { + body.unshift(to_moz(new AST_EmptyStatement(node.body[0]))); + } + return { + type: type, + body: body + }; + } +})(); + +// return true if the node at the top of the stack (that means the +// innermost node in the current output) is lexically the first in +// a statement. +function first_in_statement(stack) { + let node = stack.parent(-1); + for (let i = 0, p; p = stack.parent(i); i++) { + if (p instanceof AST_Statement && p.body === node) + return true; + if ((p instanceof AST_Sequence && p.expressions[0] === node) || + (p.TYPE === "Call" && p.expression === node) || + (p instanceof AST_PrefixedTemplateString && p.prefix === node) || + (p instanceof AST_Dot && p.expression === node) || + (p instanceof AST_Sub && p.expression === node) || + (p instanceof AST_Chain && p.expression === node) || + (p instanceof AST_Conditional && p.condition === node) || + (p instanceof AST_Binary && p.left === node) || + (p instanceof AST_UnaryPostfix && p.expression === node) + ) { + node = p; + } else { + return false; + } + } +} + +// Returns whether the leftmost item in the expression is an object +function left_is_object(node) { + if (node instanceof AST_Object) return true; + if (node instanceof AST_Sequence) return left_is_object(node.expressions[0]); + if (node.TYPE === "Call") return left_is_object(node.expression); + if (node instanceof AST_PrefixedTemplateString) return left_is_object(node.prefix); + if (node instanceof AST_Dot || node instanceof AST_Sub) return left_is_object(node.expression); + if (node instanceof AST_Chain) return left_is_object(node.expression); + if (node instanceof AST_Conditional) return left_is_object(node.condition); + if (node instanceof AST_Binary) return left_is_object(node.left); + if (node instanceof AST_UnaryPostfix) return left_is_object(node.expression); + return false; +} + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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 CODE_LINE_BREAK = 10; +const CODE_SPACE = 32; + +const r_annotation = /[@#]__(PURE|INLINE|NOINLINE)__/; + +function is_some_comments(comment) { + // multiline comment + return ( + (comment.type === "comment2" || comment.type === "comment1") + && /@preserve|@copyright|@lic|@cc_on|^\**!/i.test(comment.value) + ); +} + +const ROPE_COMMIT_WHEN = 8 * 1000; +class Rope { + constructor() { + this.committed = ""; + this.current = ""; + } + + append(str) { + /** When `this.current` is too long, commit it. */ + if (this.current.length > ROPE_COMMIT_WHEN) { + this.committed += this.current + str; + this.current = ""; + } else { + this.current += str; + } + } + + insertAt(char, index) { + const { committed, current } = this; + if (index < committed.length) { + this.committed = committed.slice(0, index) + char + committed.slice(index); + } else if (index === committed.length) { + this.committed += char; + } else { + index -= committed.length; + this.committed += current.slice(0, index) + char; + this.current = current.slice(index); + } + } + + charAt(index) { + const { committed } = this; + if (index < committed.length) return committed[index]; + return this.current[index - committed.length]; + } + + charCodeAt(index) { + const { committed } = this; + if (index < committed.length) return committed.charCodeAt(index); + return this.current.charCodeAt(index - committed.length); + } + + length() { + return this.committed.length + this.current.length; + } + + expectDirective() { + // /^$|[;{][\s\n]*$/ + + let ch, n = this.length(); + + if (n <= 0) return true; + + // Skip N whitespace from the end + while ( + (ch = this.charCodeAt(--n)) + && (ch == CODE_SPACE || ch == CODE_LINE_BREAK) + ); + + // either ";", or "{", or the string ended + return !ch || ch === 59 || ch === 123; + } + + hasNLB() { + let n = this.length() - 1; + while (n >= 0) { + const code = this.charCodeAt(n--); + + if (code === CODE_LINE_BREAK) return true; + if (code !== CODE_SPACE) return false; + } + return true; + } + + + toString() { + return this.committed + this.current; + } +} + +function OutputStream(options) { + + var readonly = !options; + options = defaults(options, { + ascii_only : false, + beautify : false, + braces : false, + comments : "some", + ecma : 5, + ie8 : false, + indent_level : 4, + indent_start : 0, + inline_script : true, + keep_numbers : false, + keep_quoted_props : false, + max_line_len : false, + preamble : null, + preserve_annotations : false, + quote_keys : false, + quote_style : 0, + safari10 : false, + semicolons : true, + shebang : true, + shorthand : undefined, + source_map : null, + webkit : false, + width : 80, + wrap_iife : false, + wrap_func_args : false, + + _destroy_ast : false + }, true); + + if (options.shorthand === undefined) + options.shorthand = options.ecma > 5; + + // Convert comment option to RegExp if necessary and set up comments filter + var comment_filter = return_false; // Default case, throw all comments away + if (options.comments) { + let comments = options.comments; + if (typeof options.comments === "string" && /^\/.*\/[a-zA-Z]*$/.test(options.comments)) { + var regex_pos = options.comments.lastIndexOf("/"); + comments = new RegExp( + options.comments.substr(1, regex_pos - 1), + options.comments.substr(regex_pos + 1) + ); + } + if (comments instanceof RegExp) { + comment_filter = function(comment) { + return comment.type != "comment5" && comments.test(comment.value); + }; + } else if (typeof comments === "function") { + comment_filter = function(comment) { + return comment.type != "comment5" && comments(this, comment); + }; + } else if (comments === "some") { + comment_filter = is_some_comments; + } else { // NOTE includes "all" option + comment_filter = return_true; + } + } + + if (options.preserve_annotations) { + let prev_comment_filter = comment_filter; + comment_filter = function (comment) { + return r_annotation.test(comment.value) || prev_comment_filter.apply(this, arguments); + }; + } + + var indentation = 0; + var current_col = 0; + var current_line = 1; + var current_pos = 0; + var OUTPUT = new Rope(); + let printed_comments = new Set(); + + var to_utf8 = options.ascii_only ? function(str, identifier = false, regexp = false) { + if (options.ecma >= 2015 && !options.safari10 && !regexp) { + str = str.replace(/[\ud800-\udbff][\udc00-\udfff]/g, function(ch) { + var code = get_full_char_code(ch, 0).toString(16); + return "\\u{" + code + "}"; + }); + } + return str.replace(/[\u0000-\u001f\u007f-\uffff]/g, function(ch) { + var code = ch.charCodeAt(0).toString(16); + if (code.length <= 2 && !identifier) { + while (code.length < 2) code = "0" + code; + return "\\x" + code; + } else { + while (code.length < 4) code = "0" + code; + return "\\u" + code; + } + }); + } : function(str) { + return str.replace(/[\ud800-\udbff][\udc00-\udfff]|([\ud800-\udbff]|[\udc00-\udfff])/g, function(match, lone) { + if (lone) { + return "\\u" + lone.charCodeAt(0).toString(16); + } + return match; + }); + }; + + function make_string(str, quote) { + var dq = 0, sq = 0; + str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g, + function(s, i) { + switch (s) { + case '"': ++dq; return '"'; + case "'": ++sq; return "'"; + case "\\": return "\\\\"; + case "\n": return "\\n"; + case "\r": return "\\r"; + case "\t": return "\\t"; + case "\b": return "\\b"; + case "\f": return "\\f"; + case "\x0B": return options.ie8 ? "\\x0B" : "\\v"; + case "\u2028": return "\\u2028"; + case "\u2029": return "\\u2029"; + case "\ufeff": return "\\ufeff"; + case "\0": + return /[0-9]/.test(get_full_char(str, i+1)) ? "\\x00" : "\\0"; + } + return s; + }); + function quote_single() { + return "'" + str.replace(/\x27/g, "\\'") + "'"; + } + function quote_double() { + return '"' + str.replace(/\x22/g, '\\"') + '"'; + } + function quote_template() { + return "`" + str.replace(/`/g, "\\`") + "`"; + } + str = to_utf8(str); + if (quote === "`") return quote_template(); + switch (options.quote_style) { + case 1: + return quote_single(); + case 2: + return quote_double(); + case 3: + return quote == "'" ? quote_single() : quote_double(); + default: + return dq > sq ? quote_single() : quote_double(); + } + } + + function encode_string(str, quote) { + var ret = make_string(str, quote); + if (options.inline_script) { + ret = ret.replace(/<\x2f(script)([>\/\t\n\f\r ])/gi, "<\\/$1$2"); + ret = ret.replace(/\x3c!--/g, "\\x3c!--"); + ret = ret.replace(/--\x3e/g, "--\\x3e"); + } + return ret; + } + + function make_name(name) { + name = name.toString(); + name = to_utf8(name, true); + return name; + } + + function make_indent(back) { + return " ".repeat(options.indent_start + indentation - back * options.indent_level); + } + + /* -----[ beautification/minification ]----- */ + + var has_parens = false; + var might_need_space = false; + var might_need_semicolon = false; + var might_add_newline = 0; + var need_newline_indented = false; + var need_space = false; + var newline_insert = -1; + var last = ""; + var mapping_token, mapping_name, mappings = options.source_map && []; + + var do_add_mapping = mappings ? function() { + mappings.forEach(function(mapping) { + try { + let { name, token } = mapping; + if (name !== false) { + if (token.type == "name" || token.type === "privatename") { + name = token.value; + } else if (name instanceof AST_Symbol) { + name = token.type === "string" ? token.value : name.name; + } + } + options.source_map.add( + mapping.token.file, + mapping.line, mapping.col, + mapping.token.line, mapping.token.col, + is_basic_identifier_string(name) ? name : undefined + ); + } catch(ex) { + // Ignore bad mapping + } + }); + mappings = []; + } : noop; + + var ensure_line_len = options.max_line_len ? function() { + if (current_col > options.max_line_len) { + if (might_add_newline) { + OUTPUT.insertAt("\n", might_add_newline); + const len_after_newline = OUTPUT.length() - might_add_newline - 1; + if (mappings) { + var delta = len_after_newline - current_col; + mappings.forEach(function(mapping) { + mapping.line++; + mapping.col += delta; + }); + } + current_line++; + current_pos++; + current_col = len_after_newline; + } + } + if (might_add_newline) { + might_add_newline = 0; + do_add_mapping(); + } + } : noop; + + var requireSemicolonChars = makePredicate("( [ + * / - , . `"); + + function print(str) { + str = String(str); + var ch = get_full_char(str, 0); + if (need_newline_indented && ch) { + need_newline_indented = false; + if (ch !== "\n") { + print("\n"); + indent(); + } + } + if (need_space && ch) { + need_space = false; + if (!/[\s;})]/.test(ch)) { + space(); + } + } + newline_insert = -1; + var prev = last.charAt(last.length - 1); + if (might_need_semicolon) { + might_need_semicolon = false; + + if (prev === ":" && ch === "}" || (!ch || !";}".includes(ch)) && prev !== ";") { + if (options.semicolons || requireSemicolonChars.has(ch)) { + OUTPUT.append(";"); + current_col++; + current_pos++; + } else { + ensure_line_len(); + if (current_col > 0) { + OUTPUT.append("\n"); + current_pos++; + current_line++; + current_col = 0; + } + + if (/^\s+$/.test(str)) { + // reset the semicolon flag, since we didn't print one + // now and might still have to later + might_need_semicolon = true; + } + } + + if (!options.beautify) + might_need_space = false; + } + } + + if (might_need_space) { + if ((is_identifier_char(prev) + && (is_identifier_char(ch) || ch == "\\")) + || (ch == "/" && ch == prev) + || ((ch == "+" || ch == "-") && ch == last) + ) { + OUTPUT.append(" "); + current_col++; + current_pos++; + } + might_need_space = false; + } + + if (mapping_token) { + mappings.push({ + token: mapping_token, + name: mapping_name, + line: current_line, + col: current_col + }); + mapping_token = false; + if (!might_add_newline) do_add_mapping(); + } + + OUTPUT.append(str); + has_parens = str[str.length - 1] == "("; + current_pos += str.length; + var a = str.split(/\r?\n/), n = a.length - 1; + current_line += n; + current_col += a[0].length; + if (n > 0) { + ensure_line_len(); + current_col = a[n].length; + } + last = str; + } + + var star = function() { + print("*"); + }; + + var space = options.beautify ? function() { + print(" "); + } : function() { + might_need_space = true; + }; + + var indent = options.beautify ? function(half) { + if (options.beautify) { + print(make_indent(half ? 0.5 : 0)); + } + } : noop; + + var with_indent = options.beautify ? function(col, cont) { + if (col === true) col = next_indent(); + var save_indentation = indentation; + indentation = col; + var ret = cont(); + indentation = save_indentation; + return ret; + } : function(col, cont) { return cont(); }; + + var newline = options.beautify ? function() { + if (newline_insert < 0) return print("\n"); + if (OUTPUT.charAt(newline_insert) != "\n") { + OUTPUT.insertAt("\n", newline_insert); + current_pos++; + current_line++; + } + newline_insert++; + } : options.max_line_len ? function() { + ensure_line_len(); + might_add_newline = OUTPUT.length(); + } : noop; + + var semicolon = options.beautify ? function() { + print(";"); + } : function() { + might_need_semicolon = true; + }; + + function force_semicolon() { + might_need_semicolon = false; + print(";"); + } + + function next_indent() { + return indentation + options.indent_level; + } + + function with_block(cont) { + var ret; + print("{"); + newline(); + with_indent(next_indent(), function() { + ret = cont(); + }); + indent(); + print("}"); + return ret; + } + + function with_parens(cont) { + print("("); + //XXX: still nice to have that for argument lists + //var ret = with_indent(current_col, cont); + var ret = cont(); + print(")"); + return ret; + } + + function with_square(cont) { + print("["); + //var ret = with_indent(current_col, cont); + var ret = cont(); + print("]"); + return ret; + } + + function comma() { + print(","); + space(); + } + + function colon() { + print(":"); + space(); + } + + var add_mapping = mappings ? function(token, name) { + mapping_token = token; + mapping_name = name; + } : noop; + + function get() { + if (might_add_newline) { + ensure_line_len(); + } + return OUTPUT.toString(); + } + + function filter_comment(comment) { + if (!options.preserve_annotations) { + comment = comment.replace(r_annotation, " "); + } + if (/^\s*$/.test(comment)) { + return ""; + } + return comment.replace(/(<\s*\/\s*)(script)/i, "<\\/$2"); + } + + function prepend_comments(node) { + var self = this; + var start = node.start; + if (!start) return; + var printed_comments = self.printed_comments; + + // There cannot be a newline between return/yield and its value. + const keyword_with_value = + node instanceof AST_Exit && node.value + || (node instanceof AST_Await || node instanceof AST_Yield) + && node.expression; + + if ( + start.comments_before + && printed_comments.has(start.comments_before) + ) { + if (keyword_with_value) { + start.comments_before = []; + } else { + return; + } + } + + var comments = start.comments_before; + if (!comments) { + comments = start.comments_before = []; + } + printed_comments.add(comments); + + if (keyword_with_value) { + var tw = new TreeWalker(function(node) { + var parent = tw.parent(); + if (parent instanceof AST_Exit + || parent instanceof AST_Await + || parent instanceof AST_Yield + || parent instanceof AST_Binary && parent.left === node + || parent.TYPE == "Call" && parent.expression === node + || parent instanceof AST_Conditional && parent.condition === node + || parent instanceof AST_Dot && parent.expression === node + || parent instanceof AST_Sequence && parent.expressions[0] === node + || parent instanceof AST_Sub && parent.expression === node + || parent instanceof AST_UnaryPostfix) { + if (!node.start) return; + var text = node.start.comments_before; + if (text && !printed_comments.has(text)) { + printed_comments.add(text); + comments = comments.concat(text); + } + } else { + return true; + } + }); + tw.push(node); + keyword_with_value.walk(tw); + } + + if (current_pos == 0) { + if (comments.length > 0 && options.shebang && comments[0].type === "comment5" + && !printed_comments.has(comments[0])) { + print("#!" + comments.shift().value + "\n"); + indent(); + } + var preamble = options.preamble; + if (preamble) { + print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n")); + } + } + + comments = comments.filter(comment_filter, node).filter(c => !printed_comments.has(c)); + if (comments.length == 0) return; + var last_nlb = OUTPUT.hasNLB(); + comments.forEach(function(c, i) { + printed_comments.add(c); + if (!last_nlb) { + if (c.nlb) { + print("\n"); + indent(); + last_nlb = true; + } else if (i > 0) { + space(); + } + } + + if (/comment[134]/.test(c.type)) { + var value = filter_comment(c.value); + if (value) { + print("//" + value + "\n"); + indent(); + } + last_nlb = true; + } else if (c.type == "comment2") { + var value = filter_comment(c.value); + if (value) { + print("/*" + value + "*/"); + } + last_nlb = false; + } + }); + if (!last_nlb) { + if (start.nlb) { + print("\n"); + indent(); + } else { + space(); + } + } + } + + function append_comments(node, tail) { + var self = this; + var token = node.end; + if (!token) return; + var printed_comments = self.printed_comments; + var comments = token[tail ? "comments_before" : "comments_after"]; + if (!comments || printed_comments.has(comments)) return; + if (!(node instanceof AST_Statement || comments.every((c) => + !/comment[134]/.test(c.type) + ))) return; + printed_comments.add(comments); + var insert = OUTPUT.length(); + comments.filter(comment_filter, node).forEach(function(c, i) { + if (printed_comments.has(c)) return; + printed_comments.add(c); + need_space = false; + if (need_newline_indented) { + print("\n"); + indent(); + need_newline_indented = false; + } else if (c.nlb && (i > 0 || !OUTPUT.hasNLB())) { + print("\n"); + indent(); + } else if (i > 0 || !tail) { + space(); + } + if (/comment[134]/.test(c.type)) { + const value = filter_comment(c.value); + if (value) { + print("//" + value); + } + need_newline_indented = true; + } else if (c.type == "comment2") { + const value = filter_comment(c.value); + if (value) { + print("/*" + value + "*/"); + } + need_space = true; + } + }); + if (OUTPUT.length() > insert) newline_insert = insert; + } + + /** + * When output.option("_destroy_ast") is enabled, destroy the function. + * Call this after printing it. + */ + const gc_scope = + options["_destroy_ast"] + ? function gc_scope(scope) { + scope.body.length = 0; + scope.argnames.length = 0; + } + : noop; + + var stack = []; + return { + get : get, + toString : get, + indent : indent, + in_directive : false, + use_asm : null, + active_scope : null, + indentation : function() { return indentation; }, + current_width : function() { return current_col - indentation; }, + should_break : function() { return options.width && this.current_width() >= options.width; }, + has_parens : function() { return has_parens; }, + newline : newline, + print : print, + star : star, + space : space, + comma : comma, + colon : colon, + last : function() { return last; }, + semicolon : semicolon, + force_semicolon : force_semicolon, + to_utf8 : to_utf8, + print_name : function(name) { print(make_name(name)); }, + print_string : function(str, quote, escape_directive) { + var encoded = encode_string(str, quote); + if (escape_directive === true && !encoded.includes("\\")) { + // Insert semicolons to break directive prologue + if (!OUTPUT.expectDirective()) { + force_semicolon(); + } + force_semicolon(); + } + print(encoded); + }, + print_template_string_chars: function(str) { + var encoded = encode_string(str, "`").replace(/\${/g, "\\${"); + return print(encoded.substr(1, encoded.length - 2)); + }, + encode_string : encode_string, + next_indent : next_indent, + with_indent : with_indent, + with_block : with_block, + with_parens : with_parens, + with_square : with_square, + add_mapping : add_mapping, + option : function(opt) { return options[opt]; }, + gc_scope, + printed_comments: printed_comments, + prepend_comments: readonly ? noop : prepend_comments, + append_comments : readonly || comment_filter === return_false ? noop : append_comments, + line : function() { return current_line; }, + col : function() { return current_col; }, + pos : function() { return current_pos; }, + push_node : function(node) { stack.push(node); }, + pop_node : function() { return stack.pop(); }, + parent : function(n) { + return stack[stack.length - 2 - (n || 0)]; + } + }; + +} + +/* -----[ code generators ]----- */ + +(function() { + + /* -----[ utils ]----- */ + + function DEFPRINT(nodetype, generator) { + nodetype.DEFMETHOD("_codegen", generator); + } + + AST_Node.DEFMETHOD("print", function(output, force_parens) { + var self = this, generator = self._codegen; + if (self instanceof AST_Scope) { + output.active_scope = self; + } else if (!output.use_asm && self instanceof AST_Directive && self.value == "use asm") { + output.use_asm = output.active_scope; + } + function doit() { + output.prepend_comments(self); + self.add_source_map(output); + generator(self, output); + output.append_comments(self); + } + output.push_node(self); + if (force_parens || self.needs_parens(output)) { + output.with_parens(doit); + } else { + doit(); + } + output.pop_node(); + if (self === output.use_asm) { + output.use_asm = null; + } + }); + AST_Node.DEFMETHOD("_print", AST_Node.prototype.print); + + AST_Node.DEFMETHOD("print_to_string", function(options) { + var output = OutputStream(options); + this.print(output); + return output.get(); + }); + + /* -----[ PARENTHESES ]----- */ + + function PARENS(nodetype, func) { + if (Array.isArray(nodetype)) { + nodetype.forEach(function(nodetype) { + PARENS(nodetype, func); + }); + } else { + nodetype.DEFMETHOD("needs_parens", func); + } + } + + PARENS(AST_Node, return_false); + + // a function expression needs parens around it when it's provably + // the first token to appear in a statement. + PARENS(AST_Function, function(output) { + if (!output.has_parens() && first_in_statement(output)) { + return true; + } + + if (output.option("webkit")) { + var p = output.parent(); + if (p instanceof AST_PropAccess && p.expression === this) { + return true; + } + } + + if (output.option("wrap_iife")) { + var p = output.parent(); + if (p instanceof AST_Call && p.expression === this) { + return true; + } + } + + if (output.option("wrap_func_args")) { + var p = output.parent(); + if (p instanceof AST_Call && p.args.includes(this)) { + return true; + } + } + + return false; + }); + + PARENS(AST_Arrow, function(output) { + var p = output.parent(); + + if ( + output.option("wrap_func_args") + && p instanceof AST_Call + && p.args.includes(this) + ) { + return true; + } + return p instanceof AST_PropAccess && p.expression === this + || p instanceof AST_Conditional && p.condition === this; + }); + + // same goes for an object literal (as in AST_Function), because + // otherwise {...} would be interpreted as a block of code. + PARENS(AST_Object, function(output) { + return !output.has_parens() && first_in_statement(output); + }); + + PARENS(AST_ClassExpression, first_in_statement); + + PARENS(AST_Unary, function(output) { + var p = output.parent(); + return p instanceof AST_PropAccess && p.expression === this + || p instanceof AST_Call && p.expression === this + || p instanceof AST_Binary + && p.operator === "**" + && this instanceof AST_UnaryPrefix + && p.left === this + && this.operator !== "++" + && this.operator !== "--"; + }); + + PARENS(AST_Await, function(output) { + var p = output.parent(); + return p instanceof AST_PropAccess && p.expression === this + || p instanceof AST_Call && p.expression === this + || p instanceof AST_Binary && p.operator === "**" && p.left === this + || output.option("safari10") && p instanceof AST_UnaryPrefix; + }); + + PARENS(AST_Sequence, function(output) { + var p = output.parent(); + return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4) + || p instanceof AST_Unary // !(foo, bar, baz) + || p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8 + || p instanceof AST_VarDefLike // var a = (1, 2), b = a + a; ==> b == 4 + || p instanceof AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2 + || p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ] + || p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2 + || p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30) + * ==> 20 (side effect, set a := 10 and b := 20) */ + || p instanceof AST_Arrow // x => (x, x) + || p instanceof AST_DefaultAssign // x => (x = (0, function(){})) + || p instanceof AST_Expansion // [...(a, b)] + || p instanceof AST_ForOf && this === p.object // for (e of (foo, bar)) {} + || p instanceof AST_Yield // yield (foo, bar) + || p instanceof AST_Export // export default (foo, bar) + ; + }); + + PARENS(AST_Binary, function(output) { + var p = output.parent(); + // (foo && bar)() + if (p instanceof AST_Call && p.expression === this) + return true; + // typeof (foo && bar) + if (p instanceof AST_Unary) + return true; + // (foo && bar)["prop"], (foo && bar).prop + if (p instanceof AST_PropAccess && p.expression === this) + return true; + // this deals with precedence: 3 * (2 + 1) + if (p instanceof AST_Binary) { + const parent_op = p.operator; + const op = this.operator; + + // It is forbidden for ?? to be used with || or && without parens. + if (op === "??" && (parent_op === "||" || parent_op === "&&")) { + return true; + } + if (parent_op === "??" && (op === "||" || op === "&&")) { + return true; + } + + const pp = PRECEDENCE[parent_op]; + const sp = PRECEDENCE[op]; + if (pp > sp + || (pp == sp + && (this === p.right || parent_op == "**"))) { + return true; + } + } + if (p instanceof AST_PrivateIn) { + const op = this.operator; + + const pp = PRECEDENCE["in"]; + const sp = PRECEDENCE[op]; + if (pp > sp || (pp == sp && this === p.value)) { + return true; + } + } + }); + + PARENS(AST_PrivateIn, function(output) { + var p = output.parent(); + // (#x in this)() + if (p instanceof AST_Call && p.expression === this) { + return true; + } + // typeof (#x in this) + if (p instanceof AST_Unary) { + return true; + } + // (#x in this)["prop"], (#x in this).prop + if (p instanceof AST_PropAccess && p.expression === this) { + return true; + } + // same precedence as regular in operator + if (p instanceof AST_Binary) { + const parent_op = p.operator; + + const pp = PRECEDENCE[parent_op]; + const sp = PRECEDENCE["in"]; + if (pp > sp + || (pp == sp + && (this === p.right || parent_op == "**"))) { + return true; + } + } + // rules are the same as binary in, but the class differs + if (p instanceof AST_PrivateIn && this === p.value) { + return true; + } + }); + + PARENS(AST_Yield, function(output) { + var p = output.parent(); + // (yield 1) + (yield 2) + // a = yield 3 + if (p instanceof AST_Binary && p.operator !== "=") + return true; + // (yield 1)() + // new (yield 1)() + if (p instanceof AST_Call && p.expression === this) + return true; + // (yield 1) ? yield 2 : yield 3 + if (p instanceof AST_Conditional && p.condition === this) + return true; + // -(yield 4) + if (p instanceof AST_Unary) + return true; + // (yield x).foo + // (yield x)['foo'] + if (p instanceof AST_PropAccess && p.expression === this) + return true; + }); + + PARENS(AST_Chain, function(output) { + var p = output.parent(); + if (!(p instanceof AST_Call || p instanceof AST_PropAccess)) return false; + return p.expression === this; + }); + + PARENS(AST_PropAccess, function(output) { + var p = output.parent(); + if (p instanceof AST_New && p.expression === this) { + // i.e. new (foo.bar().baz) + // + // if there's one call into this subtree, then we need + // parens around it too, otherwise the call will be + // interpreted as passing the arguments to the upper New + // expression. + return walk(this, node => { + if (node instanceof AST_Scope) return true; + if (node instanceof AST_Call) { + return walk_abort; // makes walk() return true. + } + }); + } + }); + + PARENS(AST_Call, function(output) { + var p = output.parent(), p1; + if (p instanceof AST_New && p.expression === this + || p instanceof AST_Export && p.is_default && this.expression instanceof AST_Function) + return true; + + // workaround for Safari bug. + // https://bugs.webkit.org/show_bug.cgi?id=123506 + return this.expression instanceof AST_Function + && p instanceof AST_PropAccess + && p.expression === this + && (p1 = output.parent(1)) instanceof AST_Assign + && p1.left === p; + }); + + PARENS(AST_New, function(output) { + var p = output.parent(); + if (this.args.length === 0 + && (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]() + || p instanceof AST_Call && p.expression === this + || p instanceof AST_PrefixedTemplateString && p.prefix === this)) // (new foo)(bar) + return true; + }); + + PARENS(AST_Number, function(output) { + var p = output.parent(); + if (p instanceof AST_PropAccess && p.expression === this) { + var value = this.getValue(); + if (value < 0 || /^0/.test(make_num(value))) { + return true; + } + } + }); + + PARENS(AST_BigInt, function(output) { + var p = output.parent(); + if (p instanceof AST_PropAccess && p.expression === this) { + var value = this.getValue(); + if (value.startsWith("-")) { + return true; + } + } + }); + + PARENS([ AST_Assign, AST_Conditional ], function(output) { + var p = output.parent(); + // !(a = false) → true + if (p instanceof AST_Unary) + return true; + // 1 + (a = 2) + 3 → 6, side effect setting a = 2 + if (p instanceof AST_Binary && !(p instanceof AST_Assign)) + return true; + // (a = func)() —or— new (a = Object)() + if (p instanceof AST_Call && p.expression === this) + return true; + // (a = foo) ? bar : baz + if (p instanceof AST_Conditional && p.condition === this) + return true; + // (a = foo)["prop"] —or— (a = foo).prop + if (p instanceof AST_PropAccess && p.expression === this) + return true; + // ({a, b} = {a: 1, b: 2}), a destructuring assignment + if (this instanceof AST_Assign && this.left instanceof AST_Destructuring && this.left.is_array === false) + return true; + }); + + /* -----[ PRINTERS ]----- */ + + DEFPRINT(AST_Directive, function(self, output) { + output.print_string(self.value, self.quote); + output.semicolon(); + }); + + DEFPRINT(AST_Expansion, function (self, output) { + output.print("..."); + self.expression.print(output); + }); + + DEFPRINT(AST_Destructuring, function (self, output) { + output.print(self.is_array ? "[" : "{"); + var len = self.names.length; + self.names.forEach(function (name, i) { + if (i > 0) output.comma(); + name.print(output); + // If the final element is a hole, we need to make sure it + // doesn't look like a trailing comma, by inserting an actual + // trailing comma. + if (i == len - 1 && name instanceof AST_Hole) output.comma(); + }); + output.print(self.is_array ? "]" : "}"); + }); + + DEFPRINT(AST_Debugger, function(self, output) { + output.print("debugger"); + output.semicolon(); + }); + + /* -----[ statements ]----- */ + + function display_body(body, is_toplevel, output, allow_directives) { + var last = body.length - 1; + output.in_directive = allow_directives; + body.forEach(function(stmt, i) { + if (output.in_directive === true && !(stmt instanceof AST_Directive || + stmt instanceof AST_EmptyStatement || + (stmt instanceof AST_SimpleStatement && stmt.body instanceof AST_String) + )) { + output.in_directive = false; + } + if (!(stmt instanceof AST_EmptyStatement)) { + output.indent(); + stmt.print(output); + if (!(i == last && is_toplevel)) { + output.newline(); + if (is_toplevel) output.newline(); + } + } + if (output.in_directive === true && + stmt instanceof AST_SimpleStatement && + stmt.body instanceof AST_String + ) { + output.in_directive = false; + } + }); + output.in_directive = false; + } + + AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output) { + print_maybe_braced_body(this.body, output); + }); + + DEFPRINT(AST_Statement, function(self, output) { + self.body.print(output); + output.semicolon(); + }); + DEFPRINT(AST_Toplevel, function(self, output) { + display_body(self.body, true, output, true); + output.print(""); + }); + DEFPRINT(AST_LabeledStatement, function(self, output) { + self.label.print(output); + output.colon(); + self.body.print(output); + }); + DEFPRINT(AST_SimpleStatement, function(self, output) { + self.body.print(output); + output.semicolon(); + }); + function print_braced_empty(self, output) { + output.print("{"); + output.with_indent(output.next_indent(), function() { + output.append_comments(self, true); + }); + output.add_mapping(self.end); + output.print("}"); + } + function print_braced(self, output, allow_directives) { + if (self.body.length > 0) { + output.with_block(function() { + display_body(self.body, false, output, allow_directives); + output.add_mapping(self.end); + }); + } else print_braced_empty(self, output); + } + DEFPRINT(AST_BlockStatement, function(self, output) { + print_braced(self, output); + }); + DEFPRINT(AST_EmptyStatement, function(self, output) { + output.semicolon(); + }); + DEFPRINT(AST_Do, function(self, output) { + output.print("do"); + output.space(); + make_block(self.body, output); + output.space(); + output.print("while"); + output.space(); + output.with_parens(function() { + self.condition.print(output); + }); + output.semicolon(); + }); + DEFPRINT(AST_While, function(self, output) { + output.print("while"); + output.space(); + output.with_parens(function() { + self.condition.print(output); + }); + output.space(); + self._do_print_body(output); + }); + DEFPRINT(AST_For, function(self, output) { + output.print("for"); + output.space(); + output.with_parens(function() { + if (self.init) { + if (self.init instanceof AST_DefinitionsLike) { + self.init.print(output); + } else { + parenthesize_for_noin(self.init, output, true); + } + output.print(";"); + output.space(); + } else { + output.print(";"); + } + if (self.condition) { + self.condition.print(output); + output.print(";"); + output.space(); + } else { + output.print(";"); + } + if (self.step) { + self.step.print(output); + } + }); + output.space(); + self._do_print_body(output); + }); + DEFPRINT(AST_ForIn, function(self, output) { + output.print("for"); + if (self.await) { + output.space(); + output.print("await"); + } + output.space(); + output.with_parens(function() { + self.init.print(output); + output.space(); + output.print(self instanceof AST_ForOf ? "of" : "in"); + output.space(); + self.object.print(output); + }); + output.space(); + self._do_print_body(output); + }); + DEFPRINT(AST_With, function(self, output) { + output.print("with"); + output.space(); + output.with_parens(function() { + self.expression.print(output); + }); + output.space(); + self._do_print_body(output); + }); + + /* -----[ functions ]----- */ + AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword) { + var self = this; + if (!nokeyword) { + if (self.async) { + output.print("async"); + output.space(); + } + output.print("function"); + if (self.is_generator) { + output.star(); + } + if (self.name) { + output.space(); + } + } + if (self.name instanceof AST_Symbol) { + self.name.print(output); + } else if (nokeyword && self.name instanceof AST_Node) { + output.with_square(function() { + self.name.print(output); // Computed method name + }); + } + output.with_parens(function() { + self.argnames.forEach(function(arg, i) { + if (i) output.comma(); + arg.print(output); + }); + }); + output.space(); + print_braced(self, output, true); + }); + DEFPRINT(AST_Lambda, function(self, output) { + self._do_print(output); + output.gc_scope(self); + }); + + DEFPRINT(AST_PrefixedTemplateString, function(self, output) { + var tag = self.prefix; + var parenthesize_tag = tag instanceof AST_Lambda + || tag instanceof AST_Binary + || tag instanceof AST_Conditional + || tag instanceof AST_Sequence + || tag instanceof AST_Unary + || tag instanceof AST_Dot && tag.expression instanceof AST_Object; + if (parenthesize_tag) output.print("("); + self.prefix.print(output); + if (parenthesize_tag) output.print(")"); + self.template_string.print(output); + }); + DEFPRINT(AST_TemplateString, function(self, output) { + var is_tagged = output.parent() instanceof AST_PrefixedTemplateString; + + output.print("`"); + for (var i = 0; i < self.segments.length; i++) { + if (!(self.segments[i] instanceof AST_TemplateSegment)) { + output.print("${"); + self.segments[i].print(output); + output.print("}"); + } else if (is_tagged) { + output.print(self.segments[i].raw); + } else { + output.print_template_string_chars(self.segments[i].value); + } + } + output.print("`"); + }); + DEFPRINT(AST_TemplateSegment, function(self, output) { + output.print_template_string_chars(self.value); + }); + + AST_Arrow.DEFMETHOD("_do_print", function(output) { + var self = this; + var parent = output.parent(); + var needs_parens = (parent instanceof AST_Binary && + !(parent instanceof AST_Assign) && + !(parent instanceof AST_DefaultAssign)) || + parent instanceof AST_Unary || + (parent instanceof AST_Call && self === parent.expression); + if (needs_parens) { output.print("("); } + if (self.async) { + output.print("async"); + output.space(); + } + if (self.argnames.length === 1 && self.argnames[0] instanceof AST_Symbol) { + self.argnames[0].print(output); + } else { + output.with_parens(function() { + self.argnames.forEach(function(arg, i) { + if (i) output.comma(); + arg.print(output); + }); + }); + } + output.space(); + output.print("=>"); + output.space(); + const first_statement = self.body[0]; + if ( + self.body.length === 1 + && first_statement instanceof AST_Return + ) { + const returned = first_statement.value; + if (!returned) { + output.print("{}"); + } else if (left_is_object(returned)) { + output.print("("); + returned.print(output); + output.print(")"); + } else { + returned.print(output); + } + } else { + print_braced(self, output); + } + if (needs_parens) { output.print(")"); } + output.gc_scope(self); + }); + + /* -----[ exits ]----- */ + AST_Exit.DEFMETHOD("_do_print", function(output, kind) { + output.print(kind); + if (this.value) { + output.space(); + const comments = this.value.start.comments_before; + if (comments && comments.length && !output.printed_comments.has(comments)) { + output.print("("); + this.value.print(output); + output.print(")"); + } else { + this.value.print(output); + } + } + output.semicolon(); + }); + DEFPRINT(AST_Return, function(self, output) { + self._do_print(output, "return"); + }); + DEFPRINT(AST_Throw, function(self, output) { + self._do_print(output, "throw"); + }); + + /* -----[ yield ]----- */ + + DEFPRINT(AST_Yield, function(self, output) { + var star = self.is_star ? "*" : ""; + output.print("yield" + star); + if (self.expression) { + output.space(); + self.expression.print(output); + } + }); + + DEFPRINT(AST_Await, function(self, output) { + output.print("await"); + output.space(); + var e = self.expression; + var parens = !( + e instanceof AST_Call + || e instanceof AST_SymbolRef + || e instanceof AST_PropAccess + || e instanceof AST_Unary + || e instanceof AST_Constant + || e instanceof AST_Await + || e instanceof AST_Object + ); + if (parens) output.print("("); + self.expression.print(output); + if (parens) output.print(")"); + }); + + /* -----[ loop control ]----- */ + AST_LoopControl.DEFMETHOD("_do_print", function(output, kind) { + output.print(kind); + if (this.label) { + output.space(); + this.label.print(output); + } + output.semicolon(); + }); + DEFPRINT(AST_Break, function(self, output) { + self._do_print(output, "break"); + }); + DEFPRINT(AST_Continue, function(self, output) { + self._do_print(output, "continue"); + }); + + /* -----[ if ]----- */ + function make_then(self, output) { + var b = self.body; + if (output.option("braces") + || output.option("ie8") && b instanceof AST_Do) + return make_block(b, output); + // The squeezer replaces "block"-s that contain only a single + // statement with the statement itself; technically, the AST + // is correct, but this can create problems when we output an + // IF having an ELSE clause where the THEN clause ends in an + // IF *without* an ELSE block (then the outer ELSE would refer + // to the inner IF). This function checks for this case and + // adds the block braces if needed. + if (!b) return output.force_semicolon(); + while (true) { + if (b instanceof AST_If) { + if (!b.alternative) { + make_block(self.body, output); + return; + } + b = b.alternative; + } else if (b instanceof AST_StatementWithBody) { + b = b.body; + } else break; + } + print_maybe_braced_body(self.body, output); + } + DEFPRINT(AST_If, function(self, output) { + output.print("if"); + output.space(); + output.with_parens(function() { + self.condition.print(output); + }); + output.space(); + if (self.alternative) { + make_then(self, output); + output.space(); + output.print("else"); + output.space(); + if (self.alternative instanceof AST_If) + self.alternative.print(output); + else + print_maybe_braced_body(self.alternative, output); + } else { + self._do_print_body(output); + } + }); + + /* -----[ switch ]----- */ + DEFPRINT(AST_Switch, function(self, output) { + output.print("switch"); + output.space(); + output.with_parens(function() { + self.expression.print(output); + }); + output.space(); + var last = self.body.length - 1; + if (last < 0) print_braced_empty(self, output); + else output.with_block(function() { + self.body.forEach(function(branch, i) { + output.indent(true); + branch.print(output); + if (i < last && branch.body.length > 0) + output.newline(); + }); + }); + }); + AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output) { + output.newline(); + this.body.forEach(function(stmt) { + output.indent(); + stmt.print(output); + output.newline(); + }); + }); + DEFPRINT(AST_Default, function(self, output) { + output.print("default:"); + self._do_print_body(output); + }); + DEFPRINT(AST_Case, function(self, output) { + output.print("case"); + output.space(); + self.expression.print(output); + output.print(":"); + self._do_print_body(output); + }); + + /* -----[ exceptions ]----- */ + DEFPRINT(AST_Try, function(self, output) { + output.print("try"); + output.space(); + self.body.print(output); + if (self.bcatch) { + output.space(); + self.bcatch.print(output); + } + if (self.bfinally) { + output.space(); + self.bfinally.print(output); + } + }); + DEFPRINT(AST_TryBlock, function(self, output) { + print_braced(self, output); + }); + DEFPRINT(AST_Catch, function(self, output) { + output.print("catch"); + if (self.argname) { + output.space(); + output.with_parens(function() { + self.argname.print(output); + }); + } + output.space(); + print_braced(self, output); + }); + DEFPRINT(AST_Finally, function(self, output) { + output.print("finally"); + output.space(); + print_braced(self, output); + }); + + /* -----[ var/const ]----- */ + AST_DefinitionsLike.DEFMETHOD("_do_print", function(output, kind) { + output.print(kind); + output.space(); + this.definitions.forEach(function(def, i) { + if (i) output.comma(); + def.print(output); + }); + var p = output.parent(); + var in_for = p instanceof AST_For || p instanceof AST_ForIn; + var output_semicolon = !in_for || p && p.init !== this; + if (output_semicolon) + output.semicolon(); + }); + DEFPRINT(AST_Let, function(self, output) { + self._do_print(output, "let"); + }); + DEFPRINT(AST_Var, function(self, output) { + self._do_print(output, "var"); + }); + DEFPRINT(AST_Const, function(self, output) { + self._do_print(output, "const"); + }); + DEFPRINT(AST_Using, function(self, output) { + self._do_print(output, self.await ? "await using" : "using"); + }); + DEFPRINT(AST_Import, function(self, output) { + output.print("import"); + output.space(); + if (self.imported_name) { + self.imported_name.print(output); + } + if (self.imported_name && self.imported_names) { + output.print(","); + output.space(); + } + if (self.imported_names) { + if (self.imported_names.length === 1 && + self.imported_names[0].foreign_name.name === "*" && + !self.imported_names[0].foreign_name.quote) { + self.imported_names[0].print(output); + } else { + output.print("{"); + self.imported_names.forEach(function (name_import, i) { + output.space(); + name_import.print(output); + if (i < self.imported_names.length - 1) { + output.print(","); + } + }); + output.space(); + output.print("}"); + } + } + if (self.imported_name || self.imported_names) { + output.space(); + output.print("from"); + output.space(); + } + self.module_name.print(output); + if (self.attributes) { + output.print("with"); + self.attributes.print(output); + } + output.semicolon(); + }); + DEFPRINT(AST_ImportMeta, function(self, output) { + output.print("import.meta"); + }); + + DEFPRINT(AST_NameMapping, function(self, output) { + var is_import = output.parent() instanceof AST_Import; + var definition = self.name.definition(); + var foreign_name = self.foreign_name; + var names_are_different = + (definition && definition.mangled_name || self.name.name) !== + foreign_name.name; + if (!names_are_different && + foreign_name.name === "*" && + !!foreign_name.quote != !!self.name.quote) { + // export * as "*" + names_are_different = true; + } + var foreign_name_is_name = !foreign_name.quote; + if (names_are_different) { + if (is_import) { + if (foreign_name_is_name) { + output.print(foreign_name.name); + } else { + output.print_string(foreign_name.name, foreign_name.quote); + } + } else { + if (!self.name.quote) { + self.name.print(output); + } else { + output.print_string(self.name.name, self.name.quote); + } + + } + output.space(); + output.print("as"); + output.space(); + if (is_import) { + self.name.print(output); + } else { + if (foreign_name_is_name) { + output.print(foreign_name.name); + } else { + output.print_string(foreign_name.name, foreign_name.quote); + } + } + } else { + if (!self.name.quote) { + self.name.print(output); + } else { + output.print_string(self.name.name, self.name.quote); + } + } + }); + + DEFPRINT(AST_Export, function(self, output) { + output.print("export"); + output.space(); + if (self.is_default) { + output.print("default"); + output.space(); + } + if (self.exported_names) { + if (self.exported_names.length === 1 && + self.exported_names[0].name.name === "*" && + !self.exported_names[0].name.quote) { + self.exported_names[0].print(output); + } else { + output.print("{"); + self.exported_names.forEach(function(name_export, i) { + output.space(); + name_export.print(output); + if (i < self.exported_names.length - 1) { + output.print(","); + } + }); + output.space(); + output.print("}"); + } + } else if (self.exported_value) { + self.exported_value.print(output); + } else if (self.exported_definition) { + self.exported_definition.print(output); + if (self.exported_definition instanceof AST_Definitions) return; + } + if (self.module_name) { + output.space(); + output.print("from"); + output.space(); + self.module_name.print(output); + } + if (self.attributes) { + output.print("with"); + self.attributes.print(output); + } + if (self.exported_value + && !(self.exported_value instanceof AST_Defun || + self.exported_value instanceof AST_Function || + self.exported_value instanceof AST_Class) + || self.module_name + || self.exported_names + ) { + output.semicolon(); + } + }); + + function parenthesize_for_noin(node, output, noin) { + var parens = false; + // need to take some precautions here: + // https://github.com/mishoo/UglifyJS2/issues/60 + if (noin) { + parens = walk(node, node => { + // Don't go into scopes -- except arrow functions: + // https://github.com/terser/terser/issues/1019#issuecomment-877642607 + if (node instanceof AST_Scope && !(node instanceof AST_Arrow)) { + return true; + } + if ( + node instanceof AST_Binary && node.operator == "in" + || node instanceof AST_PrivateIn + ) { + return walk_abort; // makes walk() return true + } + }); + } + node.print(output, parens); + } + + DEFPRINT(AST_VarDefLike, function(self, output) { + self.name.print(output); + if (self.value) { + output.space(); + output.print("="); + output.space(); + var p = output.parent(1); + var noin = p instanceof AST_For || p instanceof AST_ForIn; + parenthesize_for_noin(self.value, output, noin); + } + }); + + /* -----[ other expressions ]----- */ + DEFPRINT(AST_Call, function(self, output) { + self.expression.print(output); + if (self instanceof AST_New && self.args.length === 0) + return; + if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) { + output.add_mapping(self.start); + } + if (self.optional) output.print("?."); + output.with_parens(function() { + self.args.forEach(function(expr, i) { + if (i) output.comma(); + expr.print(output); + }); + }); + }); + DEFPRINT(AST_New, function(self, output) { + output.print("new"); + output.space(); + AST_Call.prototype._codegen(self, output); + }); + + AST_Sequence.DEFMETHOD("_do_print", function(output) { + this.expressions.forEach(function(node, index) { + if (index > 0) { + output.comma(); + if (output.should_break()) { + output.newline(); + output.indent(); + } + } + node.print(output); + }); + }); + DEFPRINT(AST_Sequence, function(self, output) { + self._do_print(output); + // var p = output.parent(); + // if (p instanceof AST_Statement) { + // output.with_indent(output.next_indent(), function(){ + // self._do_print(output); + // }); + // } else { + // self._do_print(output); + // } + }); + DEFPRINT(AST_Dot, function(self, output) { + var expr = self.expression; + expr.print(output); + var prop = self.property; + var print_computed = ALL_RESERVED_WORDS.has(prop) + ? output.option("ie8") + : !is_identifier_string( + prop, + output.option("ecma") >= 2015 && !output.option("safari10") + ); + + if (self.optional) output.print("?."); + + if (print_computed) { + output.print("["); + output.add_mapping(self.end); + output.print_string(prop); + output.print("]"); + } else { + if (expr instanceof AST_Number && expr.getValue() >= 0) { + if (!/[xa-f.)]/i.test(output.last())) { + output.print("."); + } + } + if (!self.optional) output.print("."); + // the name after dot would be mapped about here. + output.add_mapping(self.end); + output.print_name(prop); + } + }); + DEFPRINT(AST_DotHash, function(self, output) { + var expr = self.expression; + expr.print(output); + var prop = self.property; + + if (self.optional) output.print("?"); + output.print(".#"); + output.add_mapping(self.end); + output.print_name(prop); + }); + DEFPRINT(AST_Sub, function(self, output) { + self.expression.print(output); + if (self.optional) output.print("?."); + output.print("["); + self.property.print(output); + output.print("]"); + }); + DEFPRINT(AST_Chain, function(self, output) { + self.expression.print(output); + }); + DEFPRINT(AST_UnaryPrefix, function(self, output) { + var op = self.operator; + if (op === "--" && output.last().endsWith("!")) { + // avoid printing " + output.print(" "); + } else { + // the space is optional depending on "beautify" + output.space(); + } + output.print(op); + output.space(); + self.right.print(output); + }); + DEFPRINT(AST_Conditional, function(self, output) { + self.condition.print(output); + output.space(); + output.print("?"); + output.space(); + self.consequent.print(output); + output.space(); + output.colon(); + self.alternative.print(output); + }); + + /* -----[ literals ]----- */ + DEFPRINT(AST_Array, function(self, output) { + output.with_square(function() { + var a = self.elements, len = a.length; + if (len > 0) output.space(); + a.forEach(function(exp, i) { + if (i) output.comma(); + exp.print(output); + // If the final element is a hole, we need to make sure it + // doesn't look like a trailing comma, by inserting an actual + // trailing comma. + if (i === len - 1 && exp instanceof AST_Hole) + output.comma(); + }); + if (len > 0) output.space(); + }); + }); + DEFPRINT(AST_Object, function(self, output) { + if (self.properties.length > 0) output.with_block(function() { + self.properties.forEach(function(prop, i) { + if (i) { + output.print(","); + output.newline(); + } + output.indent(); + prop.print(output); + }); + output.newline(); + }); + else print_braced_empty(self, output); + }); + DEFPRINT(AST_Class, function(self, output) { + output.print("class"); + output.space(); + if (self.name) { + self.name.print(output); + output.space(); + } + if (self.extends) { + var parens = ( + !(self.extends instanceof AST_SymbolRef) + && !(self.extends instanceof AST_PropAccess) + && !(self.extends instanceof AST_ClassExpression) + && !(self.extends instanceof AST_Function) + ); + output.print("extends"); + if (parens) { + output.print("("); + } else { + output.space(); + } + self.extends.print(output); + if (parens) { + output.print(")"); + } else { + output.space(); + } + } + if (self.properties.length > 0) output.with_block(function() { + self.properties.forEach(function(prop, i) { + if (i) { + output.newline(); + } + output.indent(); + prop.print(output); + }); + output.newline(); + }); + else output.print("{}"); + }); + DEFPRINT(AST_NewTarget, function(self, output) { + output.print("new.target"); + }); + + /** Prints a prop name. Returns whether it can be used as a shorthand. */ + function print_property_name(key, quote, output) { + if (output.option("quote_keys")) { + output.print_string(key); + return false; + } + if ("" + +key == key && key >= 0) { + if (output.option("keep_numbers")) { + output.print(key); + return false; + } + output.print(make_num(key)); + return false; + } + var print_string = ALL_RESERVED_WORDS.has(key) + ? output.option("ie8") + : ( + output.option("ecma") < 2015 || output.option("safari10") + ? !is_basic_identifier_string(key) + : !is_identifier_string(key, true) + ); + if (print_string || (quote && output.option("keep_quoted_props"))) { + output.print_string(key, quote); + return false; + } + output.print_name(key); + return true; + } + + DEFPRINT(AST_ObjectKeyVal, function(self, output) { + function get_name(self) { + var def = self.definition(); + return def ? def.mangled_name || def.name : self.name; + } + + const try_shorthand = output.option("shorthand") && !(self.key instanceof AST_Node); + if ( + try_shorthand + && self.value instanceof AST_Symbol + && get_name(self.value) === self.key + && !ALL_RESERVED_WORDS.has(self.key) + ) { + const was_shorthand = print_property_name(self.key, self.quote, output); + if (!was_shorthand) { + output.colon(); + self.value.print(output); + } + } else if ( + try_shorthand + && self.value instanceof AST_DefaultAssign + && self.value.left instanceof AST_Symbol + && get_name(self.value.left) === self.key + ) { + const was_shorthand = print_property_name(self.key, self.quote, output); + if (!was_shorthand) { + output.colon(); + self.value.left.print(output); + } + output.space(); + output.print("="); + output.space(); + self.value.right.print(output); + } else { + if (!(self.key instanceof AST_Node)) { + print_property_name(self.key, self.quote, output); + } else { + output.with_square(function() { + self.key.print(output); + }); + } + output.colon(); + self.value.print(output); + } + }); + DEFPRINT(AST_ClassPrivateProperty, (self, output) => { + if (self.static) { + output.print("static"); + output.space(); + } + + output.print("#"); + + print_property_name(self.key.name, undefined, output); + + if (self.value) { + output.print("="); + self.value.print(output); + } + + output.semicolon(); + }); + DEFPRINT(AST_ClassProperty, (self, output) => { + if (self.static) { + output.print("static"); + output.space(); + } + + if (self.key instanceof AST_SymbolClassProperty) { + print_property_name(self.key.name, self.quote, output); + } else { + output.print("["); + self.key.print(output); + output.print("]"); + } + + if (self.value) { + output.print("="); + self.value.print(output); + } + + output.semicolon(); + }); + AST_ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, is_private, output) { + var self = this; + if (self.static) { + output.print("static"); + output.space(); + } + if (type) { + output.print(type); + output.space(); + } + if (self.key instanceof AST_SymbolMethod) { + if (is_private) output.print("#"); + print_property_name(self.key.name, self.quote, output); + self.key.add_source_map(output); + } else { + output.with_square(function() { + self.key.print(output); + }); + } + self.value._do_print(output, true); + }); + DEFPRINT(AST_ObjectSetter, function(self, output) { + self._print_getter_setter("set", false, output); + }); + DEFPRINT(AST_ObjectGetter, function(self, output) { + self._print_getter_setter("get", false, output); + }); + DEFPRINT(AST_PrivateSetter, function(self, output) { + self._print_getter_setter("set", true, output); + }); + DEFPRINT(AST_PrivateGetter, function(self, output) { + self._print_getter_setter("get", true, output); + }); + DEFPRINT(AST_ConciseMethod, function(self, output) { + var type; + if (self.value.is_generator && self.value.async) { + type = "async*"; + } else if (self.value.is_generator) { + type = "*"; + } else if (self.value.async) { + type = "async"; + } + self._print_getter_setter(type, false, output); + }); + DEFPRINT(AST_PrivateMethod, function(self, output) { + var type; + if (self.value.is_generator && self.value.async) { + type = "async*"; + } else if (self.value.is_generator) { + type = "*"; + } else if (self.value.async) { + type = "async"; + } + self._print_getter_setter(type, true, output); + }); + DEFPRINT(AST_PrivateIn, function(self, output) { + self.key.print(output); + output.space(); + output.print("in"); + output.space(); + self.value.print(output); + }); + DEFPRINT(AST_SymbolPrivateProperty, function(self, output) { + output.print("#" + self.name); + }); + DEFPRINT(AST_ClassStaticBlock, function (self, output) { + output.print("static"); + output.space(); + print_braced(self, output); + }); + AST_Symbol.DEFMETHOD("_do_print", function(output) { + var def = this.definition(); + output.print_name(def ? def.mangled_name || def.name : this.name); + }); + DEFPRINT(AST_Symbol, function (self, output) { + self._do_print(output); + }); + DEFPRINT(AST_Hole, noop); + DEFPRINT(AST_This, function(self, output) { + output.print("this"); + }); + DEFPRINT(AST_Super, function(self, output) { + output.print("super"); + }); + DEFPRINT(AST_Constant, function(self, output) { + output.print(self.getValue()); + }); + DEFPRINT(AST_String, function(self, output) { + output.print_string(self.getValue(), self.quote, output.in_directive); + }); + DEFPRINT(AST_Number, function(self, output) { + if ((output.option("keep_numbers") || output.use_asm) && self.raw) { + output.print(self.raw); + } else { + output.print(make_num(self.getValue())); + } + }); + DEFPRINT(AST_BigInt, function(self, output) { + if (output.option("keep_numbers") && self.raw) { + output.print(self.raw); + } else { + output.print(self.getValue() + "n"); + } + }); + + const r_slash_script = /(<\s*\/\s*script)/i; + const r_starts_with_script = /^\s*script/i; + const slash_script_replace = (_, $1) => $1.replace("/", "\\/"); + DEFPRINT(AST_RegExp, function(self, output) { + let { source, flags } = self.getValue(); + source = regexp_source_fix(source); + flags = flags ? sort_regexp_flags(flags) : ""; + + // Avoid outputting end of script tag + source = source.replace(r_slash_script, slash_script_replace); + if (r_starts_with_script.test(source) && output.last().endsWith("<")) { + output.print(" "); + } + + output.print(output.to_utf8(`/${source}/${flags}`, false, true)); + + const parent = output.parent(); + if ( + parent instanceof AST_Binary + && /^\w/.test(parent.operator) + && parent.left === self + ) { + output.print(" "); + } + }); + + /** if, for, while, may or may not have braces surrounding its body */ + function print_maybe_braced_body(stat, output) { + if (output.option("braces")) { + make_block(stat, output); + } else { + if (!stat || stat instanceof AST_EmptyStatement) + output.force_semicolon(); + else if ((stat instanceof AST_DefinitionsLike && !(stat instanceof AST_Var)) || stat instanceof AST_Class) + make_block(stat, output); + else + stat.print(output); + } + } + + function best_of(a) { + var best = a[0], len = best.length; + for (var i = 1; i < a.length; ++i) { + if (a[i].length < len) { + best = a[i]; + len = best.length; + } + } + return best; + } + + function make_num(num) { + var str = num.toString(10).replace(/^0\./, ".").replace("e+", "e"); + var candidates = [ str ]; + if (Math.floor(num) === num) { + if (num < 0) { + candidates.push("-0x" + (-num).toString(16).toLowerCase()); + } else { + candidates.push("0x" + num.toString(16).toLowerCase()); + } + } + var match, len, digits; + if (match = /^\.0+/.exec(str)) { + len = match[0].length; + digits = str.slice(len); + candidates.push(digits + "e-" + (digits.length + len - 1)); + } else if (match = /0+$/.exec(str)) { + len = match[0].length; + candidates.push(str.slice(0, -len) + "e" + len); + } else if (match = /^(\d)\.(\d+)e(-?\d+)$/.exec(str)) { + candidates.push(match[1] + match[2] + "e" + (match[3] - match[2].length)); + } + return best_of(candidates); + } + + function make_block(stmt, output) { + if (!stmt || stmt instanceof AST_EmptyStatement) + output.print("{}"); + else if (stmt instanceof AST_BlockStatement) + stmt.print(output); + else output.with_block(function() { + output.indent(); + stmt.print(output); + output.newline(); + }); + } + + /* -----[ source map generators ]----- */ + + function DEFMAP(nodetype, generator) { + nodetype.forEach(function(nodetype) { + nodetype.DEFMETHOD("add_source_map", generator); + }); + } + + DEFMAP([ + // We could easily add info for ALL nodes, but it seems to me that + // would be quite wasteful, hence this noop in the base class. + AST_Node, + // since the label symbol will mark it + AST_LabeledStatement, + AST_Toplevel, + ], noop); + + // XXX: I'm not exactly sure if we need it for all of these nodes, + // or if we should add even more. + DEFMAP([ + AST_Array, + AST_BlockStatement, + AST_Catch, + AST_Class, + AST_Constant, + AST_Debugger, + AST_DefinitionsLike, + AST_Directive, + AST_Finally, + AST_Jump, + AST_Lambda, + AST_New, + AST_Object, + AST_StatementWithBody, + AST_Symbol, + AST_Switch, + AST_SwitchBranch, + AST_TemplateString, + AST_TemplateSegment, + AST_Try, + ], function(output) { + output.add_mapping(this.start); + }); + + DEFMAP([ + AST_ObjectGetter, + AST_ObjectSetter, + AST_PrivateGetter, + AST_PrivateSetter, + AST_ConciseMethod, + AST_PrivateMethod, + ], function(output) { + output.add_mapping(this.start, false /*name handled below*/); + }); + + DEFMAP([ + AST_SymbolMethod, + AST_SymbolPrivateProperty + ], function(output) { + const tok_type = this.end && this.end.type; + if (tok_type === "name" || tok_type === "privatename") { + output.add_mapping(this.end, this.name); + } else { + output.add_mapping(this.end); + } + }); + + DEFMAP([ AST_ObjectProperty ], function(output) { + output.add_mapping(this.start, this.key); + }); +})(); + +const shallow_cmp = (node1, node2) => { + return ( + node1 === null && node2 === null + || node1.TYPE === node2.TYPE && node1.shallow_cmp(node2) + ); +}; + +const equivalent_to = (tree1, tree2) => { + if (!shallow_cmp(tree1, tree2)) return false; + const walk_1_state = [tree1]; + const walk_2_state = [tree2]; + + const walk_1_push = walk_1_state.push.bind(walk_1_state); + const walk_2_push = walk_2_state.push.bind(walk_2_state); + + while (walk_1_state.length && walk_2_state.length) { + const node_1 = walk_1_state.pop(); + const node_2 = walk_2_state.pop(); + + if (!shallow_cmp(node_1, node_2)) return false; + + node_1._children_backwards(walk_1_push); + node_2._children_backwards(walk_2_push); + + if (walk_1_state.length !== walk_2_state.length) { + // Different number of children + return false; + } + } + + return walk_1_state.length == 0 && walk_2_state.length == 0; +}; + +const pass_through = () => true; + +AST_Node.prototype.shallow_cmp = function () { + throw new Error("did not find a shallow_cmp function for " + this.constructor.name); +}; + +AST_Debugger.prototype.shallow_cmp = pass_through; + +AST_Directive.prototype.shallow_cmp = function(other) { + return this.value === other.value; +}; + +AST_SimpleStatement.prototype.shallow_cmp = pass_through; + +AST_Block.prototype.shallow_cmp = pass_through; + +AST_EmptyStatement.prototype.shallow_cmp = pass_through; + +AST_LabeledStatement.prototype.shallow_cmp = function(other) { + return this.label.name === other.label.name; +}; + +AST_Do.prototype.shallow_cmp = pass_through; + +AST_While.prototype.shallow_cmp = pass_through; + +AST_For.prototype.shallow_cmp = function(other) { + return (this.init == null ? other.init == null : this.init === other.init) && (this.condition == null ? other.condition == null : this.condition === other.condition) && (this.step == null ? other.step == null : this.step === other.step); +}; + +AST_ForIn.prototype.shallow_cmp = pass_through; + +AST_ForOf.prototype.shallow_cmp = pass_through; + +AST_With.prototype.shallow_cmp = pass_through; + +AST_Toplevel.prototype.shallow_cmp = pass_through; + +AST_Expansion.prototype.shallow_cmp = pass_through; + +AST_Lambda.prototype.shallow_cmp = function(other) { + return this.is_generator === other.is_generator && this.async === other.async; +}; + +AST_Destructuring.prototype.shallow_cmp = function(other) { + return this.is_array === other.is_array; +}; + +AST_PrefixedTemplateString.prototype.shallow_cmp = pass_through; + +AST_TemplateString.prototype.shallow_cmp = pass_through; + +AST_TemplateSegment.prototype.shallow_cmp = function(other) { + return this.value === other.value; +}; + +AST_Jump.prototype.shallow_cmp = pass_through; + +AST_LoopControl.prototype.shallow_cmp = pass_through; + +AST_Await.prototype.shallow_cmp = pass_through; + +AST_Yield.prototype.shallow_cmp = function(other) { + return this.is_star === other.is_star; +}; + +AST_If.prototype.shallow_cmp = function(other) { + return this.alternative == null ? other.alternative == null : this.alternative === other.alternative; +}; + +AST_Switch.prototype.shallow_cmp = pass_through; + +AST_SwitchBranch.prototype.shallow_cmp = pass_through; + +AST_Try.prototype.shallow_cmp = function(other) { + return (this.body === other.body) && (this.bcatch == null ? other.bcatch == null : this.bcatch === other.bcatch) && (this.bfinally == null ? other.bfinally == null : this.bfinally === other.bfinally); +}; + +AST_Catch.prototype.shallow_cmp = function(other) { + return this.argname == null ? other.argname == null : this.argname === other.argname; +}; + +AST_Finally.prototype.shallow_cmp = pass_through; + +AST_DefinitionsLike.prototype.shallow_cmp = pass_through; + +AST_VarDefLike.prototype.shallow_cmp = function(other) { + return this.value == null ? other.value == null : this.value === other.value; +}; + +AST_NameMapping.prototype.shallow_cmp = pass_through; + +AST_Import.prototype.shallow_cmp = function(other) { + return (this.imported_name == null ? other.imported_name == null : this.imported_name === other.imported_name) && (this.imported_names == null ? other.imported_names == null : this.imported_names === other.imported_names) && (this.attributes == null ? other.attributes == null : this.attributes === other.attributes); +}; + +AST_ImportMeta.prototype.shallow_cmp = pass_through; + +AST_Export.prototype.shallow_cmp = function(other) { + return (this.exported_definition == null ? other.exported_definition == null : this.exported_definition === other.exported_definition) && (this.exported_value == null ? other.exported_value == null : this.exported_value === other.exported_value) && (this.exported_names == null ? other.exported_names == null : this.exported_names === other.exported_names) && (this.attributes == null ? other.attributes == null : this.attributes === other.attributes) && this.module_name === other.module_name && this.is_default === other.is_default; +}; + +AST_Call.prototype.shallow_cmp = pass_through; + +AST_Sequence.prototype.shallow_cmp = pass_through; + +AST_PropAccess.prototype.shallow_cmp = pass_through; + +AST_Chain.prototype.shallow_cmp = pass_through; + +AST_Dot.prototype.shallow_cmp = function(other) { + return this.property === other.property; +}; + +AST_DotHash.prototype.shallow_cmp = function(other) { + return this.property === other.property; +}; + +AST_Unary.prototype.shallow_cmp = function(other) { + return this.operator === other.operator; +}; + +AST_Binary.prototype.shallow_cmp = function(other) { + return this.operator === other.operator; +}; + +AST_PrivateIn.prototype.shallow_cmp = pass_through; + +AST_Conditional.prototype.shallow_cmp = pass_through; + +AST_Array.prototype.shallow_cmp = pass_through; + +AST_Object.prototype.shallow_cmp = pass_through; + +AST_ObjectProperty.prototype.shallow_cmp = pass_through; + +AST_ObjectKeyVal.prototype.shallow_cmp = function(other) { + return this.key === other.key && this.quote === other.quote; +}; + +AST_ObjectSetter.prototype.shallow_cmp = function(other) { + return this.static === other.static; +}; + +AST_ObjectGetter.prototype.shallow_cmp = function(other) { + return this.static === other.static; +}; + +AST_ConciseMethod.prototype.shallow_cmp = function(other) { + return this.static === other.static; +}; + +AST_PrivateMethod.prototype.shallow_cmp = function(other) { + return this.static === other.static; +}; + +AST_Class.prototype.shallow_cmp = function(other) { + return (this.name == null ? other.name == null : this.name === other.name) && (this.extends == null ? other.extends == null : this.extends === other.extends); +}; + +AST_ClassProperty.prototype.shallow_cmp = function(other) { + return this.static === other.static + && (typeof this.key === "string" + ? this.key === other.key + : true /* AST_Node handled elsewhere */); +}; + +AST_ClassPrivateProperty.prototype.shallow_cmp = function(other) { + return this.static === other.static; +}; + +AST_Symbol.prototype.shallow_cmp = function(other) { + return this.name === other.name; +}; + +AST_NewTarget.prototype.shallow_cmp = pass_through; + +AST_This.prototype.shallow_cmp = pass_through; + +AST_Super.prototype.shallow_cmp = pass_through; + +AST_String.prototype.shallow_cmp = function(other) { + return this.value === other.value; +}; + +AST_Number.prototype.shallow_cmp = function(other) { + return this.value === other.value; +}; + +AST_BigInt.prototype.shallow_cmp = function(other) { + return this.value === other.value; +}; + +AST_RegExp.prototype.shallow_cmp = function (other) { + return ( + this.value.flags === other.value.flags + && this.value.source === other.value.source + ); +}; + +AST_Atom.prototype.shallow_cmp = pass_through; + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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 MASK_EXPORT_DONT_MANGLE = 1 << 0; +const MASK_EXPORT_WANT_MANGLE = 1 << 1; + +let function_defs = null; +let unmangleable_names = null; +/** + * When defined, there is a function declaration somewhere that's inside of a block. + * See https://tc39.es/ecma262/multipage/additional-ecmascript-features-for-web-browsers.html#sec-block-level-function-declarations-web-legacy-compatibility-semantics +*/ +let scopes_with_block_defuns = null; + +class SymbolDef { + constructor(scope, orig, init) { + this.name = orig.name; + this.orig = [ orig ]; + this.init = init; + this.eliminated = 0; + this.assignments = 0; + this.scope = scope; + this.replaced = 0; + this.global = false; + this.export = 0; + this.mangled_name = null; + this.undeclared = false; + this.id = SymbolDef.next_id++; + this.chained = false; + this.direct_access = false; + this.escaped = 0; + this.recursive_refs = 0; + this.references = []; + this.should_replace = undefined; + this.single_use = false; + this.fixed = false; + Object.seal(this); + } + fixed_value() { + if (!this.fixed || this.fixed instanceof AST_Node) return this.fixed; + return this.fixed(); + } + unmangleable(options) { + if (!options) options = {}; + + if ( + function_defs && + function_defs.has(this.id) && + keep_name(options.keep_fnames, this.orig[0].name) + ) return true; + + return this.global && !options.toplevel + || (this.export & MASK_EXPORT_DONT_MANGLE) + || this.undeclared + || !options.eval && this.scope.pinned() + || (this.orig[0] instanceof AST_SymbolLambda + || this.orig[0] instanceof AST_SymbolDefun) && keep_name(options.keep_fnames, this.orig[0].name) + || this.orig[0] instanceof AST_SymbolMethod + || (this.orig[0] instanceof AST_SymbolClass + || this.orig[0] instanceof AST_SymbolDefClass) && keep_name(options.keep_classnames, this.orig[0].name); + } + mangle(options) { + const cache = options.cache && options.cache.props; + if (this.global && cache && cache.has(this.name)) { + this.mangled_name = cache.get(this.name); + } else if (!this.mangled_name && !this.unmangleable(options)) { + var s = this.scope; + var sym = this.orig[0]; + if (options.ie8 && sym instanceof AST_SymbolLambda) + s = s.parent_scope; + const redefinition = redefined_catch_def(this); + this.mangled_name = redefinition + ? redefinition.mangled_name || redefinition.name + : s.next_mangled(options, this); + if (this.global && cache) { + cache.set(this.name, this.mangled_name); + } + } + } +} + +SymbolDef.next_id = 1; + +function redefined_catch_def(def) { + if (def.orig[0] instanceof AST_SymbolCatch + && def.scope.is_block_scope() + ) { + return def.scope.get_defun_scope().variables.get(def.name); + } +} + +AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = undefined, toplevel = this } = {}) { + options = defaults(options, { + cache: null, + ie8: false, + safari10: false, + module: false, + }); + + if (!(toplevel instanceof AST_Toplevel)) { + throw new Error("Invalid toplevel scope"); + } + + // pass 1: setup scope chaining and handle definitions + var scope = this.parent_scope = parent_scope; + var labels = new Map(); + var defun = null; + var in_destructuring = null; + var for_scopes = []; + var tw = new TreeWalker((node, descend) => { + if (node.is_block_scope()) { + const save_scope = scope; + node.block_scope = scope = new AST_Scope(node); + scope._block_scope = true; + scope.init_scope_vars(save_scope); + scope.uses_with = save_scope.uses_with; + scope.uses_eval = save_scope.uses_eval; + + if (options.safari10) { + if (node instanceof AST_For || node instanceof AST_ForIn || node instanceof AST_ForOf) { + for_scopes.push(scope); + } + } + + if (node instanceof AST_Switch) { + // XXX: HACK! Ensure the switch expression gets the correct scope (the parent scope) and the body gets the contained scope + // AST_Switch has a scope within the body, but it itself "is a block scope" + // This means the switched expression has to belong to the outer scope + // while the body inside belongs to the switch itself. + // This is pretty nasty and warrants an AST change + const the_block_scope = scope; + scope = save_scope; + node.expression.walk(tw); + scope = the_block_scope; + for (let i = 0; i < node.body.length; i++) { + node.body[i].walk(tw); + } + } else { + descend(); + } + scope = save_scope; + return true; + } + if (node instanceof AST_Destructuring) { + const save_destructuring = in_destructuring; + in_destructuring = node; + descend(); + in_destructuring = save_destructuring; + return true; + } + if (node instanceof AST_Scope) { + node.init_scope_vars(scope); + var save_scope = scope; + var save_defun = defun; + var save_labels = labels; + defun = scope = node; + labels = new Map(); + descend(); + scope = save_scope; + defun = save_defun; + labels = save_labels; + return true; // don't descend again in TreeWalker + } + if (node instanceof AST_LabeledStatement) { + var l = node.label; + if (labels.has(l.name)) { + throw new Error(string_template("Label {name} defined twice", l)); + } + labels.set(l.name, l); + descend(); + labels.delete(l.name); + return true; // no descend again + } + if (node instanceof AST_With) { + for (var s = scope; s; s = s.parent_scope) + s.uses_with = true; + return; + } + if (node instanceof AST_Symbol) { + node.scope = scope; + } + if (node instanceof AST_Label) { + node.thedef = node; + node.references = []; + } + if (node instanceof AST_SymbolLambda) { + defun.def_function(node, node.name == "arguments" ? undefined : defun); + } else if (node instanceof AST_SymbolDefun) { + // Careful here, the scope where this should be defined is + // the parent scope. The reason is that we enter a new + // scope when we encounter the AST_Defun node (which is + // instanceof AST_Scope) but we get to the symbol a bit + // later. + const closest_scope = defun.parent_scope; + + // In strict mode, function definitions are block-scoped + node.scope = tw.directives["use strict"] + ? closest_scope + : closest_scope.get_defun_scope(); + + mark_export(node.scope.def_function(node, defun), 1); + } else if (node instanceof AST_SymbolClass) { + mark_export(defun.def_variable(node, defun), 1); + } else if (node instanceof AST_SymbolImport) { + scope.def_variable(node); + } else if (node instanceof AST_SymbolDefClass) { + // This deals with the name of the class being available + // inside the class. + mark_export((node.scope = defun.parent_scope).def_function(node, defun), 1); + } else if ( + node instanceof AST_SymbolVar + || node instanceof AST_SymbolLet + || node instanceof AST_SymbolConst + || node instanceof AST_SymbolUsing + || node instanceof AST_SymbolCatch + ) { + var def; + if (node instanceof AST_SymbolBlockDeclaration) { + def = scope.def_variable(node, null); + } else { + def = defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined); + } + if (!def.orig.every((sym) => { + if (sym === node) return true; + if (node instanceof AST_SymbolBlockDeclaration) { + return sym instanceof AST_SymbolLambda; + } + return !(sym instanceof AST_SymbolLet || sym instanceof AST_SymbolConst || sym instanceof AST_SymbolUsing); + })) { + js_error( + `"${node.name}" is redeclared`, + node.start.file, + node.start.line, + node.start.col, + node.start.pos + ); + } + if (!(node instanceof AST_SymbolFunarg)) mark_export(def, 2); + if (defun !== scope) { + node.mark_enclosed(); + var def = scope.find_variable(node); + if (node.thedef !== def) { + node.thedef = def; + node.reference(); + } + } + } else if (node instanceof AST_LabelRef) { + var sym = labels.get(node.name); + if (!sym) throw new Error(string_template("Undefined label {name} [{line},{col}]", { + name: node.name, + line: node.start.line, + col: node.start.col + })); + node.thedef = sym; + } + if (!(scope instanceof AST_Toplevel) && (node instanceof AST_Export || node instanceof AST_Import)) { + js_error( + `"${node.TYPE}" statement may only appear at the top level`, + node.start.file, + node.start.line, + node.start.col, + node.start.pos + ); + } + }); + + if (options.module) { + tw.directives["use strict"] = true; + } + + this.walk(tw); + + function mark_export(def, level) { + if (in_destructuring) { + var i = 0; + do { + level++; + } while (tw.parent(i++) !== in_destructuring); + } + var node = tw.parent(level); + if (def.export = node instanceof AST_Export ? MASK_EXPORT_DONT_MANGLE : 0) { + var exported = node.exported_definition; + if ((exported instanceof AST_Defun || exported instanceof AST_DefClass) && node.is_default) { + def.export = MASK_EXPORT_WANT_MANGLE; + } + } + } + + // pass 2: find back references and eval + const is_toplevel = this instanceof AST_Toplevel; + if (is_toplevel) { + this.globals = new Map(); + } + + var tw = new TreeWalker(node => { + if (node instanceof AST_LoopControl && node.label) { + node.label.thedef.references.push(node); + return true; + } + if (node instanceof AST_SymbolRef) { + var name = node.name; + if (name == "eval" && tw.parent() instanceof AST_Call) { + for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) { + s.uses_eval = true; + } + } + var sym; + if (tw.parent() instanceof AST_NameMapping && tw.parent(1).module_name + || !(sym = node.scope.find_variable(name))) { + + sym = toplevel.def_global(node); + if (node instanceof AST_SymbolExport) sym.export = MASK_EXPORT_DONT_MANGLE; + } else if (sym.scope instanceof AST_Lambda && name == "arguments") { + sym.scope.get_defun_scope().uses_arguments = true; + } + node.thedef = sym; + node.reference(); + if (node.scope.is_block_scope() + && !(sym.orig[0] instanceof AST_SymbolBlockDeclaration)) { + node.scope = node.scope.get_defun_scope(); + } + return true; + } + // ensure mangling works if catch reuses a scope variable + var def; + if (node instanceof AST_SymbolCatch && (def = redefined_catch_def(node.definition()))) { + var s = node.scope; + while (s) { + push_uniq(s.enclosed, def); + if (s === def.scope) break; + s = s.parent_scope; + } + } + }); + this.walk(tw); + + // pass 3: work around IE8 and Safari catch scope bugs + if (options.ie8 || options.safari10) { + walk(this, node => { + if (node instanceof AST_SymbolCatch) { + var name = node.name; + var refs = node.thedef.references; + var scope = node.scope.get_defun_scope(); + var def = scope.find_variable(name) + || toplevel.globals.get(name) + || scope.def_variable(node); + refs.forEach(function(ref) { + ref.thedef = def; + ref.reference(); + }); + node.thedef = def; + node.reference(); + return true; + } + }); + } + + // pass 4: add symbol definitions to loop scopes + // Safari/Webkit bug workaround - loop init let variable shadowing argument. + // https://github.com/mishoo/UglifyJS2/issues/1753 + // https://bugs.webkit.org/show_bug.cgi?id=171041 + if (options.safari10) { + for (const scope of for_scopes) { + scope.parent_scope.variables.forEach(function(def) { + push_uniq(scope.enclosed, def); + }); + } + } +}); + +AST_Toplevel.DEFMETHOD("def_global", function(node) { + var globals = this.globals, name = node.name; + if (globals.has(name)) { + return globals.get(name); + } else { + var g = new SymbolDef(this, node); + g.undeclared = true; + g.global = true; + globals.set(name, g); + return g; + } +}); + +AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope) { + this.variables = new Map(); // map name to AST_SymbolVar (variables defined in this scope; includes functions) + this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement + this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval` + this.parent_scope = parent_scope; // the parent scope + this.enclosed = []; // a list of variables from this or outer scope(s) that are referenced from this or inner scopes + this.cname = -1; // the current index for mangling functions/variables +}); + +AST_Scope.DEFMETHOD("conflicting_def", function (name) { + return ( + this.enclosed.find(def => def.name === name) + || this.variables.has(name) + || (this.parent_scope && this.parent_scope.conflicting_def(name)) + ); +}); + +AST_Scope.DEFMETHOD("conflicting_def_shallow", function (name) { + return ( + this.enclosed.find(def => def.name === name) + || this.variables.has(name) + ); +}); + +AST_Scope.DEFMETHOD("add_child_scope", function (scope) { + // `scope` is going to be moved into `this` right now. + // Update the required scopes' information + + if (scope.parent_scope === this) return; + + scope.parent_scope = this; + + // Propagate to this.uses_arguments from arrow functions + if ((scope instanceof AST_Arrow) && (this instanceof AST_Lambda && !this.uses_arguments)) { + this.uses_arguments = walk(scope, node => { + if ( + node instanceof AST_SymbolRef + && node.scope instanceof AST_Lambda + && node.name === "arguments" + ) { + return walk_abort; + } + + if (node instanceof AST_Lambda && !(node instanceof AST_Arrow)) { + return true; + } + }); + } + + this.uses_with = this.uses_with || scope.uses_with; + this.uses_eval = this.uses_eval || scope.uses_eval; + + const scope_ancestry = (() => { + const ancestry = []; + let cur = this; + do { + ancestry.push(cur); + } while ((cur = cur.parent_scope)); + ancestry.reverse(); + return ancestry; + })(); + + const new_scope_enclosed_set = new Set(scope.enclosed); + const to_enclose = []; + for (const scope_topdown of scope_ancestry) { + to_enclose.forEach(e => push_uniq(scope_topdown.enclosed, e)); + for (const def of scope_topdown.variables.values()) { + if (new_scope_enclosed_set.has(def)) { + push_uniq(to_enclose, def); + push_uniq(scope_topdown.enclosed, def); + } + } + } +}); + +function find_scopes_visible_from(scopes) { + const found_scopes = new Set(); + + for (const scope of new Set(scopes)) { + (function bubble_up(scope) { + if (scope == null || found_scopes.has(scope)) return; + + found_scopes.add(scope); + + bubble_up(scope.parent_scope); + })(scope); + } + + return [...found_scopes]; +} + +// Creates a symbol during compression +AST_Scope.DEFMETHOD("create_symbol", function(SymClass, { + source, + tentative_name, + scope, + conflict_scopes = [scope], + init = null +} = {}) { + let symbol_name; + + conflict_scopes = find_scopes_visible_from(conflict_scopes); + + if (tentative_name) { + // Implement hygiene (no new names are conflicting with existing names) + tentative_name = + symbol_name = + tentative_name.replace(/(?:^[^a-z_$]|[^a-z0-9_$])/ig, "_"); + + let i = 0; + while (conflict_scopes.find(s => s.conflicting_def_shallow(symbol_name))) { + symbol_name = tentative_name + "$" + i++; + } + } + + if (!symbol_name) { + throw new Error("No symbol name could be generated in create_symbol()"); + } + + const symbol = make_node(SymClass, source, { + name: symbol_name, + scope + }); + + this.def_variable(symbol, init || null); + + symbol.mark_enclosed(); + + return symbol; +}); + + +AST_Node.DEFMETHOD("is_block_scope", return_false); +AST_Class.DEFMETHOD("is_block_scope", return_false); +AST_Lambda.DEFMETHOD("is_block_scope", return_false); +AST_Toplevel.DEFMETHOD("is_block_scope", return_false); +AST_SwitchBranch.DEFMETHOD("is_block_scope", return_false); +AST_Block.DEFMETHOD("is_block_scope", return_true); +AST_Scope.DEFMETHOD("is_block_scope", function () { + return this._block_scope || false; +}); +AST_IterationStatement.DEFMETHOD("is_block_scope", return_true); + +AST_Lambda.DEFMETHOD("init_scope_vars", function() { + AST_Scope.prototype.init_scope_vars.apply(this, arguments); + this.uses_arguments = false; + this.def_variable(new AST_SymbolFunarg({ + name: "arguments", + start: this.start, + end: this.end + })); +}); + +AST_Arrow.DEFMETHOD("init_scope_vars", function() { + AST_Scope.prototype.init_scope_vars.apply(this, arguments); + this.uses_arguments = false; +}); + +AST_Symbol.DEFMETHOD("mark_enclosed", function() { + var def = this.definition(); + var s = this.scope; + while (s) { + push_uniq(s.enclosed, def); + if (s === def.scope) break; + s = s.parent_scope; + } +}); + +AST_Symbol.DEFMETHOD("reference", function() { + this.definition().references.push(this); + this.mark_enclosed(); +}); + +AST_Scope.DEFMETHOD("find_variable", function(name) { + if (name instanceof AST_Symbol) name = name.name; + return this.variables.get(name) + || (this.parent_scope && this.parent_scope.find_variable(name)); +}); + +AST_Scope.DEFMETHOD("def_function", function(symbol, init) { + var def = this.def_variable(symbol, init); + if (!def.init || def.init instanceof AST_Defun) def.init = init; + return def; +}); + +AST_Scope.DEFMETHOD("def_variable", function(symbol, init) { + var def = this.variables.get(symbol.name); + if (def) { + def.orig.push(symbol); + if (def.init && (def.scope !== symbol.scope || def.init instanceof AST_Function)) { + def.init = init; + } + } else { + def = new SymbolDef(this, symbol, init); + this.variables.set(symbol.name, def); + def.global = !this.parent_scope; + } + return symbol.thedef = def; +}); + +function next_mangled(scope, options) { + let defun_scope; + if ( + scopes_with_block_defuns + && (defun_scope = scope.get_defun_scope()) + && scopes_with_block_defuns.has(defun_scope) + ) { + scope = defun_scope; + } + + var ext = scope.enclosed; + var nth_identifier = options.nth_identifier; + out: while (true) { + var m = nth_identifier.get(++scope.cname); + if (ALL_RESERVED_WORDS.has(m)) continue; // skip over "do" + + // https://github.com/mishoo/UglifyJS2/issues/242 -- do not + // shadow a name reserved from mangling. + if (options.reserved.has(m)) continue; + + // Functions with short names might collide with base54 output + // and therefore cause collisions when keep_fnames is true. + if (unmangleable_names && unmangleable_names.has(m)) continue out; + + // we must ensure that the mangled name does not shadow a name + // from some parent scope that is referenced in this or in + // inner scopes. + for (let i = ext.length; --i >= 0;) { + const def = ext[i]; + const name = def.mangled_name || (def.unmangleable(options) && def.name); + if (m == name) continue out; + } + return m; + } +} + +AST_Scope.DEFMETHOD("next_mangled", function(options) { + return next_mangled(this, options); +}); + +AST_Toplevel.DEFMETHOD("next_mangled", function(options) { + let name; + const mangled_names = this.mangled_names; + do { + name = next_mangled(this, options); + } while (mangled_names.has(name)); + return name; +}); + +AST_Function.DEFMETHOD("next_mangled", function(options, def) { + // #179, #326 + // in Safari strict mode, something like (function x(x){...}) is a syntax error; + // a function expression's argument cannot shadow the function expression's name + + var tricky_def = def.orig[0] instanceof AST_SymbolFunarg && this.name && this.name.definition(); + + // the function's mangled_name is null when keep_fnames is true + var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null; + + while (true) { + var name = next_mangled(this, options); + if (!tricky_name || tricky_name != name) + return name; + } +}); + +AST_Symbol.DEFMETHOD("unmangleable", function(options) { + var def = this.definition(); + return !def || def.unmangleable(options); +}); + +// labels are always mangleable +AST_Label.DEFMETHOD("unmangleable", return_false); + +AST_Symbol.DEFMETHOD("unreferenced", function() { + return !this.definition().references.length && !this.scope.pinned(); +}); + +AST_Symbol.DEFMETHOD("definition", function() { + return this.thedef; +}); + +AST_Symbol.DEFMETHOD("global", function() { + return this.thedef.global; +}); + +/** + * Format the mangler options (if any) into their appropriate types + */ +function format_mangler_options(options) { + options = defaults(options, { + eval : false, + nth_identifier : base54, + ie8 : false, + keep_classnames: false, + keep_fnames : false, + module : false, + reserved : [], + toplevel : false, + }); + if (options.module) options.toplevel = true; + if (!Array.isArray(options.reserved) + && !(options.reserved instanceof Set) + ) { + options.reserved = []; + } + options.reserved = new Set(options.reserved); + // Never mangle arguments + options.reserved.add("arguments"); + return options; +} + +AST_Toplevel.DEFMETHOD("mangle_names", function(options) { + options = format_mangler_options(options); + var nth_identifier = options.nth_identifier; + + // We only need to mangle declaration nodes. Special logic wired + // into the code generator will display the mangled name if it's + // present (and for AST_SymbolRef-s it'll use the mangled name of + // the AST_SymbolDeclaration that it points to). + var lname = -1; + var to_mangle = []; + + if (options.keep_fnames) { + function_defs = new Set(); + } + + const mangled_names = this.mangled_names = new Set(); + unmangleable_names = new Set(); + + if (options.cache) { + this.globals.forEach(collect); + if (options.cache.props) { + options.cache.props.forEach(function(mangled_name) { + mangled_names.add(mangled_name); + }); + } + } + + var tw = new TreeWalker(function(node, descend) { + if (node instanceof AST_LabeledStatement) { + // lname is incremented when we get to the AST_Label + var save_nesting = lname; + descend(); + lname = save_nesting; + return true; // don't descend again in TreeWalker + } + if ( + node instanceof AST_Defun + && !(tw.parent() instanceof AST_Scope) + ) { + scopes_with_block_defuns = scopes_with_block_defuns || new Set(); + scopes_with_block_defuns.add(node.parent_scope.get_defun_scope()); + } + if (node instanceof AST_Scope) { + node.variables.forEach(collect); + return; + } + if (node.is_block_scope()) { + node.block_scope.variables.forEach(collect); + return; + } + if ( + function_defs + && node instanceof AST_VarDef + && node.value instanceof AST_Lambda + && !node.value.name + && keep_name(options.keep_fnames, node.name.name) + ) { + function_defs.add(node.name.definition().id); + return; + } + if (node instanceof AST_Label) { + let name; + do { + name = nth_identifier.get(++lname); + } while (ALL_RESERVED_WORDS.has(name)); + node.mangled_name = name; + return true; + } + if (!(options.ie8 || options.safari10) && node instanceof AST_SymbolCatch) { + to_mangle.push(node.definition()); + return; + } + }); + + this.walk(tw); + + if (options.keep_fnames || options.keep_classnames) { + // Collect a set of short names which are unmangleable, + // for use in avoiding collisions in next_mangled. + to_mangle.forEach(def => { + if (def.name.length < 6 && def.unmangleable(options)) { + unmangleable_names.add(def.name); + } + }); + } + + to_mangle.forEach(def => { def.mangle(options); }); + + function_defs = null; + unmangleable_names = null; + scopes_with_block_defuns = null; + + function collect(symbol) { + if (symbol.export & MASK_EXPORT_DONT_MANGLE) { + unmangleable_names.add(symbol.name); + } else if (!options.reserved.has(symbol.name)) { + to_mangle.push(symbol); + } + } +}); + +AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) { + const cache = options.cache && options.cache.props; + const avoid = new Set(); + options.reserved.forEach(to_avoid); + this.globals.forEach(add_def); + this.walk(new TreeWalker(function(node) { + if (node instanceof AST_Scope) node.variables.forEach(add_def); + if (node instanceof AST_SymbolCatch) add_def(node.definition()); + })); + return avoid; + + function to_avoid(name) { + avoid.add(name); + } + + function add_def(def) { + var name = def.name; + if (def.global && cache && cache.has(name)) name = cache.get(name); + else if (!def.unmangleable(options)) return; + to_avoid(name); + } +}); + +AST_Toplevel.DEFMETHOD("expand_names", function(options) { + options = format_mangler_options(options); + var nth_identifier = options.nth_identifier; + if (nth_identifier.reset && nth_identifier.sort) { + nth_identifier.reset(); + nth_identifier.sort(); + } + var avoid = this.find_colliding_names(options); + var cname = 0; + this.globals.forEach(rename); + this.walk(new TreeWalker(function(node) { + if (node instanceof AST_Scope) node.variables.forEach(rename); + if (node instanceof AST_SymbolCatch) rename(node.definition()); + })); + + function next_name() { + var name; + do { + name = nth_identifier.get(cname++); + } while (avoid.has(name) || ALL_RESERVED_WORDS.has(name)); + return name; + } + + function rename(def) { + if (def.global && options.cache) return; + if (def.unmangleable(options)) return; + if (options.reserved.has(def.name)) return; + const redefinition = redefined_catch_def(def); + const name = def.name = redefinition ? redefinition.name : next_name(); + def.orig.forEach(function(sym) { + sym.name = name; + }); + def.references.forEach(function(sym) { + sym.name = name; + }); + } +}); + +AST_Node.DEFMETHOD("tail_node", return_this); +AST_Sequence.DEFMETHOD("tail_node", function() { + return this.expressions[this.expressions.length - 1]; +}); + +AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) { + options = format_mangler_options(options); + var nth_identifier = options.nth_identifier; + if (!nth_identifier.reset || !nth_identifier.consider || !nth_identifier.sort) { + // If the identifier mangler is invariant, skip computing character frequency. + return; + } + nth_identifier.reset(); + + try { + AST_Node.prototype.print = function(stream, force_parens) { + this._print(stream, force_parens); + if (this instanceof AST_Symbol && !this.unmangleable(options)) { + nth_identifier.consider(this.name, -1); + } else if (options.properties) { + if (this instanceof AST_DotHash) { + nth_identifier.consider("#" + this.property, -1); + } else if (this instanceof AST_Dot) { + nth_identifier.consider(this.property, -1); + } else if (this instanceof AST_Sub) { + skip_string(this.property); + } + } + }; + nth_identifier.consider(this.print_to_string(), 1); + } finally { + AST_Node.prototype.print = AST_Node.prototype._print; + } + nth_identifier.sort(); + + function skip_string(node) { + if (node instanceof AST_String) { + nth_identifier.consider(node.value, -1); + } else if (node instanceof AST_Conditional) { + skip_string(node.consequent); + skip_string(node.alternative); + } else if (node instanceof AST_Sequence) { + skip_string(node.tail_node()); + } + } +}); + +const base54 = (() => { + const leading = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_".split(""); + const digits = "0123456789".split(""); + let chars; + let frequency; + function reset() { + frequency = new Map(); + leading.forEach(function(ch) { + frequency.set(ch, 0); + }); + digits.forEach(function(ch) { + frequency.set(ch, 0); + }); + } + function consider(str, delta) { + for (var i = str.length; --i >= 0;) { + frequency.set(str[i], frequency.get(str[i]) + delta); + } + } + function compare(a, b) { + return frequency.get(b) - frequency.get(a); + } + function sort() { + chars = mergeSort(leading, compare).concat(mergeSort(digits, compare)); + } + // Ensure this is in a usable initial state. + reset(); + sort(); + function base54(num) { + var ret = "", base = 54; + num++; + do { + num--; + ret += chars[num % base]; + num = Math.floor(num / base); + base = 64; + } while (num > 0); + return ret; + } + + return { + get: base54, + consider, + reset, + sort + }; +})(); + +let mangle_options = undefined; +AST_Node.prototype.size = function (compressor, stack) { + mangle_options = compressor && compressor._mangle_options; + + let size = 0; + walk_parent(this, (node, info) => { + size += node._size(info); + + // Braceless arrow functions have fake "return" statements + if (node instanceof AST_Arrow && node.is_braceless()) { + size += node.body[0].value._size(info); + return true; + } + }, stack || (compressor && compressor.stack)); + + // just to save a bit of memory + mangle_options = undefined; + + return size; +}; + +AST_Node.prototype._size = () => 0; + +AST_Debugger.prototype._size = () => 8; + +AST_Directive.prototype._size = function () { + // TODO string encoding stuff + return 2 + this.value.length; +}; + +/** Count commas/semicolons necessary to show a list of expressions/statements */ +const list_overhead = (array) => array.length && array.length - 1; + +AST_Block.prototype._size = function () { + return 2 + list_overhead(this.body); +}; + +AST_Toplevel.prototype._size = function() { + return list_overhead(this.body); +}; + +AST_EmptyStatement.prototype._size = () => 1; + +AST_LabeledStatement.prototype._size = () => 2; // x: + +AST_Do.prototype._size = () => 9; + +AST_While.prototype._size = () => 7; + +AST_For.prototype._size = () => 8; + +AST_ForIn.prototype._size = () => 8; +// AST_ForOf inherits ^ + +AST_With.prototype._size = () => 6; + +AST_Expansion.prototype._size = () => 3; + +const lambda_modifiers = func => + (func.is_generator ? 1 : 0) + (func.async ? 6 : 0); + +AST_Accessor.prototype._size = function () { + return lambda_modifiers(this) + 4 + list_overhead(this.argnames) + list_overhead(this.body); +}; + +AST_Function.prototype._size = function (info) { + const first = !!first_in_statement(info); + return (first * 2) + lambda_modifiers(this) + 12 + list_overhead(this.argnames) + list_overhead(this.body); +}; + +AST_Defun.prototype._size = function () { + return lambda_modifiers(this) + 13 + list_overhead(this.argnames) + list_overhead(this.body); +}; + +AST_Arrow.prototype._size = function () { + let args_and_arrow = 2 + list_overhead(this.argnames); + + if ( + !( + this.argnames.length === 1 + && this.argnames[0] instanceof AST_Symbol + ) + ) { + args_and_arrow += 2; // parens around the args + } + + const body_overhead = this.is_braceless() ? 0 : list_overhead(this.body) + 2; + + return lambda_modifiers(this) + args_and_arrow + body_overhead; +}; + +AST_Destructuring.prototype._size = () => 2; + +AST_TemplateString.prototype._size = function () { + return 2 + (Math.floor(this.segments.length / 2) * 3); /* "${}" */ +}; + +AST_TemplateSegment.prototype._size = function () { + return this.value.length; +}; + +AST_Return.prototype._size = function () { + return this.value ? 7 : 6; +}; + +AST_Throw.prototype._size = () => 6; + +AST_Break.prototype._size = function () { + return this.label ? 6 : 5; +}; + +AST_Continue.prototype._size = function () { + return this.label ? 9 : 8; +}; + +AST_If.prototype._size = () => 4; + +AST_Switch.prototype._size = function () { + return 8 + list_overhead(this.body); +}; + +AST_Case.prototype._size = function () { + return 5 + list_overhead(this.body); +}; + +AST_Default.prototype._size = function () { + return 8 + list_overhead(this.body); +}; + +AST_Try.prototype._size = () => 3; + +AST_Catch.prototype._size = function () { + let size = 7 + list_overhead(this.body); + if (this.argname) { + size += 2; + } + return size; +}; + +AST_Finally.prototype._size = function () { + return 7 + list_overhead(this.body); +}; + +AST_Var.prototype._size = function () { + return 4 + list_overhead(this.definitions); +}; + +AST_Let.prototype._size = function () { + return 4 + list_overhead(this.definitions); +}; + +AST_Const.prototype._size = function () { + return 6 + list_overhead(this.definitions); +}; + +AST_Using.prototype._size = function () { + const await_size = this.await ? 6 : 0; + return await_size + 6 + list_overhead(this.definitions); +}; + +AST_VarDefLike.prototype._size = function () { + return this.value ? 1 : 0; +}; + +AST_NameMapping.prototype._size = function () { + // foreign name isn't mangled + return this.name ? 4 : 0; +}; + +AST_Import.prototype._size = function () { + // import + let size = 6; + + if (this.imported_name) size += 1; + + // from + if (this.imported_name || this.imported_names) size += 5; + + // braces, and the commas + if (this.imported_names) { + size += 2 + list_overhead(this.imported_names); + } + + return size; +}; + +AST_ImportMeta.prototype._size = () => 11; + +AST_Export.prototype._size = function () { + let size = 7 + (this.is_default ? 8 : 0); + + if (this.exported_value) { + size += this.exported_value._size(); + } + + if (this.exported_names) { + // Braces and commas + size += 2 + list_overhead(this.exported_names); + } + + if (this.module_name) { + // "from " + size += 5; + } + + return size; +}; + +AST_Call.prototype._size = function () { + if (this.optional) { + return 4 + list_overhead(this.args); + } + return 2 + list_overhead(this.args); +}; + +AST_New.prototype._size = function () { + return 6 + list_overhead(this.args); +}; + +AST_Sequence.prototype._size = function () { + return list_overhead(this.expressions); +}; + +AST_Dot.prototype._size = function () { + if (this.optional) { + return this.property.length + 2; + } + return this.property.length + 1; +}; + +AST_DotHash.prototype._size = function () { + if (this.optional) { + return this.property.length + 3; + } + return this.property.length + 2; +}; + +AST_Sub.prototype._size = function () { + return this.optional ? 4 : 2; +}; + +AST_Unary.prototype._size = function () { + if (this.operator === "typeof") return 7; + if (this.operator === "void") return 5; + return this.operator.length; +}; + +AST_Binary.prototype._size = function (info) { + if (this.operator === "in") return 4; + + let size = this.operator.length; + + if ( + (this.operator === "+" || this.operator === "-") + && this.right instanceof AST_Unary && this.right.operator === this.operator + ) { + // 1+ +a > needs space between the + + size += 1; + } + + if (this.needs_parens(info)) { + size += 2; + } + + return size; +}; + +AST_Conditional.prototype._size = () => 3; + +AST_Array.prototype._size = function () { + return 2 + list_overhead(this.elements); +}; + +AST_Object.prototype._size = function (info) { + let base = 2; + if (first_in_statement(info)) { + base += 2; // parens + } + return base + list_overhead(this.properties); +}; + +/*#__INLINE__*/ +const key_size = key => + typeof key === "string" ? key.length : 0; + +AST_ObjectKeyVal.prototype._size = function () { + return key_size(this.key) + 1; +}; + +/*#__INLINE__*/ +const static_size = is_static => is_static ? 7 : 0; + +AST_ObjectGetter.prototype._size = function () { + return 5 + static_size(this.static) + key_size(this.key); +}; + +AST_ObjectSetter.prototype._size = function () { + return 5 + static_size(this.static) + key_size(this.key); +}; + +AST_ConciseMethod.prototype._size = function () { + return static_size(this.static) + key_size(this.key); +}; + +AST_PrivateMethod.prototype._size = function () { + return AST_ConciseMethod.prototype._size.call(this) + 1; +}; + +AST_PrivateGetter.prototype._size = function () { + return AST_ConciseMethod.prototype._size.call(this) + 4; +}; + +AST_PrivateSetter.prototype._size = function () { + return AST_ConciseMethod.prototype._size.call(this) + 4; +}; + +AST_PrivateIn.prototype._size = function () { + return 5; // "#", and " in " +}; + +AST_Class.prototype._size = function () { + return ( + (this.name ? 8 : 7) + + (this.extends ? 8 : 0) + ); +}; + +AST_ClassStaticBlock.prototype._size = function () { + // "static{}" + semicolons + return 8 + list_overhead(this.body); +}; + +AST_ClassProperty.prototype._size = function () { + return ( + static_size(this.static) + + (typeof this.key === "string" ? this.key.length + 2 : 0) + + (this.value ? 1 : 0) + ); +}; + +AST_ClassPrivateProperty.prototype._size = function () { + return AST_ClassProperty.prototype._size.call(this) + 1; +}; + +AST_Symbol.prototype._size = function () { + if (!(mangle_options && this.thedef && !this.thedef.unmangleable(mangle_options))) { + return this.name.length; + } else { + return 1; + } +}; + +// TODO take propmangle into account +AST_SymbolClassProperty.prototype._size = function () { + return this.name.length; +}; + +AST_SymbolRef.prototype._size = AST_SymbolDeclaration.prototype._size = function () { + if (this.name === "arguments") return 9; + + return AST_Symbol.prototype._size.call(this); +}; + +AST_NewTarget.prototype._size = () => 10; + +AST_SymbolImportForeign.prototype._size = function () { + return this.name.length; +}; + +AST_SymbolExportForeign.prototype._size = function () { + return this.name.length; +}; + +AST_This.prototype._size = () => 4; + +AST_Super.prototype._size = () => 5; + +AST_String.prototype._size = function () { + return this.value.length + 2; +}; + +AST_Number.prototype._size = function () { + const { value } = this; + if (value === 0) return 1; + if (value > 0 && Math.floor(value) === value) { + return Math.floor(Math.log10(value) + 1); + } + return value.toString().length; +}; + +AST_BigInt.prototype._size = function () { + return this.value.length; +}; + +AST_RegExp.prototype._size = function () { + return this.value.toString().length; +}; + +AST_Null.prototype._size = () => 4; + +AST_NaN.prototype._size = () => 3; + +AST_Undefined.prototype._size = () => 6; // "void 0" + +AST_Hole.prototype._size = () => 0; // comma is taken into account by list_overhead() + +AST_Infinity.prototype._size = () => 8; + +AST_True.prototype._size = () => 4; + +AST_False.prototype._size = () => 5; + +AST_Await.prototype._size = () => 6; + +AST_Yield.prototype._size = () => 6; + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +// bitfield flags to be stored in node.flags. +// These are set and unset during compression, and store information in the node without requiring multiple fields. +const UNUSED = 0b00000001; +const TRUTHY = 0b00000010; +const FALSY = 0b00000100; +const UNDEFINED = 0b00001000; +const INLINED = 0b00010000; +// Nodes to which values are ever written. Used when keep_assign is part of the unused option string. +const WRITE_ONLY = 0b00100000; + +// information specific to a single compression pass +const SQUEEZED = 0b0000000100000000; +const OPTIMIZED = 0b0000001000000000; +const TOP = 0b0000010000000000; +const CLEAR_BETWEEN_PASSES = SQUEEZED | OPTIMIZED | TOP; + +const has_flag = (node, flag) => node.flags & flag; +const set_flag = (node, flag) => { node.flags |= flag; }; +const clear_flag = (node, flag) => { node.flags &= ~flag; }; + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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 merge_sequence(array, node) { + if (node instanceof AST_Sequence) { + array.push(...node.expressions); + } else { + array.push(node); + } + return array; +} + +function make_sequence(orig, expressions) { + if (expressions.length == 1) return expressions[0]; + if (expressions.length == 0) throw new Error("trying to create a sequence with length zero!"); + return make_node(AST_Sequence, orig, { + expressions: expressions.reduce(merge_sequence, []) + }); +} + +function make_empty_function(self) { + return make_node(AST_Function, self, { + uses_arguments: false, + argnames: [], + body: [], + is_generator: false, + async: false, + variables: new Map(), + uses_with: false, + uses_eval: false, + parent_scope: null, + enclosed: [], + cname: 0, + block_scope: undefined, + }); +} + +function make_node_from_constant(val, orig) { + switch (typeof val) { + case "string": + return make_node(AST_String, orig, { + value: val + }); + case "number": + if (isNaN(val)) return make_node(AST_NaN, orig); + if (isFinite(val)) { + return 1 / val < 0 ? make_node(AST_UnaryPrefix, orig, { + operator: "-", + expression: make_node(AST_Number, orig, { value: -val }) + }) : make_node(AST_Number, orig, { value: val }); + } + return val < 0 ? make_node(AST_UnaryPrefix, orig, { + operator: "-", + expression: make_node(AST_Infinity, orig) + }) : make_node(AST_Infinity, orig); + case "bigint": + return make_node(AST_BigInt, orig, { value: val.toString() }); + case "boolean": + return make_node(val ? AST_True : AST_False, orig); + case "undefined": + return make_node(AST_Undefined, orig); + default: + if (val === null) { + return make_node(AST_Null, orig, { value: null }); + } + if (val instanceof RegExp) { + return make_node(AST_RegExp, orig, { + value: { + source: regexp_source_fix(val.source), + flags: val.flags + } + }); + } + throw new Error(string_template("Can't handle constant of type: {type}", { + type: typeof val + })); + } +} + +function best_of_expression(ast1, ast2) { + return ast1.size() > ast2.size() ? ast2 : ast1; +} + +function best_of_statement(ast1, ast2) { + return best_of_expression( + make_node(AST_SimpleStatement, ast1, { + body: ast1 + }), + make_node(AST_SimpleStatement, ast2, { + body: ast2 + }) + ).body; +} + +/** Find which node is smaller, and return that */ +function best_of(compressor, ast1, ast2) { + if (first_in_statement(compressor)) { + return best_of_statement(ast1, ast2); + } else { + return best_of_expression(ast1, ast2); + } +} + +/** Simplify an object property's key, if possible */ +function get_simple_key(key) { + if (key instanceof AST_Constant) { + return key.getValue(); + } + if (key instanceof AST_UnaryPrefix + && key.operator == "void" + && key.expression instanceof AST_Constant) { + return undefined; + } + return key; +} + +function read_property(obj, key) { + key = get_simple_key(key); + if (key instanceof AST_Node) return; + + var value; + if (obj instanceof AST_Array) { + var elements = obj.elements; + if (key == "length") return make_node_from_constant(elements.length, obj); + if (typeof key == "number" && key in elements) value = elements[key]; + } else if (obj instanceof AST_Object) { + key = "" + key; + var props = obj.properties; + for (var i = props.length; --i >= 0;) { + var prop = props[i]; + if (!(prop instanceof AST_ObjectKeyVal)) return; + if (!value && props[i].key === key) value = props[i].value; + } + } + + return value instanceof AST_SymbolRef && value.fixed_value() || value; +} + +function has_break_or_continue(loop, parent) { + var found = false; + var tw = new TreeWalker(function(node) { + if (found || node instanceof AST_Scope) return true; + if (node instanceof AST_LoopControl && tw.loopcontrol_target(node) === loop) { + return found = true; + } + }); + if (parent instanceof AST_LabeledStatement) tw.push(parent); + tw.push(loop); + loop.body.walk(tw); + return found; +} + +// we shouldn't compress (1,func)(something) to +// func(something) because that changes the meaning of +// the func (becomes lexical instead of global). +function maintain_this_binding(parent, orig, val) { + if (requires_sequence_to_maintain_binding(parent, orig, val)) { + const zero = make_node(AST_Number, orig, { value: 0 }); + return make_sequence(orig, [ zero, val ]); + } else { + return val; + } +} + +/** Detect (1, x.noThis)(), (0, eval)(), which need sequences */ +function requires_sequence_to_maintain_binding(parent, orig, val) { + return ( + parent instanceof AST_UnaryPrefix && parent.operator == "delete" + || parent instanceof AST_Call && parent.expression === orig + && ( + val instanceof AST_Chain + || val instanceof AST_PropAccess + || val instanceof AST_SymbolRef && val.name == "eval" + ) + ); +} + +function is_func_expr(node) { + return node instanceof AST_Arrow || node instanceof AST_Function; +} + +/** + * Used to determine whether the node can benefit from negation. + * Not the case with arrow functions (you need an extra set of parens). */ +function is_iife_call(node) { + if (node.TYPE != "Call") return false; + return node.expression instanceof AST_Function || is_iife_call(node.expression); +} + +function is_empty(thing) { + if (thing === null) return true; + if (thing instanceof AST_EmptyStatement) return true; + if (thing instanceof AST_BlockStatement) return thing.body.length == 0; + return false; +} + +const identifier_atom = makePredicate("Infinity NaN undefined"); +function is_identifier_atom(node) { + return node instanceof AST_Infinity + || node instanceof AST_NaN + || node instanceof AST_Undefined; +} + +/** Check if this is a SymbolRef node which has one def of a certain AST type */ +function is_ref_of(ref, type) { + if (!(ref instanceof AST_SymbolRef)) return false; + var orig = ref.definition().orig; + for (var i = orig.length; --i >= 0;) { + if (orig[i] instanceof type) return true; + } +} + +/**Can we turn { block contents... } into just the block contents ? + * Not if one of these is inside. + **/ +function can_be_evicted_from_block(node) { + return !( + node instanceof AST_DefClass || + node instanceof AST_Defun || + node instanceof AST_Let || + node instanceof AST_Const || + node instanceof AST_Using || + node instanceof AST_Export || + node instanceof AST_Import + ); +} + +function as_statement_array(thing) { + if (thing === null) return []; + if (thing instanceof AST_BlockStatement) return thing.body; + if (thing instanceof AST_EmptyStatement) return []; + if (thing instanceof AST_Statement) return [ thing ]; + throw new Error("Can't convert thing to statement array"); +} + +function is_reachable(scope_node, defs) { + const find_ref = node => { + if (node instanceof AST_SymbolRef && defs.includes(node.definition())) { + return walk_abort; + } + }; + + return walk_parent(scope_node, (node, info) => { + if (node instanceof AST_Scope && node !== scope_node) { + var parent = info.parent(); + + if ( + parent instanceof AST_Call + && parent.expression === node + // Async/Generators aren't guaranteed to sync evaluate all of + // their body steps, so it's possible they close over the variable. + && !(node.async || node.is_generator) + ) { + return; + } + + if (walk(node, find_ref)) return walk_abort; + + return true; + } + }); +} + +/** Check if a ref refers to the name of a function/class it's defined within */ +function is_recursive_ref(tw, def) { + var node; + for (var i = 0; node = tw.parent(i); i++) { + if (node instanceof AST_Lambda || node instanceof AST_Class) { + var name = node.name; + if (name && name.definition() === def) { + return true; + } + } + } + return false; +} + +// TODO this only works with AST_Defun, shouldn't it work for other ways of defining functions? +function retain_top_func(fn, compressor) { + return compressor.top_retain + && fn instanceof AST_Defun + && has_flag(fn, TOP) + && fn.name + && compressor.top_retain(fn.name.definition()); +} + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +// Lists of native methods, useful for `unsafe` option which assumes they exist. +// Note: Lots of methods and functions are missing here, in case they aren't pure +// or not available in all JS environments. + +function make_nested_lookup(obj) { + const out = new Map(); + for (var key of Object.keys(obj)) { + out.set(key, makePredicate(obj[key])); + } + + const does_have = (global_name, fname) => { + const inner_map = out.get(global_name); + return inner_map != null && inner_map.has(fname); + }; + return does_have; +} + +// Objects which are safe to access without throwing or causing a side effect. +// Usually we'd check the `unsafe` option first but these are way too common for that +const pure_prop_access_globals = new Set([ + "Number", + "String", + "Array", + "Object", + "Function", + "Promise", +]); + +const object_methods = [ + "constructor", + "toString", + "valueOf", +]; + +const is_pure_native_method = make_nested_lookup({ + Array: [ + "at", + "flat", + "includes", + "indexOf", + "join", + "lastIndexOf", + "slice", + ...object_methods, + ], + Boolean: object_methods, + Function: object_methods, + Number: [ + "toExponential", + "toFixed", + "toPrecision", + ...object_methods, + ], + Object: object_methods, + RegExp: [ + "test", + ...object_methods, + ], + String: [ + "at", + "charAt", + "charCodeAt", + "charPointAt", + "concat", + "endsWith", + "fromCharCode", + "fromCodePoint", + "includes", + "indexOf", + "italics", + "lastIndexOf", + "localeCompare", + "match", + "matchAll", + "normalize", + "padStart", + "padEnd", + "repeat", + "replace", + "replaceAll", + "search", + "slice", + "split", + "startsWith", + "substr", + "substring", + "repeat", + "toLocaleLowerCase", + "toLocaleUpperCase", + "toLowerCase", + "toUpperCase", + "trim", + "trimEnd", + "trimStart", + ...object_methods, + ], +}); + +const is_pure_native_fn = make_nested_lookup({ + Array: [ + "isArray", + ], + Math: [ + "abs", + "acos", + "asin", + "atan", + "ceil", + "cos", + "exp", + "floor", + "log", + "round", + "sin", + "sqrt", + "tan", + "atan2", + "pow", + "max", + "min", + ], + Number: [ + "isFinite", + "isNaN", + ], + Object: [ + "create", + "getOwnPropertyDescriptor", + "getOwnPropertyNames", + "getPrototypeOf", + "isExtensible", + "isFrozen", + "isSealed", + "hasOwn", + "keys", + ], + String: [ + "fromCharCode", + ], +}); + +// Known numeric values which come with JS environments +const is_pure_native_value = make_nested_lookup({ + Math: [ + "E", + "LN10", + "LN2", + "LOG2E", + "LOG10E", + "PI", + "SQRT1_2", + "SQRT2", + ], + Number: [ + "MAX_VALUE", + "MIN_VALUE", + "NaN", + "NEGATIVE_INFINITY", + "POSITIVE_INFINITY", + ], +}); + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +// Functions and methods to infer certain facts about expressions +// It's not always possible to be 100% sure about something just by static analysis, +// so `true` means yes, and `false` means maybe + +const is_undeclared_ref = (node) => + node instanceof AST_SymbolRef && node.definition().undeclared; + +const bitwise_binop = makePredicate("<<< >> << & | ^ ~"); +const lazy_op = makePredicate("&& || ??"); +const unary_side_effects = makePredicate("delete ++ --"); + +// methods to determine whether an expression has a boolean result type +(function(def_is_boolean) { + const unary_bool = makePredicate("! delete"); + const binary_bool = makePredicate("in instanceof == != === !== < <= >= >"); + def_is_boolean(AST_Node, return_false); + def_is_boolean(AST_UnaryPrefix, function() { + return unary_bool.has(this.operator); + }); + def_is_boolean(AST_Binary, function() { + return binary_bool.has(this.operator) + || lazy_op.has(this.operator) + && this.left.is_boolean() + && this.right.is_boolean(); + }); + def_is_boolean(AST_Conditional, function() { + return this.consequent.is_boolean() && this.alternative.is_boolean(); + }); + def_is_boolean(AST_Assign, function() { + return this.operator == "=" && this.right.is_boolean(); + }); + def_is_boolean(AST_Sequence, function() { + return this.tail_node().is_boolean(); + }); + def_is_boolean(AST_True, return_true); + def_is_boolean(AST_False, return_true); +})(function(node, func) { + node.DEFMETHOD("is_boolean", func); +}); + +// methods to determine if an expression has a numeric result type +(function(def_is_number) { + def_is_number(AST_Node, return_false); + def_is_number(AST_Number, return_true); + const unary = makePredicate("+ - ~ ++ --"); + def_is_number(AST_Unary, function(compressor) { + return unary.has(this.operator) && this.expression.is_number(compressor); + }); + const numeric_ops = makePredicate("- * / % & | ^ << >> >>>"); + def_is_number(AST_Binary, function(compressor) { + if (this.operator === "+") { + // Both sides need to be `number`. Or one is a `number` and the other is number-ish. + return this.left.is_number(compressor) && this.right.is_number_or_bigint(compressor) + || this.right.is_number(compressor) && this.left.is_number_or_bigint(compressor); + } else if (numeric_ops.has(this.operator)) { + return this.left.is_number(compressor) || this.right.is_number(compressor); + } else { + return false; + } + }); + def_is_number(AST_Assign, function(compressor) { + return (this.operator === "=" || numeric_ops.has(this.operator.slice(0, -1))) + && this.right.is_number(compressor); + }); + def_is_number(AST_Sequence, function(compressor) { + return this.tail_node().is_number(compressor); + }); + def_is_number(AST_Conditional, function(compressor) { + return this.consequent.is_number(compressor) && this.alternative.is_number(compressor); + }); +})(function(node, func) { + node.DEFMETHOD("is_number", func); +}); + +// methods to determine if an expression returns a BigInt +(function(def_is_bigint) { + def_is_bigint(AST_Node, return_false); + def_is_bigint(AST_BigInt, return_true); + const unary = makePredicate("+ - ~ ++ --"); + def_is_bigint(AST_Unary, function(compressor) { + return unary.has(this.operator) && this.expression.is_bigint(compressor); + }); + const numeric_ops = makePredicate("- * / % & | ^ << >>"); + def_is_bigint(AST_Binary, function(compressor) { + if (this.operator === "+") { + return this.left.is_bigint(compressor) && this.right.is_number_or_bigint(compressor) + || this.right.is_bigint(compressor) && this.left.is_number_or_bigint(compressor); + } else if (numeric_ops.has(this.operator)) { + return this.left.is_bigint(compressor) || this.right.is_bigint(compressor); + } else { + return false; + } + }); + def_is_bigint(AST_Assign, function(compressor) { + return (numeric_ops.has(this.operator.slice(0, -1)) || this.operator == "=") + && this.right.is_bigint(compressor); + }); + def_is_bigint(AST_Sequence, function(compressor) { + return this.tail_node().is_bigint(compressor); + }); + def_is_bigint(AST_Conditional, function(compressor) { + return this.consequent.is_bigint(compressor) && this.alternative.is_bigint(compressor); + }); +})(function(node, func) { + node.DEFMETHOD("is_bigint", func); +}); + +// methods to determine if an expression is a number or a bigint +(function(def_is_number_or_bigint) { + def_is_number_or_bigint(AST_Node, return_false); + def_is_number_or_bigint(AST_Number, return_true); + def_is_number_or_bigint(AST_BigInt, return_true); + const numeric_unary_ops = makePredicate("+ - ~ ++ --"); + def_is_number_or_bigint(AST_Unary, function(_compressor) { + return numeric_unary_ops.has(this.operator); + }); + const numeric_ops = makePredicate("- * / % & | ^ << >>"); + def_is_number_or_bigint(AST_Binary, function(compressor) { + return this.operator === "+" + ? this.left.is_number_or_bigint(compressor) && this.right.is_number_or_bigint(compressor) + : numeric_ops.has(this.operator); + }); + def_is_number_or_bigint(AST_Assign, function(compressor) { + return numeric_ops.has(this.operator.slice(0, -1)) + || this.operator == "=" && this.right.is_number_or_bigint(compressor); + }); + def_is_number_or_bigint(AST_Sequence, function(compressor) { + return this.tail_node().is_number_or_bigint(compressor); + }); + def_is_number_or_bigint(AST_Conditional, function(compressor) { + return this.consequent.is_number_or_bigint(compressor) && this.alternative.is_number_or_bigint(compressor); + }); +}(function (node, func) { + node.DEFMETHOD("is_number_or_bigint", func); +})); + + +// methods to determine if an expression is a 32 bit integer (IE results from bitwise ops, or is an integer constant fitting in that size +(function(def_is_32_bit_integer) { + def_is_32_bit_integer(AST_Node, return_false); + def_is_32_bit_integer(AST_Number, function(_compressor) { + return this.value === (this.value | 0); + }); + def_is_32_bit_integer(AST_UnaryPrefix, function(compressor) { + return this.operator == "~" ? this.expression.is_number(compressor) + : this.operator === "+" ? this.expression.is_32_bit_integer(compressor) + : false; + }); + def_is_32_bit_integer(AST_Binary, function(compressor) { + return bitwise_binop.has(this.operator) + && (this.left.is_number(compressor) || this.right.is_number(compressor)); + }); +}(function (node, func) { + node.DEFMETHOD("is_32_bit_integer", func); +})); + +// methods to determine if an expression has a string result type +(function(def_is_string) { + def_is_string(AST_Node, return_false); + def_is_string(AST_String, return_true); + def_is_string(AST_TemplateString, return_true); + def_is_string(AST_UnaryPrefix, function() { + return this.operator == "typeof"; + }); + def_is_string(AST_Binary, function(compressor) { + return this.operator == "+" && + (this.left.is_string(compressor) || this.right.is_string(compressor)); + }); + def_is_string(AST_Assign, function(compressor) { + return (this.operator == "=" || this.operator == "+=") && this.right.is_string(compressor); + }); + def_is_string(AST_Sequence, function(compressor) { + return this.tail_node().is_string(compressor); + }); + def_is_string(AST_Conditional, function(compressor) { + return this.consequent.is_string(compressor) && this.alternative.is_string(compressor); + }); +})(function(node, func) { + node.DEFMETHOD("is_string", func); +}); + +function is_undefined(node, compressor) { + return ( + has_flag(node, UNDEFINED) + || node instanceof AST_Undefined + || node instanceof AST_UnaryPrefix + && node.operator == "void" + && !node.expression.has_side_effects(compressor) + ); +} + +// Is the node explicitly null or undefined. +function is_null_or_undefined(node, compressor) { + let fixed; + return ( + node instanceof AST_Null + || is_undefined(node, compressor) + || ( + node instanceof AST_SymbolRef + && (fixed = node.definition().fixed) instanceof AST_Node + && is_nullish(fixed, compressor) + ) + ); +} + +// Find out if this expression is optionally chained from a base-point that we +// can statically analyze as null or undefined. +function is_nullish_shortcircuited(node, compressor) { + if (node instanceof AST_PropAccess || node instanceof AST_Call) { + return ( + (node.optional && is_null_or_undefined(node.expression, compressor)) + || is_nullish_shortcircuited(node.expression, compressor) + ); + } + if (node instanceof AST_Chain) return is_nullish_shortcircuited(node.expression, compressor); + return false; +} + +// Find out if something is == null, or can short circuit into nullish. +// Used to optimize ?. and ?? +function is_nullish(node, compressor) { + if (is_null_or_undefined(node, compressor)) return true; + return is_nullish_shortcircuited(node, compressor); +} + +// Determine if expression might cause side effects +// If there's a possibility that a node may change something when it's executed, this returns true +(function(def_has_side_effects) { + def_has_side_effects(AST_Node, return_true); + + def_has_side_effects(AST_EmptyStatement, return_false); + def_has_side_effects(AST_Constant, return_false); + def_has_side_effects(AST_This, return_false); + + function any(list, compressor) { + for (var i = list.length; --i >= 0;) + if (list[i].has_side_effects(compressor)) + return true; + return false; + } + + def_has_side_effects(AST_Block, function(compressor) { + return any(this.body, compressor); + }); + def_has_side_effects(AST_Call, function(compressor) { + if ( + !this.is_callee_pure(compressor) + && (!this.expression.is_call_pure(compressor) + || this.expression.has_side_effects(compressor)) + ) { + return true; + } + return any(this.args, compressor); + }); + def_has_side_effects(AST_Switch, function(compressor) { + return this.expression.has_side_effects(compressor) + || any(this.body, compressor); + }); + def_has_side_effects(AST_Case, function(compressor) { + return this.expression.has_side_effects(compressor) + || any(this.body, compressor); + }); + def_has_side_effects(AST_Try, function(compressor) { + return this.body.has_side_effects(compressor) + || this.bcatch && this.bcatch.has_side_effects(compressor) + || this.bfinally && this.bfinally.has_side_effects(compressor); + }); + def_has_side_effects(AST_If, function(compressor) { + return this.condition.has_side_effects(compressor) + || this.body && this.body.has_side_effects(compressor) + || this.alternative && this.alternative.has_side_effects(compressor); + }); + def_has_side_effects(AST_ImportMeta, return_false); + def_has_side_effects(AST_LabeledStatement, function(compressor) { + return this.body.has_side_effects(compressor); + }); + def_has_side_effects(AST_SimpleStatement, function(compressor) { + return this.body.has_side_effects(compressor); + }); + def_has_side_effects(AST_Lambda, return_false); + def_has_side_effects(AST_Class, function (compressor) { + if (this.extends && this.extends.has_side_effects(compressor)) { + return true; + } + return any(this.properties, compressor); + }); + def_has_side_effects(AST_ClassStaticBlock, function(compressor) { + return any(this.body, compressor); + }); + def_has_side_effects(AST_Binary, function(compressor) { + return this.left.has_side_effects(compressor) + || this.right.has_side_effects(compressor); + }); + def_has_side_effects(AST_Assign, return_true); + def_has_side_effects(AST_Conditional, function(compressor) { + return this.condition.has_side_effects(compressor) + || this.consequent.has_side_effects(compressor) + || this.alternative.has_side_effects(compressor); + }); + def_has_side_effects(AST_Unary, function(compressor) { + return unary_side_effects.has(this.operator) + || this.expression.has_side_effects(compressor); + }); + def_has_side_effects(AST_SymbolRef, function(compressor) { + return !this.is_declared(compressor) && !pure_prop_access_globals.has(this.name); + }); + def_has_side_effects(AST_SymbolClassProperty, return_false); + def_has_side_effects(AST_SymbolDeclaration, return_false); + def_has_side_effects(AST_Object, function(compressor) { + return any(this.properties, compressor); + }); + def_has_side_effects(AST_ObjectKeyVal, function(compressor) { + return ( + this.computed_key() && this.key.has_side_effects(compressor) + || this.value && this.value.has_side_effects(compressor) + ); + }); + def_has_side_effects([ + AST_ClassProperty, + AST_ClassPrivateProperty, + ], function(compressor) { + return ( + this.computed_key() && this.key.has_side_effects(compressor) + || this.static && this.value && this.value.has_side_effects(compressor) + ); + }); + def_has_side_effects([ + AST_PrivateMethod, + AST_PrivateGetter, + AST_PrivateSetter, + AST_ConciseMethod, + AST_ObjectGetter, + AST_ObjectSetter, + ], function(compressor) { + return this.computed_key() && this.key.has_side_effects(compressor); + }); + def_has_side_effects(AST_Array, function(compressor) { + return any(this.elements, compressor); + }); + def_has_side_effects(AST_Dot, function(compressor) { + if (is_nullish(this, compressor)) { + return this.expression.has_side_effects(compressor); + } + if (!this.optional && this.expression.may_throw_on_access(compressor)) { + return true; + } + + return this.expression.has_side_effects(compressor); + }); + def_has_side_effects(AST_Sub, function(compressor) { + if (is_nullish(this, compressor)) { + return this.expression.has_side_effects(compressor); + } + if (!this.optional && this.expression.may_throw_on_access(compressor)) { + return true; + } + + var property = this.property.has_side_effects(compressor); + if (property && this.optional) return true; // "?." is a condition + + return property || this.expression.has_side_effects(compressor); + }); + def_has_side_effects(AST_Chain, function (compressor) { + return this.expression.has_side_effects(compressor); + }); + def_has_side_effects(AST_Sequence, function(compressor) { + return any(this.expressions, compressor); + }); + def_has_side_effects(AST_Definitions, function(compressor) { + return any(this.definitions, compressor); + }); + def_has_side_effects(AST_VarDef, function() { + return this.value != null; + }); + def_has_side_effects(AST_TemplateSegment, return_false); + def_has_side_effects(AST_TemplateString, function(compressor) { + return any(this.segments, compressor); + }); +})(function(node_or_nodes, func) { + for (const node of [].concat(node_or_nodes)) { + node.DEFMETHOD("has_side_effects", func); + } +}); + +// determine if expression may throw +(function(def_may_throw) { + def_may_throw(AST_Node, return_true); + + def_may_throw(AST_Constant, return_false); + def_may_throw(AST_EmptyStatement, return_false); + def_may_throw(AST_Lambda, return_false); + def_may_throw(AST_SymbolDeclaration, return_false); + def_may_throw(AST_This, return_false); + def_may_throw(AST_ImportMeta, return_false); + + function any(list, compressor) { + for (var i = list.length; --i >= 0;) + if (list[i].may_throw(compressor)) + return true; + return false; + } + + def_may_throw(AST_Class, function(compressor) { + if (this.extends && this.extends.may_throw(compressor)) return true; + return any(this.properties, compressor); + }); + def_may_throw(AST_ClassStaticBlock, function (compressor) { + return any(this.body, compressor); + }); + + def_may_throw(AST_Array, function(compressor) { + return any(this.elements, compressor); + }); + def_may_throw(AST_Assign, function(compressor) { + if (this.right.may_throw(compressor)) return true; + if (!compressor.has_directive("use strict") + && this.operator == "=" + && this.left instanceof AST_SymbolRef) { + return false; + } + return this.left.may_throw(compressor); + }); + def_may_throw(AST_Binary, function(compressor) { + return this.left.may_throw(compressor) + || this.right.may_throw(compressor); + }); + def_may_throw(AST_Block, function(compressor) { + return any(this.body, compressor); + }); + def_may_throw(AST_Call, function(compressor) { + if (is_nullish(this, compressor)) return false; + if (any(this.args, compressor)) return true; + if (this.is_callee_pure(compressor)) return false; + if (this.expression.may_throw(compressor)) return true; + return !(this.expression instanceof AST_Lambda) + || any(this.expression.body, compressor); + }); + def_may_throw(AST_Case, function(compressor) { + return this.expression.may_throw(compressor) + || any(this.body, compressor); + }); + def_may_throw(AST_Conditional, function(compressor) { + return this.condition.may_throw(compressor) + || this.consequent.may_throw(compressor) + || this.alternative.may_throw(compressor); + }); + def_may_throw(AST_Definitions, function(compressor) { + return any(this.definitions, compressor); + }); + def_may_throw(AST_If, function(compressor) { + return this.condition.may_throw(compressor) + || this.body && this.body.may_throw(compressor) + || this.alternative && this.alternative.may_throw(compressor); + }); + def_may_throw(AST_LabeledStatement, function(compressor) { + return this.body.may_throw(compressor); + }); + def_may_throw(AST_Object, function(compressor) { + return any(this.properties, compressor); + }); + def_may_throw(AST_ObjectKeyVal, function(compressor) { + return ( + this.computed_key() && this.key.may_throw(compressor) + || this.value ? this.value.may_throw(compressor) : false + ); + }); + def_may_throw([ + AST_ClassProperty, + AST_ClassPrivateProperty, + ], function(compressor) { + return ( + this.computed_key() && this.key.may_throw(compressor) + || this.static && this.value && this.value.may_throw(compressor) + ); + }); + def_may_throw([ + AST_ConciseMethod, + AST_ObjectGetter, + AST_ObjectSetter, + ], function(compressor) { + return this.computed_key() && this.key.may_throw(compressor); + }); + def_may_throw([ + AST_PrivateMethod, + AST_PrivateGetter, + AST_PrivateSetter, + ], return_false); + def_may_throw(AST_Return, function(compressor) { + return this.value && this.value.may_throw(compressor); + }); + def_may_throw(AST_Sequence, function(compressor) { + return any(this.expressions, compressor); + }); + def_may_throw(AST_SimpleStatement, function(compressor) { + return this.body.may_throw(compressor); + }); + def_may_throw(AST_Dot, function(compressor) { + if (is_nullish(this, compressor)) return false; + return !this.optional && this.expression.may_throw_on_access(compressor) + || this.expression.may_throw(compressor); + }); + def_may_throw(AST_Sub, function(compressor) { + if (is_nullish(this, compressor)) return false; + return !this.optional && this.expression.may_throw_on_access(compressor) + || this.expression.may_throw(compressor) + || this.property.may_throw(compressor); + }); + def_may_throw(AST_Chain, function(compressor) { + return this.expression.may_throw(compressor); + }); + def_may_throw(AST_Switch, function(compressor) { + return this.expression.may_throw(compressor) + || any(this.body, compressor); + }); + def_may_throw(AST_SymbolRef, function(compressor) { + return !this.is_declared(compressor) && !pure_prop_access_globals.has(this.name); + }); + def_may_throw(AST_SymbolClassProperty, return_false); + def_may_throw(AST_Try, function(compressor) { + return this.bcatch ? this.bcatch.may_throw(compressor) : this.body.may_throw(compressor) + || this.bfinally && this.bfinally.may_throw(compressor); + }); + def_may_throw(AST_Unary, function(compressor) { + if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef) + return false; + return this.expression.may_throw(compressor); + }); + def_may_throw(AST_VarDef, function(compressor) { + if (!this.value) return false; + return this.value.may_throw(compressor); + }); +})(function(node_or_nodes, func) { + for (const node of [].concat(node_or_nodes)) { + node.DEFMETHOD("may_throw", func); + } +}); + +// determine if expression is constant +(function(def_is_constant_expression) { + function all_refs_local(scope) { + let result = true; + walk(this, node => { + if (node instanceof AST_SymbolRef) { + if (has_flag(this, INLINED)) { + result = false; + return walk_abort; + } + var def = node.definition(); + if ( + member(def, this.enclosed) + && !this.variables.has(def.name) + ) { + if (scope) { + var scope_def = scope.find_variable(node); + if (def.undeclared ? !scope_def : scope_def === def) { + result = "f"; + return true; + } + } + result = false; + return walk_abort; + } + return true; + } + if (node instanceof AST_This && this instanceof AST_Arrow) { + result = false; + return walk_abort; + } + }); + return result; + } + + def_is_constant_expression(AST_Node, return_false); + def_is_constant_expression(AST_Constant, return_true); + def_is_constant_expression(AST_Class, function(scope) { + if (this.extends && !this.extends.is_constant_expression(scope)) { + return false; + } + + for (const prop of this.properties) { + if (prop.computed_key() && !prop.key.is_constant_expression(scope)) { + return false; + } + if (prop.static && prop.value && !prop.value.is_constant_expression(scope)) { + return false; + } + if (prop instanceof AST_ClassStaticBlock) { + return false; + } + } + + return all_refs_local.call(this, scope); + }); + def_is_constant_expression(AST_Lambda, all_refs_local); + def_is_constant_expression(AST_Unary, function() { + return this.expression.is_constant_expression(); + }); + def_is_constant_expression(AST_Binary, function() { + return this.left.is_constant_expression() + && this.right.is_constant_expression(); + }); + def_is_constant_expression(AST_Array, function() { + return this.elements.every((l) => l.is_constant_expression()); + }); + def_is_constant_expression(AST_Object, function() { + return this.properties.every((l) => l.is_constant_expression()); + }); + def_is_constant_expression(AST_ObjectProperty, function() { + return !!(!(this.key instanceof AST_Node) && this.value && this.value.is_constant_expression()); + }); +})(function(node, func) { + node.DEFMETHOD("is_constant_expression", func); +}); + + +// may_throw_on_access() +// returns true if this node may be null, undefined or contain `AST_Accessor` +(function(def_may_throw_on_access) { + AST_Node.DEFMETHOD("may_throw_on_access", function(compressor) { + return !compressor.option("pure_getters") + || this._dot_throw(compressor); + }); + + function is_strict(compressor) { + return /strict/.test(compressor.option("pure_getters")); + } + + def_may_throw_on_access(AST_Node, is_strict); + def_may_throw_on_access(AST_Null, return_true); + def_may_throw_on_access(AST_Undefined, return_true); + def_may_throw_on_access(AST_Constant, return_false); + def_may_throw_on_access(AST_Array, return_false); + def_may_throw_on_access(AST_Object, function(compressor) { + if (!is_strict(compressor)) return false; + for (var i = this.properties.length; --i >=0;) + if (this.properties[i]._dot_throw(compressor)) return true; + return false; + }); + // Do not be as strict with classes as we are with objects. + // Hopefully the community is not going to abuse static getters and setters. + // https://github.com/terser/terser/issues/724#issuecomment-643655656 + def_may_throw_on_access(AST_Class, return_false); + def_may_throw_on_access(AST_ObjectProperty, return_false); + def_may_throw_on_access(AST_ObjectGetter, return_true); + def_may_throw_on_access(AST_Expansion, function(compressor) { + return this.expression._dot_throw(compressor); + }); + def_may_throw_on_access(AST_Function, return_false); + def_may_throw_on_access(AST_Arrow, return_false); + def_may_throw_on_access(AST_UnaryPostfix, return_false); + def_may_throw_on_access(AST_UnaryPrefix, function() { + return this.operator == "void"; + }); + def_may_throw_on_access(AST_Binary, function(compressor) { + return (this.operator == "&&" || this.operator == "||" || this.operator == "??") + && (this.left._dot_throw(compressor) || this.right._dot_throw(compressor)); + }); + def_may_throw_on_access(AST_Assign, function(compressor) { + if (this.logical) return true; + + return this.operator == "=" + && this.right._dot_throw(compressor); + }); + def_may_throw_on_access(AST_Conditional, function(compressor) { + return this.consequent._dot_throw(compressor) + || this.alternative._dot_throw(compressor); + }); + def_may_throw_on_access(AST_Dot, function(compressor) { + if (!is_strict(compressor)) return false; + + if (this.property == "prototype") { + return !( + this.expression instanceof AST_Function + || this.expression instanceof AST_Class + ); + } + return true; + }); + def_may_throw_on_access(AST_Chain, function(compressor) { + return this.expression._dot_throw(compressor); + }); + def_may_throw_on_access(AST_Sequence, function(compressor) { + return this.tail_node()._dot_throw(compressor); + }); + def_may_throw_on_access(AST_SymbolRef, function(compressor) { + if (this.name === "arguments" && this.scope instanceof AST_Lambda) return false; + if (has_flag(this, UNDEFINED)) return true; + if (!is_strict(compressor)) return false; + if (is_undeclared_ref(this) && this.is_declared(compressor)) return false; + if (this.is_immutable()) return false; + var fixed = this.fixed_value(); + return !fixed || fixed._dot_throw(compressor); + }); +})(function(node, func) { + node.DEFMETHOD("_dot_throw", func); +}); + +function is_lhs(node, parent) { + if (parent instanceof AST_Unary && unary_side_effects.has(parent.operator)) return parent.expression; + if (parent instanceof AST_Assign && parent.left === node) return node; + if (parent instanceof AST_ForIn && parent.init === node) return node; +} + +// method to negate an expression +(function(def_negate) { + function basic_negation(exp) { + return make_node(AST_UnaryPrefix, exp, { + operator: "!", + expression: exp + }); + } + function best(orig, alt, first_in_statement) { + var negated = basic_negation(orig); + if (first_in_statement) { + var stat = make_node(AST_SimpleStatement, alt, { + body: alt + }); + return best_of_expression(negated, stat) === stat ? alt : negated; + } + return best_of_expression(negated, alt); + } + def_negate(AST_Node, function() { + return basic_negation(this); + }); + def_negate(AST_Statement, function() { + throw new Error("Cannot negate a statement"); + }); + def_negate(AST_Function, function() { + return basic_negation(this); + }); + def_negate(AST_Class, function() { + return basic_negation(this); + }); + def_negate(AST_Arrow, function() { + return basic_negation(this); + }); + def_negate(AST_UnaryPrefix, function() { + if (this.operator == "!") + return this.expression; + return basic_negation(this); + }); + def_negate(AST_Sequence, function(compressor) { + var expressions = this.expressions.slice(); + expressions.push(expressions.pop().negate(compressor)); + return make_sequence(this, expressions); + }); + def_negate(AST_Conditional, function(compressor, first_in_statement) { + var self = this.clone(); + self.consequent = self.consequent.negate(compressor); + self.alternative = self.alternative.negate(compressor); + return best(this, self, first_in_statement); + }); + def_negate(AST_Binary, function(compressor, first_in_statement) { + var self = this.clone(), op = this.operator; + if (compressor.option("unsafe_comps")) { + switch (op) { + case "<=" : self.operator = ">" ; return self; + case "<" : self.operator = ">=" ; return self; + case ">=" : self.operator = "<" ; return self; + case ">" : self.operator = "<=" ; return self; + } + } + switch (op) { + case "==" : self.operator = "!="; return self; + case "!=" : self.operator = "=="; return self; + case "===": self.operator = "!=="; return self; + case "!==": self.operator = "==="; return self; + case "&&": + self.operator = "||"; + self.left = self.left.negate(compressor, first_in_statement); + self.right = self.right.negate(compressor); + return best(this, self, first_in_statement); + case "||": + self.operator = "&&"; + self.left = self.left.negate(compressor, first_in_statement); + self.right = self.right.negate(compressor); + return best(this, self, first_in_statement); + } + return basic_negation(this); + }); +})(function(node, func) { + node.DEFMETHOD("negate", function(compressor, first_in_statement) { + return func.call(this, compressor, first_in_statement); + }); +}); + +(function (def_bitwise_negate) { + function basic_bitwise_negation(exp) { + return make_node(AST_UnaryPrefix, exp, { + operator: "~", + expression: exp + }); + } + + def_bitwise_negate(AST_Node, function(_compressor) { + return basic_bitwise_negation(this); + }); + + def_bitwise_negate(AST_Number, function(_compressor) { + const neg = ~this.value; + if (neg.toString().length > this.value.toString().length) { + return basic_bitwise_negation(this); + } + return make_node(AST_Number, this, { value: neg }); + }); + + def_bitwise_negate(AST_UnaryPrefix, function(compressor, in_32_bit_context) { + if ( + this.operator == "~" + && ( + this.expression.is_32_bit_integer(compressor) || + (in_32_bit_context != null ? in_32_bit_context : compressor.in_32_bit_context()) + ) + ) { + return this.expression; + } else { + return basic_bitwise_negation(this); + } + }); +})(function (node, func) { + node.DEFMETHOD("bitwise_negate", func); +}); + +// Is the callee of this function pure? +var global_pure_fns = makePredicate("Boolean decodeURI decodeURIComponent Date encodeURI encodeURIComponent Error escape EvalError isFinite isNaN Number Object parseFloat parseInt RangeError ReferenceError String SyntaxError TypeError unescape URIError"); +AST_Call.DEFMETHOD("is_callee_pure", function(compressor) { + if (compressor.option("unsafe")) { + var expr = this.expression; + var first_arg = (this.args && this.args[0] && this.args[0].evaluate(compressor)); + if ( + expr.expression && expr.expression.name === "hasOwnProperty" && + (first_arg == null || first_arg.thedef && first_arg.thedef.undeclared) + ) { + return false; + } + if (is_undeclared_ref(expr) && global_pure_fns.has(expr.name)) return true; + if ( + expr instanceof AST_Dot + && is_undeclared_ref(expr.expression) + && is_pure_native_fn(expr.expression.name, expr.property) + ) { + return true; + } + } + if ((this instanceof AST_New) && compressor.option("pure_new")) { + return true; + } + if (compressor.option("side_effects") && has_annotation(this, _PURE)) { + return true; + } + return !compressor.pure_funcs(this); +}); + +// If I call this, is it a pure function? +AST_Node.DEFMETHOD("is_call_pure", return_false); +AST_Dot.DEFMETHOD("is_call_pure", function(compressor) { + if (!compressor.option("unsafe")) return; + const expr = this.expression; + + let native_obj; + if (expr instanceof AST_Array) { + native_obj = "Array"; + } else if (expr.is_boolean()) { + native_obj = "Boolean"; + } else if (expr.is_number(compressor)) { + native_obj = "Number"; + } else if (expr instanceof AST_RegExp) { + native_obj = "RegExp"; + } else if (expr.is_string(compressor)) { + native_obj = "String"; + } else if (!this.may_throw_on_access(compressor)) { + native_obj = "Object"; + } + return native_obj != null && is_pure_native_method(native_obj, this.property); +}); + +// tell me if a statement aborts +const aborts = (thing) => thing && thing.aborts(); + +(function(def_aborts) { + def_aborts(AST_Statement, return_null); + def_aborts(AST_Jump, return_this); + function block_aborts() { + for (var i = 0; i < this.body.length; i++) { + if (aborts(this.body[i])) { + return this.body[i]; + } + } + return null; + } + def_aborts(AST_Import, return_null); + def_aborts(AST_BlockStatement, block_aborts); + def_aborts(AST_SwitchBranch, block_aborts); + def_aborts(AST_DefClass, function () { + for (const prop of this.properties) { + if (prop instanceof AST_ClassStaticBlock) { + if (prop.aborts()) return prop; + } + } + return null; + }); + def_aborts(AST_ClassStaticBlock, block_aborts); + def_aborts(AST_If, function() { + return this.alternative && aborts(this.body) && aborts(this.alternative) && this; + }); +})(function(node, func) { + node.DEFMETHOD("aborts", func); +}); + +AST_Node.DEFMETHOD("contains_this", function() { + return walk(this, node => { + if (node instanceof AST_This) return walk_abort; + if ( + node !== this + && node instanceof AST_Scope + && !(node instanceof AST_Arrow) + ) { + return true; + } + }); +}); + +function is_modified(compressor, tw, node, value, level, immutable) { + var parent = tw.parent(level); + var lhs = is_lhs(node, parent); + if (lhs) return lhs; + if (!immutable + && parent instanceof AST_Call + && parent.expression === node + && !(value instanceof AST_Arrow) + && !(value instanceof AST_Class) + && !parent.is_callee_pure(compressor) + && (!(value instanceof AST_Function) + || !(parent instanceof AST_New) && value.contains_this())) { + return true; + } + if (parent instanceof AST_Array) { + return is_modified(compressor, tw, parent, parent, level + 1); + } + if (parent instanceof AST_ObjectKeyVal && node === parent.value) { + var obj = tw.parent(level + 1); + return is_modified(compressor, tw, obj, obj, level + 2); + } + if (parent instanceof AST_PropAccess && parent.expression === node) { + var prop = read_property(value, parent.property); + return !immutable && is_modified(compressor, tw, parent, prop, level + 1); + } +} + +/** + * Check if a node may be used by the expression it's in + * void (0, 1, {node}, 2) -> false + * console.log(0, {node}) -> true + */ +function is_used_in_expression(tw) { + for (let p = -1, node, parent; node = tw.parent(p), parent = tw.parent(p + 1); p++) { + if (parent instanceof AST_Sequence) { + const nth_expression = parent.expressions.indexOf(node); + if (nth_expression !== parent.expressions.length - 1) { + // Detect (0, x.noThis)() constructs + const grandparent = tw.parent(p + 2); + if ( + parent.expressions.length > 2 + || parent.expressions.length === 1 + || !requires_sequence_to_maintain_binding(grandparent, parent, parent.expressions[1]) + ) { + return false; + } + return true; + } else { + continue; + } + } + if (parent instanceof AST_Unary) { + const op = parent.operator; + if (op === "void") { + return false; + } + if (op === "typeof" || op === "+" || op === "-" || op === "!" || op === "~") { + continue; + } + } + if ( + parent instanceof AST_SimpleStatement + || parent instanceof AST_LabeledStatement + ) { + return false; + } + if (parent instanceof AST_Scope) { + return false; + } + return true; + } + + return true; +} + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +// methods to evaluate a constant expression + +function def_eval(node, func) { + node.DEFMETHOD("_eval", func); +} + +// Used to propagate a nullish short-circuit signal upwards through the chain. +const nullish = Symbol("This AST_Chain is nullish"); + +// If the node has been successfully reduced to a constant, +// then its value is returned; otherwise the element itself +// is returned. +// They can be distinguished as constant value is never a +// descendant of AST_Node. +AST_Node.DEFMETHOD("evaluate", function (compressor) { + if (!compressor.option("evaluate")) + return this; + var val = this._eval(compressor, 1); + if (!val || val instanceof RegExp) + return val; + if (typeof val == "function" || typeof val == "object" || val == nullish) + return this; + + // Evaluated strings can be larger than the original expression + if (typeof val === "string") { + const unevaluated_size = this.size(compressor); + if (val.length + 2 > unevaluated_size) return this; + } + + return val; +}); + +var unaryPrefix = makePredicate("! ~ - + void"); +AST_Node.DEFMETHOD("is_constant", function () { + // Accomodate when compress option evaluate=false + // as well as the common constant expressions !0 and -1 + if (this instanceof AST_Constant) { + return !(this instanceof AST_RegExp); + } else { + return this instanceof AST_UnaryPrefix + && unaryPrefix.has(this.operator) + && ( + // `this.expression` may be an `AST_RegExp`, + // so not only `.is_constant()`. + this.expression instanceof AST_Constant + || this.expression.is_constant() + ); + } +}); + +def_eval(AST_Statement, function () { + throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start)); +}); + +def_eval(AST_Lambda, return_this); +def_eval(AST_Class, return_this); +def_eval(AST_Node, return_this); +def_eval(AST_Constant, function () { + return this.getValue(); +}); + +const supports_bigint = typeof BigInt === "function"; +def_eval(AST_BigInt, function () { + if (supports_bigint) { + return BigInt(this.value); + } else { + return this; + } +}); + +def_eval(AST_RegExp, function (compressor) { + let evaluated = compressor.evaluated_regexps.get(this.value); + if (evaluated === undefined && regexp_is_safe(this.value.source)) { + try { + const { source, flags } = this.value; + evaluated = new RegExp(source, flags); + } catch (e) { + evaluated = null; + } + compressor.evaluated_regexps.set(this.value, evaluated); + } + return evaluated || this; +}); + +def_eval(AST_TemplateString, function () { + if (this.segments.length !== 1) return this; + return this.segments[0].value; +}); + +def_eval(AST_Function, function (compressor) { + if (compressor.option("unsafe")) { + var fn = function () { }; + fn.node = this; + fn.toString = () => this.print_to_string(); + return fn; + } + return this; +}); + +def_eval(AST_Array, function (compressor, depth) { + if (compressor.option("unsafe")) { + var elements = []; + for (var i = 0, len = this.elements.length; i < len; i++) { + var element = this.elements[i]; + var value = element._eval(compressor, depth); + if (element === value) + return this; + elements.push(value); + } + return elements; + } + return this; +}); + +def_eval(AST_Object, function (compressor, depth) { + if (compressor.option("unsafe")) { + var val = {}; + for (var i = 0, len = this.properties.length; i < len; i++) { + var prop = this.properties[i]; + if (prop instanceof AST_Expansion) + return this; + var key = prop.key; + if (key instanceof AST_Symbol) { + key = key.name; + } else if (key instanceof AST_Node) { + key = key._eval(compressor, depth); + if (key === prop.key) + return this; + } + if (typeof Object.prototype[key] === "function") { + return this; + } + if (prop.value instanceof AST_Function) + continue; + val[key] = prop.value._eval(compressor, depth); + if (val[key] === prop.value) + return this; + } + return val; + } + return this; +}); + +var non_converting_unary = makePredicate("! typeof void"); +def_eval(AST_UnaryPrefix, function (compressor, depth) { + var e = this.expression; + if (compressor.option("typeofs") + && this.operator == "typeof") { + // Function would be evaluated to an array and so typeof would + // incorrectly return 'object'. Hence making is a special case. + if (e instanceof AST_Lambda + || e instanceof AST_SymbolRef + && e.fixed_value() instanceof AST_Lambda) { + return typeof function () { }; + } + if ( + (e instanceof AST_Object + || e instanceof AST_Array + || (e instanceof AST_SymbolRef + && (e.fixed_value() instanceof AST_Object + || e.fixed_value() instanceof AST_Array))) + && !e.has_side_effects(compressor) + ) { + return typeof {}; + } + } + if (!non_converting_unary.has(this.operator)) + depth++; + e = e._eval(compressor, depth); + if (e === this.expression) + return this; + switch (this.operator) { + case "!": return !e; + case "typeof": + // typeof returns "object" or "function" on different platforms + // so cannot evaluate reliably + if (e instanceof RegExp) + return this; + return typeof e; + case "void": return void e; + case "~": return ~e; + case "-": return -e; + case "+": return +e; + } + return this; +}); + +var non_converting_binary = makePredicate("&& || ?? === !=="); +const identity_comparison = makePredicate("== != === !=="); +const has_identity = value => typeof value === "object" + || typeof value === "function" + || typeof value === "symbol"; + +def_eval(AST_Binary, function (compressor, depth) { + if (!non_converting_binary.has(this.operator)) + depth++; + + var left = this.left._eval(compressor, depth); + if (left === this.left) + return this; + var right = this.right._eval(compressor, depth); + if (right === this.right) + return this; + + if (left != null + && right != null + && identity_comparison.has(this.operator) + && has_identity(left) + && has_identity(right) + && typeof left === typeof right) { + // Do not compare by reference + return this; + } + + // Do not mix BigInt and Number; Don't use `>>>` on BigInt or `/ 0n` + if ( + (typeof left === "bigint") !== (typeof right === "bigint") + || typeof left === "bigint" + && (this.operator === ">>>" + || this.operator === "/" && Number(right) === 0) + ) { + return this; + } + + var result; + switch (this.operator) { + case "&&": result = left && right; break; + case "||": result = left || right; break; + case "??": result = left != null ? left : right; break; + case "|": result = left | right; break; + case "&": result = left & right; break; + case "^": result = left ^ right; break; + case "+": result = left + right; break; + case "*": result = left * right; break; + case "**": result = left ** right; break; + case "/": result = left / right; break; + case "%": result = left % right; break; + case "-": result = left - right; break; + case "<<": result = left << right; break; + case ">>": result = left >> right; break; + case ">>>": result = left >>> right; break; + case "==": result = left == right; break; + case "===": result = left === right; break; + case "!=": result = left != right; break; + case "!==": result = left !== right; break; + case "<": result = left < right; break; + case "<=": result = left <= right; break; + case ">": result = left > right; break; + case ">=": result = left >= right; break; + default: + return this; + } + if (typeof result === "number" && isNaN(result) && compressor.find_parent(AST_With)) { + // leave original expression as is + return this; + } + return result; +}); + +def_eval(AST_Conditional, function (compressor, depth) { + var condition = this.condition._eval(compressor, depth); + if (condition === this.condition) + return this; + var node = condition ? this.consequent : this.alternative; + var value = node._eval(compressor, depth); + return value === node ? this : value; +}); + +// Set of AST_SymbolRef which are currently being evaluated. +// Avoids infinite recursion of ._eval() +const reentrant_ref_eval = new Set(); +def_eval(AST_SymbolRef, function (compressor, depth) { + if (reentrant_ref_eval.has(this)) + return this; + + var fixed = this.fixed_value(); + if (!fixed) + return this; + + reentrant_ref_eval.add(this); + const value = fixed._eval(compressor, depth); + reentrant_ref_eval.delete(this); + + if (value === fixed) + return this; + + if (value && typeof value == "object") { + var escaped = this.definition().escaped; + if (escaped && depth > escaped) + return this; + } + return value; +}); + +const global_objs = { Array, Math, Number, Object, String }; + +const regexp_flags = new Set([ + "dotAll", + "global", + "ignoreCase", + "multiline", + "sticky", + "unicode", +]); + +def_eval(AST_PropAccess, function (compressor, depth) { + let obj = this.expression._eval(compressor, depth + 1); + if (obj === nullish || (this.optional && obj == null)) return nullish; + + // `.length` of strings and arrays is always safe + if (this.property === "length") { + if (typeof obj === "string") { + return obj.length; + } + + const is_spreadless_array = + obj instanceof AST_Array + && obj.elements.every(el => !(el instanceof AST_Expansion)); + + if ( + is_spreadless_array + && obj.elements.every(el => !el.has_side_effects(compressor)) + ) { + return obj.elements.length; + } + } + + if (compressor.option("unsafe")) { + var key = this.property; + if (key instanceof AST_Node) { + key = key._eval(compressor, depth); + if (key === this.property) + return this; + } + + var exp = this.expression; + if (is_undeclared_ref(exp)) { + var aa; + var first_arg = exp.name === "hasOwnProperty" + && key === "call" + && (aa = compressor.parent() && compressor.parent().args) + && (aa && aa[0] + && aa[0].evaluate(compressor)); + + first_arg = first_arg instanceof AST_Dot ? first_arg.expression : first_arg; + + if (first_arg == null || first_arg.thedef && first_arg.thedef.undeclared) { + return this.clone(); + } + if (!is_pure_native_value(exp.name, key)) + return this; + obj = global_objs[exp.name]; + } else { + if (obj instanceof RegExp) { + if (key == "source") { + return regexp_source_fix(obj.source); + } else if (key == "flags" || regexp_flags.has(key)) { + return obj[key]; + } + } + if (!obj || obj === exp || !HOP(obj, key)) + return this; + + if (typeof obj == "function") + switch (key) { + case "name": + return obj.node.name ? obj.node.name.name : ""; + case "length": + return obj.node.length_property(); + default: + return this; + } + } + return obj[key]; + } + return this; +}); + +def_eval(AST_Chain, function (compressor, depth) { + const evaluated = this.expression._eval(compressor, depth); + return evaluated === nullish + ? undefined + : evaluated === this.expression + ? this + : evaluated; +}); + +def_eval(AST_Call, function (compressor, depth) { + var exp = this.expression; + + const callee = exp._eval(compressor, depth); + if (callee === nullish || (this.optional && callee == null)) return nullish; + + if (compressor.option("unsafe") && exp instanceof AST_PropAccess) { + var key = exp.property; + if (key instanceof AST_Node) { + key = key._eval(compressor, depth); + if (key === exp.property) + return this; + } + var val; + var e = exp.expression; + if (is_undeclared_ref(e)) { + var first_arg = e.name === "hasOwnProperty" && + key === "call" && + (this.args[0] && this.args[0].evaluate(compressor)); + + first_arg = first_arg instanceof AST_Dot ? first_arg.expression : first_arg; + + if ((first_arg == null || first_arg.thedef && first_arg.thedef.undeclared)) { + return this.clone(); + } + if (!is_pure_native_fn(e.name, key)) return this; + val = global_objs[e.name]; + } else { + val = e._eval(compressor, depth + 1); + if (val === e || !val) + return this; + if (!is_pure_native_method(val.constructor.name, key)) + return this; + } + var args = []; + for (var i = 0, len = this.args.length; i < len; i++) { + var arg = this.args[i]; + var value = arg._eval(compressor, depth); + if (arg === value) + return this; + if (arg instanceof AST_Lambda) + return this; + args.push(value); + } + try { + return val[key].apply(val, args); + } catch (ex) { + // We don't really care + } + } + return this; +}); + +// Also a subclass of AST_Call +def_eval(AST_New, return_this); + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +// AST_Node#drop_side_effect_free() gets called when we don't care about the value, +// only about side effects. We'll be defining this method for each node type in this module +// +// Examples: +// foo++ -> foo++ +// 1 + func() -> func() +// 10 -> (nothing) +// knownPureFunc(foo++) -> foo++ + +function def_drop_side_effect_free(node_or_nodes, func) { + for (const node of [].concat(node_or_nodes)) { + node.DEFMETHOD("drop_side_effect_free", func); + } +} + +// Drop side-effect-free elements from an array of expressions. +// Returns an array of expressions with side-effects or null +// if all elements were dropped. Note: original array may be +// returned if nothing changed. +function trim(nodes, compressor, first_in_statement) { + var len = nodes.length; + if (!len) return null; + + var ret = [], changed = false; + for (var i = 0; i < len; i++) { + var node = nodes[i].drop_side_effect_free(compressor, first_in_statement); + changed |= node !== nodes[i]; + if (node) { + ret.push(node); + first_in_statement = false; + } + } + return changed ? ret.length ? ret : null : nodes; +} + +def_drop_side_effect_free(AST_Node, return_this); +def_drop_side_effect_free(AST_Constant, return_null); +def_drop_side_effect_free(AST_This, return_null); + +def_drop_side_effect_free(AST_Call, function (compressor, first_in_statement) { + if (is_nullish_shortcircuited(this, compressor)) { + return this.expression.drop_side_effect_free(compressor, first_in_statement); + } + + if (!this.is_callee_pure(compressor)) { + if (this.expression.is_call_pure(compressor)) { + var exprs = this.args.slice(); + exprs.unshift(this.expression.expression); + exprs = trim(exprs, compressor, first_in_statement); + return exprs && make_sequence(this, exprs); + } + if (is_func_expr(this.expression) + && (!this.expression.name || !this.expression.name.definition().references.length)) { + var node = this.clone(); + node.expression.process_expression(false, compressor); + return node; + } + return this; + } + + var args = trim(this.args, compressor, first_in_statement); + return args && make_sequence(this, args); +}); + +def_drop_side_effect_free(AST_Accessor, return_null); + +def_drop_side_effect_free(AST_Function, return_null); + +def_drop_side_effect_free(AST_Arrow, return_null); + +def_drop_side_effect_free(AST_Class, function (compressor) { + const with_effects = []; + + if (this.is_self_referential() && this.has_side_effects(compressor)) { + return this; + } + + const trimmed_extends = this.extends && this.extends.drop_side_effect_free(compressor); + if (trimmed_extends) with_effects.push(trimmed_extends); + + for (const prop of this.properties) { + if (prop instanceof AST_ClassStaticBlock) { + if (prop.has_side_effects(compressor)) { + return this; // Be cautious about these + } + } else { + const trimmed_prop = prop.drop_side_effect_free(compressor); + if (trimmed_prop) with_effects.push(trimmed_prop); + } + } + + if (!with_effects.length) + return null; + + const exprs = make_sequence(this, with_effects); + if (this instanceof AST_DefClass) { + // We want a statement + return make_node(AST_SimpleStatement, this, { body: exprs }); + } else { + return exprs; + } +}); + +def_drop_side_effect_free([ + AST_ClassProperty, + AST_ClassPrivateProperty, +], function (compressor) { + const key = this.computed_key() && this.key.drop_side_effect_free(compressor); + + const value = this.static && this.value + && this.value.drop_side_effect_free(compressor); + + if (key && value) + return make_sequence(this, [key, value]); + return key || value || null; +}); + +def_drop_side_effect_free(AST_Binary, function (compressor, first_in_statement) { + var right = this.right.drop_side_effect_free(compressor); + if (!right) + return this.left.drop_side_effect_free(compressor, first_in_statement); + if (lazy_op.has(this.operator)) { + if (right === this.right) + return this; + var node = this.clone(); + node.right = right; + return node; + } else { + var left = this.left.drop_side_effect_free(compressor, first_in_statement); + if (!left) + return this.right.drop_side_effect_free(compressor, first_in_statement); + return make_sequence(this, [left, right]); + } +}); + +def_drop_side_effect_free(AST_Assign, function (compressor) { + if (this.logical) + return this; + + var left = this.left; + if (left.has_side_effects(compressor) + || compressor.has_directive("use strict") + && left instanceof AST_PropAccess + && left.expression.is_constant()) { + return this; + } + set_flag(this, WRITE_ONLY); + while (left instanceof AST_PropAccess) { + left = left.expression; + } + if (left.is_constant_expression(compressor.find_parent(AST_Scope))) { + return this.right.drop_side_effect_free(compressor); + } + return this; +}); + +def_drop_side_effect_free(AST_Conditional, function (compressor) { + var consequent = this.consequent.drop_side_effect_free(compressor); + var alternative = this.alternative.drop_side_effect_free(compressor); + if (consequent === this.consequent && alternative === this.alternative) + return this; + if (!consequent) + return alternative ? make_node(AST_Binary, this, { + operator: "||", + left: this.condition, + right: alternative + }) : this.condition.drop_side_effect_free(compressor); + if (!alternative) + return make_node(AST_Binary, this, { + operator: "&&", + left: this.condition, + right: consequent + }); + var node = this.clone(); + node.consequent = consequent; + node.alternative = alternative; + return node; +}); + +def_drop_side_effect_free(AST_Unary, function (compressor, first_in_statement) { + if (unary_side_effects.has(this.operator)) { + if (!this.expression.has_side_effects(compressor)) { + set_flag(this, WRITE_ONLY); + } else { + clear_flag(this, WRITE_ONLY); + } + return this; + } + if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef) + return null; + var expression = this.expression.drop_side_effect_free(compressor, first_in_statement); + if (first_in_statement && expression && is_iife_call(expression)) { + if (expression === this.expression && this.operator == "!") + return this; + return expression.negate(compressor, first_in_statement); + } + return expression; +}); + +def_drop_side_effect_free(AST_SymbolRef, function (compressor) { + const safe_access = this.is_declared(compressor) + || pure_prop_access_globals.has(this.name); + return safe_access ? null : this; +}); + +def_drop_side_effect_free(AST_Object, function (compressor, first_in_statement) { + var values = trim(this.properties, compressor, first_in_statement); + return values && make_sequence(this, values); +}); + +def_drop_side_effect_free(AST_ObjectKeyVal, function (compressor, first_in_statement) { + const computed_key = this.key instanceof AST_Node; + const key = computed_key && this.key.drop_side_effect_free(compressor, first_in_statement); + const value = this.value.drop_side_effect_free(compressor, first_in_statement); + if (key && value) { + return make_sequence(this, [key, value]); + } + return key || value; +}); + +def_drop_side_effect_free([ + AST_ConciseMethod, + AST_ObjectGetter, + AST_ObjectSetter, +], function () { + return this.computed_key() ? this.key : null; +}); + +def_drop_side_effect_free([ + AST_PrivateMethod, + AST_PrivateGetter, + AST_PrivateSetter, +], function () { + return null; +}); + +def_drop_side_effect_free(AST_Array, function (compressor, first_in_statement) { + var values = trim(this.elements, compressor, first_in_statement); + return values && make_sequence(this, values); +}); + +def_drop_side_effect_free(AST_Dot, function (compressor, first_in_statement) { + if (is_nullish_shortcircuited(this, compressor)) { + return this.expression.drop_side_effect_free(compressor, first_in_statement); + } + if (!this.optional && this.expression.may_throw_on_access(compressor)) { + return this; + } + + return this.expression.drop_side_effect_free(compressor, first_in_statement); +}); + +def_drop_side_effect_free(AST_Sub, function (compressor, first_in_statement) { + if (is_nullish_shortcircuited(this, compressor)) { + return this.expression.drop_side_effect_free(compressor, first_in_statement); + } + if (!this.optional && this.expression.may_throw_on_access(compressor)) { + return this; + } + + var property = this.property.drop_side_effect_free(compressor); + if (property && this.optional) return this; + + var expression = this.expression.drop_side_effect_free(compressor, first_in_statement); + + if (expression && property) return make_sequence(this, [expression, property]); + return expression || property; +}); + +def_drop_side_effect_free(AST_Chain, function (compressor, first_in_statement) { + return this.expression.drop_side_effect_free(compressor, first_in_statement); +}); + +def_drop_side_effect_free(AST_Sequence, function (compressor) { + var last = this.tail_node(); + var expr = last.drop_side_effect_free(compressor); + if (expr === last) + return this; + var expressions = this.expressions.slice(0, -1); + if (expr) + expressions.push(expr); + if (!expressions.length) { + return make_node(AST_Number, this, { value: 0 }); + } + return make_sequence(this, expressions); +}); + +def_drop_side_effect_free(AST_Expansion, function (compressor, first_in_statement) { + return this.expression.drop_side_effect_free(compressor, first_in_statement); +}); + +def_drop_side_effect_free(AST_TemplateSegment, return_null); + +def_drop_side_effect_free(AST_TemplateString, function (compressor) { + var values = trim(this.segments, compressor, first_in_statement); + return values && make_sequence(this, values); +}); + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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 r_keep_assign = /keep_assign/; + +/** Drop unused variables from this scope */ +AST_Scope.DEFMETHOD("drop_unused", function(compressor) { + if (!compressor.option("unused")) return; + if (compressor.has_directive("use asm")) return; + if (!this.variables) return; // not really a scope (eg: AST_Class) + + var self = this; + if (self.pinned()) return; + var drop_funcs = !(self instanceof AST_Toplevel) || compressor.toplevel.funcs; + var drop_vars = !(self instanceof AST_Toplevel) || compressor.toplevel.vars; + const assign_as_unused = r_keep_assign.test(compressor.option("unused")) ? return_false : function(node) { + if (node instanceof AST_Assign + && !node.logical + && (has_flag(node, WRITE_ONLY) || node.operator == "=") + ) { + return node.left; + } + if (node instanceof AST_Unary && has_flag(node, WRITE_ONLY)) { + return node.expression; + } + }; + var in_use_ids = new Map(); + var fixed_ids = new Map(); + if (self instanceof AST_Toplevel && compressor.top_retain) { + self.variables.forEach(function(def) { + if (compressor.top_retain(def)) { + in_use_ids.set(def.id, def); + } + }); + } + var var_defs_by_id = new Map(); + var initializations = new Map(); + + // pass 1: find out which symbols are directly used in + // this scope (not in nested scopes). + var scope = this; + var tw = new TreeWalker(function(node, descend) { + if (node instanceof AST_Lambda && node.uses_arguments && !tw.has_directive("use strict")) { + node.argnames.forEach(function(argname) { + if (!(argname instanceof AST_SymbolDeclaration)) return; + var def = argname.definition(); + in_use_ids.set(def.id, def); + }); + } + if (node === self) return; + if (node instanceof AST_Class && node.has_side_effects(compressor)) { + if (node.is_self_referential()) { + descend(); + } else { + node.visit_nondeferred_class_parts(tw); + } + } + if (node instanceof AST_Defun || node instanceof AST_DefClass) { + var node_def = node.name.definition(); + const in_export = tw.parent() instanceof AST_Export; + if (in_export || !drop_funcs && scope === self) { + if (node_def.global) { + in_use_ids.set(node_def.id, node_def); + } + } + + map_add(initializations, node_def.id, node); + return true; // don't go in nested scopes + } + // In the root scope, we drop things. In inner scopes, we just check for uses. + const in_root_scope = scope === self; + if (node instanceof AST_SymbolFunarg && in_root_scope) { + map_add(var_defs_by_id, node.definition().id, node); + } + if (node instanceof AST_Definitions && in_root_scope) { + const in_export = tw.parent() instanceof AST_Export; + node.definitions.forEach(function(def) { + if (def.name instanceof AST_SymbolVar) { + map_add(var_defs_by_id, def.name.definition().id, def); + } + if (in_export || !drop_vars) { + walk(def.name, node => { + if (node instanceof AST_SymbolDeclaration) { + const def = node.definition(); + if (def.global) { + in_use_ids.set(def.id, def); + } + } + }); + } + if (def.name instanceof AST_Destructuring) { + def.walk(tw); + } + if (def.name instanceof AST_SymbolDeclaration && def.value) { + var node_def = def.name.definition(); + map_add(initializations, node_def.id, def.value); + if (!node_def.chained && def.name.fixed_value() === def.value) { + fixed_ids.set(node_def.id, def); + } + if (def.value.has_side_effects(compressor)) { + def.value.walk(tw); + } + } + }); + return true; + } + return scan_ref_scoped(node, descend); + }); + self.walk(tw); + // pass 2: for every used symbol we need to walk its + // initialization code to figure out if it uses other + // symbols (that may not be in_use). + tw = new TreeWalker(scan_ref_scoped); + in_use_ids.forEach(function (def) { + var init = initializations.get(def.id); + if (init) init.forEach(function(init) { + init.walk(tw); + }); + }); + // pass 3: we should drop declarations not in_use + var tt = new TreeTransformer( + function before(node, descend, in_list) { + var parent = tt.parent(); + if (drop_vars) { + const sym = assign_as_unused(node); + if (sym instanceof AST_SymbolRef) { + var def = sym.definition(); + var in_use = in_use_ids.has(def.id); + if (node instanceof AST_Assign) { + if (!in_use || fixed_ids.has(def.id) && fixed_ids.get(def.id) !== node) { + const assignee = node.right.transform(tt); + if (!in_use && !assignee.has_side_effects(compressor) && !is_used_in_expression(tt)) { + return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 }); + } + return maintain_this_binding(parent, node, assignee); + } + } else if (!in_use) { + return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 }); + } + } + } + if (scope !== self) return; + var def; + if (node.name + && (node instanceof AST_ClassExpression + && !keep_name(compressor.option("keep_classnames"), (def = node.name.definition()).name) + || node instanceof AST_Function + && !keep_name(compressor.option("keep_fnames"), (def = node.name.definition()).name))) { + // any declarations with same name will overshadow + // name of this anonymous function and can therefore + // never be used anywhere + if (!in_use_ids.has(def.id) || def.orig.length > 1) node.name = null; + } + if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) { + var trim = + !compressor.option("keep_fargs") + // Is this an IIFE that won't refer to its name? + || parent instanceof AST_Call + && parent.expression === node + && !node.pinned() + && (!node.name || node.name.unreferenced()); + for (var a = node.argnames, i = a.length; --i >= 0;) { + var sym = a[i]; + if (sym instanceof AST_Expansion) { + sym = sym.expression; + } + if (sym instanceof AST_DefaultAssign) { + sym = sym.left; + } + // Do not drop destructuring arguments. + // They constitute a type assertion of sorts + if ( + !(sym instanceof AST_Destructuring) + && !in_use_ids.has(sym.definition().id) + ) { + set_flag(sym, UNUSED); + if (trim) { + a.pop(); + } + } else { + trim = false; + } + } + } + if (node instanceof AST_DefClass && node !== self) { + const def = node.name.definition(); + descend(node, this); + const keep_class = def.global && !drop_funcs || in_use_ids.has(def.id); + if (!keep_class) { + const kept = node.drop_side_effect_free(compressor); + if (kept == null) { + def.eliminated++; + return in_list ? MAP.skip : make_node(AST_EmptyStatement, node); + } + return kept; + } + return node; + } + if (node instanceof AST_Defun && node !== self) { + const def = node.name.definition(); + const keep = def.global && !drop_funcs || in_use_ids.has(def.id); + if (!keep) { + def.eliminated++; + return in_list ? MAP.skip : make_node(AST_EmptyStatement, node); + } + } + if (node instanceof AST_Definitions && !(parent instanceof AST_ForIn && parent.init === node)) { + var drop_block = !(parent instanceof AST_Toplevel) && !(node instanceof AST_Var); + // place uninitialized names at the start + var body = [], head = [], tail = []; + // for unused names whose initialization has + // side effects, we can cascade the init. code + // into the next one, or next statement. + var side_effects = []; + node.definitions.forEach(function(def) { + if (def.value) def.value = def.value.transform(tt); + var is_destructure = def.name instanceof AST_Destructuring; + var sym = is_destructure + ? new SymbolDef(null, { name: "" }) /* fake SymbolDef */ + : def.name.definition(); + if (drop_block && sym.global) return tail.push(def); + if (!(drop_vars || drop_block) + || is_destructure + && (def.name.names.length + || def.name.is_array + || compressor.option("pure_getters") != true) + || in_use_ids.has(sym.id) + ) { + if (def.value && fixed_ids.has(sym.id) && fixed_ids.get(sym.id) !== def) { + def.value = def.value.drop_side_effect_free(compressor); + } + if (def.name instanceof AST_SymbolVar) { + var var_defs = var_defs_by_id.get(sym.id); + if (var_defs.length > 1 && (!def.value || sym.orig.indexOf(def.name) > sym.eliminated)) { + if (def.value) { + var ref = make_node(AST_SymbolRef, def.name, def.name); + sym.references.push(ref); + var assign = make_node(AST_Assign, def, { + operator: "=", + logical: false, + left: ref, + right: def.value + }); + if (fixed_ids.get(sym.id) === def) { + fixed_ids.set(sym.id, assign); + } + side_effects.push(assign.transform(tt)); + } + remove(var_defs, def); + sym.eliminated++; + return; + } + } + if (def.value) { + if (side_effects.length > 0) { + if (tail.length > 0) { + side_effects.push(def.value); + def.value = make_sequence(def.value, side_effects); + } else { + body.push(make_node(AST_SimpleStatement, node, { + body: make_sequence(node, side_effects) + })); + } + side_effects = []; + } + tail.push(def); + } else { + head.push(def); + } + } else if (sym.orig[0] instanceof AST_SymbolCatch) { + var value = def.value && def.value.drop_side_effect_free(compressor); + if (value) side_effects.push(value); + def.value = null; + head.push(def); + } else { + var value = def.value && def.value.drop_side_effect_free(compressor); + if (value) { + side_effects.push(value); + } + sym.eliminated++; + } + }); + if (head.length > 0 || tail.length > 0) { + node.definitions = head.concat(tail); + body.push(node); + } + if (side_effects.length > 0) { + body.push(make_node(AST_SimpleStatement, node, { + body: make_sequence(node, side_effects) + })); + } + switch (body.length) { + case 0: + return in_list ? MAP.skip : make_node(AST_EmptyStatement, node); + case 1: + return body[0]; + default: + return in_list ? MAP.splice(body) : make_node(AST_BlockStatement, node, { body }); + } + } + // certain combination of unused name + side effect leads to: + // https://github.com/mishoo/UglifyJS2/issues/44 + // https://github.com/mishoo/UglifyJS2/issues/1830 + // https://github.com/mishoo/UglifyJS2/issues/1838 + // that's an invalid AST. + // We fix it at this stage by moving the `var` outside the `for`. + if (node instanceof AST_For) { + descend(node, this); + var block; + if (node.init instanceof AST_BlockStatement) { + block = node.init; + node.init = block.body.pop(); + block.body.push(node); + } + if (node.init instanceof AST_SimpleStatement) { + node.init = node.init.body; + } else if (is_empty(node.init)) { + node.init = null; + } + return !block ? node : in_list ? MAP.splice(block.body) : block; + } + if (node instanceof AST_LabeledStatement + && node.body instanceof AST_For + ) { + descend(node, this); + if (node.body instanceof AST_BlockStatement) { + var block = node.body; + node.body = block.body.pop(); + block.body.push(node); + return in_list ? MAP.splice(block.body) : block; + } + return node; + } + if (node instanceof AST_BlockStatement) { + descend(node, this); + if (in_list && node.body.every(can_be_evicted_from_block)) { + return MAP.splice(node.body); + } + return node; + } + if (node instanceof AST_Scope && !(node instanceof AST_ClassStaticBlock)) { + const save_scope = scope; + scope = node; + descend(node, this); + scope = save_scope; + return node; + } + }, + function after(node, in_list) { + if (node instanceof AST_Sequence) { + switch (node.expressions.length) { + case 0: return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 }); + case 1: return node.expressions[0]; + } + } + } + ); + + self.transform(tt); + + function scan_ref_scoped(node, descend) { + var node_def; + const sym = assign_as_unused(node); + if (sym instanceof AST_SymbolRef + && !is_ref_of(node.left, AST_SymbolBlockDeclaration) + && self.variables.get(sym.name) === (node_def = sym.definition()) + ) { + if (node instanceof AST_Assign) { + node.right.walk(tw); + if (!node_def.chained && node.left.fixed_value() === node.right) { + fixed_ids.set(node_def.id, node); + } + } + return true; + } + if (node instanceof AST_SymbolRef) { + node_def = node.definition(); + if (!in_use_ids.has(node_def.id)) { + in_use_ids.set(node_def.id, node_def); + if (node_def.orig[0] instanceof AST_SymbolCatch) { + const redef = node_def.scope.is_block_scope() + && node_def.scope.get_defun_scope().variables.get(node_def.name); + if (redef) in_use_ids.set(redef.id, redef); + } + } + return true; + } + if (node instanceof AST_Class) { + descend(); + return true; + } + if (node instanceof AST_Scope && !(node instanceof AST_ClassStaticBlock)) { + var save_scope = scope; + scope = node; + descend(); + scope = save_scope; + return true; + } + } +}); + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +/** + * Define the method AST_Node#reduce_vars, which goes through the AST in + * execution order to perform basic flow analysis + */ +function def_reduce_vars(node, func) { + node.DEFMETHOD("reduce_vars", func); +} + +def_reduce_vars(AST_Node, noop); + +/** Clear definition properties */ +function reset_def(compressor, def) { + def.assignments = 0; + def.chained = false; + def.direct_access = false; + def.escaped = 0; + def.recursive_refs = 0; + def.references = []; + def.single_use = undefined; + if ( + def.scope.pinned() + || (def.orig[0] instanceof AST_SymbolFunarg && def.scope.uses_arguments) + ) { + def.fixed = false; + } else if (def.orig[0] instanceof AST_SymbolConst || !compressor.exposed(def)) { + def.fixed = def.init; + } else { + def.fixed = false; + } +} + +function reset_variables(tw, compressor, node) { + node.variables.forEach(function(def) { + reset_def(compressor, def); + if (def.fixed === null) { + tw.defs_to_safe_ids.set(def.id, tw.safe_ids); + mark(tw, def, true); + } else if (def.fixed) { + tw.loop_ids.set(def.id, tw.in_loop); + mark(tw, def, true); + } + }); +} + +function reset_block_variables(compressor, node) { + if (node.block_scope) node.block_scope.variables.forEach((def) => { + reset_def(compressor, def); + }); +} + +function push(tw) { + tw.safe_ids = Object.create(tw.safe_ids); +} + +function pop(tw) { + tw.safe_ids = Object.getPrototypeOf(tw.safe_ids); +} + +function mark(tw, def, safe) { + tw.safe_ids[def.id] = safe; +} + +function safe_to_read(tw, def) { + if (def.single_use == "m") return false; + if (tw.safe_ids[def.id]) { + if (def.fixed == null) { + var orig = def.orig[0]; + if (orig instanceof AST_SymbolFunarg || orig.name == "arguments") return false; + def.fixed = make_node(AST_Undefined, orig); + } + return true; + } + return def.fixed instanceof AST_Defun; +} + +function safe_to_assign(tw, def, scope, value) { + if (def.fixed === undefined) return true; + let def_safe_ids; + if (def.fixed === null + && (def_safe_ids = tw.defs_to_safe_ids.get(def.id)) + ) { + def_safe_ids[def.id] = false; + tw.defs_to_safe_ids.delete(def.id); + return true; + } + if (!HOP(tw.safe_ids, def.id)) return false; + if (!safe_to_read(tw, def)) return false; + if (def.fixed === false) return false; + if (def.fixed != null && (!value || def.references.length > def.assignments)) return false; + if (def.fixed instanceof AST_Defun) { + return value instanceof AST_Node && def.fixed.parent_scope === scope; + } + return def.orig.every((sym) => { + return !(sym instanceof AST_SymbolConst + || sym instanceof AST_SymbolDefun + || sym instanceof AST_SymbolLambda); + }); +} + +function ref_once(tw, compressor, def) { + return compressor.option("unused") + && !def.scope.pinned() + && def.references.length - def.recursive_refs == 1 + && tw.loop_ids.get(def.id) === tw.in_loop; +} + +function is_immutable(value) { + if (!value) return false; + return value.is_constant() + || value instanceof AST_Lambda + || value instanceof AST_This; +} + +// A definition "escapes" when its value can leave the point of use. +// Example: `a = b || c` +// In this example, "b" and "c" are escaping, because they're going into "a" +// +// def.escaped is != 0 when it escapes. +// +// When greater than 1, it means that N chained properties will be read off +// of that def before an escape occurs. This is useful for evaluating +// property accesses, where you need to know when to stop. +function mark_escaped(tw, d, scope, node, value, level = 0, depth = 1) { + var parent = tw.parent(level); + if (value) { + if (value.is_constant()) return; + if (value instanceof AST_ClassExpression) return; + } + + if ( + parent instanceof AST_Assign && (parent.operator === "=" || parent.logical) && node === parent.right + || parent instanceof AST_Call && (node !== parent.expression || parent instanceof AST_New) + || parent instanceof AST_Exit && node === parent.value && node.scope !== d.scope + || parent instanceof AST_VarDefLike && node === parent.value + || parent instanceof AST_Yield && node === parent.value && node.scope !== d.scope + ) { + if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1; + if (!d.escaped || d.escaped > depth) d.escaped = depth; + return; + } else if ( + parent instanceof AST_Array + || parent instanceof AST_Await + || parent instanceof AST_Binary && lazy_op.has(parent.operator) + || parent instanceof AST_Conditional && node !== parent.condition + || parent instanceof AST_Expansion + || parent instanceof AST_Sequence && node === parent.tail_node() + ) { + mark_escaped(tw, d, scope, parent, parent, level + 1, depth); + } else if (parent instanceof AST_ObjectKeyVal && node === parent.value) { + var obj = tw.parent(level + 1); + + mark_escaped(tw, d, scope, obj, obj, level + 2, depth); + } else if (parent instanceof AST_PropAccess && node === parent.expression) { + value = read_property(value, parent.property); + + mark_escaped(tw, d, scope, parent, value, level + 1, depth + 1); + if (value) return; + } + + if (level > 0) return; + if (parent instanceof AST_Sequence && node !== parent.tail_node()) return; + if (parent instanceof AST_SimpleStatement) return; + + d.direct_access = true; +} + +const suppress = node => walk(node, node => { + if (!(node instanceof AST_Symbol)) return; + var d = node.definition(); + if (!d) return; + if (node instanceof AST_SymbolRef) d.references.push(node); + d.fixed = false; +}); + +def_reduce_vars(AST_Accessor, function(tw, descend, compressor) { + push(tw); + reset_variables(tw, compressor, this); + descend(); + pop(tw); + return true; +}); + +def_reduce_vars(AST_Assign, function(tw, descend, compressor) { + var node = this; + if (node.left instanceof AST_Destructuring) { + suppress(node.left); + return; + } + + const finish_walk = () => { + if (node.logical) { + node.left.walk(tw); + + push(tw); + node.right.walk(tw); + pop(tw); + + return true; + } + }; + + var sym = node.left; + if (!(sym instanceof AST_SymbolRef)) return finish_walk(); + + var def = sym.definition(); + var safe = safe_to_assign(tw, def, sym.scope, node.right); + def.assignments++; + if (!safe) return finish_walk(); + + var fixed = def.fixed; + if (!fixed && node.operator != "=" && !node.logical) return finish_walk(); + + var eq = node.operator == "="; + var value = eq ? node.right : node; + if (is_modified(compressor, tw, node, value, 0)) return finish_walk(); + + def.references.push(sym); + + if (!node.logical) { + if (!eq) def.chained = true; + + def.fixed = eq ? function() { + return node.right; + } : function() { + return make_node(AST_Binary, node, { + operator: node.operator.slice(0, -1), + left: fixed instanceof AST_Node ? fixed : fixed(), + right: node.right + }); + }; + } + + if (node.logical) { + mark(tw, def, false); + push(tw); + node.right.walk(tw); + pop(tw); + return true; + } + + mark(tw, def, false); + node.right.walk(tw); + mark(tw, def, true); + + mark_escaped(tw, def, sym.scope, node, value, 0, 1); + + return true; +}); + +def_reduce_vars(AST_Binary, function(tw) { + if (!lazy_op.has(this.operator)) return; + this.left.walk(tw); + push(tw); + this.right.walk(tw); + pop(tw); + return true; +}); + +def_reduce_vars(AST_Block, function(tw, descend, compressor) { + reset_block_variables(compressor, this); +}); + +def_reduce_vars(AST_Case, function(tw) { + push(tw); + this.expression.walk(tw); + pop(tw); + push(tw); + walk_body(this, tw); + pop(tw); + return true; +}); + +def_reduce_vars(AST_Class, function(tw, descend) { + clear_flag(this, INLINED); + push(tw); + descend(); + pop(tw); + return true; +}); + +def_reduce_vars(AST_ClassStaticBlock, function(tw, descend, compressor) { + reset_block_variables(compressor, this); +}); + +def_reduce_vars(AST_Conditional, function(tw) { + this.condition.walk(tw); + push(tw); + this.consequent.walk(tw); + pop(tw); + push(tw); + this.alternative.walk(tw); + pop(tw); + return true; +}); + +def_reduce_vars(AST_Chain, function(tw, descend) { + // Chains' conditions apply left-to-right, cumulatively. + // If we walk normally we don't go in that order because we would pop before pushing again + // Solution: AST_PropAccess and AST_Call push when they are optional, and never pop. + // Then we pop everything when they are done being walked. + const safe_ids = tw.safe_ids; + + descend(); + + // Unroll back to start + tw.safe_ids = safe_ids; + return true; +}); + +def_reduce_vars(AST_Call, function (tw) { + this.expression.walk(tw); + + if (this.optional) { + // Never pop -- it's popped at AST_Chain above + push(tw); + } + + for (const arg of this.args) arg.walk(tw); + + return true; +}); + +def_reduce_vars(AST_PropAccess, function (tw) { + if (!this.optional) return; + + this.expression.walk(tw); + + // Never pop -- it's popped at AST_Chain above + push(tw); + + if (this.property instanceof AST_Node) this.property.walk(tw); + + return true; +}); + +def_reduce_vars(AST_Default, function(tw, descend) { + push(tw); + descend(); + pop(tw); + return true; +}); + +function mark_lambda(tw, descend, compressor) { + clear_flag(this, INLINED); + push(tw); + reset_variables(tw, compressor, this); + + var iife; + if (!this.name + && !this.uses_arguments + && !this.pinned() + && (iife = tw.parent()) instanceof AST_Call + && iife.expression === this + && !iife.args.some(arg => arg instanceof AST_Expansion) + && this.argnames.every(arg_name => arg_name instanceof AST_Symbol) + ) { + // Virtually turn IIFE parameters into variable definitions: + // (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})() + // So existing transformation rules can work on them. + this.argnames.forEach((arg, i) => { + if (!arg.definition) return; + var d = arg.definition(); + // Avoid setting fixed when there's more than one origin for a variable value + if (d.orig.length > 1) return; + if (d.fixed === undefined && (!this.uses_arguments || tw.has_directive("use strict"))) { + d.fixed = function() { + return iife.args[i] || make_node(AST_Undefined, iife); + }; + tw.loop_ids.set(d.id, tw.in_loop); + mark(tw, d, true); + } else { + d.fixed = false; + } + }); + } + + descend(); + pop(tw); + + handle_defined_after_hoist(this); + + return true; +} + +/** + * It's possible for a hoisted function to use something that's not defined yet. Example: + * + * hoisted(); + * var defined_after = true; + * function hoisted() { + * // use defined_after + * } + * + * Or even indirectly: + * + * B(); + * var defined_after = true; + * function A() { + * // use defined_after + * } + * function B() { + * A(); + * } + * + * Access a variable before declaration will either throw a ReferenceError + * (if the variable is declared with `let` or `const`), + * or get an `undefined` (if the variable is declared with `var`). + * + * If the variable is inlined into the function, the behavior will change. + * + * This function is called on the parent to disallow inlining of such variables, + */ +function handle_defined_after_hoist(parent) { + const defuns = []; + walk(parent, node => { + if (node === parent) return; + if (node instanceof AST_Defun) { + defuns.push(node); + return true; + } + if ( + node instanceof AST_Scope + || node instanceof AST_SimpleStatement + ) return true; + }); + + // `defun` id to array of `defun` it uses + const defun_dependencies_map = new Map(); + // `defun` id to array of enclosing `def` that are used by the function + const dependencies_map = new Map(); + // all symbol ids that will be tracked for read/write + const symbols_of_interest = new Set(); + const defuns_of_interest = new Set(); + + for (const defun of defuns) { + const fname_def = defun.name.definition(); + const enclosing_defs = []; + + for (const def of defun.enclosed) { + if ( + def.fixed === false + || def === fname_def + || def.scope.get_defun_scope() !== parent + ) { + continue; + } + + symbols_of_interest.add(def.id); + + // found a reference to another function + if ( + def.assignments === 0 + && def.orig.length === 1 + && def.orig[0] instanceof AST_SymbolDefun + ) { + defuns_of_interest.add(def.id); + symbols_of_interest.add(def.id); + + defuns_of_interest.add(fname_def.id); + symbols_of_interest.add(fname_def.id); + + if (!defun_dependencies_map.has(fname_def.id)) { + defun_dependencies_map.set(fname_def.id, []); + } + defun_dependencies_map.get(fname_def.id).push(def.id); + + continue; + } + + enclosing_defs.push(def); + } + + if (enclosing_defs.length) { + dependencies_map.set(fname_def.id, enclosing_defs); + defuns_of_interest.add(fname_def.id); + symbols_of_interest.add(fname_def.id); + } + } + + // No defuns use outside constants + if (!dependencies_map.size) { + return; + } + + // Increment to count "symbols of interest" (defuns or defs) that we found. + // These are tracked in AST order so we can check which is after which. + let symbol_index = 1; + // Map a defun ID to its first read (a `symbol_index`) + const defun_first_read_map = new Map(); + // Map a symbol ID to its last write (a `symbol_index`) + const symbol_last_write_map = new Map(); + + walk_parent(parent, (node, walk_info) => { + if (node instanceof AST_Symbol && node.thedef) { + const id = node.definition().id; + + symbol_index++; + + // Track last-writes to symbols + if (symbols_of_interest.has(id)) { + if (node instanceof AST_SymbolDeclaration || is_lhs(node, walk_info.parent())) { + symbol_last_write_map.set(id, symbol_index); + } + } + + // Track first-reads of defuns (refined later) + if (defuns_of_interest.has(id)) { + if (!defun_first_read_map.has(id) && !is_recursive_ref(walk_info, id)) { + defun_first_read_map.set(id, symbol_index); + } + } + } + }); + + // Refine `defun_first_read_map` to be as high as possible + for (const [defun, defun_first_read] of defun_first_read_map) { + // Update all dependencies of `defun` + const queue = new Set(defun_dependencies_map.get(defun)); + for (const enclosed_defun of queue) { + let enclosed_defun_first_read = defun_first_read_map.get(enclosed_defun); + if (enclosed_defun_first_read != null && enclosed_defun_first_read < defun_first_read) { + continue; + } + + defun_first_read_map.set(enclosed_defun, defun_first_read); + + for (const enclosed_enclosed_defun of defun_dependencies_map.get(enclosed_defun) || []) { + queue.add(enclosed_enclosed_defun); + } + } + } + + // ensure write-then-read order, otherwise clear `fixed` + // This is safe because last-writes (found_symbol_writes) are assumed to be as late as possible, and first-reads (defun_first_read_map) are assumed to be as early as possible. + for (const [defun, defs] of dependencies_map) { + const defun_first_read = defun_first_read_map.get(defun); + if (defun_first_read === undefined) { + continue; + } + + for (const def of defs) { + if (def.fixed === false) { + continue; + } + + let def_last_write = symbol_last_write_map.get(def.id) || 0; + + if (defun_first_read < def_last_write) { + def.fixed = false; + } + } + } +} + +def_reduce_vars(AST_Lambda, mark_lambda); + +def_reduce_vars(AST_Do, function(tw, descend, compressor) { + reset_block_variables(compressor, this); + const saved_loop = tw.in_loop; + tw.in_loop = this; + push(tw); + this.body.walk(tw); + if (has_break_or_continue(this)) { + pop(tw); + push(tw); + } + this.condition.walk(tw); + pop(tw); + tw.in_loop = saved_loop; + return true; +}); + +def_reduce_vars(AST_For, function(tw, descend, compressor) { + reset_block_variables(compressor, this); + if (this.init) this.init.walk(tw); + const saved_loop = tw.in_loop; + tw.in_loop = this; + push(tw); + if (this.condition) this.condition.walk(tw); + this.body.walk(tw); + if (this.step) { + if (has_break_or_continue(this)) { + pop(tw); + push(tw); + } + this.step.walk(tw); + } + pop(tw); + tw.in_loop = saved_loop; + return true; +}); + +def_reduce_vars(AST_ForIn, function(tw, descend, compressor) { + reset_block_variables(compressor, this); + suppress(this.init); + this.object.walk(tw); + const saved_loop = tw.in_loop; + tw.in_loop = this; + push(tw); + this.body.walk(tw); + pop(tw); + tw.in_loop = saved_loop; + return true; +}); + +def_reduce_vars(AST_If, function(tw) { + this.condition.walk(tw); + push(tw); + this.body.walk(tw); + pop(tw); + if (this.alternative) { + push(tw); + this.alternative.walk(tw); + pop(tw); + } + return true; +}); + +def_reduce_vars(AST_LabeledStatement, function(tw) { + push(tw); + this.body.walk(tw); + pop(tw); + return true; +}); + +def_reduce_vars(AST_SymbolCatch, function() { + this.definition().fixed = false; +}); + +def_reduce_vars(AST_SymbolRef, function(tw, descend, compressor) { + var d = this.definition(); + d.references.push(this); + if (d.references.length == 1 + && !d.fixed + && d.orig[0] instanceof AST_SymbolDefun) { + tw.loop_ids.set(d.id, tw.in_loop); + } + var fixed_value; + if (d.fixed === undefined || !safe_to_read(tw, d)) { + d.fixed = false; + } else if (d.fixed) { + fixed_value = this.fixed_value(); + if ( + fixed_value instanceof AST_Lambda + && is_recursive_ref(tw, d) + ) { + d.recursive_refs++; + } else if (fixed_value + && !compressor.exposed(d) + && ref_once(tw, compressor, d) + ) { + d.single_use = + fixed_value instanceof AST_Lambda && !fixed_value.pinned() + || fixed_value instanceof AST_Class + || d.scope === this.scope && fixed_value.is_constant_expression(); + } else { + d.single_use = false; + } + if (is_modified(compressor, tw, this, fixed_value, 0, is_immutable(fixed_value))) { + if (d.single_use) { + d.single_use = "m"; + } else { + d.fixed = false; + } + } + } + mark_escaped(tw, d, this.scope, this, fixed_value, 0, 1); +}); + +def_reduce_vars(AST_Toplevel, function(tw, descend, compressor) { + this.globals.forEach(function(def) { + reset_def(compressor, def); + }); + reset_variables(tw, compressor, this); + descend(); + handle_defined_after_hoist(this); + return true; +}); + +def_reduce_vars(AST_Try, function(tw, descend, compressor) { + reset_block_variables(compressor, this); + push(tw); + this.body.walk(tw); + pop(tw); + if (this.bcatch) { + push(tw); + this.bcatch.walk(tw); + pop(tw); + } + if (this.bfinally) this.bfinally.walk(tw); + return true; +}); + +def_reduce_vars(AST_Unary, function(tw) { + var node = this; + if (node.operator !== "++" && node.operator !== "--") return; + var exp = node.expression; + if (!(exp instanceof AST_SymbolRef)) return; + var def = exp.definition(); + var safe = safe_to_assign(tw, def, exp.scope, true); + def.assignments++; + if (!safe) return; + var fixed = def.fixed; + if (!fixed) return; + def.references.push(exp); + def.chained = true; + def.fixed = function() { + return make_node(AST_Binary, node, { + operator: node.operator.slice(0, -1), + left: make_node(AST_UnaryPrefix, node, { + operator: "+", + expression: fixed instanceof AST_Node ? fixed : fixed() + }), + right: make_node(AST_Number, node, { + value: 1 + }) + }); + }; + mark(tw, def, true); + return true; +}); + +def_reduce_vars(AST_VarDef, function(tw, descend) { + var node = this; + if (node.name instanceof AST_Destructuring) { + suppress(node.name); + return; + } + var d = node.name.definition(); + if (node.value) { + if (safe_to_assign(tw, d, node.name.scope, node.value)) { + d.fixed = function() { + return node.value; + }; + tw.loop_ids.set(d.id, tw.in_loop); + mark(tw, d, false); + descend(); + mark(tw, d, true); + return true; + } else { + d.fixed = false; + } + } +}); + +def_reduce_vars(AST_UsingDef, function() { + suppress(this.name); +}); + +def_reduce_vars(AST_While, function(tw, descend, compressor) { + reset_block_variables(compressor, this); + const saved_loop = tw.in_loop; + tw.in_loop = this; + push(tw); + descend(); + pop(tw); + tw.in_loop = saved_loop; + return true; +}); + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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 loop_body(x) { + if (x instanceof AST_IterationStatement) { + return x.body instanceof AST_BlockStatement ? x.body : x; + } + return x; +} + +function is_lhs_read_only(lhs) { + if (lhs instanceof AST_This) return true; + if (lhs instanceof AST_SymbolRef) return lhs.definition().orig[0] instanceof AST_SymbolLambda; + if (lhs instanceof AST_PropAccess) { + lhs = lhs.expression; + if (lhs instanceof AST_SymbolRef) { + if (lhs.is_immutable()) return false; + lhs = lhs.fixed_value(); + } + if (!lhs) return true; + if (lhs instanceof AST_RegExp) return false; + if (lhs instanceof AST_Constant) return true; + return is_lhs_read_only(lhs); + } + return false; +} + +/** var a = 1 --> var a*/ +function remove_initializers(var_statement) { + var decls = []; + var_statement.definitions.forEach(function(def) { + if (def.name instanceof AST_SymbolDeclaration) { + def.value = null; + decls.push(def); + } else { + def.declarations_as_names().forEach(name => { + decls.push(make_node(AST_VarDef, def, { + name, + value: null + })); + }); + } + }); + return decls.length ? make_node(AST_Var, var_statement, { definitions: decls }) : null; +} + +/** Called on code which we know is unreachable, to keep elements that affect outside of it. */ +function trim_unreachable_code(compressor, stat, target) { + walk(stat, node => { + if (node instanceof AST_Var) { + const no_initializers = remove_initializers(node); + if (no_initializers) target.push(no_initializers); + return true; + } + if ( + node instanceof AST_Defun + && (node === stat || !compressor.has_directive("use strict")) + ) { + target.push(node === stat ? node : make_node(AST_Var, node, { + definitions: [ + make_node(AST_VarDef, node, { + name: make_node(AST_SymbolVar, node.name, node.name), + value: null + }) + ] + })); + return true; + } + if (node instanceof AST_Export || node instanceof AST_Import) { + target.push(node); + return true; + } + if (node instanceof AST_Scope) { + return true; + } + }); +} + +/** Tighten a bunch of statements together, and perform statement-level optimization. */ +function tighten_body(statements, compressor) { + const nearest_scope = compressor.find_scope(); + const defun_scope = nearest_scope.get_defun_scope(); + const { in_loop, in_try } = find_loop_scope_try(); + + var CHANGED, max_iter = 10; + do { + CHANGED = false; + eliminate_spurious_blocks(statements); + if (compressor.option("dead_code")) { + eliminate_dead_code(statements, compressor); + } + if (compressor.option("if_return")) { + handle_if_return(statements, compressor); + } + if (compressor.sequences_limit > 0) { + sequencesize(statements, compressor); + sequencesize_2(statements, compressor); + } + if (compressor.option("join_vars")) { + join_consecutive_vars(statements); + } + if (compressor.option("collapse_vars")) { + collapse(statements, compressor); + } + } while (CHANGED && max_iter-- > 0); + + function find_loop_scope_try() { + var node = compressor.self(), level = 0, in_loop = false, in_try = false; + do { + if (node instanceof AST_IterationStatement) { + in_loop = true; + } else if (node instanceof AST_Scope) { + break; + } else if (node instanceof AST_TryBlock) { + in_try = true; + } + } while (node = compressor.parent(level++)); + + return { in_loop, in_try }; + } + + // Search from right to left for assignment-like expressions: + // - `var a = x;` + // - `a = x;` + // - `++a` + // For each candidate, scan from left to right for first usage, then try + // to fold assignment into the site for compression. + // Will not attempt to collapse assignments into or past code blocks + // which are not sequentially executed, e.g. loops and conditionals. + function collapse(statements, compressor) { + if (nearest_scope.pinned() || defun_scope.pinned()) + return statements; + var args; + var candidates = []; + var stat_index = statements.length; + var scanner = new TreeTransformer(function (node) { + if (abort) + return node; + // Skip nodes before `candidate` as quickly as possible + if (!hit) { + if (node !== hit_stack[hit_index]) + return node; + hit_index++; + if (hit_index < hit_stack.length) + return handle_custom_scan_order(node); + hit = true; + stop_after = find_stop(node, 0); + if (stop_after === node) + abort = true; + return node; + } + // Stop immediately if these node types are encountered + var parent = scanner.parent(); + if (node instanceof AST_Assign + && (node.logical || node.operator != "=" && lhs.equivalent_to(node.left)) + || node instanceof AST_Await + || node instanceof AST_Using + || node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression) + || + (node instanceof AST_Call || node instanceof AST_PropAccess) + && node.optional + || node instanceof AST_Debugger + || node instanceof AST_Destructuring + || node instanceof AST_Expansion + && node.expression instanceof AST_Symbol + && ( + node.expression instanceof AST_This + || node.expression.definition().references.length > 1 + ) + || node instanceof AST_IterationStatement && !(node instanceof AST_For) + || node instanceof AST_LoopControl + || node instanceof AST_Try + || node instanceof AST_With + || node instanceof AST_Yield + || node instanceof AST_Export + || node instanceof AST_Class + || parent instanceof AST_For && node !== parent.init + || !replace_all + && ( + node instanceof AST_SymbolRef + && !node.is_declared(compressor) + && !pure_prop_access_globals.has(node) + ) + || node instanceof AST_SymbolRef + && parent instanceof AST_Call + && has_annotation(parent, _NOINLINE) + || node instanceof AST_ObjectProperty && node.key instanceof AST_Node + ) { + abort = true; + return node; + } + // Stop only if candidate is found within conditional branches + if (!stop_if_hit && (!lhs_local || !replace_all) + && (parent instanceof AST_Binary && lazy_op.has(parent.operator) && parent.left !== node + || parent instanceof AST_Conditional && parent.condition !== node + || parent instanceof AST_If && parent.condition !== node)) { + stop_if_hit = parent; + } + // Replace variable with assignment when found + if ( + can_replace + && !(node instanceof AST_SymbolDeclaration) + && lhs.equivalent_to(node) + && !shadows(scanner.find_scope() || nearest_scope, lvalues) + ) { + if (stop_if_hit) { + abort = true; + return node; + } + if (is_lhs(node, parent)) { + if (value_def) + replaced++; + return node; + } else { + replaced++; + if (value_def && candidate instanceof AST_VarDef) + return node; + } + CHANGED = abort = true; + if (candidate instanceof AST_UnaryPostfix) { + return make_node(AST_UnaryPrefix, candidate, candidate); + } + if (candidate instanceof AST_VarDef) { + var def = candidate.name.definition(); + var value = candidate.value; + if (def.references.length - def.replaced == 1 && !compressor.exposed(def)) { + def.replaced++; + if (funarg && is_identifier_atom(value)) { + return value.transform(compressor); + } else { + return maintain_this_binding(parent, node, value); + } + } + return make_node(AST_Assign, candidate, { + operator: "=", + logical: false, + left: make_node(AST_SymbolRef, candidate.name, candidate.name), + right: value + }); + } + clear_flag(candidate, WRITE_ONLY); + return candidate; + } + // These node types have child nodes that execute sequentially, + // but are otherwise not safe to scan into or beyond them. + var sym; + if (node instanceof AST_Call + || node instanceof AST_Exit + && (side_effects || lhs instanceof AST_PropAccess || may_modify(lhs)) + || node instanceof AST_PropAccess + && (side_effects || node.expression.may_throw_on_access(compressor)) + || node instanceof AST_SymbolRef + && ((lvalues.has(node.name) && lvalues.get(node.name).modified) || side_effects && may_modify(node)) + || node instanceof AST_VarDef && node.value + && (lvalues.has(node.name.name) || side_effects && may_modify(node.name)) + || node instanceof AST_Using + || (sym = is_lhs(node.left, node)) + && (sym instanceof AST_PropAccess || lvalues.has(sym.name)) + || may_throw + && (in_try ? node.has_side_effects(compressor) : side_effects_external(node))) { + stop_after = node; + if (node instanceof AST_Scope) + abort = true; + } + return handle_custom_scan_order(node); + }, function (node) { + if (abort) + return; + if (stop_after === node) + abort = true; + if (stop_if_hit === node) + stop_if_hit = null; + }); + + var multi_replacer = new TreeTransformer(function (node) { + if (abort) + return node; + // Skip nodes before `candidate` as quickly as possible + if (!hit) { + if (node !== hit_stack[hit_index]) + return node; + hit_index++; + if (hit_index < hit_stack.length) + return; + hit = true; + return node; + } + // Replace variable when found + if (node instanceof AST_SymbolRef + && node.name == def.name) { + if (!--replaced) + abort = true; + if (is_lhs(node, multi_replacer.parent())) + return node; + def.replaced++; + value_def.replaced--; + return candidate.value; + } + // Skip (non-executed) functions and (leading) default case in switch statements + if (node instanceof AST_Default || node instanceof AST_Scope) + return node; + }); + + while (--stat_index >= 0) { + // Treat parameters as collapsible in IIFE, i.e. + // function(a, b){ ... }(x()); + // would be translated into equivalent assignments: + // var a = x(), b = undefined; + if (stat_index == 0 && compressor.option("unused")) + extract_args(); + // Find collapsible assignments + var hit_stack = []; + extract_candidates(statements[stat_index]); + while (candidates.length > 0) { + hit_stack = candidates.pop(); + var hit_index = 0; + var candidate = hit_stack[hit_stack.length - 1]; + var value_def = null; + var stop_after = null; + var stop_if_hit = null; + var lhs = get_lhs(candidate); + if (!lhs || is_lhs_read_only(lhs) || lhs.has_side_effects(compressor)) + continue; + // Locate symbols which may execute code outside of scanning range + var lvalues = get_lvalues(candidate); + var lhs_local = is_lhs_local(lhs); + if (lhs instanceof AST_SymbolRef) { + lvalues.set(lhs.name, { def: lhs.definition(), modified: false }); + } + var side_effects = value_has_side_effects(candidate); + var replace_all = replace_all_symbols(); + var may_throw = candidate.may_throw(compressor); + var funarg = candidate.name instanceof AST_SymbolFunarg; + var hit = funarg; + var abort = false, replaced = 0, can_replace = !args || !hit; + if (!can_replace) { + for ( + let j = compressor.self().argnames.lastIndexOf(candidate.name) + 1; + !abort && j < args.length; + j++ + ) { + args[j].transform(scanner); + } + can_replace = true; + } + for (var i = stat_index; !abort && i < statements.length; i++) { + statements[i].transform(scanner); + } + if (value_def) { + var def = candidate.name.definition(); + if (abort && def.references.length - def.replaced > replaced) + replaced = false; + else { + abort = false; + hit_index = 0; + hit = funarg; + for (var i = stat_index; !abort && i < statements.length; i++) { + statements[i].transform(multi_replacer); + } + value_def.single_use = false; + } + } + if (replaced && !remove_candidate(candidate)) + statements.splice(stat_index, 1); + } + } + + function handle_custom_scan_order(node) { + // Skip (non-executed) functions + if (node instanceof AST_Scope) + return node; + + // Scan case expressions first in a switch statement + if (node instanceof AST_Switch) { + node.expression = node.expression.transform(scanner); + for (var i = 0, len = node.body.length; !abort && i < len; i++) { + var branch = node.body[i]; + if (branch instanceof AST_Case) { + if (!hit) { + if (branch !== hit_stack[hit_index]) + continue; + hit_index++; + } + branch.expression = branch.expression.transform(scanner); + if (!replace_all) + break; + } + } + abort = true; + return node; + } + } + + function redefined_within_scope(def, scope) { + if (def.global) + return false; + let cur_scope = def.scope; + while (cur_scope && cur_scope !== scope) { + if (cur_scope.variables.has(def.name)) { + return true; + } + cur_scope = cur_scope.parent_scope; + } + return false; + } + + function has_overlapping_symbol(fn, arg, fn_strict) { + var found = false, scan_this = !(fn instanceof AST_Arrow); + arg.walk(new TreeWalker(function (node, descend) { + if (found) + return true; + if (node instanceof AST_SymbolRef && (fn.variables.has(node.name) || redefined_within_scope(node.definition(), fn))) { + var s = node.definition().scope; + if (s !== defun_scope) + while (s = s.parent_scope) { + if (s === defun_scope) + return true; + } + return found = true; + } + if ((fn_strict || scan_this) && node instanceof AST_This) { + return found = true; + } + if (node instanceof AST_Scope && !(node instanceof AST_Arrow)) { + var prev = scan_this; + scan_this = false; + descend(); + scan_this = prev; + return true; + } + })); + return found; + } + + function arg_is_injectable(arg) { + if (arg instanceof AST_Expansion) return false; + const contains_await = walk(arg, (node) => { + if (node instanceof AST_Await) return walk_abort; + }); + if (contains_await) return false; + return true; + } + function extract_args() { + var iife, fn = compressor.self(); + if (is_func_expr(fn) + && !fn.name + && !fn.uses_arguments + && !fn.pinned() + && (iife = compressor.parent()) instanceof AST_Call + && iife.expression === fn + && iife.args.every(arg_is_injectable) + ) { + var fn_strict = compressor.has_directive("use strict"); + if (fn_strict && !member(fn_strict, fn.body)) + fn_strict = false; + var len = fn.argnames.length; + args = iife.args.slice(len); + var names = new Set(); + for (var i = len; --i >= 0;) { + var sym = fn.argnames[i]; + var arg = iife.args[i]; + // The following two line fix is a duplicate of the fix at + // https://github.com/terser/terser/commit/011d3eb08cefe6922c7d1bdfa113fc4aeaca1b75 + // This might mean that these two pieces of code (one here in collapse_vars and another in reduce_vars + // Might be doing the exact same thing. + const def = sym.definition && sym.definition(); + const is_reassigned = def && def.orig.length > 1; + if (is_reassigned) + continue; + args.unshift(make_node(AST_VarDef, sym, { + name: sym, + value: arg + })); + if (names.has(sym.name)) + continue; + names.add(sym.name); + if (sym instanceof AST_Expansion) { + var elements = iife.args.slice(i); + if (elements.every((arg) => !has_overlapping_symbol(fn, arg, fn_strict) + )) { + candidates.unshift([make_node(AST_VarDef, sym, { + name: sym.expression, + value: make_node(AST_Array, iife, { + elements: elements + }) + })]); + } + } else { + if (!arg) { + arg = make_node(AST_Undefined, sym).transform(compressor); + } else if (arg instanceof AST_Lambda && arg.pinned() + || has_overlapping_symbol(fn, arg, fn_strict)) { + arg = null; + } + if (arg) + candidates.unshift([make_node(AST_VarDef, sym, { + name: sym, + value: arg + })]); + } + } + } + } + + function extract_candidates(expr) { + hit_stack.push(expr); + if (expr instanceof AST_Assign) { + if (!expr.left.has_side_effects(compressor) + && !(expr.right instanceof AST_Chain)) { + candidates.push(hit_stack.slice()); + } + extract_candidates(expr.right); + } else if (expr instanceof AST_Binary) { + extract_candidates(expr.left); + extract_candidates(expr.right); + } else if (expr instanceof AST_Call && !has_annotation(expr, _NOINLINE)) { + extract_candidates(expr.expression); + expr.args.forEach(extract_candidates); + } else if (expr instanceof AST_Case) { + extract_candidates(expr.expression); + } else if (expr instanceof AST_Conditional) { + extract_candidates(expr.condition); + extract_candidates(expr.consequent); + extract_candidates(expr.alternative); + } else if (expr instanceof AST_Definitions) { + var len = expr.definitions.length; + // limit number of trailing variable definitions for consideration + var i = len - 200; + if (i < 0) + i = 0; + for (; i < len; i++) { + extract_candidates(expr.definitions[i]); + } + } else if (expr instanceof AST_DWLoop) { + extract_candidates(expr.condition); + if (!(expr.body instanceof AST_Block)) { + extract_candidates(expr.body); + } + } else if (expr instanceof AST_Exit) { + if (expr.value) + extract_candidates(expr.value); + } else if (expr instanceof AST_For) { + if (expr.init) + extract_candidates(expr.init); + if (expr.condition) + extract_candidates(expr.condition); + if (expr.step) + extract_candidates(expr.step); + if (!(expr.body instanceof AST_Block)) { + extract_candidates(expr.body); + } + } else if (expr instanceof AST_ForIn) { + extract_candidates(expr.object); + if (!(expr.body instanceof AST_Block)) { + extract_candidates(expr.body); + } + } else if (expr instanceof AST_If) { + extract_candidates(expr.condition); + if (!(expr.body instanceof AST_Block)) { + extract_candidates(expr.body); + } + if (expr.alternative && !(expr.alternative instanceof AST_Block)) { + extract_candidates(expr.alternative); + } + } else if (expr instanceof AST_Sequence) { + expr.expressions.forEach(extract_candidates); + } else if (expr instanceof AST_SimpleStatement) { + extract_candidates(expr.body); + } else if (expr instanceof AST_Switch) { + extract_candidates(expr.expression); + expr.body.forEach(extract_candidates); + } else if (expr instanceof AST_Unary) { + if (expr.operator == "++" || expr.operator == "--") { + candidates.push(hit_stack.slice()); + } + } else if (expr instanceof AST_VarDef) { + if (expr.value && !(expr.value instanceof AST_Chain)) { + candidates.push(hit_stack.slice()); + extract_candidates(expr.value); + } + } + hit_stack.pop(); + } + + function find_stop(node, level, write_only) { + var parent = scanner.parent(level); + if (parent instanceof AST_Assign) { + if (write_only + && !parent.logical + && !(parent.left instanceof AST_PropAccess + || lvalues.has(parent.left.name))) { + return find_stop(parent, level + 1, write_only); + } + return node; + } + if (parent instanceof AST_Binary) { + if (write_only && (!lazy_op.has(parent.operator) || parent.left === node)) { + return find_stop(parent, level + 1, write_only); + } + return node; + } + if (parent instanceof AST_Call) + return node; + if (parent instanceof AST_Case) + return node; + if (parent instanceof AST_Conditional) { + if (write_only && parent.condition === node) { + return find_stop(parent, level + 1, write_only); + } + return node; + } + if (parent instanceof AST_Definitions) { + return find_stop(parent, level + 1, true); + } + if (parent instanceof AST_Exit) { + return write_only ? find_stop(parent, level + 1, write_only) : node; + } + if (parent instanceof AST_If) { + if (write_only && parent.condition === node) { + return find_stop(parent, level + 1, write_only); + } + return node; + } + if (parent instanceof AST_IterationStatement) + return node; + if (parent instanceof AST_Sequence) { + return find_stop(parent, level + 1, parent.tail_node() !== node); + } + if (parent instanceof AST_SimpleStatement) { + return find_stop(parent, level + 1, true); + } + if (parent instanceof AST_Switch) + return node; + if (parent instanceof AST_VarDef) + return node; + return null; + } + + function mangleable_var(var_def) { + var value = var_def.value; + if (!(value instanceof AST_SymbolRef)) + return; + if (value.name == "arguments") + return; + var def = value.definition(); + if (def.undeclared) + return; + return value_def = def; + } + + function get_lhs(expr) { + if (expr instanceof AST_Assign && expr.logical) { + return false; + } else if (expr instanceof AST_VarDef && expr.name instanceof AST_SymbolDeclaration) { + var def = expr.name.definition(); + if (!member(expr.name, def.orig)) + return; + var referenced = def.references.length - def.replaced; + if (!referenced) + return; + var declared = def.orig.length - def.eliminated; + if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg) + || (referenced > 1 ? mangleable_var(expr) : !compressor.exposed(def))) { + return make_node(AST_SymbolRef, expr.name, expr.name); + } + } else { + const lhs = expr instanceof AST_Assign + ? expr.left + : expr.expression; + return !is_ref_of(lhs, AST_SymbolConst) + && !is_ref_of(lhs, AST_SymbolLet) + && !is_ref_of(lhs, AST_SymbolUsing) + && lhs; + } + } + + function get_rvalue(expr) { + if (expr instanceof AST_Assign) { + return expr.right; + } else { + return expr.value; + } + } + + function get_lvalues(expr) { + var lvalues = new Map(); + if (expr instanceof AST_Unary) + return lvalues; + var tw = new TreeWalker(function (node) { + var sym = node; + while (sym instanceof AST_PropAccess) + sym = sym.expression; + if (sym instanceof AST_SymbolRef) { + const prev = lvalues.get(sym.name); + if (!prev || !prev.modified) { + lvalues.set(sym.name, { + def: sym.definition(), + modified: is_modified(compressor, tw, node, node, 0) + }); + } + } + }); + get_rvalue(expr).walk(tw); + return lvalues; + } + + function remove_candidate(expr) { + if (expr.name instanceof AST_SymbolFunarg) { + var iife = compressor.parent(), argnames = compressor.self().argnames; + var index = argnames.indexOf(expr.name); + if (index < 0) { + iife.args.length = Math.min(iife.args.length, argnames.length - 1); + } else { + var args = iife.args; + if (args[index]) + args[index] = make_node(AST_Number, args[index], { + value: 0 + }); + } + return true; + } + var found = false; + return statements[stat_index].transform(new TreeTransformer(function (node, descend, in_list) { + if (found) + return node; + if (node === expr || node.body === expr) { + found = true; + if (node instanceof AST_VarDef) { + node.value = node.name instanceof AST_SymbolConst + ? make_node(AST_Undefined, node.value) // `const` always needs value. + : null; + return node; + } + return in_list ? MAP.skip : null; + } + }, function (node) { + if (node instanceof AST_Sequence) + switch (node.expressions.length) { + case 0: return null; + case 1: return node.expressions[0]; + } + })); + } + + function is_lhs_local(lhs) { + while (lhs instanceof AST_PropAccess) + lhs = lhs.expression; + return lhs instanceof AST_SymbolRef + && lhs.definition().scope.get_defun_scope() === defun_scope + && !(in_loop + && (lvalues.has(lhs.name) + || candidate instanceof AST_Unary + || (candidate instanceof AST_Assign + && !candidate.logical + && candidate.operator != "="))); + } + + function value_has_side_effects(expr) { + if (expr instanceof AST_Unary) + return unary_side_effects.has(expr.operator); + return get_rvalue(expr).has_side_effects(compressor); + } + + function replace_all_symbols() { + if (side_effects) + return false; + if (value_def) + return true; + if (lhs instanceof AST_SymbolRef) { + var def = lhs.definition(); + if (def.references.length - def.replaced == (candidate instanceof AST_VarDef ? 1 : 2)) { + return true; + } + } + return false; + } + + function may_modify(sym) { + if (!sym.definition) + return true; // AST_Destructuring + var def = sym.definition(); + if (def.orig.length == 1 && def.orig[0] instanceof AST_SymbolDefun) + return false; + if (def.scope.get_defun_scope() !== defun_scope) + return true; + return def.references.some((ref) => + ref.scope.get_defun_scope() !== defun_scope + ); + } + + function side_effects_external(node, lhs) { + if (node instanceof AST_Assign) + return side_effects_external(node.left, true); + if (node instanceof AST_Unary) + return side_effects_external(node.expression, true); + if (node instanceof AST_VarDef) + return node.value && side_effects_external(node.value); + if (lhs) { + if (node instanceof AST_Dot) + return side_effects_external(node.expression, true); + if (node instanceof AST_Sub) + return side_effects_external(node.expression, true); + if (node instanceof AST_SymbolRef) + return node.definition().scope.get_defun_scope() !== defun_scope; + } + return false; + } + + /** + * Will any of the pulled-in lvalues shadow a variable in newScope or parents? + * similar to scope_encloses_variables_in_this_scope */ + function shadows(my_scope, lvalues) { + for (const { def } of lvalues.values()) { + const looked_up = my_scope.find_variable(def.name); + if (looked_up) { + if (looked_up === def) continue; + return true; + } + } + return false; + } + } + + function eliminate_spurious_blocks(statements) { + var seen_dirs = []; + for (var i = 0; i < statements.length;) { + var stat = statements[i]; + if (stat instanceof AST_BlockStatement && stat.body.every(can_be_evicted_from_block)) { + CHANGED = true; + eliminate_spurious_blocks(stat.body); + statements.splice(i, 1, ...stat.body); + i += stat.body.length; + } else if (stat instanceof AST_EmptyStatement) { + CHANGED = true; + statements.splice(i, 1); + } else if (stat instanceof AST_Directive) { + if (seen_dirs.indexOf(stat.value) < 0) { + i++; + seen_dirs.push(stat.value); + } else { + CHANGED = true; + statements.splice(i, 1); + } + } else + i++; + } + } + + function handle_if_return(statements, compressor) { + var self = compressor.self(); + var multiple_if_returns = has_multiple_if_returns(statements); + var in_lambda = self instanceof AST_Lambda; + // Prevent extremely deep nesting + // https://github.com/terser/terser/issues/1432 + // https://github.com/webpack/webpack/issues/17548 + const iteration_start = Math.min(statements.length, 500); + for (var i = iteration_start; --i >= 0;) { + var stat = statements[i]; + var j = next_index(i); + var next = statements[j]; + + if (in_lambda && !next && stat instanceof AST_Return) { + if (!stat.value) { + CHANGED = true; + statements.splice(i, 1); + continue; + } + if (stat.value instanceof AST_UnaryPrefix && stat.value.operator == "void") { + CHANGED = true; + statements[i] = make_node(AST_SimpleStatement, stat, { + body: stat.value.expression + }); + continue; + } + } + + if (stat instanceof AST_If) { + let ab, new_else; + + ab = aborts(stat.body); + if ( + can_merge_flow(ab) + && (new_else = as_statement_array_with_return(stat.body, ab)) + ) { + if (ab.label) { + remove(ab.label.thedef.references, ab); + } + CHANGED = true; + stat = stat.clone(); + stat.condition = stat.condition.negate(compressor); + stat.body = make_node(AST_BlockStatement, stat, { + body: as_statement_array(stat.alternative).concat(extract_defuns()) + }); + stat.alternative = make_node(AST_BlockStatement, stat, { + body: new_else + }); + statements[i] = stat.transform(compressor); + continue; + } + + ab = aborts(stat.alternative); + if ( + can_merge_flow(ab) + && (new_else = as_statement_array_with_return(stat.alternative, ab)) + ) { + if (ab.label) { + remove(ab.label.thedef.references, ab); + } + CHANGED = true; + stat = stat.clone(); + stat.body = make_node(AST_BlockStatement, stat.body, { + body: as_statement_array(stat.body).concat(extract_defuns()) + }); + stat.alternative = make_node(AST_BlockStatement, stat.alternative, { + body: new_else + }); + statements[i] = stat.transform(compressor); + continue; + } + } + + if (stat instanceof AST_If && stat.body instanceof AST_Return) { + var value = stat.body.value; + //--- + // pretty silly case, but: + // if (foo()) return; return; ==> foo(); return; + if (!value && !stat.alternative + && (in_lambda && !next || next instanceof AST_Return && !next.value)) { + CHANGED = true; + statements[i] = make_node(AST_SimpleStatement, stat.condition, { + body: stat.condition + }); + continue; + } + //--- + // if (foo()) return x; return y; ==> return foo() ? x : y; + if (value && !stat.alternative && next instanceof AST_Return && next.value) { + CHANGED = true; + stat = stat.clone(); + stat.alternative = next; + statements[i] = stat.transform(compressor); + statements.splice(j, 1); + continue; + } + //--- + // if (foo()) return x; [ return ; ] ==> return foo() ? x : undefined; + if (value && !stat.alternative + && (!next && in_lambda && multiple_if_returns + || next instanceof AST_Return)) { + CHANGED = true; + stat = stat.clone(); + stat.alternative = next || make_node(AST_Return, stat, { + value: null + }); + statements[i] = stat.transform(compressor); + if (next) + statements.splice(j, 1); + continue; + } + //--- + // if (a) return b; if (c) return d; e; ==> return a ? b : c ? d : void e; + // + // if sequences is not enabled, this can lead to an endless loop (issue #866). + // however, with sequences on this helps producing slightly better output for + // the example code. + var prev = statements[prev_index(i)]; + if (compressor.option("sequences") && in_lambda && !stat.alternative + && prev instanceof AST_If && prev.body instanceof AST_Return + && next_index(j) == statements.length && next instanceof AST_SimpleStatement) { + CHANGED = true; + stat = stat.clone(); + stat.alternative = make_node(AST_BlockStatement, next, { + body: [ + next, + make_node(AST_Return, next, { + value: null + }) + ] + }); + statements[i] = stat.transform(compressor); + statements.splice(j, 1); + continue; + } + } + } + + function has_multiple_if_returns(statements) { + var n = 0; + for (var i = statements.length; --i >= 0;) { + var stat = statements[i]; + if (stat instanceof AST_If && stat.body instanceof AST_Return) { + if (++n > 1) + return true; + } + } + return false; + } + + function is_return_void(value) { + return !value || value instanceof AST_UnaryPrefix && value.operator == "void"; + } + + function can_merge_flow(ab) { + if (!ab) + return false; + for (var j = i + 1, len = statements.length; j < len; j++) { + var stat = statements[j]; + if (stat instanceof AST_DefinitionsLike && !(stat instanceof AST_Var)) + return false; + } + var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab) : null; + return ab instanceof AST_Return && in_lambda && is_return_void(ab.value) + || ab instanceof AST_Continue && self === loop_body(lct) + || ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct; + } + + function extract_defuns() { + var tail = statements.slice(i + 1); + statements.length = i + 1; + return tail.filter(function (stat) { + if (stat instanceof AST_Defun) { + statements.push(stat); + return false; + } + return true; + }); + } + + function as_statement_array_with_return(node, ab) { + var body = as_statement_array(node); + if (ab !== body[body.length - 1]) { + return undefined; + } + body = body.slice(0, -1); + if (!body.every(stat => can_be_evicted_from_block(stat))) { + return undefined; + } + if (ab.value) { + body.push(make_node(AST_SimpleStatement, ab.value, { + body: ab.value.expression + })); + } + return body; + } + + function next_index(i) { + for (var j = i + 1, len = statements.length; j < len; j++) { + var stat = statements[j]; + if (!(stat instanceof AST_Var && declarations_only(stat))) { + break; + } + } + return j; + } + + function prev_index(i) { + for (var j = i; --j >= 0;) { + var stat = statements[j]; + if (!(stat instanceof AST_Var && declarations_only(stat))) { + break; + } + } + return j; + } + } + + function eliminate_dead_code(statements, compressor) { + var has_quit; + var self = compressor.self(); + for (var i = 0, n = 0, len = statements.length; i < len; i++) { + var stat = statements[i]; + if (stat instanceof AST_LoopControl) { + var lct = compressor.loopcontrol_target(stat); + if (stat instanceof AST_Break + && !(lct instanceof AST_IterationStatement) + && loop_body(lct) === self + || stat instanceof AST_Continue + && loop_body(lct) === self) { + if (stat.label) { + remove(stat.label.thedef.references, stat); + } + } else { + statements[n++] = stat; + } + } else { + statements[n++] = stat; + } + if (aborts(stat)) { + has_quit = statements.slice(i + 1); + break; + } + } + statements.length = n; + CHANGED = n != len; + if (has_quit) + has_quit.forEach(function (stat) { + trim_unreachable_code(compressor, stat, statements); + }); + } + + function declarations_only(node) { + return node.definitions.every((var_def) => !var_def.value); + } + + function sequencesize(statements, compressor) { + if (statements.length < 2) + return; + var seq = [], n = 0; + function push_seq() { + if (!seq.length) + return; + var body = make_sequence(seq[0], seq); + statements[n++] = make_node(AST_SimpleStatement, body, { body: body }); + seq = []; + } + for (var i = 0, len = statements.length; i < len; i++) { + var stat = statements[i]; + if (stat instanceof AST_SimpleStatement) { + if (seq.length >= compressor.sequences_limit) + push_seq(); + var body = stat.body; + if (seq.length > 0) + body = body.drop_side_effect_free(compressor); + if (body) + merge_sequence(seq, body); + } else if (stat instanceof AST_Definitions && declarations_only(stat) + || stat instanceof AST_Defun) { + statements[n++] = stat; + } else { + push_seq(); + statements[n++] = stat; + } + } + push_seq(); + statements.length = n; + if (n != len) + CHANGED = true; + } + + function to_simple_statement(block, decls) { + if (!(block instanceof AST_BlockStatement)) + return block; + var stat = null; + for (var i = 0, len = block.body.length; i < len; i++) { + var line = block.body[i]; + if (line instanceof AST_Var && declarations_only(line)) { + decls.push(line); + } else if (stat || line instanceof AST_DefinitionsLike && !(line instanceof AST_Var)) { + return false; + } else { + stat = line; + } + } + return stat; + } + + function sequencesize_2(statements, compressor) { + function cons_seq(right) { + n--; + CHANGED = true; + var left = prev.body; + return make_sequence(left, [left, right]).transform(compressor); + } + var n = 0, prev; + for (var i = 0; i < statements.length; i++) { + var stat = statements[i]; + if (prev) { + if (stat instanceof AST_Exit) { + stat.value = cons_seq(stat.value || make_node(AST_Undefined, stat).transform(compressor)); + } else if (stat instanceof AST_For) { + if (!(stat.init instanceof AST_DefinitionsLike)) { + const abort = walk(prev.body, node => { + if (node instanceof AST_Scope) + return true; + if (node instanceof AST_Binary + && node.operator === "in") { + return walk_abort; + } + }); + if (!abort) { + if (stat.init) + stat.init = cons_seq(stat.init); + else { + stat.init = prev.body; + n--; + CHANGED = true; + } + } + } + } else if (stat instanceof AST_ForIn) { + if (!(stat.init instanceof AST_DefinitionsLike) || stat.init instanceof AST_Var) { + stat.object = cons_seq(stat.object); + } + } else if (stat instanceof AST_If) { + stat.condition = cons_seq(stat.condition); + } else if (stat instanceof AST_Switch) { + stat.expression = cons_seq(stat.expression); + } else if (stat instanceof AST_With) { + stat.expression = cons_seq(stat.expression); + } + } + if (compressor.option("conditionals") && stat instanceof AST_If) { + var decls = []; + var body = to_simple_statement(stat.body, decls); + var alt = to_simple_statement(stat.alternative, decls); + if (body !== false && alt !== false && decls.length > 0) { + var len = decls.length; + decls.push(make_node(AST_If, stat, { + condition: stat.condition, + body: body || make_node(AST_EmptyStatement, stat.body), + alternative: alt + })); + decls.unshift(n, 1); + [].splice.apply(statements, decls); + i += len; + n += len + 1; + prev = null; + CHANGED = true; + continue; + } + } + statements[n++] = stat; + prev = stat instanceof AST_SimpleStatement ? stat : null; + } + statements.length = n; + } + + function join_object_assignments(defn, body) { + if (!(defn instanceof AST_Definitions)) + return; + var def = defn.definitions[defn.definitions.length - 1]; + if (!(def.value instanceof AST_Object)) + return; + var exprs; + if (body instanceof AST_Assign && !body.logical) { + exprs = [body]; + } else if (body instanceof AST_Sequence) { + exprs = body.expressions.slice(); + } + if (!exprs) + return; + var trimmed = false; + do { + var node = exprs[0]; + if (!(node instanceof AST_Assign)) + break; + if (node.operator != "=") + break; + if (!(node.left instanceof AST_PropAccess)) + break; + var sym = node.left.expression; + if (!(sym instanceof AST_SymbolRef)) + break; + if (def.name.name != sym.name) + break; + if (!node.right.is_constant_expression(nearest_scope)) + break; + var prop = node.left.property; + if (prop instanceof AST_Node) { + prop = prop.evaluate(compressor); + } + if (prop instanceof AST_Node) + break; + prop = "" + prop; + var diff = compressor.option("ecma") < 2015 + && compressor.has_directive("use strict") ? function (node) { + return node.key != prop && (node.key && node.key.name != prop); + } : function (node) { + return node.key && node.key.name != prop; + }; + if (!def.value.properties.every(diff)) + break; + var p = def.value.properties.filter(function (p) { return p.key === prop; })[0]; + if (!p) { + def.value.properties.push(make_node(AST_ObjectKeyVal, node, { + key: prop, + value: node.right + })); + } else { + p.value = new AST_Sequence({ + start: p.start, + expressions: [p.value.clone(), node.right.clone()], + end: p.end + }); + } + exprs.shift(); + trimmed = true; + } while (exprs.length); + return trimmed && exprs; + } + + function join_consecutive_vars(statements) { + var defs; + for (var i = 0, j = -1, len = statements.length; i < len; i++) { + var stat = statements[i]; + var prev = statements[j]; + if (stat instanceof AST_Definitions) { + if (prev && prev.TYPE == stat.TYPE) { + prev.definitions = prev.definitions.concat(stat.definitions); + CHANGED = true; + } else if (defs && defs.TYPE == stat.TYPE && declarations_only(stat)) { + defs.definitions = defs.definitions.concat(stat.definitions); + CHANGED = true; + } else { + statements[++j] = stat; + defs = stat; + } + } else if ( + stat instanceof AST_Using + && prev instanceof AST_Using + && prev.await === stat.await + ) { + prev.definitions = prev.definitions.concat(stat.definitions); + } else if (stat instanceof AST_Exit) { + stat.value = extract_object_assignments(stat.value); + } else if (stat instanceof AST_For) { + var exprs = join_object_assignments(prev, stat.init); + if (exprs) { + CHANGED = true; + stat.init = exprs.length ? make_sequence(stat.init, exprs) : null; + statements[++j] = stat; + } else if ( + prev instanceof AST_Var + && (!stat.init || stat.init.TYPE == prev.TYPE) + ) { + if (stat.init) { + prev.definitions = prev.definitions.concat(stat.init.definitions); + } + stat.init = prev; + statements[j] = stat; + CHANGED = true; + } else if ( + defs instanceof AST_Var + && stat.init instanceof AST_Var + && declarations_only(stat.init) + ) { + defs.definitions = defs.definitions.concat(stat.init.definitions); + stat.init = null; + statements[++j] = stat; + CHANGED = true; + } else { + statements[++j] = stat; + } + } else if (stat instanceof AST_ForIn) { + stat.object = extract_object_assignments(stat.object); + } else if (stat instanceof AST_If) { + stat.condition = extract_object_assignments(stat.condition); + } else if (stat instanceof AST_SimpleStatement) { + var exprs = join_object_assignments(prev, stat.body); + if (exprs) { + CHANGED = true; + if (!exprs.length) + continue; + stat.body = make_sequence(stat.body, exprs); + } + statements[++j] = stat; + } else if (stat instanceof AST_Switch) { + stat.expression = extract_object_assignments(stat.expression); + } else if (stat instanceof AST_With) { + stat.expression = extract_object_assignments(stat.expression); + } else { + statements[++j] = stat; + } + } + statements.length = j + 1; + + function extract_object_assignments(value) { + statements[++j] = stat; + var exprs = join_object_assignments(prev, value); + if (exprs) { + CHANGED = true; + if (exprs.length) { + return make_sequence(value, exprs); + } else if (value instanceof AST_Sequence) { + return value.tail_node().left; + } else { + return value.left; + } + } + return value; + } + } +} + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +/** + * Module that contains the inlining logic. + * + * @module + * + * The stars of the show are `inline_into_symbolref` and `inline_into_call`. + */ + +function within_array_or_object_literal(compressor) { + var node, level = 0; + while (node = compressor.parent(level++)) { + if (node instanceof AST_Statement) return false; + if (node instanceof AST_Array + || node instanceof AST_ObjectKeyVal + || node instanceof AST_Object) { + return true; + } + } + return false; +} + +function scope_encloses_variables_in_this_scope(scope, pulled_scope) { + for (const enclosed of pulled_scope.enclosed) { + if (pulled_scope.variables.has(enclosed.name)) { + continue; + } + const looked_up = scope.find_variable(enclosed.name); + if (looked_up) { + if (looked_up === enclosed) continue; + return true; + } + } + return false; +} + +/** + * An extra check function for `top_retain` option, compare the length of const identifier + * and init value length and return true if init value is longer than identifier. for example: + * ``` + * // top_retain: ["example"] + * const example = 100 + * ``` + * it will return false because length of "100" is short than identifier "example". + */ +function is_const_symbol_short_than_init_value(def, fixed_value) { + if (def.orig.length === 1 && fixed_value) { + const init_value_length = fixed_value.size(); + const identifer_length = def.name.length; + return init_value_length > identifer_length; + } + return true; +} + +function inline_into_symbolref(self, compressor) { + if (compressor.in_computed_key()) return self; + + const parent = compressor.parent(); + const def = self.definition(); + const nearest_scope = compressor.find_scope(); + let fixed = self.fixed_value(); + if ( + compressor.top_retain && + def.global && + compressor.top_retain(def) && + // when identifier is in top_retain option dose not mean we can always inline it. + // if identifier name is longer then init value, we can replace it. + is_const_symbol_short_than_init_value(def, fixed) + ) { + // keep it + def.fixed = false; + def.single_use = false; + return self; + } + + if (dont_inline_lambda_in_loop(compressor, fixed)) return self; + + let single_use = def.single_use + && !(parent instanceof AST_Call + && (parent.is_callee_pure(compressor)) + || has_annotation(parent, _NOINLINE)) + && !(parent instanceof AST_Export + && fixed instanceof AST_Lambda + && fixed.name); + + if (single_use && fixed instanceof AST_Node) { + single_use = + !fixed.has_side_effects(compressor) + && !fixed.may_throw(compressor); + } + + if (fixed instanceof AST_Class && def.scope !== self.scope) { + return self; + } + + if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) { + if (retain_top_func(fixed, compressor)) { + single_use = false; + } else if (def.scope !== self.scope + && (def.escaped == 1 + || has_flag(fixed, INLINED) + || within_array_or_object_literal(compressor) + || !compressor.option("reduce_funcs"))) { + single_use = false; + } else if (is_recursive_ref(compressor, def)) { + single_use = false; + } else if (def.scope !== self.scope || def.orig[0] instanceof AST_SymbolFunarg) { + single_use = fixed.is_constant_expression(self.scope); + if (single_use == "f") { + var scope = self.scope; + do { + if (scope instanceof AST_Defun || is_func_expr(scope)) { + set_flag(scope, INLINED); + } + } while (scope = scope.parent_scope); + } + } + } + + if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) { + single_use = + def.scope === self.scope + && !scope_encloses_variables_in_this_scope(nearest_scope, fixed) + || parent instanceof AST_Call + && parent.expression === self + && !scope_encloses_variables_in_this_scope(nearest_scope, fixed) + && !(fixed.name && fixed.name.definition().recursive_refs > 0); + } + + if (single_use && fixed) { + if (fixed instanceof AST_DefClass) { + set_flag(fixed, SQUEEZED); + fixed = make_node(AST_ClassExpression, fixed, fixed); + } + if (fixed instanceof AST_Defun) { + set_flag(fixed, SQUEEZED); + fixed = make_node(AST_Function, fixed, fixed); + } + if (def.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) { + const defun_def = fixed.name.definition(); + let lambda_def = fixed.variables.get(fixed.name.name); + let name = lambda_def && lambda_def.orig[0]; + if (!(name instanceof AST_SymbolLambda)) { + name = make_node(AST_SymbolLambda, fixed.name, fixed.name); + name.scope = fixed; + fixed.name = name; + lambda_def = fixed.def_function(name); + } + walk(fixed, node => { + if (node instanceof AST_SymbolRef && node.definition() === defun_def) { + node.thedef = lambda_def; + lambda_def.references.push(node); + } + }); + } + if ( + (fixed instanceof AST_Lambda || fixed instanceof AST_Class) + && fixed.parent_scope !== nearest_scope + ) { + fixed = fixed.clone(true, compressor.get_toplevel()); + + nearest_scope.add_child_scope(fixed); + } + return fixed.optimize(compressor); + } + + // multiple uses + if (fixed) { + let replace; + + if (fixed instanceof AST_This) { + if (!(def.orig[0] instanceof AST_SymbolFunarg) + && def.references.every((ref) => + def.scope === ref.scope + )) { + replace = fixed; + } + } else { + var ev = fixed.evaluate(compressor); + if ( + ev !== fixed + && (compressor.option("unsafe_regexp") || !(ev instanceof RegExp)) + ) { + replace = make_node_from_constant(ev, fixed); + } + } + + if (replace) { + const name_length = self.size(compressor); + const replace_size = replace.size(compressor); + + let overhead = 0; + if (compressor.option("unused") && !compressor.exposed(def)) { + overhead = + (name_length + 2 + fixed.size(compressor)) / + (def.references.length - def.assignments); + } + + if (replace_size <= name_length + overhead) { + return replace; + } + } + } + + return self; +} + +function inline_into_call(self, compressor) { + if (compressor.in_computed_key()) return self; + + var exp = self.expression; + var fn = exp; + var simple_args = self.args.every((arg) => !(arg instanceof AST_Expansion)); + + if (compressor.option("reduce_vars") + && fn instanceof AST_SymbolRef + && !has_annotation(self, _NOINLINE) + ) { + const fixed = fn.fixed_value(); + + if ( + retain_top_func(fixed, compressor) + || !compressor.toplevel.funcs && exp.definition().global + ) { + return self; + } + + fn = fixed; + } + + if ( + dont_inline_lambda_in_loop(compressor, fn) + && !has_annotation(self, _INLINE) + ) return self; + + var is_func = fn instanceof AST_Lambda; + + var stat = is_func && fn.body[0]; + var is_regular_func = is_func && !fn.is_generator && !fn.async; + var can_inline = is_regular_func && compressor.option("inline") && !self.is_callee_pure(compressor); + if (can_inline && stat instanceof AST_Return) { + let returned = stat.value; + if (!returned || returned.is_constant_expression()) { + if (returned) { + returned = returned.clone(true); + } else { + returned = make_node(AST_Undefined, self); + } + const args = self.args.concat(returned); + return make_sequence(self, args).optimize(compressor); + } + + // optimize identity function + if ( + fn.argnames.length === 1 + && (fn.argnames[0] instanceof AST_SymbolFunarg) + && self.args.length < 2 + && !(self.args[0] instanceof AST_Expansion) + && returned instanceof AST_SymbolRef + && returned.name === fn.argnames[0].name + ) { + const replacement = + (self.args[0] || make_node(AST_Undefined)).optimize(compressor); + + let parent; + if ( + replacement instanceof AST_PropAccess + && (parent = compressor.parent()) instanceof AST_Call + && parent.expression === self + ) { + // identity function was being used to remove `this`, like in + // + // id(bag.no_this)(...) + // + // Replace with a larger but more effish (0, bag.no_this) wrapper. + + return make_sequence(self, [ + make_node(AST_Number, self, { value: 0 }), + replacement + ]); + } + // replace call with first argument or undefined if none passed + return replacement; + } + } + + if (can_inline) { + var scope, in_loop, level = -1; + let def; + let returned_value; + let nearest_scope; + if (simple_args + && !fn.uses_arguments + && !(compressor.parent() instanceof AST_Class) + && !(fn.name && fn instanceof AST_Function) + && (returned_value = can_flatten_body(stat)) + && (exp === fn + || has_annotation(self, _INLINE) + || compressor.option("unused") + && (def = exp.definition()).references.length == 1 + && !is_recursive_ref(compressor, def) + && fn.is_constant_expression(exp.scope)) + && !has_annotation(self, _PURE | _NOINLINE) + && !fn.contains_this() + && can_inject_symbols() + && (nearest_scope = compressor.find_scope()) + && !scope_encloses_variables_in_this_scope(nearest_scope, fn) + && !(function in_default_assign() { + // Due to the fact function parameters have their own scope + // which can't use `var something` in the function body within, + // we simply don't inline into DefaultAssign. + let i = 0; + let p; + while ((p = compressor.parent(i++))) { + if (p instanceof AST_DefaultAssign) return true; + if (p instanceof AST_Block) break; + } + return false; + })() + && !(scope instanceof AST_Class) + ) { + set_flag(fn, SQUEEZED); + nearest_scope.add_child_scope(fn); + return make_sequence(self, flatten_fn(returned_value)).optimize(compressor); + } + } + + if (can_inline && has_annotation(self, _INLINE)) { + set_flag(fn, SQUEEZED); + fn = make_node(fn.CTOR === AST_Defun ? AST_Function : fn.CTOR, fn, fn); + fn = fn.clone(true); + fn.figure_out_scope({}, { + parent_scope: compressor.find_scope(), + toplevel: compressor.get_toplevel() + }); + + return make_node(AST_Call, self, { + expression: fn, + args: self.args, + }).optimize(compressor); + } + + const can_drop_this_call = is_regular_func && compressor.option("side_effects") && fn.body.every(is_empty); + if (can_drop_this_call) { + var args = self.args.concat(make_node(AST_Undefined, self)); + return make_sequence(self, args).optimize(compressor); + } + + if (compressor.option("negate_iife") + && compressor.parent() instanceof AST_SimpleStatement + && is_iife_call(self)) { + return self.negate(compressor, true); + } + + var ev = self.evaluate(compressor); + if (ev !== self) { + ev = make_node_from_constant(ev, self).optimize(compressor); + return best_of(compressor, ev, self); + } + + return self; + + function return_value(stat) { + if (!stat) return make_node(AST_Undefined, self); + if (stat instanceof AST_Return) { + if (!stat.value) return make_node(AST_Undefined, self); + return stat.value.clone(true); + } + if (stat instanceof AST_SimpleStatement) { + return make_node(AST_UnaryPrefix, stat, { + operator: "void", + expression: stat.body.clone(true) + }); + } + } + + function can_flatten_body(stat) { + var body = fn.body; + var len = body.length; + if (compressor.option("inline") < 3) { + return len == 1 && return_value(stat); + } + stat = null; + for (var i = 0; i < len; i++) { + var line = body[i]; + if (line instanceof AST_Var) { + if (stat && !line.definitions.every((var_def) => + !var_def.value + )) { + return false; + } + } else if (stat) { + return false; + } else if (!(line instanceof AST_EmptyStatement)) { + stat = line; + } + } + return return_value(stat); + } + + function can_inject_args(block_scoped, safe_to_inject) { + for (var i = 0, len = fn.argnames.length; i < len; i++) { + var arg = fn.argnames[i]; + if (arg instanceof AST_DefaultAssign) { + if (has_flag(arg.left, UNUSED)) continue; + return false; + } + if (arg instanceof AST_Destructuring) return false; + if (arg instanceof AST_Expansion) { + if (has_flag(arg.expression, UNUSED)) continue; + return false; + } + if (has_flag(arg, UNUSED)) continue; + if (!safe_to_inject + || block_scoped.has(arg.name) + || identifier_atom.has(arg.name) + || scope.conflicting_def(arg.name)) { + return false; + } + if (in_loop) in_loop.push(arg.definition()); + } + return true; + } + + function can_inject_vars(block_scoped, safe_to_inject) { + var len = fn.body.length; + for (var i = 0; i < len; i++) { + var stat = fn.body[i]; + if (!(stat instanceof AST_Var)) continue; + if (!safe_to_inject) return false; + for (var j = stat.definitions.length; --j >= 0;) { + var name = stat.definitions[j].name; + if (name instanceof AST_Destructuring + || block_scoped.has(name.name) + || identifier_atom.has(name.name) + || scope.conflicting_def(name.name)) { + return false; + } + if (in_loop) in_loop.push(name.definition()); + } + } + return true; + } + + function can_inject_symbols() { + var block_scoped = new Set(); + do { + scope = compressor.parent(++level); + if (scope.is_block_scope() && scope.block_scope) { + // TODO this is sometimes undefined during compression. + // But it should always have a value! + scope.block_scope.variables.forEach(function (variable) { + block_scoped.add(variable.name); + }); + } + if (scope instanceof AST_Catch) { + // TODO can we delete? AST_Catch is a block scope. + if (scope.argname) { + block_scoped.add(scope.argname.name); + } + } else if (scope instanceof AST_IterationStatement) { + in_loop = []; + } else if (scope instanceof AST_SymbolRef) { + if (scope.fixed_value() instanceof AST_Scope) return false; + } + } while (!(scope instanceof AST_Scope)); + + var safe_to_inject = !(scope instanceof AST_Toplevel) || compressor.toplevel.vars; + var inline = compressor.option("inline"); + if (!can_inject_vars(block_scoped, inline >= 3 && safe_to_inject)) return false; + if (!can_inject_args(block_scoped, inline >= 2 && safe_to_inject)) return false; + return !in_loop || in_loop.length == 0 || !is_reachable(fn, in_loop); + } + + function append_var(decls, expressions, name, value) { + var def = name.definition(); + + // Name already exists, only when a function argument had the same name + const already_appended = scope.variables.has(name.name); + if (!already_appended) { + scope.variables.set(name.name, def); + scope.enclosed.push(def); + decls.push(make_node(AST_VarDef, name, { + name: name, + value: null + })); + } + + var sym = make_node(AST_SymbolRef, name, name); + def.references.push(sym); + if (value) expressions.push(make_node(AST_Assign, self, { + operator: "=", + logical: false, + left: sym, + right: value.clone() + })); + } + + function flatten_args(decls, expressions) { + var len = fn.argnames.length; + for (var i = self.args.length; --i >= len;) { + expressions.push(self.args[i]); + } + for (i = len; --i >= 0;) { + var name = fn.argnames[i]; + var value = self.args[i]; + if (has_flag(name, UNUSED) || !name.name || scope.conflicting_def(name.name)) { + if (value) expressions.push(value); + } else { + var symbol = make_node(AST_SymbolVar, name, name); + name.definition().orig.push(symbol); + if (!value && in_loop) value = make_node(AST_Undefined, self); + append_var(decls, expressions, symbol, value); + } + } + decls.reverse(); + expressions.reverse(); + } + + function flatten_vars(decls, expressions) { + var pos = expressions.length; + for (var i = 0, lines = fn.body.length; i < lines; i++) { + var stat = fn.body[i]; + if (!(stat instanceof AST_Var)) continue; + for (var j = 0, defs = stat.definitions.length; j < defs; j++) { + var var_def = stat.definitions[j]; + var name = var_def.name; + append_var(decls, expressions, name, var_def.value); + if (in_loop && fn.argnames.every((argname) => + argname.name != name.name + )) { + var def = fn.variables.get(name.name); + var sym = make_node(AST_SymbolRef, name, name); + def.references.push(sym); + expressions.splice(pos++, 0, make_node(AST_Assign, var_def, { + operator: "=", + logical: false, + left: sym, + right: make_node(AST_Undefined, name) + })); + } + } + } + } + + function flatten_fn(returned_value) { + var decls = []; + var expressions = []; + flatten_args(decls, expressions); + flatten_vars(decls, expressions); + expressions.push(returned_value); + + if (decls.length) { + const i = scope.body.indexOf(compressor.parent(level - 1)) + 1; + scope.body.splice(i, 0, make_node(AST_Var, fn, { + definitions: decls + })); + } + + return expressions.map(exp => exp.clone(true)); + } +} + +/** prevent inlining functions into loops, for performance reasons */ +function dont_inline_lambda_in_loop(compressor, maybe_lambda) { + return ( + (maybe_lambda instanceof AST_Lambda || maybe_lambda instanceof AST_Class) + && !!compressor.is_within_loop() + ); +} + +(function(def_find_defs) { + function to_node(value, orig) { + if (value instanceof AST_Node) { + if (!(value instanceof AST_Constant)) { + // Value may be a function, an array including functions and even a complex assign / block expression, + // so it should never be shared in different places. + // Otherwise wrong information may be used in the compression phase + value = value.clone(true); + } + return make_node(value.CTOR, orig, value); + } + if (Array.isArray(value)) return make_node(AST_Array, orig, { + elements: value.map(function(value) { + return to_node(value, orig); + }) + }); + if (value && typeof value == "object") { + var props = []; + for (var key in value) if (HOP(value, key)) { + props.push(make_node(AST_ObjectKeyVal, orig, { + key: key, + value: to_node(value[key], orig) + })); + } + return make_node(AST_Object, orig, { + properties: props + }); + } + return make_node_from_constant(value, orig); + } + + AST_Toplevel.DEFMETHOD("resolve_defines", function(compressor) { + if (!compressor.option("global_defs")) return this; + this.figure_out_scope({ ie8: compressor.option("ie8") }); + return this.transform(new TreeTransformer(function(node) { + var def = node._find_defs(compressor, ""); + if (!def) return; + var level = 0, child = node, parent; + while (parent = this.parent(level++)) { + if (!(parent instanceof AST_PropAccess)) break; + if (parent.expression !== child) break; + child = parent; + } + if (is_lhs(child, parent)) { + return; + } + return def; + })); + }); + def_find_defs(AST_Node, noop); + def_find_defs(AST_Chain, function(compressor, suffix) { + return this.expression._find_defs(compressor, suffix); + }); + def_find_defs(AST_Dot, function(compressor, suffix) { + return this.expression._find_defs(compressor, "." + this.property + suffix); + }); + def_find_defs(AST_SymbolDeclaration, function() { + if (!this.global()) return; + }); + def_find_defs(AST_SymbolRef, function(compressor, suffix) { + if (!this.global()) return; + var defines = compressor.option("global_defs"); + var name = this.name + suffix; + if (HOP(defines, name)) return to_node(defines[name], this); + }); + def_find_defs(AST_ImportMeta, function(compressor, suffix) { + var defines = compressor.option("global_defs"); + var name = "import.meta" + suffix; + if (HOP(defines, name)) return to_node(defines[name], this); + }); +})(function(node, func) { + node.DEFMETHOD("_find_defs", func); +}); + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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 Compressor extends TreeWalker { + constructor(options, { false_by_default = false, mangle_options = false }) { + super(); + if (options.defaults !== undefined && !options.defaults) false_by_default = true; + this.options = defaults(options, { + arguments : false, + arrows : !false_by_default, + booleans : !false_by_default, + booleans_as_integers : false, + collapse_vars : !false_by_default, + comparisons : !false_by_default, + computed_props: !false_by_default, + conditionals : !false_by_default, + dead_code : !false_by_default, + defaults : true, + directives : !false_by_default, + drop_console : false, + drop_debugger : !false_by_default, + ecma : 5, + evaluate : !false_by_default, + expression : false, + global_defs : false, + hoist_funs : false, + hoist_props : !false_by_default, + hoist_vars : false, + ie8 : false, + if_return : !false_by_default, + inline : !false_by_default, + join_vars : !false_by_default, + keep_classnames: false, + keep_fargs : true, + keep_fnames : false, + keep_infinity : false, + lhs_constants : !false_by_default, + loops : !false_by_default, + module : false, + negate_iife : !false_by_default, + passes : 1, + properties : !false_by_default, + pure_getters : !false_by_default && "strict", + pure_funcs : null, + pure_new : false, + reduce_funcs : !false_by_default, + reduce_vars : !false_by_default, + sequences : !false_by_default, + side_effects : !false_by_default, + switches : !false_by_default, + top_retain : null, + toplevel : !!(options && options["top_retain"]), + typeofs : !false_by_default, + unsafe : false, + unsafe_arrows : false, + unsafe_comps : false, + unsafe_Function: false, + unsafe_math : false, + unsafe_symbols: false, + unsafe_methods: false, + unsafe_proto : false, + unsafe_regexp : false, + unsafe_undefined: false, + unused : !false_by_default, + warnings : false // legacy + }, true); + var global_defs = this.options["global_defs"]; + if (typeof global_defs == "object") for (var key in global_defs) { + if (key[0] === "@" && HOP(global_defs, key)) { + global_defs[key.slice(1)] = parse(global_defs[key], { + expression: true + }); + } + } + if (this.options["inline"] === true) this.options["inline"] = 3; + var pure_funcs = this.options["pure_funcs"]; + if (typeof pure_funcs == "function") { + this.pure_funcs = pure_funcs; + } else { + this.pure_funcs = pure_funcs ? function(node) { + return !pure_funcs.includes(node.expression.print_to_string()); + } : return_true; + } + var top_retain = this.options["top_retain"]; + if (top_retain instanceof RegExp) { + this.top_retain = function(def) { + return top_retain.test(def.name); + }; + } else if (typeof top_retain == "function") { + this.top_retain = top_retain; + } else if (top_retain) { + if (typeof top_retain == "string") { + top_retain = top_retain.split(/,/); + } + this.top_retain = function(def) { + return top_retain.includes(def.name); + }; + } + if (this.options["module"]) { + this.directives["use strict"] = true; + this.options["toplevel"] = true; + } + var toplevel = this.options["toplevel"]; + this.toplevel = typeof toplevel == "string" ? { + funcs: /funcs/.test(toplevel), + vars: /vars/.test(toplevel) + } : { + funcs: toplevel, + vars: toplevel + }; + var sequences = this.options["sequences"]; + this.sequences_limit = sequences == 1 ? 800 : sequences | 0; + this.evaluated_regexps = new Map(); + this._toplevel = undefined; + this._mangle_options = mangle_options + ? format_mangler_options(mangle_options) + : mangle_options; + } + + mangle_options() { + var nth_identifier = this._mangle_options && this._mangle_options.nth_identifier || base54; + var module = this._mangle_options && this._mangle_options.module || this.option("module"); + return { ie8: this.option("ie8"), nth_identifier, module }; + } + + option(key) { + return this.options[key]; + } + + exposed(def) { + if (def.export) return true; + if (def.global) for (var i = 0, len = def.orig.length; i < len; i++) + if (!this.toplevel[def.orig[i] instanceof AST_SymbolDefun ? "funcs" : "vars"]) + return true; + return false; + } + + in_boolean_context() { + if (!this.option("booleans")) return false; + var self = this.self(); + for (var i = 0, p; p = this.parent(i); i++) { + if (p instanceof AST_SimpleStatement + || p instanceof AST_Conditional && p.condition === self + || p instanceof AST_DWLoop && p.condition === self + || p instanceof AST_For && p.condition === self + || p instanceof AST_If && p.condition === self + || p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self) { + return true; + } + if ( + p instanceof AST_Binary + && ( + p.operator == "&&" + || p.operator == "||" + || p.operator == "??" + ) + || p instanceof AST_Conditional + || p.tail_node() === self + ) { + self = p; + } else { + return false; + } + } + } + + in_32_bit_context(other_operand_must_be_number) { + if (!this.option("evaluate")) return false; + var self = this.self(); + for (var i = 0, p; p = this.parent(i); i++) { + if (p instanceof AST_Binary && bitwise_binop.has(p.operator)) { + if (other_operand_must_be_number) { + return (self === p.left ? p.right : p.left).is_number(this); + } else { + return true; + } + } + if (p instanceof AST_UnaryPrefix) { + return p.operator === "~"; + } + if ( + p instanceof AST_Binary + && ( + p.operator == "&&" + || p.operator == "||" + || p.operator == "??" + ) + || p instanceof AST_Conditional && p.condition !== self + || p.tail_node() === self + ) { + self = p; + } else { + return false; + } + } + } + + in_computed_key() { + if (!this.option("evaluate")) return false; + var self = this.self(); + for (var i = 0, p; p = this.parent(i); i++) { + if (p instanceof AST_ObjectProperty && p.key === self) { + return true; + } + } + return false; + } + + get_toplevel() { + return this._toplevel; + } + + compress(toplevel) { + toplevel = toplevel.resolve_defines(this); + this._toplevel = toplevel; + if (this.option("expression")) { + this._toplevel.process_expression(true); + } + var passes = +this.options.passes || 1; + var min_count = 1 / 0; + var stopping = false; + var mangle = this.mangle_options(); + for (var pass = 0; pass < passes; pass++) { + this._toplevel.figure_out_scope(mangle); + if (pass === 0 && this.option("drop_console")) { + // must be run before reduce_vars and compress pass + this._toplevel = this._toplevel.drop_console(this.option("drop_console")); + } + if (pass > 0 || this.option("reduce_vars")) { + this._toplevel.reset_opt_flags(this); + } + this._toplevel = this._toplevel.transform(this); + if (passes > 1) { + let count = 0; + walk(this._toplevel, () => { count++; }); + if (count < min_count) { + min_count = count; + stopping = false; + } else if (stopping) { + break; + } else { + stopping = true; + } + } + } + if (this.option("expression")) { + this._toplevel.process_expression(false); + } + toplevel = this._toplevel; + this._toplevel = undefined; + return toplevel; + } + + before(node, descend) { + if (has_flag(node, SQUEEZED)) return node; + var was_scope = false; + if (node instanceof AST_Scope) { + node = node.hoist_properties(this); + node = node.hoist_declarations(this); + was_scope = true; + } + // Before https://github.com/mishoo/UglifyJS2/pull/1602 AST_Node.optimize() + // would call AST_Node.transform() if a different instance of AST_Node is + // produced after def_optimize(). + // This corrupts TreeWalker.stack, which cause AST look-ups to malfunction. + // Migrate and defer all children's AST_Node.transform() to below, which + // will now happen after this parent AST_Node has been properly substituted + // thus gives a consistent AST snapshot. + descend(node, this); + // Existing code relies on how AST_Node.optimize() worked, and omitting the + // following replacement call would result in degraded efficiency of both + // output and performance. + descend(node, this); + var opt = node.optimize(this); + if (was_scope && opt instanceof AST_Scope) { + opt.drop_unused(this); + descend(opt, this); + } + if (opt === node) set_flag(opt, SQUEEZED); + return opt; + } + + /** Alternative to plain is_lhs() which doesn't work within .optimize() */ + is_lhs() { + const self = this.stack[this.stack.length - 1]; + const parent = this.stack[this.stack.length - 2]; + return is_lhs(self, parent); + } +} + + +function def_optimize(node, optimizer) { + node.DEFMETHOD("optimize", function(compressor) { + var self = this; + if (has_flag(self, OPTIMIZED)) return self; + if (compressor.has_directive("use asm")) return self; + var opt = optimizer(self, compressor); + set_flag(opt, OPTIMIZED); + return opt; + }); +} + +def_optimize(AST_Node, function(self) { + return self; +}); + +AST_Toplevel.DEFMETHOD("drop_console", function(options) { + const isArray = Array.isArray(options); + const tt = new TreeTransformer(function(self) { + if (self.TYPE !== "Call") { + return; + } + + var exp = self.expression; + + if (!(exp instanceof AST_PropAccess)) { + return; + } + + var name = exp.expression; + var property = exp.property; + var depth = 2; + while (name.expression) { + property = name.property; + name = name.expression; + depth++; + } + + if (isArray && !options.includes(property)) { + return; + } + + if (is_undeclared_ref(name) && name.name == "console") { + if ( + depth === 3 + && !["call", "apply"].includes(exp.property) + && is_used_in_expression(tt) + ) { + // a (used) call to Function.prototype methods (eg: console.log.bind(console)) + // but not .call and .apply which would also return undefined. + exp.expression = make_empty_function(self); + set_flag(exp.expression, SQUEEZED); + self.args = []; + } else { + return make_node(AST_Undefined, self); + } + } + }); + + return this.transform(tt); +}); + +AST_Node.DEFMETHOD("equivalent_to", function(node) { + return equivalent_to(this, node); +}); + +AST_Scope.DEFMETHOD("process_expression", function(insert, compressor) { + var self = this; + var tt = new TreeTransformer(function(node) { + if (insert && node instanceof AST_SimpleStatement) { + return make_node(AST_Return, node, { + value: node.body + }); + } + if (!insert && node instanceof AST_Return) { + if (compressor) { + var value = node.value && node.value.drop_side_effect_free(compressor, true); + return value + ? make_node(AST_SimpleStatement, node, { body: value }) + : make_node(AST_EmptyStatement, node); + } + return make_node(AST_SimpleStatement, node, { + body: node.value || make_node(AST_UnaryPrefix, node, { + operator: "void", + expression: make_node(AST_Number, node, { + value: 0 + }) + }) + }); + } + if (node instanceof AST_Class || node instanceof AST_Lambda && node !== self) { + return node; + } + if (node instanceof AST_Block) { + var index = node.body.length - 1; + if (index >= 0) { + node.body[index] = node.body[index].transform(tt); + } + } else if (node instanceof AST_If) { + node.body = node.body.transform(tt); + if (node.alternative) { + node.alternative = node.alternative.transform(tt); + } + } else if (node instanceof AST_With) { + node.body = node.body.transform(tt); + } + return node; + }); + self.transform(tt); +}); + +AST_Toplevel.DEFMETHOD("reset_opt_flags", function(compressor) { + const self = this; + const reduce_vars = compressor.option("reduce_vars"); + + const preparation = new TreeWalker(function(node, descend) { + clear_flag(node, CLEAR_BETWEEN_PASSES); + if (reduce_vars) { + if (compressor.top_retain + && node instanceof AST_Defun // Only functions are retained + && preparation.parent() === self + ) { + set_flag(node, TOP); + } + return node.reduce_vars(preparation, descend, compressor); + } + }); + // Stack of look-up tables to keep track of whether a `SymbolDef` has been + // properly assigned before use: + // - `push()` & `pop()` when visiting conditional branches + preparation.safe_ids = Object.create(null); + preparation.in_loop = null; + preparation.loop_ids = new Map(); + preparation.defs_to_safe_ids = new Map(); + self.walk(preparation); +}); + +AST_Symbol.DEFMETHOD("fixed_value", function() { + var fixed = this.thedef.fixed; + if (!fixed || fixed instanceof AST_Node) return fixed; + return fixed(); +}); + +AST_SymbolRef.DEFMETHOD("is_immutable", function() { + var orig = this.definition().orig; + return orig.length == 1 && orig[0] instanceof AST_SymbolLambda; +}); + +function find_variable(compressor, name) { + var scope, i = 0; + while (scope = compressor.parent(i++)) { + if (scope instanceof AST_Scope) break; + if (scope instanceof AST_Catch && scope.argname) { + scope = scope.argname.definition().scope; + break; + } + } + return scope.find_variable(name); +} + +var global_names = makePredicate("Array Boolean clearInterval clearTimeout console Date decodeURI decodeURIComponent encodeURI encodeURIComponent Error escape eval EvalError Function isFinite isNaN JSON Math Number parseFloat parseInt RangeError ReferenceError RegExp Object setInterval setTimeout String SyntaxError TypeError unescape URIError"); +AST_SymbolRef.DEFMETHOD("is_declared", function(compressor) { + return !this.definition().undeclared + || compressor.option("unsafe") && global_names.has(this.name); +}); + +/* -----[ optimizers ]----- */ + +var directives = new Set(["use asm", "use strict"]); +def_optimize(AST_Directive, function(self, compressor) { + if (compressor.option("directives") + && (!directives.has(self.value) || compressor.has_directive(self.value) !== self)) { + return make_node(AST_EmptyStatement, self); + } + return self; +}); + +def_optimize(AST_Debugger, function(self, compressor) { + if (compressor.option("drop_debugger")) + return make_node(AST_EmptyStatement, self); + return self; +}); + +def_optimize(AST_LabeledStatement, function(self, compressor) { + if (self.body instanceof AST_Break + && compressor.loopcontrol_target(self.body) === self.body) { + return make_node(AST_EmptyStatement, self); + } + return self.label.references.length == 0 ? self.body : self; +}); + +def_optimize(AST_Block, function(self, compressor) { + tighten_body(self.body, compressor); + return self; +}); + +function can_be_extracted_from_if_block(node) { + return !( + node instanceof AST_Const + || node instanceof AST_Let + || node instanceof AST_Using + || node instanceof AST_Class + ); +} + +def_optimize(AST_BlockStatement, function(self, compressor) { + tighten_body(self.body, compressor); + switch (self.body.length) { + case 1: + if (!compressor.has_directive("use strict") + && compressor.parent() instanceof AST_If + && can_be_extracted_from_if_block(self.body[0]) + || can_be_evicted_from_block(self.body[0])) { + return self.body[0]; + } + break; + case 0: return make_node(AST_EmptyStatement, self); + } + return self; +}); + +function opt_AST_Lambda(self, compressor) { + tighten_body(self.body, compressor); + if (compressor.option("side_effects") + && self.body.length == 1 + && self.body[0] === compressor.has_directive("use strict")) { + self.body.length = 0; + } + return self; +} +def_optimize(AST_Lambda, opt_AST_Lambda); + +AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) { + var self = this; + if (compressor.has_directive("use asm")) return self; + + var hoist_funs = compressor.option("hoist_funs"); + var hoist_vars = compressor.option("hoist_vars"); + + if (hoist_funs || hoist_vars) { + var dirs = []; + var hoisted = []; + var vars = new Map(), vars_found = 0, var_decl = 0; + // let's count var_decl first, we seem to waste a lot of + // space if we hoist `var` when there's only one. + walk(self, node => { + if (node instanceof AST_Scope && node !== self) + return true; + if (node instanceof AST_Var) { + ++var_decl; + return true; + } + }); + hoist_vars = hoist_vars && var_decl > 1; + var tt = new TreeTransformer( + function before(node) { + if (node !== self) { + if (node instanceof AST_Directive) { + dirs.push(node); + return make_node(AST_EmptyStatement, node); + } + if (hoist_funs && node instanceof AST_Defun + && !(tt.parent() instanceof AST_Export) + && tt.parent() === self) { + hoisted.push(node); + return make_node(AST_EmptyStatement, node); + } + if ( + hoist_vars + && node instanceof AST_Var + && !node.definitions.some(def => def.name instanceof AST_Destructuring) + ) { + node.definitions.forEach(function(def) { + vars.set(def.name.name, def); + ++vars_found; + }); + var seq = node.to_assignments(compressor); + var p = tt.parent(); + if (p instanceof AST_ForIn && p.init === node) { + if (seq == null) { + var def = node.definitions[0].name; + return make_node(AST_SymbolRef, def, def); + } + return seq; + } + if (p instanceof AST_For && p.init === node) { + return seq; + } + if (!seq) return make_node(AST_EmptyStatement, node); + return make_node(AST_SimpleStatement, node, { + body: seq + }); + } + if (node instanceof AST_Scope) + return node; // to avoid descending in nested scopes + } + } + ); + self = self.transform(tt); + if (vars_found > 0) { + // collect only vars which don't show up in self's arguments list + var defs = []; + const is_lambda = self instanceof AST_Lambda; + const args_as_names = is_lambda ? self.args_as_names() : null; + vars.forEach((def, name) => { + if (is_lambda && args_as_names.some((x) => x.name === def.name.name)) { + vars.delete(name); + } else { + def = def.clone(); + def.value = null; + defs.push(def); + vars.set(name, def); + } + }); + if (defs.length > 0) { + // try to merge in assignments + for (var i = 0; i < self.body.length;) { + if (self.body[i] instanceof AST_SimpleStatement) { + var expr = self.body[i].body, sym, assign; + if (expr instanceof AST_Assign + && expr.operator == "=" + && (sym = expr.left) instanceof AST_Symbol + && vars.has(sym.name) + ) { + var def = vars.get(sym.name); + if (def.value) break; + def.value = expr.right; + remove(defs, def); + defs.push(def); + self.body.splice(i, 1); + continue; + } + if (expr instanceof AST_Sequence + && (assign = expr.expressions[0]) instanceof AST_Assign + && assign.operator == "=" + && (sym = assign.left) instanceof AST_Symbol + && vars.has(sym.name) + ) { + var def = vars.get(sym.name); + if (def.value) break; + def.value = assign.right; + remove(defs, def); + defs.push(def); + self.body[i].body = make_sequence(expr, expr.expressions.slice(1)); + continue; + } + } + if (self.body[i] instanceof AST_EmptyStatement) { + self.body.splice(i, 1); + continue; + } + if (self.body[i] instanceof AST_BlockStatement) { + self.body.splice(i, 1, ...self.body[i].body); + continue; + } + break; + } + defs = make_node(AST_Var, self, { + definitions: defs + }); + hoisted.push(defs); + } + } + self.body = dirs.concat(hoisted, self.body); + } + return self; +}); + +AST_Scope.DEFMETHOD("hoist_properties", function(compressor) { + var self = this; + if (!compressor.option("hoist_props") || compressor.has_directive("use asm")) return self; + var top_retain = self instanceof AST_Toplevel && compressor.top_retain || return_false; + var defs_by_id = new Map(); + var hoister = new TreeTransformer(function(node, descend) { + if (node instanceof AST_VarDef) { + const sym = node.name; + let def; + let value; + if (sym.scope === self + && !(sym instanceof AST_SymbolUsing) + && (def = sym.definition()).escaped != 1 + && !def.assignments + && !def.direct_access + && !def.single_use + && !compressor.exposed(def) + && !top_retain(def) + && (value = sym.fixed_value()) === node.value + && value instanceof AST_Object + && !value.properties.some(prop => + prop instanceof AST_Expansion || prop.computed_key() + ) + ) { + descend(node, this); + const defs = new Map(); + const assignments = []; + value.properties.forEach(({ key, value }) => { + const scope = hoister.find_scope(); + const symbol = self.create_symbol(sym.CTOR, { + source: sym, + scope, + conflict_scopes: new Set([ + scope, + ...sym.definition().references.map(ref => ref.scope) + ]), + tentative_name: sym.name + "_" + key + }); + + defs.set(String(key), symbol.definition()); + + assignments.push(make_node(AST_VarDef, node, { + name: symbol, + value + })); + }); + defs_by_id.set(def.id, defs); + return MAP.splice(assignments); + } + } else if (node instanceof AST_PropAccess + && node.expression instanceof AST_SymbolRef + ) { + const defs = defs_by_id.get(node.expression.definition().id); + if (defs) { + const def = defs.get(String(get_simple_key(node.property))); + const sym = make_node(AST_SymbolRef, node, { + name: def.name, + scope: node.expression.scope, + thedef: def + }); + sym.reference({}); + return sym; + } + } + }); + return self.transform(hoister); +}); + +def_optimize(AST_SimpleStatement, function(self, compressor) { + if (compressor.option("side_effects")) { + var body = self.body; + var node = body.drop_side_effect_free(compressor, true); + if (!node) { + return make_node(AST_EmptyStatement, self); + } + if (node !== body) { + return make_node(AST_SimpleStatement, self, { body: node }); + } + } + return self; +}); + +def_optimize(AST_While, function(self, compressor) { + return compressor.option("loops") ? make_node(AST_For, self, self).optimize(compressor) : self; +}); + +def_optimize(AST_Do, function(self, compressor) { + if (!compressor.option("loops")) return self; + var cond = self.condition.tail_node().evaluate(compressor); + if (!(cond instanceof AST_Node)) { + if (cond) return make_node(AST_For, self, { + body: make_node(AST_BlockStatement, self.body, { + body: [ + self.body, + make_node(AST_SimpleStatement, self.condition, { + body: self.condition + }) + ] + }) + }).optimize(compressor); + if (!has_break_or_continue(self, compressor.parent())) { + return make_node(AST_BlockStatement, self.body, { + body: [ + self.body, + make_node(AST_SimpleStatement, self.condition, { + body: self.condition + }) + ] + }).optimize(compressor); + } + } + return self; +}); + +function if_break_in_loop(self, compressor) { + var first = self.body instanceof AST_BlockStatement ? self.body.body[0] : self.body; + if (compressor.option("dead_code") && is_break(first)) { + var body = []; + if (self.init instanceof AST_Statement) { + body.push(self.init); + } else if (self.init) { + body.push(make_node(AST_SimpleStatement, self.init, { + body: self.init + })); + } + if (self.condition) { + body.push(make_node(AST_SimpleStatement, self.condition, { + body: self.condition + })); + } + trim_unreachable_code(compressor, self.body, body); + return make_node(AST_BlockStatement, self, { + body: body + }); + } + if (first instanceof AST_If) { + if (is_break(first.body)) { + if (self.condition) { + self.condition = make_node(AST_Binary, self.condition, { + left: self.condition, + operator: "&&", + right: first.condition.negate(compressor), + }); + } else { + self.condition = first.condition.negate(compressor); + } + drop_it(first.alternative); + } else if (is_break(first.alternative)) { + if (self.condition) { + self.condition = make_node(AST_Binary, self.condition, { + left: self.condition, + operator: "&&", + right: first.condition, + }); + } else { + self.condition = first.condition; + } + drop_it(first.body); + } + } + return self; + + function is_break(node) { + return node instanceof AST_Break + && compressor.loopcontrol_target(node) === compressor.self(); + } + + function drop_it(rest) { + rest = as_statement_array(rest); + if (self.body instanceof AST_BlockStatement) { + self.body = self.body.clone(); + self.body.body = rest.concat(self.body.body.slice(1)); + self.body = self.body.transform(compressor); + } else { + self.body = make_node(AST_BlockStatement, self.body, { + body: rest + }).transform(compressor); + } + self = if_break_in_loop(self, compressor); + } +} + +def_optimize(AST_For, function(self, compressor) { + if (!compressor.option("loops")) return self; + if (compressor.option("side_effects") && self.init) { + self.init = self.init.drop_side_effect_free(compressor); + } + if (self.condition) { + var cond = self.condition.evaluate(compressor); + if (!(cond instanceof AST_Node)) { + if (cond) self.condition = null; + else if (!compressor.option("dead_code")) { + var orig = self.condition; + self.condition = make_node_from_constant(cond, self.condition); + self.condition = best_of_expression(self.condition.transform(compressor), orig); + } + } + if (compressor.option("dead_code")) { + if (cond instanceof AST_Node) cond = self.condition.tail_node().evaluate(compressor); + if (!cond) { + var body = []; + trim_unreachable_code(compressor, self.body, body); + if (self.init instanceof AST_Statement) { + body.push(self.init); + } else if (self.init) { + body.push(make_node(AST_SimpleStatement, self.init, { + body: self.init + })); + } + body.push(make_node(AST_SimpleStatement, self.condition, { + body: self.condition + })); + return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); + } + } + } + return if_break_in_loop(self, compressor); +}); + +def_optimize(AST_If, function(self, compressor) { + if (is_empty(self.alternative)) self.alternative = null; + + if (!compressor.option("conditionals")) return self; + // if condition can be statically determined, drop + // one of the blocks. note, statically determined implies + // “has no side effects”; also it doesn't work for cases like + // `x && true`, though it probably should. + var cond = self.condition.evaluate(compressor); + if (!compressor.option("dead_code") && !(cond instanceof AST_Node)) { + var orig = self.condition; + self.condition = make_node_from_constant(cond, orig); + self.condition = best_of_expression(self.condition.transform(compressor), orig); + } + if (compressor.option("dead_code")) { + if (cond instanceof AST_Node) cond = self.condition.tail_node().evaluate(compressor); + if (!cond) { + var body = []; + trim_unreachable_code(compressor, self.body, body); + body.push(make_node(AST_SimpleStatement, self.condition, { + body: self.condition + })); + if (self.alternative) body.push(self.alternative); + return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); + } else if (!(cond instanceof AST_Node)) { + var body = []; + body.push(make_node(AST_SimpleStatement, self.condition, { + body: self.condition + })); + body.push(self.body); + if (self.alternative) { + trim_unreachable_code(compressor, self.alternative, body); + } + return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); + } + } + var negated = self.condition.negate(compressor); + var self_condition_length = self.condition.size(); + var negated_length = negated.size(); + var negated_is_best = negated_length < self_condition_length; + if (self.alternative && negated_is_best) { + negated_is_best = false; // because we already do the switch here. + // no need to swap values of self_condition_length and negated_length + // here because they are only used in an equality comparison later on. + self.condition = negated; + var tmp = self.body; + self.body = self.alternative || make_node(AST_EmptyStatement, self); + self.alternative = tmp; + } + if (is_empty(self.body) && is_empty(self.alternative)) { + return make_node(AST_SimpleStatement, self.condition, { + body: self.condition.clone() + }).optimize(compressor); + } + if (self.body instanceof AST_SimpleStatement + && self.alternative instanceof AST_SimpleStatement) { + return make_node(AST_SimpleStatement, self, { + body: make_node(AST_Conditional, self, { + condition : self.condition, + consequent : self.body.body, + alternative : self.alternative.body + }) + }).optimize(compressor); + } + if (is_empty(self.alternative) && self.body instanceof AST_SimpleStatement) { + if (self_condition_length === negated_length && !negated_is_best + && self.condition instanceof AST_Binary && self.condition.operator == "||") { + // although the code length of self.condition and negated are the same, + // negated does not require additional surrounding parentheses. + // see https://github.com/mishoo/UglifyJS2/issues/979 + negated_is_best = true; + } + if (negated_is_best) return make_node(AST_SimpleStatement, self, { + body: make_node(AST_Binary, self, { + operator : "||", + left : negated, + right : self.body.body + }) + }).optimize(compressor); + return make_node(AST_SimpleStatement, self, { + body: make_node(AST_Binary, self, { + operator : "&&", + left : self.condition, + right : self.body.body + }) + }).optimize(compressor); + } + if (self.body instanceof AST_EmptyStatement + && self.alternative instanceof AST_SimpleStatement) { + return make_node(AST_SimpleStatement, self, { + body: make_node(AST_Binary, self, { + operator : "||", + left : self.condition, + right : self.alternative.body + }) + }).optimize(compressor); + } + if (self.body instanceof AST_Exit + && self.alternative instanceof AST_Exit + && self.body.TYPE == self.alternative.TYPE) { + return make_node(self.body.CTOR, self, { + value: make_node(AST_Conditional, self, { + condition : self.condition, + consequent : self.body.value || make_node(AST_Undefined, self.body), + alternative : self.alternative.value || make_node(AST_Undefined, self.alternative) + }).transform(compressor) + }).optimize(compressor); + } + if (self.body instanceof AST_If + && !self.body.alternative + && !self.alternative) { + self = make_node(AST_If, self, { + condition: make_node(AST_Binary, self.condition, { + operator: "&&", + left: self.condition, + right: self.body.condition + }), + body: self.body.body, + alternative: null + }); + } + if (aborts(self.body)) { + if (self.alternative) { + var alt = self.alternative; + self.alternative = null; + return make_node(AST_BlockStatement, self, { + body: [ self, alt ] + }).optimize(compressor); + } + } + if (aborts(self.alternative)) { + var body = self.body; + self.body = self.alternative; + self.condition = negated_is_best ? negated : self.condition.negate(compressor); + self.alternative = null; + return make_node(AST_BlockStatement, self, { + body: [ self, body ] + }).optimize(compressor); + } + return self; +}); + +def_optimize(AST_Switch, function(self, compressor) { + if (!compressor.option("switches")) return self; + var branch; + var value = self.expression.evaluate(compressor); + if (!(value instanceof AST_Node)) { + var orig = self.expression; + self.expression = make_node_from_constant(value, orig); + self.expression = best_of_expression(self.expression.transform(compressor), orig); + } + if (!compressor.option("dead_code")) return self; + if (value instanceof AST_Node) { + value = self.expression.tail_node().evaluate(compressor); + } + var decl = []; + var body = []; + var default_branch; + var exact_match; + for (var i = 0, len = self.body.length; i < len && !exact_match; i++) { + branch = self.body[i]; + if (branch instanceof AST_Default) { + if (!default_branch) { + default_branch = branch; + } else { + eliminate_branch(branch, body[body.length - 1]); + } + } else if (!(value instanceof AST_Node)) { + var exp = branch.expression.evaluate(compressor); + if (!(exp instanceof AST_Node) && exp !== value) { + eliminate_branch(branch, body[body.length - 1]); + continue; + } + if (exp instanceof AST_Node && !exp.has_side_effects(compressor)) { + exp = branch.expression.tail_node().evaluate(compressor); + } + if (exp === value) { + exact_match = branch; + if (default_branch) { + var default_index = body.indexOf(default_branch); + body.splice(default_index, 1); + eliminate_branch(default_branch, body[default_index - 1]); + default_branch = null; + } + } + } + body.push(branch); + } + while (i < len) eliminate_branch(self.body[i++], body[body.length - 1]); + self.body = body; + + let default_or_exact = default_branch || exact_match; + default_branch = null; + exact_match = null; + + // group equivalent branches so they will be located next to each other, + // that way the next micro-optimization will merge them. + // ** bail micro-optimization if not a simple switch case with breaks + if (body.every((branch, i) => + (branch === default_or_exact || branch.expression instanceof AST_Constant) + && (branch.body.length === 0 || aborts(branch) || body.length - 1 === i)) + ) { + for (let i = 0; i < body.length; i++) { + const branch = body[i]; + for (let j = i + 1; j < body.length; j++) { + const next = body[j]; + if (next.body.length === 0) continue; + const last_branch = j === (body.length - 1); + const equivalentBranch = branches_equivalent(next, branch, false); + if (equivalentBranch || (last_branch && branches_equivalent(next, branch, true))) { + if (!equivalentBranch && last_branch) { + next.body.push(make_node(AST_Break)); + } + + // let's find previous siblings with inert fallthrough... + let x = j - 1; + let fallthroughDepth = 0; + while (x > i) { + if (is_inert_body(body[x--])) { + fallthroughDepth++; + } else { + break; + } + } + + const plucked = body.splice(j - fallthroughDepth, 1 + fallthroughDepth); + body.splice(i + 1, 0, ...plucked); + i += plucked.length; + } + } + } + } + + // merge equivalent branches in a row + for (let i = 0; i < body.length; i++) { + let branch = body[i]; + if (branch.body.length === 0) continue; + if (!aborts(branch)) continue; + + for (let j = i + 1; j < body.length; i++, j++) { + let next = body[j]; + if (next.body.length === 0) continue; + if ( + branches_equivalent(next, branch, false) + || (j === body.length - 1 && branches_equivalent(next, branch, true)) + ) { + branch.body = []; + branch = next; + continue; + } + break; + } + } + + // Prune any empty branches at the end of the switch statement. + { + let i = body.length - 1; + for (; i >= 0; i--) { + let bbody = body[i].body; + if (is_break(bbody[bbody.length - 1], compressor)) bbody.pop(); + if (!is_inert_body(body[i])) break; + } + // i now points to the index of a branch that contains a body. By incrementing, it's + // pointing to the first branch that's empty. + i++; + if (!default_or_exact || body.indexOf(default_or_exact) >= i) { + // The default behavior is to do nothing. We can take advantage of that to + // remove all case expressions that are side-effect free that also do + // nothing, since they'll default to doing nothing. But we can't remove any + // case expressions before one that would side-effect, since they may cause + // the side-effect to be skipped. + for (let j = body.length - 1; j >= i; j--) { + let branch = body[j]; + if (branch === default_or_exact) { + default_or_exact = null; + body.pop(); + } else if (!branch.expression.has_side_effects(compressor)) { + body.pop(); + } else { + break; + } + } + } + } + + + // Prune side-effect free branches that fall into default. + DEFAULT: if (default_or_exact) { + let default_index = body.indexOf(default_or_exact); + let default_body_index = default_index; + for (; default_body_index < body.length - 1; default_body_index++) { + if (!is_inert_body(body[default_body_index])) break; + } + if (default_body_index < body.length - 1) { + break DEFAULT; + } + + let side_effect_index = body.length - 1; + for (; side_effect_index >= 0; side_effect_index--) { + let branch = body[side_effect_index]; + if (branch === default_or_exact) continue; + if (branch.expression.has_side_effects(compressor)) break; + } + // If the default behavior comes after any side-effect case expressions, + // then we can fold all side-effect free cases into the default branch. + // If the side-effect case is after the default, then any side-effect + // free cases could prevent the side-effect from occurring. + if (default_body_index > side_effect_index) { + let prev_body_index = default_index - 1; + for (; prev_body_index >= 0; prev_body_index--) { + if (!is_inert_body(body[prev_body_index])) break; + } + let before = Math.max(side_effect_index, prev_body_index) + 1; + let after = default_index; + if (side_effect_index > default_index) { + // If the default falls into the same body as a side-effect + // case, then we need preserve that case and only prune the + // cases after it. + after = side_effect_index; + body[side_effect_index].body = body[default_body_index].body; + } else { + // The default will be the last branch. + default_or_exact.body = body[default_body_index].body; + } + + // Prune everything after the default (or last side-effect case) + // until the next case with a body. + body.splice(after + 1, default_body_index - after); + // Prune everything before the default that falls into it. + body.splice(before, default_index - before); + } + } + + // See if we can remove the switch entirely if all cases (the default) fall into the same case body. + DEFAULT: if (default_or_exact) { + let i = body.findIndex(branch => !is_inert_body(branch)); + let caseBody; + // `i` is equal to one of the following: + // - `-1`, there is no body in the switch statement. + // - `body.length - 1`, all cases fall into the same body. + // - anything else, there are multiple bodies in the switch. + if (i === body.length - 1) { + // All cases fall into the case body. + let branch = body[i]; + if (has_nested_break(self)) break DEFAULT; + + // This is the last case body, and we've already pruned any breaks, so it's + // safe to hoist. + caseBody = make_node(AST_BlockStatement, branch, { + body: branch.body + }); + branch.body = []; + } else if (i !== -1) { + // If there are multiple bodies, then we cannot optimize anything. + break DEFAULT; + } + + let sideEffect = body.find( + branch => branch !== default_or_exact && branch.expression.has_side_effects(compressor) + ); + // If no cases cause a side-effect, we can eliminate the switch entirely. + if (!sideEffect) { + return make_node(AST_BlockStatement, self, { + body: decl.concat( + statement(self.expression), + default_or_exact.expression ? statement(default_or_exact.expression) : [], + caseBody || [] + ) + }).optimize(compressor); + } + + // If we're this far, either there was no body or all cases fell into the same body. + // If there was no body, then we don't need a default branch (because the default is + // do nothing). If there was a body, we'll extract it to after the switch, so the + // switch's new default is to do nothing and we can still prune it. + const default_index = body.indexOf(default_or_exact); + body.splice(default_index, 1); + default_or_exact = null; + + if (caseBody) { + // Recurse into switch statement one more time so that we can append the case body + // outside of the switch. This recursion will only happen once since we've pruned + // the default case. + return make_node(AST_BlockStatement, self, { + body: decl.concat(self, caseBody) + }).optimize(compressor); + } + // If we fall here, there is a default branch somewhere, there are no case bodies, + // and there's a side-effect somewhere. Just let the below paths take care of it. + } + + if (body.length > 0) { + body[0].body = decl.concat(body[0].body); + } + + if (body.length == 0) { + return make_node(AST_BlockStatement, self, { + body: decl.concat(statement(self.expression)) + }).optimize(compressor); + } + if (body.length == 1 && !has_nested_break(self)) { + // This is the last case body, and we've already pruned any breaks, so it's + // safe to hoist. + let branch = body[0]; + return make_node(AST_If, self, { + condition: make_node(AST_Binary, self, { + operator: "===", + left: self.expression, + right: branch.expression, + }), + body: make_node(AST_BlockStatement, branch, { + body: branch.body + }), + alternative: null + }).optimize(compressor); + } + if (body.length === 2 && default_or_exact && !has_nested_break(self)) { + let branch = body[0] === default_or_exact ? body[1] : body[0]; + let exact_exp = default_or_exact.expression && statement(default_or_exact.expression); + if (aborts(body[0])) { + // Only the first branch body could have a break (at the last statement) + let first = body[0]; + if (is_break(first.body[first.body.length - 1], compressor)) { + first.body.pop(); + } + return make_node(AST_If, self, { + condition: make_node(AST_Binary, self, { + operator: "===", + left: self.expression, + right: branch.expression, + }), + body: make_node(AST_BlockStatement, branch, { + body: branch.body + }), + alternative: make_node(AST_BlockStatement, default_or_exact, { + body: [].concat( + exact_exp || [], + default_or_exact.body + ) + }) + }).optimize(compressor); + } + let operator = "==="; + let consequent = make_node(AST_BlockStatement, branch, { + body: branch.body, + }); + let always = make_node(AST_BlockStatement, default_or_exact, { + body: [].concat( + exact_exp || [], + default_or_exact.body + ) + }); + if (body[0] === default_or_exact) { + operator = "!=="; + let tmp = always; + always = consequent; + consequent = tmp; + } + return make_node(AST_BlockStatement, self, { + body: [ + make_node(AST_If, self, { + condition: make_node(AST_Binary, self, { + operator: operator, + left: self.expression, + right: branch.expression, + }), + body: consequent, + alternative: null, + }), + always, + ], + }).optimize(compressor); + } + return self; + + function eliminate_branch(branch, prev) { + if (prev && !aborts(prev)) { + prev.body = prev.body.concat(branch.body); + } else { + trim_unreachable_code(compressor, branch, decl); + } + } + function branches_equivalent(branch, prev, insertBreak) { + let bbody = branch.body; + let pbody = prev.body; + if (insertBreak) { + bbody = bbody.concat(make_node(AST_Break)); + } + if (bbody.length !== pbody.length) return false; + let bblock = make_node(AST_BlockStatement, branch, { body: bbody }); + let pblock = make_node(AST_BlockStatement, prev, { body: pbody }); + return bblock.equivalent_to(pblock); + } + function statement(body) { + return make_node(AST_SimpleStatement, body, { body }); + } + function has_nested_break(root) { + let has_break = false; + + let tw = new TreeWalker(node => { + if (has_break) return true; + if (node instanceof AST_Lambda) return true; + if (node instanceof AST_SimpleStatement) return true; + if (!is_break(node, tw)) return; + let parent = tw.parent(); + if ( + parent instanceof AST_SwitchBranch + && parent.body[parent.body.length - 1] === node + ) { + return; + } + has_break = true; + }); + root.walk(tw); + return has_break; + } + function is_break(node, stack) { + return node instanceof AST_Break + && stack.loopcontrol_target(node) === self; + } + function is_inert_body(branch) { + return !aborts(branch) && !make_node(AST_BlockStatement, branch, { + body: branch.body + }).has_side_effects(compressor); + } +}); + +def_optimize(AST_Try, function(self, compressor) { + if (self.bcatch && self.bfinally && self.bfinally.body.every(is_empty)) self.bfinally = null; + + if (compressor.option("dead_code") && self.body.body.every(is_empty)) { + var body = []; + if (self.bcatch) { + trim_unreachable_code(compressor, self.bcatch, body); + } + if (self.bfinally) body.push(...self.bfinally.body); + return make_node(AST_BlockStatement, self, { + body: body + }).optimize(compressor); + } + return self; +}); + +AST_Definitions.DEFMETHOD("to_assignments", function(compressor) { + var reduce_vars = compressor.option("reduce_vars"); + var assignments = []; + + for (const def of this.definitions) { + if (def.value) { + var name = make_node(AST_SymbolRef, def.name, def.name); + assignments.push(make_node(AST_Assign, def, { + operator : "=", + logical: false, + left : name, + right : def.value + })); + if (reduce_vars) name.definition().fixed = false; + } + const thedef = def.name.definition(); + thedef.eliminated++; + thedef.replaced--; + } + + if (assignments.length == 0) return null; + return make_sequence(this, assignments); +}); + +def_optimize(AST_Definitions, function(self) { + if (self.definitions.length == 0) { + return make_node(AST_EmptyStatement, self); + } + return self; +}); + +def_optimize(AST_VarDef, function(self, compressor) { + if ( + self.name instanceof AST_SymbolLet + && self.value != null + && is_undefined(self.value, compressor) + ) { + self.value = null; + } + return self; +}); + +def_optimize(AST_Import, function(self) { + return self; +}); + +def_optimize(AST_Call, function(self, compressor) { + var exp = self.expression; + var fn = exp; + inline_array_like_spread(self.args); + var simple_args = self.args.every((arg) => !(arg instanceof AST_Expansion)); + + if (compressor.option("reduce_vars") && fn instanceof AST_SymbolRef) { + fn = fn.fixed_value(); + } + + var is_func = fn instanceof AST_Lambda; + + if (is_func && fn.pinned()) return self; + + if (compressor.option("unused") + && simple_args + && is_func + && !fn.uses_arguments) { + var pos = 0, last = 0; + for (var i = 0, len = self.args.length; i < len; i++) { + if (fn.argnames[i] instanceof AST_Expansion) { + if (has_flag(fn.argnames[i].expression, UNUSED)) while (i < len) { + var node = self.args[i++].drop_side_effect_free(compressor); + if (node) { + self.args[pos++] = node; + } + } else while (i < len) { + self.args[pos++] = self.args[i++]; + } + last = pos; + break; + } + var trim = i >= fn.argnames.length; + if (trim || has_flag(fn.argnames[i], UNUSED)) { + var node = self.args[i].drop_side_effect_free(compressor); + if (node) { + self.args[pos++] = node; + } else if (!trim) { + self.args[pos++] = make_node(AST_Number, self.args[i], { + value: 0 + }); + continue; + } + } else { + self.args[pos++] = self.args[i]; + } + last = pos; + } + self.args.length = last; + } + + if ( + exp instanceof AST_Dot + && exp.expression instanceof AST_SymbolRef + && exp.expression.name === "console" + && exp.expression.definition().undeclared + && exp.property === "assert" + ) { + const condition = self.args[0]; + if (condition) { + const value = condition.evaluate(compressor); + + if (value === 1 || value === true) { + return make_node(AST_Undefined, self); + } + } + } + + if (compressor.option("unsafe") && !exp.contains_optional()) { + if (exp instanceof AST_Dot && exp.start.value === "Array" && exp.property === "from" && self.args.length === 1) { + const [argument] = self.args; + if (argument instanceof AST_Array) { + return make_node(AST_Array, argument, { + elements: argument.elements + }).optimize(compressor); + } + } + if (is_undeclared_ref(exp)) switch (exp.name) { + case "Array": + if (self.args.length != 1) { + return make_node(AST_Array, self, { + elements: self.args + }).optimize(compressor); + } else if (self.args[0] instanceof AST_Number && self.args[0].value <= 11) { + const elements = []; + for (let i = 0; i < self.args[0].value; i++) elements.push(new AST_Hole); + return new AST_Array({ elements }); + } + break; + case "Object": + if (self.args.length == 0) { + return make_node(AST_Object, self, { + properties: [] + }); + } + break; + case "String": + if (self.args.length == 0) return make_node(AST_String, self, { + value: "" + }); + if (self.args.length <= 1) return make_node(AST_Binary, self, { + left: self.args[0], + operator: "+", + right: make_node(AST_String, self, { value: "" }) + }).optimize(compressor); + break; + case "Number": + if (self.args.length == 0) return make_node(AST_Number, self, { + value: 0 + }); + if (self.args.length == 1 && compressor.option("unsafe_math")) { + return make_node(AST_UnaryPrefix, self, { + expression: self.args[0], + operator: "+" + }).optimize(compressor); + } + break; + case "Symbol": + if (self.args.length == 1 && self.args[0] instanceof AST_String && compressor.option("unsafe_symbols")) + self.args.length = 0; + break; + case "Boolean": + if (self.args.length == 0) return make_node(AST_False, self); + if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, { + expression: make_node(AST_UnaryPrefix, self, { + expression: self.args[0], + operator: "!" + }), + operator: "!" + }).optimize(compressor); + break; + case "RegExp": + var params = []; + if (self.args.length >= 1 + && self.args.length <= 2 + && self.args.every((arg) => { + var value = arg.evaluate(compressor); + params.push(value); + return arg !== value; + }) + && regexp_is_safe(params[0]) + ) { + let [ source, flags ] = params; + source = regexp_source_fix(new RegExp(source).source); + const rx = make_node(AST_RegExp, self, { + value: { source, flags } + }); + if (rx._eval(compressor) !== rx) { + return rx; + } + } + break; + } else if (exp instanceof AST_Dot) switch(exp.property) { + case "toString": + if (self.args.length == 0 && !exp.expression.may_throw_on_access(compressor)) { + return make_node(AST_Binary, self, { + left: make_node(AST_String, self, { value: "" }), + operator: "+", + right: exp.expression + }).optimize(compressor); + } + break; + case "join": + if (exp.expression instanceof AST_Array) EXIT: { + var separator; + if (self.args.length > 0) { + separator = self.args[0].evaluate(compressor); + if (separator === self.args[0]) break EXIT; // not a constant + } + var elements = []; + var consts = []; + for (var i = 0, len = exp.expression.elements.length; i < len; i++) { + var el = exp.expression.elements[i]; + if (el instanceof AST_Expansion) break EXIT; + var value = el.evaluate(compressor); + if (value !== el) { + consts.push(value); + } else { + if (consts.length > 0) { + elements.push(make_node(AST_String, self, { + value: consts.join(separator) + })); + consts.length = 0; + } + elements.push(el); + } + } + if (consts.length > 0) { + elements.push(make_node(AST_String, self, { + value: consts.join(separator) + })); + } + if (elements.length == 0) return make_node(AST_String, self, { value: "" }); + if (elements.length == 1) { + if (elements[0].is_string(compressor)) { + return elements[0]; + } + return make_node(AST_Binary, elements[0], { + operator : "+", + left : make_node(AST_String, self, { value: "" }), + right : elements[0] + }); + } + if (separator == "") { + var first; + if (elements[0].is_string(compressor) + || elements[1].is_string(compressor)) { + first = elements.shift(); + } else { + first = make_node(AST_String, self, { value: "" }); + } + return elements.reduce(function(prev, el) { + return make_node(AST_Binary, el, { + operator : "+", + left : prev, + right : el + }); + }, first).optimize(compressor); + } + // need this awkward cloning to not affect original element + // best_of will decide which one to get through. + var node = self.clone(); + node.expression = node.expression.clone(); + node.expression.expression = node.expression.expression.clone(); + node.expression.expression.elements = elements; + return best_of(compressor, self, node); + } + break; + case "charAt": + if (exp.expression.is_string(compressor)) { + var arg = self.args[0]; + var index = arg ? arg.evaluate(compressor) : 0; + if (index !== arg) { + return make_node(AST_Sub, exp, { + expression: exp.expression, + property: make_node_from_constant(index | 0, arg || exp) + }).optimize(compressor); + } + } + break; + case "apply": + if (self.args.length == 2 && self.args[1] instanceof AST_Array) { + var args = self.args[1].elements.slice(); + args.unshift(self.args[0]); + return make_node(AST_Call, self, { + expression: make_node(AST_Dot, exp, { + expression: exp.expression, + optional: false, + property: "call" + }), + args: args + }).optimize(compressor); + } + break; + case "call": + var func = exp.expression; + if (func instanceof AST_SymbolRef) { + func = func.fixed_value(); + } + if (func instanceof AST_Lambda && !func.contains_this()) { + return (self.args.length ? make_sequence(this, [ + self.args[0], + make_node(AST_Call, self, { + expression: exp.expression, + args: self.args.slice(1) + }) + ]) : make_node(AST_Call, self, { + expression: exp.expression, + args: [] + })).optimize(compressor); + } + break; + } + } + + if (compressor.option("unsafe_Function") + && is_undeclared_ref(exp) + && exp.name == "Function") { + // new Function() => function(){} + if (self.args.length == 0) return make_empty_function(self).optimize(compressor); + if (self.args.every((x) => x instanceof AST_String)) { + // quite a corner-case, but we can handle it: + // https://github.com/mishoo/UglifyJS2/issues/203 + // if the code argument is a constant, then we can minify it. + try { + var code = "n(function(" + self.args.slice(0, -1).map(function(arg) { + return arg.value; + }).join(",") + "){" + self.args[self.args.length - 1].value + "})"; + var ast = parse(code); + var mangle = compressor.mangle_options(); + ast.figure_out_scope(mangle); + var comp = new Compressor(compressor.options, { + mangle_options: compressor._mangle_options + }); + ast = ast.transform(comp); + ast.figure_out_scope(mangle); + ast.compute_char_frequency(mangle); + ast.mangle_names(mangle); + var fun; + walk(ast, node => { + if (is_func_expr(node)) { + fun = node; + return walk_abort; + } + }); + var code = OutputStream(); + AST_BlockStatement.prototype._codegen.call(fun, fun, code); + self.args = [ + make_node(AST_String, self, { + value: fun.argnames.map(function(arg) { + return arg.print_to_string(); + }).join(",") + }), + make_node(AST_String, self.args[self.args.length - 1], { + value: code.get().replace(/^{|}$/g, "") + }) + ]; + return self; + } catch (ex) { + if (!(ex instanceof JS_Parse_Error)) { + throw ex; + } + + // Otherwise, it crashes at runtime. Or maybe it's nonstandard syntax. + } + } + } + + return inline_into_call(self, compressor); +}); + +/** Does this node contain optional property access or optional call? */ +AST_Node.DEFMETHOD("contains_optional", function() { + if ( + this instanceof AST_PropAccess + || this instanceof AST_Call + || this instanceof AST_Chain + ) { + if (this.optional) { + return true; + } else { + return this.expression.contains_optional(); + } + } else { + return false; + } +}); + +def_optimize(AST_New, function(self, compressor) { + if ( + compressor.option("unsafe") && + is_undeclared_ref(self.expression) && + ["Object", "RegExp", "Function", "Error", "Array"].includes(self.expression.name) + ) return make_node(AST_Call, self, self).transform(compressor); + return self; +}); + +def_optimize(AST_Sequence, function(self, compressor) { + if (!compressor.option("side_effects")) return self; + var expressions = []; + filter_for_side_effects(); + var end = expressions.length - 1; + trim_right_for_undefined(); + if (end == 0) { + self = maintain_this_binding(compressor.parent(), compressor.self(), expressions[0]); + if (!(self instanceof AST_Sequence)) self = self.optimize(compressor); + return self; + } + self.expressions = expressions; + return self; + + function filter_for_side_effects() { + var first = first_in_statement(compressor); + var last = self.expressions.length - 1; + self.expressions.forEach(function(expr, index) { + if (index < last) expr = expr.drop_side_effect_free(compressor, first); + if (expr) { + merge_sequence(expressions, expr); + first = false; + } + }); + } + + function trim_right_for_undefined() { + while (end > 0 && is_undefined(expressions[end], compressor)) end--; + if (end < expressions.length - 1) { + expressions[end] = make_node(AST_UnaryPrefix, self, { + operator : "void", + expression : expressions[end] + }); + expressions.length = end + 1; + } + } +}); + +AST_Unary.DEFMETHOD("lift_sequences", function(compressor) { + if (compressor.option("sequences")) { + if (this.expression instanceof AST_Sequence) { + var x = this.expression.expressions.slice(); + var e = this.clone(); + e.expression = x.pop(); + x.push(e); + return make_sequence(this, x).optimize(compressor); + } + } + return this; +}); + +def_optimize(AST_UnaryPostfix, function(self, compressor) { + return self.lift_sequences(compressor); +}); + +def_optimize(AST_UnaryPrefix, function(self, compressor) { + var e = self.expression; + if ( + self.operator == "delete" && + !( + e instanceof AST_SymbolRef || + e instanceof AST_PropAccess || + e instanceof AST_Chain || + is_identifier_atom(e) + ) + ) { + return make_sequence(self, [e, make_node(AST_True, self)]).optimize(compressor); + } + var seq = self.lift_sequences(compressor); + if (seq !== self) { + return seq; + } + if (compressor.option("side_effects") && self.operator == "void") { + e = e.drop_side_effect_free(compressor); + if (e) { + self.expression = e; + return self; + } else { + return make_node(AST_Undefined, self).optimize(compressor); + } + } + if (compressor.in_boolean_context()) { + switch (self.operator) { + case "!": + if (e instanceof AST_UnaryPrefix && e.operator == "!") { + // !!foo ==> foo, if we're in boolean context + return e.expression; + } + if (e instanceof AST_Binary) { + self = best_of(compressor, self, e.negate(compressor, first_in_statement(compressor))); + } + break; + case "typeof": + // typeof always returns a non-empty string, thus it's + // always true in booleans + // And we don't need to check if it's undeclared, because in typeof, that's OK + return (e instanceof AST_SymbolRef ? make_node(AST_True, self) : make_sequence(self, [ + e, + make_node(AST_True, self) + ])).optimize(compressor); + } + } + if (self.operator == "-" && e instanceof AST_Infinity) { + e = e.transform(compressor); + } + if (e instanceof AST_Binary + && (self.operator == "+" || self.operator == "-") + && (e.operator == "*" || e.operator == "/" || e.operator == "%")) { + return make_node(AST_Binary, self, { + operator: e.operator, + left: make_node(AST_UnaryPrefix, e.left, { + operator: self.operator, + expression: e.left + }), + right: e.right + }); + } + + if (compressor.option("evaluate")) { + // ~~x => x (in 32-bit context) + // ~~{32 bit integer} => {32 bit integer} + if ( + self.operator === "~" + && self.expression instanceof AST_UnaryPrefix + && self.expression.operator === "~" + && (compressor.in_32_bit_context(false) || self.expression.expression.is_32_bit_integer(compressor)) + ) { + return self.expression.expression; + } + + // ~(x ^ y) => x ^ ~y + if ( + self.operator === "~" + && e instanceof AST_Binary + && e.operator === "^" + ) { + if (e.left instanceof AST_UnaryPrefix && e.left.operator === "~") { + // ~(~x ^ y) => x ^ y + e.left = e.left.bitwise_negate(compressor, true); + } else { + e.right = e.right.bitwise_negate(compressor, true); + } + return e; + } + } + + if ( + self.operator != "-" + // avoid infinite recursion of numerals + || !(e instanceof AST_Number || e instanceof AST_Infinity || e instanceof AST_BigInt) + ) { + var ev = self.evaluate(compressor); + if (ev !== self) { + ev = make_node_from_constant(ev, self).optimize(compressor); + return best_of(compressor, ev, self); + } + } + return self; +}); + +AST_Binary.DEFMETHOD("lift_sequences", function(compressor) { + if (compressor.option("sequences")) { + if (this.left instanceof AST_Sequence) { + var x = this.left.expressions.slice(); + var e = this.clone(); + e.left = x.pop(); + x.push(e); + return make_sequence(this, x).optimize(compressor); + } + if (this.right instanceof AST_Sequence && !this.left.has_side_effects(compressor)) { + var assign = this.operator == "=" && this.left instanceof AST_SymbolRef; + var x = this.right.expressions; + var last = x.length - 1; + for (var i = 0; i < last; i++) { + if (!assign && x[i].has_side_effects(compressor)) break; + } + if (i == last) { + x = x.slice(); + var e = this.clone(); + e.right = x.pop(); + x.push(e); + return make_sequence(this, x).optimize(compressor); + } else if (i > 0) { + var e = this.clone(); + e.right = make_sequence(this.right, x.slice(i)); + x = x.slice(0, i); + x.push(e); + return make_sequence(this, x).optimize(compressor); + } + } + } + return this; +}); + +var commutativeOperators = makePredicate("== === != !== * & | ^"); +function is_object(node) { + return node instanceof AST_Array + || node instanceof AST_Lambda + || node instanceof AST_Object + || node instanceof AST_Class; +} + +def_optimize(AST_Binary, function(self, compressor) { + function reversible() { + return self.left.is_constant() + || self.right.is_constant() + || !self.left.has_side_effects(compressor) + && !self.right.has_side_effects(compressor); + } + function reverse(op) { + if (reversible()) { + if (op) self.operator = op; + var tmp = self.left; + self.left = self.right; + self.right = tmp; + } + } + if (compressor.option("lhs_constants") && commutativeOperators.has(self.operator)) { + if (self.right.is_constant() + && !self.left.is_constant()) { + // if right is a constant, whatever side effects the + // left side might have could not influence the + // result. hence, force switch. + + if (!(self.left instanceof AST_Binary + && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) { + reverse(); + } + } + } + self = self.lift_sequences(compressor); + if (compressor.option("comparisons")) switch (self.operator) { + case "===": + case "!==": + var is_strict_comparison = true; + if ( + (self.left.is_string(compressor) && self.right.is_string(compressor)) || + (self.left.is_number(compressor) && self.right.is_number(compressor)) || + (self.left.is_bigint(compressor) && self.right.is_bigint(compressor)) || + (self.left.is_boolean() && self.right.is_boolean()) || + self.left.equivalent_to(self.right) + ) { + self.operator = self.operator.substr(0, 2); + } + + // XXX: intentionally falling down to the next case + case "==": + case "!=": + // void 0 == x => null == x + if (!is_strict_comparison && is_undefined(self.left, compressor)) { + self.left = make_node(AST_Null, self.left); + // x == void 0 => x == null + } else if (!is_strict_comparison && is_undefined(self.right, compressor)) { + self.right = make_node(AST_Null, self.right); + } else if (compressor.option("typeofs") + // "undefined" == typeof x => undefined === x + && self.left instanceof AST_String + && self.left.value == "undefined" + && self.right instanceof AST_UnaryPrefix + && self.right.operator == "typeof") { + var expr = self.right.expression; + if (expr instanceof AST_SymbolRef ? expr.is_declared(compressor) + : !(expr instanceof AST_PropAccess && compressor.option("ie8"))) { + self.right = expr; + self.left = make_node(AST_Undefined, self.left).optimize(compressor); + if (self.operator.length == 2) self.operator += "="; + } + } else if (compressor.option("typeofs") + // typeof x === "undefined" => x === undefined + && self.left instanceof AST_UnaryPrefix + && self.left.operator == "typeof" + && self.right instanceof AST_String + && self.right.value == "undefined") { + var expr = self.left.expression; + if (expr instanceof AST_SymbolRef ? expr.is_declared(compressor) + : !(expr instanceof AST_PropAccess && compressor.option("ie8"))) { + self.left = expr; + self.right = make_node(AST_Undefined, self.right).optimize(compressor); + if (self.operator.length == 2) self.operator += "="; + } + } else if (self.left instanceof AST_SymbolRef + // obj !== obj => false + && self.right instanceof AST_SymbolRef + && self.left.definition() === self.right.definition() + && is_object(self.left.fixed_value())) { + return make_node(self.operator[0] == "=" ? AST_True : AST_False, self); + } else if (self.left.is_32_bit_integer(compressor) && self.right.is_32_bit_integer(compressor)) { + const not = node => make_node(AST_UnaryPrefix, node, { + operator: "!", + expression: node + }); + const booleanify = (node, truthy) => { + if (truthy) { + return compressor.in_boolean_context() + ? node + : not(not(node)); + } else { + return not(node); + } + }; + + // The only falsy 32-bit integer is 0 + if (self.left instanceof AST_Number && self.left.value === 0) { + return booleanify(self.right, self.operator[0] === "!"); + } + if (self.right instanceof AST_Number && self.right.value === 0) { + return booleanify(self.left, self.operator[0] === "!"); + } + + // Mask all-bits check + // (x & 0xFF) != 0xFF => !(~x & 0xFF) + let and_op, x, mask; + if ( + (and_op = + self.left instanceof AST_Binary ? self.left + : self.right instanceof AST_Binary ? self.right : null) + && (mask = and_op === self.left ? self.right : self.left) + && and_op.operator === "&" + && mask instanceof AST_Number + && mask.is_32_bit_integer(compressor) + && (x = + and_op.left.equivalent_to(mask) ? and_op.right + : and_op.right.equivalent_to(mask) ? and_op.left : null) + ) { + let optimized = booleanify(make_node(AST_Binary, self, { + operator: "&", + left: mask, + right: make_node(AST_UnaryPrefix, self, { + operator: "~", + expression: x + }) + }), self.operator[0] === "!"); + + return best_of(compressor, optimized, self); + } + } + break; + case "&&": + case "||": + var lhs = self.left; + if (lhs.operator == self.operator) { + lhs = lhs.right; + } + if (lhs instanceof AST_Binary + && lhs.operator == (self.operator == "&&" ? "!==" : "===") + && self.right instanceof AST_Binary + && lhs.operator == self.right.operator + && (is_undefined(lhs.left, compressor) && self.right.left instanceof AST_Null + || lhs.left instanceof AST_Null && is_undefined(self.right.left, compressor)) + && !lhs.right.has_side_effects(compressor) + && lhs.right.equivalent_to(self.right.right)) { + var combined = make_node(AST_Binary, self, { + operator: lhs.operator.slice(0, -1), + left: make_node(AST_Null, self), + right: lhs.right + }); + if (lhs !== self.left) { + combined = make_node(AST_Binary, self, { + operator: self.operator, + left: self.left.left, + right: combined + }); + } + return combined; + } + break; + } + if (self.operator == "+" && compressor.in_boolean_context()) { + var ll = self.left.evaluate(compressor); + var rr = self.right.evaluate(compressor); + if (ll && typeof ll == "string") { + return make_sequence(self, [ + self.right, + make_node(AST_True, self) + ]).optimize(compressor); + } + if (rr && typeof rr == "string") { + return make_sequence(self, [ + self.left, + make_node(AST_True, self) + ]).optimize(compressor); + } + } + if (compressor.option("comparisons") && self.is_boolean()) { + if (!(compressor.parent() instanceof AST_Binary) + || compressor.parent() instanceof AST_Assign) { + var negated = make_node(AST_UnaryPrefix, self, { + operator: "!", + expression: self.negate(compressor, first_in_statement(compressor)) + }); + self = best_of(compressor, self, negated); + } + if (compressor.option("unsafe_comps")) { + switch (self.operator) { + case "<": reverse(">"); break; + case "<=": reverse(">="); break; + } + } + } + if (self.operator == "+") { + if (self.right instanceof AST_String + && self.right.getValue() == "" + && self.left.is_string(compressor)) { + return self.left; + } + if (self.left instanceof AST_String + && self.left.getValue() == "" + && self.right.is_string(compressor)) { + return self.right; + } + if (self.left instanceof AST_Binary + && self.left.operator == "+" + && self.left.left instanceof AST_String + && self.left.left.getValue() == "" + && self.right.is_string(compressor)) { + self.left = self.left.right; + return self; + } + } + if (compressor.option("evaluate")) { + switch (self.operator) { + case "&&": + var ll = has_flag(self.left, TRUTHY) + ? true + : has_flag(self.left, FALSY) + ? false + : self.left.evaluate(compressor); + if (!ll) { + return maintain_this_binding(compressor.parent(), compressor.self(), self.left).optimize(compressor); + } else if (!(ll instanceof AST_Node)) { + return make_sequence(self, [ self.left, self.right ]).optimize(compressor); + } + var rr = self.right.evaluate(compressor); + if (!rr) { + if (compressor.in_boolean_context()) { + return make_sequence(self, [ + self.left, + make_node(AST_False, self) + ]).optimize(compressor); + } else { + set_flag(self, FALSY); + } + } else if (!(rr instanceof AST_Node)) { + var parent = compressor.parent(); + if (parent.operator == "&&" && parent.left === compressor.self() || compressor.in_boolean_context()) { + return self.left.optimize(compressor); + } + } + // x || false && y ---> x ? y : false + if (self.left.operator == "||") { + var lr = self.left.right.evaluate(compressor); + if (!lr) return make_node(AST_Conditional, self, { + condition: self.left.left, + consequent: self.right, + alternative: self.left.right + }).optimize(compressor); + } + break; + case "||": + var ll = has_flag(self.left, TRUTHY) + ? true + : has_flag(self.left, FALSY) + ? false + : self.left.evaluate(compressor); + if (!ll) { + return make_sequence(self, [ self.left, self.right ]).optimize(compressor); + } else if (!(ll instanceof AST_Node)) { + return maintain_this_binding(compressor.parent(), compressor.self(), self.left).optimize(compressor); + } + var rr = self.right.evaluate(compressor); + if (!rr) { + var parent = compressor.parent(); + if (parent.operator == "||" && parent.left === compressor.self() || compressor.in_boolean_context()) { + return self.left.optimize(compressor); + } + } else if (!(rr instanceof AST_Node)) { + if (compressor.in_boolean_context()) { + return make_sequence(self, [ + self.left, + make_node(AST_True, self) + ]).optimize(compressor); + } else { + set_flag(self, TRUTHY); + } + } + if (self.left.operator == "&&") { + var lr = self.left.right.evaluate(compressor); + if (lr && !(lr instanceof AST_Node)) return make_node(AST_Conditional, self, { + condition: self.left.left, + consequent: self.left.right, + alternative: self.right + }).optimize(compressor); + } + break; + case "??": + if (is_nullish(self.left, compressor)) { + return self.right; + } + + var ll = self.left.evaluate(compressor); + if (!(ll instanceof AST_Node)) { + // if we know the value for sure we can simply compute right away. + return ll == null ? self.right : self.left; + } + + if (compressor.in_boolean_context()) { + const rr = self.right.evaluate(compressor); + if (!(rr instanceof AST_Node) && !rr) { + return self.left; + } + } + } + var associative = true; + switch (self.operator) { + case "+": + // (x + "foo") + "bar" => x + "foobar" + if (self.right instanceof AST_Constant + && self.left instanceof AST_Binary + && self.left.operator == "+" + && self.left.is_string(compressor)) { + var binary = make_node(AST_Binary, self, { + operator: "+", + left: self.left.right, + right: self.right, + }); + var r = binary.optimize(compressor); + if (binary !== r) { + self = make_node(AST_Binary, self, { + operator: "+", + left: self.left.left, + right: r + }); + } + } + // (x + "foo") + ("bar" + y) => (x + "foobar") + y + if (self.left instanceof AST_Binary + && self.left.operator == "+" + && self.left.is_string(compressor) + && self.right instanceof AST_Binary + && self.right.operator == "+" + && self.right.is_string(compressor)) { + var binary = make_node(AST_Binary, self, { + operator: "+", + left: self.left.right, + right: self.right.left, + }); + var m = binary.optimize(compressor); + if (binary !== m) { + self = make_node(AST_Binary, self, { + operator: "+", + left: make_node(AST_Binary, self.left, { + operator: "+", + left: self.left.left, + right: m + }), + right: self.right.right + }); + } + } + // a + -b => a - b + if (self.right instanceof AST_UnaryPrefix + && self.right.operator == "-" + && self.left.is_number_or_bigint(compressor)) { + self = make_node(AST_Binary, self, { + operator: "-", + left: self.left, + right: self.right.expression + }); + break; + } + // -a + b => b - a + if (self.left instanceof AST_UnaryPrefix + && self.left.operator == "-" + && reversible() + && self.right.is_number_or_bigint(compressor)) { + self = make_node(AST_Binary, self, { + operator: "-", + left: self.right, + right: self.left.expression + }); + break; + } + // `foo${bar}baz` + 1 => `foo${bar}baz1` + if (self.left instanceof AST_TemplateString) { + var l = self.left; + var r = self.right.evaluate(compressor); + if (r != self.right) { + l.segments[l.segments.length - 1].value += String(r); + return l; + } + } + // 1 + `foo${bar}baz` => `1foo${bar}baz` + if (self.right instanceof AST_TemplateString) { + var r = self.right; + var l = self.left.evaluate(compressor); + if (l != self.left) { + r.segments[0].value = String(l) + r.segments[0].value; + return r; + } + } + // `1${bar}2` + `foo${bar}baz` => `1${bar}2foo${bar}baz` + if (self.left instanceof AST_TemplateString + && self.right instanceof AST_TemplateString) { + var l = self.left; + var segments = l.segments; + var r = self.right; + segments[segments.length - 1].value += r.segments[0].value; + for (var i = 1; i < r.segments.length; i++) { + segments.push(r.segments[i]); + } + return l; + } + case "*": + associative = compressor.option("unsafe_math"); + case "&": + case "|": + case "^": + // a + +b => +b + a + if ( + self.left.is_number_or_bigint(compressor) + && self.right.is_number_or_bigint(compressor) + && reversible() + && !(self.left instanceof AST_Binary + && self.left.operator != self.operator + && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) { + var reversed = make_node(AST_Binary, self, { + operator: self.operator, + left: self.right, + right: self.left + }); + if (self.right instanceof AST_Constant + && !(self.left instanceof AST_Constant)) { + self = best_of(compressor, reversed, self); + } else { + self = best_of(compressor, self, reversed); + } + } + if (associative && self.is_number_or_bigint(compressor)) { + // a + (b + c) => (a + b) + c + if (self.right instanceof AST_Binary + && self.right.operator == self.operator) { + self = make_node(AST_Binary, self, { + operator: self.operator, + left: make_node(AST_Binary, self.left, { + operator: self.operator, + left: self.left, + right: self.right.left, + start: self.left.start, + end: self.right.left.end + }), + right: self.right.right + }); + } + // (n + 2) + 3 => 5 + n + // (2 * n) * 3 => 6 + n + if (self.right instanceof AST_Constant + && self.left instanceof AST_Binary + && self.left.operator == self.operator) { + if (self.left.left instanceof AST_Constant) { + self = make_node(AST_Binary, self, { + operator: self.operator, + left: make_node(AST_Binary, self.left, { + operator: self.operator, + left: self.left.left, + right: self.right, + start: self.left.left.start, + end: self.right.end + }), + right: self.left.right + }); + } else if (self.left.right instanceof AST_Constant) { + self = make_node(AST_Binary, self, { + operator: self.operator, + left: make_node(AST_Binary, self.left, { + operator: self.operator, + left: self.left.right, + right: self.right, + start: self.left.right.start, + end: self.right.end + }), + right: self.left.left + }); + } + } + // (a | 1) | (2 | d) => (3 | a) | b + if (self.left instanceof AST_Binary + && self.left.operator == self.operator + && self.left.right instanceof AST_Constant + && self.right instanceof AST_Binary + && self.right.operator == self.operator + && self.right.left instanceof AST_Constant) { + self = make_node(AST_Binary, self, { + operator: self.operator, + left: make_node(AST_Binary, self.left, { + operator: self.operator, + left: make_node(AST_Binary, self.left.left, { + operator: self.operator, + left: self.left.right, + right: self.right.left, + start: self.left.right.start, + end: self.right.left.end + }), + right: self.left.left + }), + right: self.right.right + }); + } + } + } + + // bitwise ops + if (bitwise_binop.has(self.operator)) { + // Use De Morgan's laws + // z & (X | y) + // => z & X (given y & z === 0) + // => z & X | {y & z} (given y & z !== 0) + let y, z, x_node, y_node, z_node = self.left; + if ( + self.operator === "&" + && self.right instanceof AST_Binary + && self.right.operator === "|" + && typeof (z = self.left.evaluate(compressor)) === "number" + ) { + if (typeof (y = self.right.right.evaluate(compressor)) === "number") { + // z & (X | y) + x_node = self.right.left; + y_node = self.right.right; + } else if (typeof (y = self.right.left.evaluate(compressor)) === "number") { + // z & (y | X) + x_node = self.right.right; + y_node = self.right.left; + } + + if (x_node && y_node) { + if ((y & z) === 0) { + self = make_node(AST_Binary, self, { + operator: self.operator, + left: z_node, + right: x_node + }); + } else { + const reordered_ops = make_node(AST_Binary, self, { + operator: "|", + left: make_node(AST_Binary, self, { + operator: "&", + left: x_node, + right: z_node + }), + right: make_node_from_constant(y & z, y_node), + }); + + self = best_of(compressor, self, reordered_ops); + } + } + } + + // x | x => 0 | x + // x & x => 0 | x + if ( + (self.operator === "|" || self.operator === "&") + && self.left.equivalent_to(self.right) + && !self.left.has_side_effects(compressor) + && compressor.in_32_bit_context(true) + ) { + self.left = make_node(AST_Number, self, { value: 0 }); + self.operator = "|"; + } + + // ~x ^ ~y => x ^ y + if ( + self.operator === "^" + && self.left instanceof AST_UnaryPrefix + && self.left.operator === "~" + && self.right instanceof AST_UnaryPrefix + && self.right.operator === "~" + ) { + self = make_node(AST_Binary, self, { + operator: "^", + left: self.left.expression, + right: self.right.expression + }); + } + + + // Shifts that do nothing + // {anything} >> 0 => {anything} | 0 + // {anything} << 0 => {anything} | 0 + if ( + (self.operator === "<<" || self.operator === ">>") + && self.right instanceof AST_Number && self.right.value === 0 + ) { + self.operator = "|"; + } + + // Find useless to-bitwise conversions + // {32 bit integer} | 0 => {32 bit integer} + // {32 bit integer} ^ 0 => {32 bit integer} + const zero_side = self.right instanceof AST_Number && self.right.value === 0 ? self.right + : self.left instanceof AST_Number && self.left.value === 0 ? self.left + : null; + const non_zero_side = zero_side && (zero_side === self.right ? self.left : self.right); + if ( + zero_side + && (self.operator === "|" || self.operator === "^") + && (non_zero_side.is_32_bit_integer(compressor) || compressor.in_32_bit_context(true)) + ) { + return non_zero_side; + } + + // {anything} & 0 => 0 + if ( + zero_side + && self.operator === "&" + && !non_zero_side.has_side_effects(compressor) + && non_zero_side.is_32_bit_integer(compressor) + ) { + return zero_side; + } + + // ~0 is all ones, as well as -1. + // We can ellide some operations with it. + const is_full_mask = (node) => + node instanceof AST_Number && node.value === -1 + || + node instanceof AST_UnaryPrefix + && node.operator === "-" + && node.expression instanceof AST_Number + && node.expression.value === 1; + + const full_mask = is_full_mask(self.right) ? self.right + : is_full_mask(self.left) ? self.left + : null; + const other_side = (full_mask === self.right ? self.left : self.right); + + // {32 bit integer} & -1 => {32 bit integer} + if ( + full_mask + && self.operator === "&" + && ( + other_side.is_32_bit_integer(compressor) + || compressor.in_32_bit_context(true) + ) + ) { + return other_side; + } + + // {anything} ^ -1 => ~{anything} + if ( + full_mask + && self.operator === "^" + && ( + other_side.is_32_bit_integer(compressor) + || compressor.in_32_bit_context(true) + ) + ) { + return other_side.bitwise_negate(compressor); + } + } + } + // x && (y && z) ==> x && y && z + // x || (y || z) ==> x || y || z + // x + ("y" + z) ==> x + "y" + z + // "x" + (y + "z")==> "x" + y + "z" + if (self.right instanceof AST_Binary + && self.right.operator == self.operator + && (lazy_op.has(self.operator) + || (self.operator == "+" + && (self.right.left.is_string(compressor) + || (self.left.is_string(compressor) + && self.right.right.is_string(compressor))))) + ) { + self.left = make_node(AST_Binary, self.left, { + operator : self.operator, + left : self.left.transform(compressor), + right : self.right.left.transform(compressor) + }); + self.right = self.right.right.transform(compressor); + return self.transform(compressor); + } + var ev = self.evaluate(compressor); + if (ev !== self) { + ev = make_node_from_constant(ev, self).optimize(compressor); + return best_of(compressor, ev, self); + } + return self; +}); + +def_optimize(AST_SymbolExport, function(self) { + return self; +}); + +def_optimize(AST_SymbolRef, function(self, compressor) { + if ( + !compressor.option("ie8") + && is_undeclared_ref(self) + && !compressor.find_parent(AST_With) + ) { + switch (self.name) { + case "undefined": + return make_node(AST_Undefined, self).optimize(compressor); + case "NaN": + return make_node(AST_NaN, self).optimize(compressor); + case "Infinity": + return make_node(AST_Infinity, self).optimize(compressor); + } + } + + if (compressor.option("reduce_vars") && !compressor.is_lhs()) { + return inline_into_symbolref(self, compressor); + } else { + return self; + } +}); + +function is_atomic(lhs, self) { + return lhs instanceof AST_SymbolRef || lhs.TYPE === self.TYPE; +} + +def_optimize(AST_Undefined, function(self, compressor) { + if (compressor.option("unsafe_undefined")) { + var undef = find_variable(compressor, "undefined"); + if (undef) { + var ref = make_node(AST_SymbolRef, self, { + name : "undefined", + scope : undef.scope, + thedef : undef + }); + set_flag(ref, UNDEFINED); + return ref; + } + } + var lhs = compressor.is_lhs(); + if (lhs && is_atomic(lhs, self)) return self; + return make_node(AST_UnaryPrefix, self, { + operator: "void", + expression: make_node(AST_Number, self, { + value: 0 + }) + }); +}); + +def_optimize(AST_Infinity, function(self, compressor) { + var lhs = compressor.is_lhs(); + if (lhs && is_atomic(lhs, self)) return self; + if ( + compressor.option("keep_infinity") + && !(lhs && !is_atomic(lhs, self)) + && !find_variable(compressor, "Infinity") + ) { + return self; + } + return make_node(AST_Binary, self, { + operator: "/", + left: make_node(AST_Number, self, { + value: 1 + }), + right: make_node(AST_Number, self, { + value: 0 + }) + }); +}); + +def_optimize(AST_NaN, function(self, compressor) { + var lhs = compressor.is_lhs(); + if (lhs && !is_atomic(lhs, self) + || find_variable(compressor, "NaN")) { + return make_node(AST_Binary, self, { + operator: "/", + left: make_node(AST_Number, self, { + value: 0 + }), + right: make_node(AST_Number, self, { + value: 0 + }) + }); + } + return self; +}); + +const ASSIGN_OPS = makePredicate("+ - / * % >> << >>> | ^ &"); +const ASSIGN_OPS_COMMUTATIVE = makePredicate("* | ^ &"); +def_optimize(AST_Assign, function(self, compressor) { + if (self.logical) { + return self.lift_sequences(compressor); + } + + var def; + // x = x ---> x + if ( + self.operator === "=" + && self.left instanceof AST_SymbolRef + && self.left.name !== "arguments" + && !(def = self.left.definition()).undeclared + && self.right.equivalent_to(self.left) + ) { + return self.right; + } + + if (compressor.option("dead_code") + && self.left instanceof AST_SymbolRef + && (def = self.left.definition()).scope === compressor.find_parent(AST_Lambda)) { + var level = 0, node, parent = self; + do { + node = parent; + parent = compressor.parent(level++); + if (parent instanceof AST_Exit) { + if (in_try(level, parent)) break; + if (is_reachable(def.scope, [ def ])) break; + if (self.operator == "=") return self.right; + def.fixed = false; + return make_node(AST_Binary, self, { + operator: self.operator.slice(0, -1), + left: self.left, + right: self.right + }).optimize(compressor); + } + } while (parent instanceof AST_Binary && parent.right === node + || parent instanceof AST_Sequence && parent.tail_node() === node); + } + self = self.lift_sequences(compressor); + + if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary) { + // x = expr1 OP expr2 + if (self.right.left instanceof AST_SymbolRef + && self.right.left.name == self.left.name + && ASSIGN_OPS.has(self.right.operator)) { + // x = x - 2 ---> x -= 2 + self.operator = self.right.operator + "="; + self.right = self.right.right; + } else if (self.right.right instanceof AST_SymbolRef + && self.right.right.name == self.left.name + && ASSIGN_OPS_COMMUTATIVE.has(self.right.operator) + && !self.right.left.has_side_effects(compressor)) { + // x = 2 & x ---> x &= 2 + self.operator = self.right.operator + "="; + self.right = self.right.left; + } + } + return self; + + function in_try(level, node) { + function may_assignment_throw() { + const right = self.right; + self.right = make_node(AST_Null, right); + const may_throw = node.may_throw(compressor); + self.right = right; + + return may_throw; + } + + var stop_at = self.left.definition().scope.get_defun_scope(); + var parent; + while ((parent = compressor.parent(level++)) !== stop_at) { + if (parent instanceof AST_Try) { + if (parent.bfinally) return true; + if (parent.bcatch && may_assignment_throw()) return true; + } + } + } +}); + +def_optimize(AST_DefaultAssign, function(self, compressor) { + if (!compressor.option("evaluate")) { + return self; + } + var evaluateRight = self.right.evaluate(compressor); + + // `[x = undefined] = foo` ---> `[x] = foo` + // `(arg = undefined) => ...` ---> `(arg) => ...` (unless `keep_fargs`) + // `((arg = undefined) => ...)()` ---> `((arg) => ...)()` + let lambda, iife; + if (evaluateRight === undefined) { + if ( + (lambda = compressor.parent()) instanceof AST_Lambda + ? ( + compressor.option("keep_fargs") === false + || (iife = compressor.parent(1)).TYPE === "Call" + && iife.expression === lambda + ) + : true + ) { + self = self.left; + } + } else if (evaluateRight !== self.right) { + evaluateRight = make_node_from_constant(evaluateRight, self.right); + self.right = best_of_expression(evaluateRight, self.right); + } + + return self; +}); + +function is_nullish_check(check, check_subject, compressor) { + if (check_subject.may_throw(compressor)) return false; + + let nullish_side; + + // foo == null + if ( + check instanceof AST_Binary + && check.operator === "==" + // which side is nullish? + && ( + (nullish_side = is_nullish(check.left, compressor) && check.left) + || (nullish_side = is_nullish(check.right, compressor) && check.right) + ) + // is the other side the same as the check_subject + && ( + nullish_side === check.left + ? check.right + : check.left + ).equivalent_to(check_subject) + ) { + return true; + } + + // foo === null || foo === undefined + if (check instanceof AST_Binary && check.operator === "||") { + let null_cmp; + let undefined_cmp; + + const find_comparison = cmp => { + if (!( + cmp instanceof AST_Binary + && (cmp.operator === "===" || cmp.operator === "==") + )) { + return false; + } + + let found = 0; + let defined_side; + + if (cmp.left instanceof AST_Null) { + found++; + null_cmp = cmp; + defined_side = cmp.right; + } + if (cmp.right instanceof AST_Null) { + found++; + null_cmp = cmp; + defined_side = cmp.left; + } + if (is_undefined(cmp.left, compressor)) { + found++; + undefined_cmp = cmp; + defined_side = cmp.right; + } + if (is_undefined(cmp.right, compressor)) { + found++; + undefined_cmp = cmp; + defined_side = cmp.left; + } + + if (found !== 1) { + return false; + } + + if (!defined_side.equivalent_to(check_subject)) { + return false; + } + + return true; + }; + + if (!find_comparison(check.left)) return false; + if (!find_comparison(check.right)) return false; + + if (null_cmp && undefined_cmp && null_cmp !== undefined_cmp) { + return true; + } + } + + return false; +} + +def_optimize(AST_Conditional, function(self, compressor) { + if (!compressor.option("conditionals")) return self; + // This looks like lift_sequences(), should probably be under "sequences" + if (self.condition instanceof AST_Sequence) { + var expressions = self.condition.expressions.slice(); + self.condition = expressions.pop(); + expressions.push(self); + return make_sequence(self, expressions); + } + var cond = self.condition.evaluate(compressor); + if (cond !== self.condition) { + if (cond) { + return maintain_this_binding(compressor.parent(), compressor.self(), self.consequent); + } else { + return maintain_this_binding(compressor.parent(), compressor.self(), self.alternative); + } + } + var negated = cond.negate(compressor, first_in_statement(compressor)); + if (best_of(compressor, cond, negated) === negated) { + self = make_node(AST_Conditional, self, { + condition: negated, + consequent: self.alternative, + alternative: self.consequent + }); + } + var condition = self.condition; + var consequent = self.consequent; + var alternative = self.alternative; + // x?x:y --> x||y + if (condition instanceof AST_SymbolRef + && consequent instanceof AST_SymbolRef + && condition.definition() === consequent.definition()) { + return make_node(AST_Binary, self, { + operator: "||", + left: condition, + right: alternative + }); + } + // if (foo) exp = something; else exp = something_else; + // | + // v + // exp = foo ? something : something_else; + if ( + consequent instanceof AST_Assign + && alternative instanceof AST_Assign + && consequent.operator === alternative.operator + && consequent.logical === alternative.logical + && consequent.left.equivalent_to(alternative.left) + && (!self.condition.has_side_effects(compressor) + || consequent.operator == "=" + && !consequent.left.has_side_effects(compressor)) + ) { + return make_node(AST_Assign, self, { + operator: consequent.operator, + left: consequent.left, + logical: consequent.logical, + right: make_node(AST_Conditional, self, { + condition: self.condition, + consequent: consequent.right, + alternative: alternative.right + }) + }); + } + // x ? y(a) : y(b) --> y(x ? a : b) + var arg_index; + if (consequent instanceof AST_Call + && alternative.TYPE === consequent.TYPE + && consequent.args.length > 0 + && consequent.args.length == alternative.args.length + && consequent.expression.equivalent_to(alternative.expression) + && !self.condition.has_side_effects(compressor) + && !consequent.expression.has_side_effects(compressor) + && typeof (arg_index = single_arg_diff()) == "number") { + var node = consequent.clone(); + node.args[arg_index] = make_node(AST_Conditional, self, { + condition: self.condition, + consequent: consequent.args[arg_index], + alternative: alternative.args[arg_index] + }); + return node; + } + // a ? b : c ? b : d --> (a || c) ? b : d + if (alternative instanceof AST_Conditional + && consequent.equivalent_to(alternative.consequent)) { + return make_node(AST_Conditional, self, { + condition: make_node(AST_Binary, self, { + operator: "||", + left: condition, + right: alternative.condition + }), + consequent: consequent, + alternative: alternative.alternative + }).optimize(compressor); + } + + // a == null ? b : a -> a ?? b + if ( + compressor.option("ecma") >= 2020 && + is_nullish_check(condition, alternative, compressor) + ) { + return make_node(AST_Binary, self, { + operator: "??", + left: alternative, + right: consequent + }).optimize(compressor); + } + + // a ? b : (c, b) --> (a || c), b + if (alternative instanceof AST_Sequence + && consequent.equivalent_to(alternative.expressions[alternative.expressions.length - 1])) { + return make_sequence(self, [ + make_node(AST_Binary, self, { + operator: "||", + left: condition, + right: make_sequence(self, alternative.expressions.slice(0, -1)) + }), + consequent + ]).optimize(compressor); + } + // a ? b : (c && b) --> (a || c) && b + if (alternative instanceof AST_Binary + && alternative.operator == "&&" + && consequent.equivalent_to(alternative.right)) { + return make_node(AST_Binary, self, { + operator: "&&", + left: make_node(AST_Binary, self, { + operator: "||", + left: condition, + right: alternative.left + }), + right: consequent + }).optimize(compressor); + } + // x?y?z:a:a --> x&&y?z:a + if (consequent instanceof AST_Conditional + && consequent.alternative.equivalent_to(alternative)) { + return make_node(AST_Conditional, self, { + condition: make_node(AST_Binary, self, { + left: self.condition, + operator: "&&", + right: consequent.condition + }), + consequent: consequent.consequent, + alternative: alternative + }); + } + // x ? y : y --> x, y + if (consequent.equivalent_to(alternative)) { + return make_sequence(self, [ + self.condition, + consequent + ]).optimize(compressor); + } + // x ? y || z : z --> x && y || z + if (consequent instanceof AST_Binary + && consequent.operator == "||" + && consequent.right.equivalent_to(alternative)) { + return make_node(AST_Binary, self, { + operator: "||", + left: make_node(AST_Binary, self, { + operator: "&&", + left: self.condition, + right: consequent.left + }), + right: alternative + }).optimize(compressor); + } + + const in_bool = compressor.in_boolean_context(); + if (is_true(self.consequent)) { + if (is_false(self.alternative)) { + // c ? true : false ---> !!c + return booleanize(self.condition); + } + // c ? true : x ---> !!c || x + return make_node(AST_Binary, self, { + operator: "||", + left: booleanize(self.condition), + right: self.alternative + }); + } + if (is_false(self.consequent)) { + if (is_true(self.alternative)) { + // c ? false : true ---> !c + return booleanize(self.condition.negate(compressor)); + } + // c ? false : x ---> !c && x + return make_node(AST_Binary, self, { + operator: "&&", + left: booleanize(self.condition.negate(compressor)), + right: self.alternative + }); + } + if (is_true(self.alternative)) { + // c ? x : true ---> !c || x + return make_node(AST_Binary, self, { + operator: "||", + left: booleanize(self.condition.negate(compressor)), + right: self.consequent + }); + } + if (is_false(self.alternative)) { + // c ? x : false ---> !!c && x + return make_node(AST_Binary, self, { + operator: "&&", + left: booleanize(self.condition), + right: self.consequent + }); + } + + return self; + + function booleanize(node) { + if (node.is_boolean()) return node; + // !!expression + return make_node(AST_UnaryPrefix, node, { + operator: "!", + expression: node.negate(compressor) + }); + } + + // AST_True or !0 + function is_true(node) { + return node instanceof AST_True + || in_bool + && node instanceof AST_Constant + && node.getValue() + || (node instanceof AST_UnaryPrefix + && node.operator == "!" + && node.expression instanceof AST_Constant + && !node.expression.getValue()); + } + // AST_False or !1 + function is_false(node) { + return node instanceof AST_False + || in_bool + && node instanceof AST_Constant + && !node.getValue() + || (node instanceof AST_UnaryPrefix + && node.operator == "!" + && node.expression instanceof AST_Constant + && node.expression.getValue()); + } + + function single_arg_diff() { + var a = consequent.args; + var b = alternative.args; + for (var i = 0, len = a.length; i < len; i++) { + if (a[i] instanceof AST_Expansion) return; + if (!a[i].equivalent_to(b[i])) { + if (b[i] instanceof AST_Expansion) return; + for (var j = i + 1; j < len; j++) { + if (a[j] instanceof AST_Expansion) return; + if (!a[j].equivalent_to(b[j])) return; + } + return i; + } + } + } +}); + +def_optimize(AST_Boolean, function(self, compressor) { + if (compressor.in_boolean_context()) return make_node(AST_Number, self, { + value: +self.value + }); + var p = compressor.parent(); + if (compressor.option("booleans_as_integers")) { + if (p instanceof AST_Binary && (p.operator == "===" || p.operator == "!==")) { + p.operator = p.operator.replace(/=$/, ""); + } + return make_node(AST_Number, self, { + value: +self.value + }); + } + if (compressor.option("booleans")) { + if (p instanceof AST_Binary && (p.operator == "==" + || p.operator == "!=")) { + return make_node(AST_Number, self, { + value: +self.value + }); + } + return make_node(AST_UnaryPrefix, self, { + operator: "!", + expression: make_node(AST_Number, self, { + value: 1 - self.value + }) + }); + } + return self; +}); + +function safe_to_flatten(value, compressor) { + if (value instanceof AST_SymbolRef) { + value = value.fixed_value(); + } + if (!value) return false; + if (!(value instanceof AST_Lambda || value instanceof AST_Class)) return true; + if (!(value instanceof AST_Lambda && value.contains_this())) return true; + return compressor.parent() instanceof AST_New; +} + +AST_PropAccess.DEFMETHOD("flatten_object", function(key, compressor) { + if (!compressor.option("properties")) return; + if (key === "__proto__") return; + if (this instanceof AST_DotHash) return; + + var arrows = compressor.option("unsafe_arrows") && compressor.option("ecma") >= 2015; + var expr = this.expression; + if (expr instanceof AST_Object) { + var props = expr.properties; + + for (var i = props.length; --i >= 0;) { + var prop = props[i]; + + if ("" + (prop instanceof AST_ConciseMethod ? prop.key.name : prop.key) == key) { + const all_props_flattenable = props.every((p) => + (p instanceof AST_ObjectKeyVal + || arrows && p instanceof AST_ConciseMethod && !p.value.is_generator + ) + && !p.computed_key() + ); + + if (!all_props_flattenable) return; + if (!safe_to_flatten(prop.value, compressor)) return; + + return make_node(AST_Sub, this, { + expression: make_node(AST_Array, expr, { + elements: props.map(function(prop) { + var v = prop.value; + if (v instanceof AST_Accessor) { + v = make_node(AST_Function, v, v); + } + + var k = prop.key; + if (k instanceof AST_Node && !(k instanceof AST_SymbolMethod)) { + return make_sequence(prop, [ k, v ]); + } + + return v; + }) + }), + property: make_node(AST_Number, this, { + value: i + }) + }); + } + } + } +}); + +def_optimize(AST_Sub, function(self, compressor) { + var expr = self.expression; + var prop = self.property; + if (compressor.option("properties")) { + var key = prop.evaluate(compressor); + if (key !== prop) { + if (typeof key == "string") { + if (key == "undefined") { + key = undefined; + } else { + var value = parseFloat(key); + if (value.toString() == key) { + key = value; + } + } + } + prop = self.property = best_of_expression( + prop, + make_node_from_constant(key, prop).transform(compressor) + ); + var property = "" + key; + if (is_basic_identifier_string(property) + && property.length <= prop.size() + 1) { + return make_node(AST_Dot, self, { + expression: expr, + optional: self.optional, + property: property, + quote: prop.quote, + }).optimize(compressor); + } + } + } + var fn; + OPT_ARGUMENTS: if (compressor.option("arguments") + && expr instanceof AST_SymbolRef + && expr.name == "arguments" + && expr.definition().orig.length == 1 + && (fn = expr.scope) instanceof AST_Lambda + && fn.uses_arguments + && !(fn instanceof AST_Arrow) + && prop instanceof AST_Number) { + var index = prop.getValue(); + var params = new Set(); + var argnames = fn.argnames; + for (var n = 0; n < argnames.length; n++) { + if (!(argnames[n] instanceof AST_SymbolFunarg)) { + break OPT_ARGUMENTS; // destructuring parameter - bail + } + var param = argnames[n].name; + if (params.has(param)) { + break OPT_ARGUMENTS; // duplicate parameter - bail + } + params.add(param); + } + var argname = fn.argnames[index]; + if (argname && compressor.has_directive("use strict")) { + var def = argname.definition(); + if (!compressor.option("reduce_vars") || def.assignments || def.orig.length > 1) { + argname = null; + } + } else if (!argname && !compressor.option("keep_fargs") && index < fn.argnames.length + 5) { + while (index >= fn.argnames.length) { + argname = fn.create_symbol(AST_SymbolFunarg, { + source: fn, + scope: fn, + tentative_name: "argument_" + fn.argnames.length, + }); + fn.argnames.push(argname); + } + } + if (argname) { + var sym = make_node(AST_SymbolRef, self, argname); + sym.reference({}); + clear_flag(argname, UNUSED); + return sym; + } + } + if (compressor.is_lhs()) return self; + if (key !== prop) { + var sub = self.flatten_object(property, compressor); + if (sub) { + expr = self.expression = sub.expression; + prop = self.property = sub.property; + } + } + if (compressor.option("properties") && compressor.option("side_effects") + && prop instanceof AST_Number && expr instanceof AST_Array) { + var index = prop.getValue(); + var elements = expr.elements; + var retValue = elements[index]; + FLATTEN: if (safe_to_flatten(retValue, compressor)) { + var flatten = true; + var values = []; + for (var i = elements.length; --i > index;) { + var value = elements[i].drop_side_effect_free(compressor); + if (value) { + values.unshift(value); + if (flatten && value.has_side_effects(compressor)) flatten = false; + } + } + if (retValue instanceof AST_Expansion) break FLATTEN; + retValue = retValue instanceof AST_Hole ? make_node(AST_Undefined, retValue) : retValue; + if (!flatten) values.unshift(retValue); + while (--i >= 0) { + var value = elements[i]; + if (value instanceof AST_Expansion) break FLATTEN; + value = value.drop_side_effect_free(compressor); + if (value) values.unshift(value); + else index--; + } + if (flatten) { + values.push(retValue); + return make_sequence(self, values).optimize(compressor); + } else return make_node(AST_Sub, self, { + expression: make_node(AST_Array, expr, { + elements: values + }), + property: make_node(AST_Number, prop, { + value: index + }) + }); + } + } + var ev = self.evaluate(compressor); + if (ev !== self) { + ev = make_node_from_constant(ev, self).optimize(compressor); + return best_of(compressor, ev, self); + } + return self; +}); + +def_optimize(AST_Chain, function (self, compressor) { + if (is_nullish(self.expression, compressor)) { + let parent = compressor.parent(); + // It's valid to delete a nullish optional chain, but if we optimized + // this to `delete undefined` then it would appear to be a syntax error + // when we try to optimize the delete. Thankfully, `delete 0` is fine. + if (parent instanceof AST_UnaryPrefix && parent.operator === "delete") { + return make_node_from_constant(0, self); + } + return make_node(AST_Undefined, self); + } + if ( + self.expression instanceof AST_PropAccess + || self.expression instanceof AST_Call + ) { + return self; + } else { + // Keep the AST valid, in case the child swapped itself + return self.expression; + } +}); + +def_optimize(AST_Dot, function(self, compressor) { + const parent = compressor.parent(); + if (compressor.is_lhs()) return self; + if (compressor.option("unsafe_proto") + && self.expression instanceof AST_Dot + && self.expression.property == "prototype") { + var exp = self.expression.expression; + if (is_undeclared_ref(exp)) switch (exp.name) { + case "Array": + self.expression = make_node(AST_Array, self.expression, { + elements: [] + }); + break; + case "Function": + self.expression = make_empty_function(self.expression); + break; + case "Number": + self.expression = make_node(AST_Number, self.expression, { + value: 0 + }); + break; + case "Object": + self.expression = make_node(AST_Object, self.expression, { + properties: [] + }); + break; + case "RegExp": + self.expression = make_node(AST_RegExp, self.expression, { + value: { source: "t", flags: "" } + }); + break; + case "String": + self.expression = make_node(AST_String, self.expression, { + value: "" + }); + break; + } + } + if (!(parent instanceof AST_Call) || !has_annotation(parent, _NOINLINE)) { + const sub = self.flatten_object(self.property, compressor); + if (sub) return sub.optimize(compressor); + } + + if (self.expression instanceof AST_PropAccess + && parent instanceof AST_PropAccess) { + return self; + } + + let ev = self.evaluate(compressor); + if (ev !== self) { + ev = make_node_from_constant(ev, self).optimize(compressor); + return best_of(compressor, ev, self); + } + return self; +}); + +function literals_in_boolean_context(self, compressor) { + if (compressor.in_boolean_context()) { + return best_of(compressor, self, make_sequence(self, [ + self, + make_node(AST_True, self) + ]).optimize(compressor)); + } + return self; +} + +function inline_array_like_spread(elements) { + for (var i = 0; i < elements.length; i++) { + var el = elements[i]; + if (el instanceof AST_Expansion) { + var expr = el.expression; + if ( + expr instanceof AST_Array + && !expr.elements.some(elm => elm instanceof AST_Hole) + ) { + elements.splice(i, 1, ...expr.elements); + // Step back one, as the element at i is now new. + i--; + } + // In array-like spread, spreading a non-iterable value is TypeError. + // We therefore can’t optimize anything else, unlike with object spread. + } + } +} + +def_optimize(AST_Array, function(self, compressor) { + var optimized = literals_in_boolean_context(self, compressor); + if (optimized !== self) { + return optimized; + } + inline_array_like_spread(self.elements); + return self; +}); + +function inline_object_prop_spread(props) { + for (var i = 0; i < props.length; i++) { + var prop = props[i]; + if (prop instanceof AST_Expansion) { + const expr = prop.expression; + if ( + expr instanceof AST_Object + && expr.properties.every(prop => prop instanceof AST_ObjectKeyVal) + ) { + props.splice(i, 1, ...expr.properties); + // Step back one, as the property at i is now new. + i--; + } else if (( + // `expr.is_constant()` returns `false` for `AST_RegExp`, so need both. + expr instanceof AST_Constant + || expr.is_constant() + ) && !(expr instanceof AST_String)) { + // Unlike array-like spread, in object spread, spreading a + // non-iterable value silently does nothing; it is thus safe + // to remove. AST_String is the only iterable constant. + props.splice(i, 1); + i--; + } + } + } +} + +def_optimize(AST_Object, function(self, compressor) { + var optimized = literals_in_boolean_context(self, compressor); + if (optimized !== self) { + return optimized; + } + inline_object_prop_spread(self.properties); + return self; +}); + +def_optimize(AST_RegExp, literals_in_boolean_context); + +def_optimize(AST_Return, function(self, compressor) { + if (self.value && is_undefined(self.value, compressor)) { + self.value = null; + } + return self; +}); + +def_optimize(AST_Arrow, opt_AST_Lambda); + +def_optimize(AST_Function, function(self, compressor) { + self = opt_AST_Lambda(self, compressor); + if (compressor.option("unsafe_arrows") + && compressor.option("ecma") >= 2015 + && !self.name + && !self.is_generator + && !self.uses_arguments + && !self.pinned()) { + const uses_this = walk(self, node => { + if (node instanceof AST_This) return walk_abort; + }); + if (!uses_this) return make_node(AST_Arrow, self, self).optimize(compressor); + } + return self; +}); + +def_optimize(AST_Class, function(self) { + for (let i = 0; i < self.properties.length; i++) { + const prop = self.properties[i]; + if (prop instanceof AST_ClassStaticBlock && prop.body.length == 0) { + self.properties.splice(i, 1); + i--; + } + } + + return self; +}); + +def_optimize(AST_ClassStaticBlock, function(self, compressor) { + tighten_body(self.body, compressor); + return self; +}); + +def_optimize(AST_Yield, function(self, compressor) { + if (self.expression && !self.is_star && is_undefined(self.expression, compressor)) { + self.expression = null; + } + return self; +}); + +def_optimize(AST_TemplateString, function(self, compressor) { + if ( + !compressor.option("evaluate") + || compressor.parent() instanceof AST_PrefixedTemplateString + ) { + return self; + } + + var segments = []; + for (var i = 0; i < self.segments.length; i++) { + var segment = self.segments[i]; + if (segment instanceof AST_Node) { + var result = segment.evaluate(compressor); + // Evaluate to constant value + // Constant value shorter than ${segment} + if (result !== segment && (result + "").length <= segment.size() + "${}".length) { + // There should always be a previous and next segment if segment is a node + segments[segments.length - 1].value = segments[segments.length - 1].value + result + self.segments[++i].value; + continue; + } + // `before ${`innerBefore ${any} innerAfter`} after` => `before innerBefore ${any} innerAfter after` + // TODO: + // `before ${'test' + foo} after` => `before innerBefore ${any} innerAfter after` + // `before ${foo + 'test} after` => `before innerBefore ${any} innerAfter after` + if (segment instanceof AST_TemplateString) { + var inners = segment.segments; + segments[segments.length - 1].value += inners[0].value; + for (var j = 1; j < inners.length; j++) { + segment = inners[j]; + segments.push(segment); + } + continue; + } + } + segments.push(segment); + } + self.segments = segments; + + // `foo` => "foo" + if (segments.length == 1) { + return make_node(AST_String, self, segments[0]); + } + + if ( + segments.length === 3 + && segments[1] instanceof AST_Node + && ( + segments[1].is_string(compressor) + || segments[1].is_number_or_bigint(compressor) + || is_nullish(segments[1], compressor) + || compressor.option("unsafe") + ) + ) { + // `foo${bar}` => "foo" + bar + if (segments[2].value === "") { + return make_node(AST_Binary, self, { + operator: "+", + left: make_node(AST_String, self, { + value: segments[0].value, + }), + right: segments[1], + }); + } + // `${bar}baz` => bar + "baz" + if (segments[0].value === "") { + return make_node(AST_Binary, self, { + operator: "+", + left: segments[1], + right: make_node(AST_String, self, { + value: segments[2].value, + }), + }); + } + } + return self; +}); + +def_optimize(AST_PrefixedTemplateString, function(self) { + return self; +}); + +// ["p"]:1 ---> p:1 +// [42]:1 ---> 42:1 +function lift_key(self, compressor) { + if (!compressor.option("computed_props")) return self; + // save a comparison in the typical case + if (!(self.key instanceof AST_Constant)) return self; + // allow certain acceptable props as not all AST_Constants are true constants + if (self.key instanceof AST_String || self.key instanceof AST_Number) { + const key = self.key.value.toString(); + + if (key === "__proto__") return self; + if (key == "constructor" + && compressor.parent() instanceof AST_Class) return self; + if (self instanceof AST_ObjectKeyVal) { + self.quote = self.key.quote; + self.key = key; + } else if (self instanceof AST_ClassProperty) { + self.quote = self.key.quote; + self.key = make_node(AST_SymbolClassProperty, self.key, { + name: key, + }); + } else { + self.quote = self.key.quote; + self.key = make_node(AST_SymbolMethod, self.key, { + name: key, + }); + } + } + return self; +} + +def_optimize(AST_ObjectProperty, lift_key); + +def_optimize(AST_ConciseMethod, function(self, compressor) { + lift_key(self, compressor); + // p(){return x;} ---> p:()=>x + if (compressor.option("arrows") + && compressor.parent() instanceof AST_Object + && !self.value.is_generator + && !self.value.uses_arguments + && !self.value.pinned() + && self.value.body.length == 1 + && self.value.body[0] instanceof AST_Return + && self.value.body[0].value + && !self.value.contains_this()) { + var arrow = make_node(AST_Arrow, self.value, self.value); + arrow.async = self.value.async; + arrow.is_generator = self.value.is_generator; + return make_node(AST_ObjectKeyVal, self, { + key: self.key instanceof AST_SymbolMethod ? self.key.name : self.key, + value: arrow, + quote: self.quote, + }); + } + return self; +}); + +def_optimize(AST_ObjectKeyVal, function(self, compressor) { + lift_key(self, compressor); + // p:function(){} ---> p(){} + // p:function*(){} ---> *p(){} + // p:async function(){} ---> async p(){} + // p:()=>{} ---> p(){} + // p:async()=>{} ---> async p(){} + var unsafe_methods = compressor.option("unsafe_methods"); + if (unsafe_methods + && compressor.option("ecma") >= 2015 + && (!(unsafe_methods instanceof RegExp) || unsafe_methods.test(self.key + ""))) { + var key = self.key; + var value = self.value; + var is_arrow_with_block = value instanceof AST_Arrow + && Array.isArray(value.body) + && !value.contains_this(); + if ((is_arrow_with_block || value instanceof AST_Function) && !value.name) { + return make_node(AST_ConciseMethod, self, { + key: key instanceof AST_Node ? key : make_node(AST_SymbolMethod, self, { + name: key, + }), + value: make_node(AST_Accessor, value, value), + quote: self.quote, + }); + } + } + return self; +}); + +def_optimize(AST_Destructuring, function(self, compressor) { + if (compressor.option("pure_getters") == true + && compressor.option("unused") + && !self.is_array + && Array.isArray(self.names) + && !is_destructuring_export_decl(compressor) + && !(self.names[self.names.length - 1] instanceof AST_Expansion)) { + var keep = []; + for (var i = 0; i < self.names.length; i++) { + var elem = self.names[i]; + if (!(elem instanceof AST_ObjectKeyVal + && typeof elem.key == "string" + && elem.value instanceof AST_SymbolDeclaration + && !should_retain(compressor, elem.value.definition()))) { + keep.push(elem); + } + } + if (keep.length != self.names.length) { + self.names = keep; + } + } + return self; + + function is_destructuring_export_decl(compressor) { + var ancestors = [/^VarDef$/, /^(Const|Let|Var)$/, /^Export$/]; + for (var a = 0, p = 0, len = ancestors.length; a < len; p++) { + var parent = compressor.parent(p); + if (!parent) return false; + if (a === 0 && parent.TYPE == "Destructuring") continue; + if (!ancestors[a].test(parent.TYPE)) { + return false; + } + a++; + } + return true; + } + + function should_retain(compressor, def) { + if (def.references.length) return true; + if (!def.global) return false; + if (compressor.toplevel.vars) { + if (compressor.top_retain) { + return compressor.top_retain(def); + } + return false; + } + return true; + } +}); + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +// a small wrapper around source-map and @jridgewell/source-map +function* SourceMap(options) { + options = defaults(options, { + file : null, + root : null, + orig : null, + files: {}, + }); + + var orig_map; + var generator = new sourceMap.SourceMapGenerator({ + file : options.file, + sourceRoot : options.root + }); + + let sourcesContent = {__proto__: null}; + let files = options.files; + for (var name in files) if (HOP(files, name)) { + sourcesContent[name] = files[name]; + } + if (options.orig) { + // We support both @jridgewell/source-map (which has a sync + // SourceMapConsumer) and source-map (which has an async + // SourceMapConsumer). + orig_map = yield new sourceMap.SourceMapConsumer(options.orig); + if (orig_map.sourcesContent) { + orig_map.sources.forEach(function(source, i) { + var content = orig_map.sourcesContent[i]; + if (content) { + sourcesContent[source] = content; + } + }); + } + } + + function add(source, gen_line, gen_col, orig_line, orig_col, name) { + let generatedPos = { line: gen_line, column: gen_col }; + + if (orig_map) { + var info = orig_map.originalPositionFor({ + line: orig_line, + column: orig_col + }); + if (info.source === null) { + generator.addMapping({ + generated: generatedPos, + original: null, + source: null, + name: null + }); + return; + } + source = info.source; + orig_line = info.line; + orig_col = info.column; + name = info.name || name; + } + generator.addMapping({ + generated : generatedPos, + original : { line: orig_line, column: orig_col }, + source : source, + name : name + }); + generator.setSourceContent(source, sourcesContent[source]); + } + + function clean(map) { + const allNull = map.sourcesContent && map.sourcesContent.every(c => c == null); + if (allNull) delete map.sourcesContent; + if (map.file === undefined) delete map.file; + if (map.sourceRoot === undefined) delete map.sourceRoot; + return map; + } + + function getDecoded() { + if (!generator.toDecodedMap) return null; + return clean(generator.toDecodedMap()); + } + + function getEncoded() { + return clean(generator.toJSON()); + } + + function destroy() { + // @jridgewell/source-map's SourceMapConsumer does not need to be + // manually freed. + if (orig_map && orig_map.destroy) orig_map.destroy(); + } + + return { + add, + getDecoded, + getEncoded, + destroy, + }; +} + +var domprops = [ + "$&", + "$'", + "$*", + "$+", + "$1", + "$2", + "$3", + "$4", + "$5", + "$6", + "$7", + "$8", + "$9", + "$_", + "$`", + "$input", + "-moz-animation", + "-moz-animation-delay", + "-moz-animation-direction", + "-moz-animation-duration", + "-moz-animation-fill-mode", + "-moz-animation-iteration-count", + "-moz-animation-name", + "-moz-animation-play-state", + "-moz-animation-timing-function", + "-moz-appearance", + "-moz-backface-visibility", + "-moz-border-end", + "-moz-border-end-color", + "-moz-border-end-style", + "-moz-border-end-width", + "-moz-border-image", + "-moz-border-start", + "-moz-border-start-color", + "-moz-border-start-style", + "-moz-border-start-width", + "-moz-box-align", + "-moz-box-direction", + "-moz-box-flex", + "-moz-box-ordinal-group", + "-moz-box-orient", + "-moz-box-pack", + "-moz-box-sizing", + "-moz-float-edge", + "-moz-font-feature-settings", + "-moz-font-language-override", + "-moz-force-broken-image-icon", + "-moz-hyphens", + "-moz-image-region", + "-moz-margin-end", + "-moz-margin-start", + "-moz-orient", + "-moz-osx-font-smoothing", + "-moz-outline-radius", + "-moz-outline-radius-bottomleft", + "-moz-outline-radius-bottomright", + "-moz-outline-radius-topleft", + "-moz-outline-radius-topright", + "-moz-padding-end", + "-moz-padding-start", + "-moz-perspective", + "-moz-perspective-origin", + "-moz-tab-size", + "-moz-text-size-adjust", + "-moz-transform", + "-moz-transform-origin", + "-moz-transform-style", + "-moz-transition", + "-moz-transition-delay", + "-moz-transition-duration", + "-moz-transition-property", + "-moz-transition-timing-function", + "-moz-user-focus", + "-moz-user-input", + "-moz-user-modify", + "-moz-user-select", + "-moz-window-dragging", + "-webkit-align-content", + "-webkit-align-items", + "-webkit-align-self", + "-webkit-animation", + "-webkit-animation-delay", + "-webkit-animation-direction", + "-webkit-animation-duration", + "-webkit-animation-fill-mode", + "-webkit-animation-iteration-count", + "-webkit-animation-name", + "-webkit-animation-play-state", + "-webkit-animation-timing-function", + "-webkit-appearance", + "-webkit-backface-visibility", + "-webkit-background-clip", + "-webkit-background-origin", + "-webkit-background-size", + "-webkit-border-bottom-left-radius", + "-webkit-border-bottom-right-radius", + "-webkit-border-image", + "-webkit-border-radius", + "-webkit-border-top-left-radius", + "-webkit-border-top-right-radius", + "-webkit-box-align", + "-webkit-box-direction", + "-webkit-box-flex", + "-webkit-box-ordinal-group", + "-webkit-box-orient", + "-webkit-box-pack", + "-webkit-box-shadow", + "-webkit-box-sizing", + "-webkit-clip-path", + "-webkit-filter", + "-webkit-flex", + "-webkit-flex-basis", + "-webkit-flex-direction", + "-webkit-flex-flow", + "-webkit-flex-grow", + "-webkit-flex-shrink", + "-webkit-flex-wrap", + "-webkit-font-feature-settings", + "-webkit-justify-content", + "-webkit-line-clamp", + "-webkit-mask", + "-webkit-mask-clip", + "-webkit-mask-composite", + "-webkit-mask-image", + "-webkit-mask-origin", + "-webkit-mask-position", + "-webkit-mask-position-x", + "-webkit-mask-position-y", + "-webkit-mask-repeat", + "-webkit-mask-size", + "-webkit-order", + "-webkit-perspective", + "-webkit-perspective-origin", + "-webkit-text-fill-color", + "-webkit-text-security", + "-webkit-text-size-adjust", + "-webkit-text-stroke", + "-webkit-text-stroke-color", + "-webkit-text-stroke-width", + "-webkit-transform", + "-webkit-transform-origin", + "-webkit-transform-style", + "-webkit-transition", + "-webkit-transition-delay", + "-webkit-transition-duration", + "-webkit-transition-property", + "-webkit-transition-timing-function", + "-webkit-user-select", + "@@iterator", + "ABORT_ERR", + "ACTIVE", + "ACTIVE_ATTRIBUTES", + "ACTIVE_TEXTURE", + "ACTIVE_UNIFORMS", + "ACTIVE_UNIFORM_BLOCKS", + "ADDITION", + "ALIASED_LINE_WIDTH_RANGE", + "ALIASED_POINT_SIZE_RANGE", + "ALL", + "ALLOW_KEYBOARD_INPUT", + "ALLPASS", + "ALPHA", + "ALPHA_BITS", + "ALREADY_SIGNALED", + "ALT_MASK", + "ALWAYS", + "ANY_SAMPLES_PASSED", + "ANY_SAMPLES_PASSED_CONSERVATIVE", + "ANY_TYPE", + "ANY_UNORDERED_NODE_TYPE", + "ARRAY_BUFFER", + "ARRAY_BUFFER_BINDING", + "ATTACHED_SHADERS", + "ATTRIBUTE_NODE", + "AT_TARGET", + "AbortController", + "AbortSignal", + "AbsoluteOrientationSensor", + "AbstractRange", + "Accelerometer", + "AddSearchProvider", + "AggregateError", + "AnalyserNode", + "Animation", + "AnimationEffect", + "AnimationEvent", + "AnimationPlaybackEvent", + "AnimationTimeline", + "AnonXMLHttpRequest", + "Any", + "AnyPermissions", + "ApplicationCache", + "ApplicationCacheErrorEvent", + "Array", + "ArrayBuffer", + "ArrayType", + "Atomics", + "Attr", + "Audio", + "AudioBuffer", + "AudioBufferSourceNode", + "AudioContext", + "AudioData", + "AudioDecoder", + "AudioDestinationNode", + "AudioEncoder", + "AudioListener", + "AudioNode", + "AudioParam", + "AudioParamMap", + "AudioProcessingEvent", + "AudioScheduledSourceNode", + "AudioSinkInfo", + "AudioStreamTrack", + "AudioWorklet", + "AudioWorkletNode", + "AuthenticatorAssertionResponse", + "AuthenticatorAttestationResponse", + "AuthenticatorResponse", + "AutocompleteErrorEvent", + "BACK", + "BAD_BOUNDARYPOINTS_ERR", + "BAD_REQUEST", + "BANDPASS", + "BLEND", + "BLEND_COLOR", + "BLEND_DST_ALPHA", + "BLEND_DST_RGB", + "BLEND_EQUATION", + "BLEND_EQUATION_ALPHA", + "BLEND_EQUATION_RGB", + "BLEND_SRC_ALPHA", + "BLEND_SRC_RGB", + "BLUE", + "BLUE_BITS", + "BLUR", + "BOOL", + "BOOLEAN_TYPE", + "BOOL_VEC2", + "BOOL_VEC3", + "BOOL_VEC4", + "BOTH", + "BROWSER_DEFAULT_WEBGL", + "BUBBLING_PHASE", + "BUFFER_SIZE", + "BUFFER_USAGE", + "BYTE", + "BYTES_PER_ELEMENT", + "BackgroundFetchManager", + "BackgroundFetchRecord", + "BackgroundFetchRegistration", + "BarProp", + "BarcodeDetector", + "BaseAudioContext", + "BaseHref", + "BatteryManager", + "BeforeInstallPromptEvent", + "BeforeLoadEvent", + "BeforeUnloadEvent", + "BigInt", + "BigInt64Array", + "BigUint64Array", + "BiquadFilterNode", + "Blob", + "BlobEvent", + "Bluetooth", + "BluetoothCharacteristicProperties", + "BluetoothDevice", + "BluetoothRemoteGATTCharacteristic", + "BluetoothRemoteGATTDescriptor", + "BluetoothRemoteGATTServer", + "BluetoothRemoteGATTService", + "BluetoothUUID", + "Boolean", + "BroadcastChannel", + "BrowserCaptureMediaStreamTrack", + "BrowserInfo", + "ByteLengthQueuingStrategy", + "CAPTURING_PHASE", + "CCW", + "CDATASection", + "CDATA_SECTION_NODE", + "CHANGE", + "CHARSET_RULE", + "CHECKING", + "CLAMP_TO_EDGE", + "CLICK", + "CLOSED", + "CLOSING", + "COLOR", + "COLOR_ATTACHMENT0", + "COLOR_ATTACHMENT1", + "COLOR_ATTACHMENT10", + "COLOR_ATTACHMENT11", + "COLOR_ATTACHMENT12", + "COLOR_ATTACHMENT13", + "COLOR_ATTACHMENT14", + "COLOR_ATTACHMENT15", + "COLOR_ATTACHMENT2", + "COLOR_ATTACHMENT3", + "COLOR_ATTACHMENT4", + "COLOR_ATTACHMENT5", + "COLOR_ATTACHMENT6", + "COLOR_ATTACHMENT7", + "COLOR_ATTACHMENT8", + "COLOR_ATTACHMENT9", + "COLOR_BUFFER_BIT", + "COLOR_CLEAR_VALUE", + "COLOR_WRITEMASK", + "COMMENT_NODE", + "COMPARE_REF_TO_TEXTURE", + "COMPILE_STATUS", + "COMPLETION_STATUS_KHR", + "COMPRESSED_RGBA_S3TC_DXT1_EXT", + "COMPRESSED_RGBA_S3TC_DXT3_EXT", + "COMPRESSED_RGBA_S3TC_DXT5_EXT", + "COMPRESSED_RGB_S3TC_DXT1_EXT", + "COMPRESSED_TEXTURE_FORMATS", + "COMPUTE", + "CONDITION_SATISFIED", + "CONFIGURATION_UNSUPPORTED", + "CONNECTING", + "CONSTANT_ALPHA", + "CONSTANT_COLOR", + "CONSTRAINT_ERR", + "CONTEXT_LOST_WEBGL", + "CONTROL_MASK", + "COPY_DST", + "COPY_READ_BUFFER", + "COPY_READ_BUFFER_BINDING", + "COPY_SRC", + "COPY_WRITE_BUFFER", + "COPY_WRITE_BUFFER_BINDING", + "COUNTER_STYLE_RULE", + "CSS", + "CSS2Properties", + "CSSAnimation", + "CSSCharsetRule", + "CSSConditionRule", + "CSSContainerRule", + "CSSCounterStyleRule", + "CSSFontFaceRule", + "CSSFontFeatureValuesRule", + "CSSFontPaletteValuesRule", + "CSSGroupingRule", + "CSSImageValue", + "CSSImportRule", + "CSSKeyframeRule", + "CSSKeyframesRule", + "CSSKeywordValue", + "CSSLayerBlockRule", + "CSSLayerStatementRule", + "CSSMarginRule", + "CSSMathClamp", + "CSSMathInvert", + "CSSMathMax", + "CSSMathMin", + "CSSMathNegate", + "CSSMathProduct", + "CSSMathSum", + "CSSMathValue", + "CSSMatrixComponent", + "CSSMediaRule", + "CSSMozDocumentRule", + "CSSNameSpaceRule", + "CSSNamespaceRule", + "CSSNestedDeclarations", + "CSSNumericArray", + "CSSNumericValue", + "CSSPageDescriptors", + "CSSPageRule", + "CSSPerspective", + "CSSPositionTryDescriptors", + "CSSPositionTryRule", + "CSSPositionValue", + "CSSPrimitiveValue", + "CSSPropertyRule", + "CSSRotate", + "CSSRule", + "CSSRuleList", + "CSSScale", + "CSSScopeRule", + "CSSSkew", + "CSSSkewX", + "CSSSkewY", + "CSSStartingStyleRule", + "CSSStyleDeclaration", + "CSSStyleRule", + "CSSStyleSheet", + "CSSStyleValue", + "CSSSupportsRule", + "CSSTransformComponent", + "CSSTransformValue", + "CSSTransition", + "CSSTranslate", + "CSSUnitValue", + "CSSUnknownRule", + "CSSUnparsedValue", + "CSSValue", + "CSSValueList", + "CSSVariableReferenceValue", + "CSSVariablesDeclaration", + "CSSVariablesRule", + "CSSViewTransitionRule", + "CSSViewportRule", + "CSS_ATTR", + "CSS_CM", + "CSS_COUNTER", + "CSS_CUSTOM", + "CSS_DEG", + "CSS_DIMENSION", + "CSS_EMS", + "CSS_EXS", + "CSS_FILTER_BLUR", + "CSS_FILTER_BRIGHTNESS", + "CSS_FILTER_CONTRAST", + "CSS_FILTER_CUSTOM", + "CSS_FILTER_DROP_SHADOW", + "CSS_FILTER_GRAYSCALE", + "CSS_FILTER_HUE_ROTATE", + "CSS_FILTER_INVERT", + "CSS_FILTER_OPACITY", + "CSS_FILTER_REFERENCE", + "CSS_FILTER_SATURATE", + "CSS_FILTER_SEPIA", + "CSS_GRAD", + "CSS_HZ", + "CSS_IDENT", + "CSS_IN", + "CSS_INHERIT", + "CSS_KHZ", + "CSS_MATRIX", + "CSS_MATRIX3D", + "CSS_MM", + "CSS_MS", + "CSS_NUMBER", + "CSS_PC", + "CSS_PERCENTAGE", + "CSS_PERSPECTIVE", + "CSS_PRIMITIVE_VALUE", + "CSS_PT", + "CSS_PX", + "CSS_RAD", + "CSS_RECT", + "CSS_RGBCOLOR", + "CSS_ROTATE", + "CSS_ROTATE3D", + "CSS_ROTATEX", + "CSS_ROTATEY", + "CSS_ROTATEZ", + "CSS_S", + "CSS_SCALE", + "CSS_SCALE3D", + "CSS_SCALEX", + "CSS_SCALEY", + "CSS_SCALEZ", + "CSS_SKEW", + "CSS_SKEWX", + "CSS_SKEWY", + "CSS_STRING", + "CSS_TRANSLATE", + "CSS_TRANSLATE3D", + "CSS_TRANSLATEX", + "CSS_TRANSLATEY", + "CSS_TRANSLATEZ", + "CSS_UNKNOWN", + "CSS_URI", + "CSS_VALUE_LIST", + "CSS_VH", + "CSS_VMAX", + "CSS_VMIN", + "CSS_VW", + "CULL_FACE", + "CULL_FACE_MODE", + "CURRENT_PROGRAM", + "CURRENT_QUERY", + "CURRENT_VERTEX_ATTRIB", + "CUSTOM", + "CW", + "Cache", + "CacheStorage", + "CanvasCaptureMediaStream", + "CanvasCaptureMediaStreamTrack", + "CanvasGradient", + "CanvasPattern", + "CanvasRenderingContext2D", + "CaptureController", + "CaretPosition", + "ChannelMergerNode", + "ChannelSplitterNode", + "ChapterInformation", + "CharacterBoundsUpdateEvent", + "CharacterData", + "ClientRect", + "ClientRectList", + "Clipboard", + "ClipboardEvent", + "ClipboardItem", + "CloseEvent", + "CloseWatcher", + "Collator", + "ColorArray", + "ColorValue", + "CommandEvent", + "Comment", + "CompileError", + "CompositionEvent", + "CompressionStream", + "Console", + "ConstantSourceNode", + "ContentVisibilityAutoStateChangeEvent", + "ContextFilter", + "ContextType", + "Controllers", + "ConvolverNode", + "CookieChangeEvent", + "CookieStore", + "CookieStoreManager", + "CountQueuingStrategy", + "Counter", + "CreateType", + "Credential", + "CredentialsContainer", + "CropTarget", + "Crypto", + "CryptoKey", + "CustomElementRegistry", + "CustomEvent", + "CustomStateSet", + "DATABASE_ERR", + "DATA_CLONE_ERR", + "DATA_ERR", + "DBLCLICK", + "DECR", + "DECR_WRAP", + "DELETE_STATUS", + "DEPTH", + "DEPTH24_STENCIL8", + "DEPTH32F_STENCIL8", + "DEPTH_ATTACHMENT", + "DEPTH_BITS", + "DEPTH_BUFFER_BIT", + "DEPTH_CLEAR_VALUE", + "DEPTH_COMPONENT", + "DEPTH_COMPONENT16", + "DEPTH_COMPONENT24", + "DEPTH_COMPONENT32F", + "DEPTH_FUNC", + "DEPTH_RANGE", + "DEPTH_STENCIL", + "DEPTH_STENCIL_ATTACHMENT", + "DEPTH_TEST", + "DEPTH_WRITEMASK", + "DEVICE_INELIGIBLE", + "DIRECTION_DOWN", + "DIRECTION_LEFT", + "DIRECTION_RIGHT", + "DIRECTION_UP", + "DISABLED", + "DISPATCH_REQUEST_ERR", + "DITHER", + "DOCUMENT_FRAGMENT_NODE", + "DOCUMENT_NODE", + "DOCUMENT_POSITION_CONTAINED_BY", + "DOCUMENT_POSITION_CONTAINS", + "DOCUMENT_POSITION_DISCONNECTED", + "DOCUMENT_POSITION_FOLLOWING", + "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC", + "DOCUMENT_POSITION_PRECEDING", + "DOCUMENT_TYPE_NODE", + "DOMCursor", + "DOMError", + "DOMException", + "DOMImplementation", + "DOMImplementationLS", + "DOMMatrix", + "DOMMatrixReadOnly", + "DOMParser", + "DOMPoint", + "DOMPointReadOnly", + "DOMQuad", + "DOMRect", + "DOMRectList", + "DOMRectReadOnly", + "DOMRequest", + "DOMSTRING_SIZE_ERR", + "DOMSettableTokenList", + "DOMStringList", + "DOMStringMap", + "DOMTokenList", + "DOMTransactionEvent", + "DOM_DELTA_LINE", + "DOM_DELTA_PAGE", + "DOM_DELTA_PIXEL", + "DOM_INPUT_METHOD_DROP", + "DOM_INPUT_METHOD_HANDWRITING", + "DOM_INPUT_METHOD_IME", + "DOM_INPUT_METHOD_KEYBOARD", + "DOM_INPUT_METHOD_MULTIMODAL", + "DOM_INPUT_METHOD_OPTION", + "DOM_INPUT_METHOD_PASTE", + "DOM_INPUT_METHOD_SCRIPT", + "DOM_INPUT_METHOD_UNKNOWN", + "DOM_INPUT_METHOD_VOICE", + "DOM_KEY_LOCATION_JOYSTICK", + "DOM_KEY_LOCATION_LEFT", + "DOM_KEY_LOCATION_MOBILE", + "DOM_KEY_LOCATION_NUMPAD", + "DOM_KEY_LOCATION_RIGHT", + "DOM_KEY_LOCATION_STANDARD", + "DOM_VK_0", + "DOM_VK_1", + "DOM_VK_2", + "DOM_VK_3", + "DOM_VK_4", + "DOM_VK_5", + "DOM_VK_6", + "DOM_VK_7", + "DOM_VK_8", + "DOM_VK_9", + "DOM_VK_A", + "DOM_VK_ACCEPT", + "DOM_VK_ADD", + "DOM_VK_ALT", + "DOM_VK_ALTGR", + "DOM_VK_AMPERSAND", + "DOM_VK_ASTERISK", + "DOM_VK_AT", + "DOM_VK_ATTN", + "DOM_VK_B", + "DOM_VK_BACKSPACE", + "DOM_VK_BACK_QUOTE", + "DOM_VK_BACK_SLASH", + "DOM_VK_BACK_SPACE", + "DOM_VK_C", + "DOM_VK_CANCEL", + "DOM_VK_CAPS_LOCK", + "DOM_VK_CIRCUMFLEX", + "DOM_VK_CLEAR", + "DOM_VK_CLOSE_BRACKET", + "DOM_VK_CLOSE_CURLY_BRACKET", + "DOM_VK_CLOSE_PAREN", + "DOM_VK_COLON", + "DOM_VK_COMMA", + "DOM_VK_CONTEXT_MENU", + "DOM_VK_CONTROL", + "DOM_VK_CONVERT", + "DOM_VK_CRSEL", + "DOM_VK_CTRL", + "DOM_VK_D", + "DOM_VK_DECIMAL", + "DOM_VK_DELETE", + "DOM_VK_DIVIDE", + "DOM_VK_DOLLAR", + "DOM_VK_DOUBLE_QUOTE", + "DOM_VK_DOWN", + "DOM_VK_E", + "DOM_VK_EISU", + "DOM_VK_END", + "DOM_VK_ENTER", + "DOM_VK_EQUALS", + "DOM_VK_EREOF", + "DOM_VK_ESCAPE", + "DOM_VK_EXCLAMATION", + "DOM_VK_EXECUTE", + "DOM_VK_EXSEL", + "DOM_VK_F", + "DOM_VK_F1", + "DOM_VK_F10", + "DOM_VK_F11", + "DOM_VK_F12", + "DOM_VK_F13", + "DOM_VK_F14", + "DOM_VK_F15", + "DOM_VK_F16", + "DOM_VK_F17", + "DOM_VK_F18", + "DOM_VK_F19", + "DOM_VK_F2", + "DOM_VK_F20", + "DOM_VK_F21", + "DOM_VK_F22", + "DOM_VK_F23", + "DOM_VK_F24", + "DOM_VK_F25", + "DOM_VK_F26", + "DOM_VK_F27", + "DOM_VK_F28", + "DOM_VK_F29", + "DOM_VK_F3", + "DOM_VK_F30", + "DOM_VK_F31", + "DOM_VK_F32", + "DOM_VK_F33", + "DOM_VK_F34", + "DOM_VK_F35", + "DOM_VK_F36", + "DOM_VK_F4", + "DOM_VK_F5", + "DOM_VK_F6", + "DOM_VK_F7", + "DOM_VK_F8", + "DOM_VK_F9", + "DOM_VK_FINAL", + "DOM_VK_FRONT", + "DOM_VK_G", + "DOM_VK_GREATER_THAN", + "DOM_VK_H", + "DOM_VK_HANGUL", + "DOM_VK_HANJA", + "DOM_VK_HASH", + "DOM_VK_HELP", + "DOM_VK_HK_TOGGLE", + "DOM_VK_HOME", + "DOM_VK_HYPHEN_MINUS", + "DOM_VK_I", + "DOM_VK_INSERT", + "DOM_VK_J", + "DOM_VK_JUNJA", + "DOM_VK_K", + "DOM_VK_KANA", + "DOM_VK_KANJI", + "DOM_VK_L", + "DOM_VK_LEFT", + "DOM_VK_LEFT_TAB", + "DOM_VK_LESS_THAN", + "DOM_VK_M", + "DOM_VK_META", + "DOM_VK_MODECHANGE", + "DOM_VK_MULTIPLY", + "DOM_VK_N", + "DOM_VK_NONCONVERT", + "DOM_VK_NUMPAD0", + "DOM_VK_NUMPAD1", + "DOM_VK_NUMPAD2", + "DOM_VK_NUMPAD3", + "DOM_VK_NUMPAD4", + "DOM_VK_NUMPAD5", + "DOM_VK_NUMPAD6", + "DOM_VK_NUMPAD7", + "DOM_VK_NUMPAD8", + "DOM_VK_NUMPAD9", + "DOM_VK_NUM_LOCK", + "DOM_VK_O", + "DOM_VK_OEM_1", + "DOM_VK_OEM_102", + "DOM_VK_OEM_2", + "DOM_VK_OEM_3", + "DOM_VK_OEM_4", + "DOM_VK_OEM_5", + "DOM_VK_OEM_6", + "DOM_VK_OEM_7", + "DOM_VK_OEM_8", + "DOM_VK_OEM_COMMA", + "DOM_VK_OEM_MINUS", + "DOM_VK_OEM_PERIOD", + "DOM_VK_OEM_PLUS", + "DOM_VK_OPEN_BRACKET", + "DOM_VK_OPEN_CURLY_BRACKET", + "DOM_VK_OPEN_PAREN", + "DOM_VK_P", + "DOM_VK_PA1", + "DOM_VK_PAGEDOWN", + "DOM_VK_PAGEUP", + "DOM_VK_PAGE_DOWN", + "DOM_VK_PAGE_UP", + "DOM_VK_PAUSE", + "DOM_VK_PERCENT", + "DOM_VK_PERIOD", + "DOM_VK_PIPE", + "DOM_VK_PLAY", + "DOM_VK_PLUS", + "DOM_VK_PRINT", + "DOM_VK_PRINTSCREEN", + "DOM_VK_PROCESSKEY", + "DOM_VK_PROPERITES", + "DOM_VK_Q", + "DOM_VK_QUESTION_MARK", + "DOM_VK_QUOTE", + "DOM_VK_R", + "DOM_VK_REDO", + "DOM_VK_RETURN", + "DOM_VK_RIGHT", + "DOM_VK_S", + "DOM_VK_SCROLL_LOCK", + "DOM_VK_SELECT", + "DOM_VK_SEMICOLON", + "DOM_VK_SEPARATOR", + "DOM_VK_SHIFT", + "DOM_VK_SLASH", + "DOM_VK_SLEEP", + "DOM_VK_SPACE", + "DOM_VK_SUBTRACT", + "DOM_VK_T", + "DOM_VK_TAB", + "DOM_VK_TILDE", + "DOM_VK_U", + "DOM_VK_UNDERSCORE", + "DOM_VK_UNDO", + "DOM_VK_UNICODE", + "DOM_VK_UP", + "DOM_VK_V", + "DOM_VK_VOLUME_DOWN", + "DOM_VK_VOLUME_MUTE", + "DOM_VK_VOLUME_UP", + "DOM_VK_W", + "DOM_VK_WIN", + "DOM_VK_WINDOW", + "DOM_VK_WIN_ICO_00", + "DOM_VK_WIN_ICO_CLEAR", + "DOM_VK_WIN_ICO_HELP", + "DOM_VK_WIN_OEM_ATTN", + "DOM_VK_WIN_OEM_AUTO", + "DOM_VK_WIN_OEM_BACKTAB", + "DOM_VK_WIN_OEM_CLEAR", + "DOM_VK_WIN_OEM_COPY", + "DOM_VK_WIN_OEM_CUSEL", + "DOM_VK_WIN_OEM_ENLW", + "DOM_VK_WIN_OEM_FINISH", + "DOM_VK_WIN_OEM_FJ_JISHO", + "DOM_VK_WIN_OEM_FJ_LOYA", + "DOM_VK_WIN_OEM_FJ_MASSHOU", + "DOM_VK_WIN_OEM_FJ_ROYA", + "DOM_VK_WIN_OEM_FJ_TOUROKU", + "DOM_VK_WIN_OEM_JUMP", + "DOM_VK_WIN_OEM_PA1", + "DOM_VK_WIN_OEM_PA2", + "DOM_VK_WIN_OEM_PA3", + "DOM_VK_WIN_OEM_RESET", + "DOM_VK_WIN_OEM_WSCTRL", + "DOM_VK_X", + "DOM_VK_XF86XK_ADD_FAVORITE", + "DOM_VK_XF86XK_APPLICATION_LEFT", + "DOM_VK_XF86XK_APPLICATION_RIGHT", + "DOM_VK_XF86XK_AUDIO_CYCLE_TRACK", + "DOM_VK_XF86XK_AUDIO_FORWARD", + "DOM_VK_XF86XK_AUDIO_LOWER_VOLUME", + "DOM_VK_XF86XK_AUDIO_MEDIA", + "DOM_VK_XF86XK_AUDIO_MUTE", + "DOM_VK_XF86XK_AUDIO_NEXT", + "DOM_VK_XF86XK_AUDIO_PAUSE", + "DOM_VK_XF86XK_AUDIO_PLAY", + "DOM_VK_XF86XK_AUDIO_PREV", + "DOM_VK_XF86XK_AUDIO_RAISE_VOLUME", + "DOM_VK_XF86XK_AUDIO_RANDOM_PLAY", + "DOM_VK_XF86XK_AUDIO_RECORD", + "DOM_VK_XF86XK_AUDIO_REPEAT", + "DOM_VK_XF86XK_AUDIO_REWIND", + "DOM_VK_XF86XK_AUDIO_STOP", + "DOM_VK_XF86XK_AWAY", + "DOM_VK_XF86XK_BACK", + "DOM_VK_XF86XK_BACK_FORWARD", + "DOM_VK_XF86XK_BATTERY", + "DOM_VK_XF86XK_BLUE", + "DOM_VK_XF86XK_BLUETOOTH", + "DOM_VK_XF86XK_BOOK", + "DOM_VK_XF86XK_BRIGHTNESS_ADJUST", + "DOM_VK_XF86XK_CALCULATOR", + "DOM_VK_XF86XK_CALENDAR", + "DOM_VK_XF86XK_CD", + "DOM_VK_XF86XK_CLOSE", + "DOM_VK_XF86XK_COMMUNITY", + "DOM_VK_XF86XK_CONTRAST_ADJUST", + "DOM_VK_XF86XK_COPY", + "DOM_VK_XF86XK_CUT", + "DOM_VK_XF86XK_CYCLE_ANGLE", + "DOM_VK_XF86XK_DISPLAY", + "DOM_VK_XF86XK_DOCUMENTS", + "DOM_VK_XF86XK_DOS", + "DOM_VK_XF86XK_EJECT", + "DOM_VK_XF86XK_EXCEL", + "DOM_VK_XF86XK_EXPLORER", + "DOM_VK_XF86XK_FAVORITES", + "DOM_VK_XF86XK_FINANCE", + "DOM_VK_XF86XK_FORWARD", + "DOM_VK_XF86XK_FRAME_BACK", + "DOM_VK_XF86XK_FRAME_FORWARD", + "DOM_VK_XF86XK_GAME", + "DOM_VK_XF86XK_GO", + "DOM_VK_XF86XK_GREEN", + "DOM_VK_XF86XK_HIBERNATE", + "DOM_VK_XF86XK_HISTORY", + "DOM_VK_XF86XK_HOME_PAGE", + "DOM_VK_XF86XK_HOT_LINKS", + "DOM_VK_XF86XK_I_TOUCH", + "DOM_VK_XF86XK_KBD_BRIGHTNESS_DOWN", + "DOM_VK_XF86XK_KBD_BRIGHTNESS_UP", + "DOM_VK_XF86XK_KBD_LIGHT_ON_OFF", + "DOM_VK_XF86XK_LAUNCH0", + "DOM_VK_XF86XK_LAUNCH1", + "DOM_VK_XF86XK_LAUNCH2", + "DOM_VK_XF86XK_LAUNCH3", + "DOM_VK_XF86XK_LAUNCH4", + "DOM_VK_XF86XK_LAUNCH5", + "DOM_VK_XF86XK_LAUNCH6", + "DOM_VK_XF86XK_LAUNCH7", + "DOM_VK_XF86XK_LAUNCH8", + "DOM_VK_XF86XK_LAUNCH9", + "DOM_VK_XF86XK_LAUNCH_A", + "DOM_VK_XF86XK_LAUNCH_B", + "DOM_VK_XF86XK_LAUNCH_C", + "DOM_VK_XF86XK_LAUNCH_D", + "DOM_VK_XF86XK_LAUNCH_E", + "DOM_VK_XF86XK_LAUNCH_F", + "DOM_VK_XF86XK_LIGHT_BULB", + "DOM_VK_XF86XK_LOG_OFF", + "DOM_VK_XF86XK_MAIL", + "DOM_VK_XF86XK_MAIL_FORWARD", + "DOM_VK_XF86XK_MARKET", + "DOM_VK_XF86XK_MEETING", + "DOM_VK_XF86XK_MEMO", + "DOM_VK_XF86XK_MENU_KB", + "DOM_VK_XF86XK_MENU_PB", + "DOM_VK_XF86XK_MESSENGER", + "DOM_VK_XF86XK_MON_BRIGHTNESS_DOWN", + "DOM_VK_XF86XK_MON_BRIGHTNESS_UP", + "DOM_VK_XF86XK_MUSIC", + "DOM_VK_XF86XK_MY_COMPUTER", + "DOM_VK_XF86XK_MY_SITES", + "DOM_VK_XF86XK_NEW", + "DOM_VK_XF86XK_NEWS", + "DOM_VK_XF86XK_OFFICE_HOME", + "DOM_VK_XF86XK_OPEN", + "DOM_VK_XF86XK_OPEN_URL", + "DOM_VK_XF86XK_OPTION", + "DOM_VK_XF86XK_PASTE", + "DOM_VK_XF86XK_PHONE", + "DOM_VK_XF86XK_PICTURES", + "DOM_VK_XF86XK_POWER_DOWN", + "DOM_VK_XF86XK_POWER_OFF", + "DOM_VK_XF86XK_RED", + "DOM_VK_XF86XK_REFRESH", + "DOM_VK_XF86XK_RELOAD", + "DOM_VK_XF86XK_REPLY", + "DOM_VK_XF86XK_ROCKER_DOWN", + "DOM_VK_XF86XK_ROCKER_ENTER", + "DOM_VK_XF86XK_ROCKER_UP", + "DOM_VK_XF86XK_ROTATE_WINDOWS", + "DOM_VK_XF86XK_ROTATION_KB", + "DOM_VK_XF86XK_ROTATION_PB", + "DOM_VK_XF86XK_SAVE", + "DOM_VK_XF86XK_SCREEN_SAVER", + "DOM_VK_XF86XK_SCROLL_CLICK", + "DOM_VK_XF86XK_SCROLL_DOWN", + "DOM_VK_XF86XK_SCROLL_UP", + "DOM_VK_XF86XK_SEARCH", + "DOM_VK_XF86XK_SEND", + "DOM_VK_XF86XK_SHOP", + "DOM_VK_XF86XK_SPELL", + "DOM_VK_XF86XK_SPLIT_SCREEN", + "DOM_VK_XF86XK_STANDBY", + "DOM_VK_XF86XK_START", + "DOM_VK_XF86XK_STOP", + "DOM_VK_XF86XK_SUBTITLE", + "DOM_VK_XF86XK_SUPPORT", + "DOM_VK_XF86XK_SUSPEND", + "DOM_VK_XF86XK_TASK_PANE", + "DOM_VK_XF86XK_TERMINAL", + "DOM_VK_XF86XK_TIME", + "DOM_VK_XF86XK_TOOLS", + "DOM_VK_XF86XK_TOP_MENU", + "DOM_VK_XF86XK_TO_DO_LIST", + "DOM_VK_XF86XK_TRAVEL", + "DOM_VK_XF86XK_USER1KB", + "DOM_VK_XF86XK_USER2KB", + "DOM_VK_XF86XK_USER_PB", + "DOM_VK_XF86XK_UWB", + "DOM_VK_XF86XK_VENDOR_HOME", + "DOM_VK_XF86XK_VIDEO", + "DOM_VK_XF86XK_VIEW", + "DOM_VK_XF86XK_WAKE_UP", + "DOM_VK_XF86XK_WEB_CAM", + "DOM_VK_XF86XK_WHEEL_BUTTON", + "DOM_VK_XF86XK_WLAN", + "DOM_VK_XF86XK_WORD", + "DOM_VK_XF86XK_WWW", + "DOM_VK_XF86XK_XFER", + "DOM_VK_XF86XK_YELLOW", + "DOM_VK_XF86XK_ZOOM_IN", + "DOM_VK_XF86XK_ZOOM_OUT", + "DOM_VK_Y", + "DOM_VK_Z", + "DOM_VK_ZOOM", + "DONE", + "DONT_CARE", + "DOWNLOADING", + "DRAGDROP", + "DRAW_BUFFER0", + "DRAW_BUFFER1", + "DRAW_BUFFER10", + "DRAW_BUFFER11", + "DRAW_BUFFER12", + "DRAW_BUFFER13", + "DRAW_BUFFER14", + "DRAW_BUFFER15", + "DRAW_BUFFER2", + "DRAW_BUFFER3", + "DRAW_BUFFER4", + "DRAW_BUFFER5", + "DRAW_BUFFER6", + "DRAW_BUFFER7", + "DRAW_BUFFER8", + "DRAW_BUFFER9", + "DRAW_FRAMEBUFFER", + "DRAW_FRAMEBUFFER_BINDING", + "DST_ALPHA", + "DST_COLOR", + "DYNAMIC_COPY", + "DYNAMIC_DRAW", + "DYNAMIC_READ", + "DataChannel", + "DataTransfer", + "DataTransferItem", + "DataTransferItemList", + "DataView", + "Date", + "DateTimeFormat", + "DecompressionStream", + "DelayNode", + "DelegatedInkTrailPresenter", + "DeprecationReportBody", + "DesktopNotification", + "DesktopNotificationCenter", + "Details", + "DeviceLightEvent", + "DeviceMotionEvent", + "DeviceMotionEventAcceleration", + "DeviceMotionEventRotationRate", + "DeviceOrientationEvent", + "DeviceProximityEvent", + "DeviceStorage", + "DeviceStorageChangeEvent", + "Directory", + "DisplayNames", + "Document", + "DocumentFragment", + "DocumentPictureInPicture", + "DocumentPictureInPictureEvent", + "DocumentTimeline", + "DocumentType", + "DragEvent", + "DurationFormat", + "DynamicsCompressorNode", + "E", + "ELEMENT_ARRAY_BUFFER", + "ELEMENT_ARRAY_BUFFER_BINDING", + "ELEMENT_NODE", + "EMPTY", + "ENCODING_ERR", + "ENDED", + "END_TO_END", + "END_TO_START", + "ENTITY_NODE", + "ENTITY_REFERENCE_NODE", + "EPSILON", + "EQUAL", + "EQUALPOWER", + "ERROR", + "EXPONENTIAL_DISTANCE", + "EditContext", + "Element", + "ElementInternals", + "ElementQuery", + "EncodedAudioChunk", + "EncodedVideoChunk", + "EnterPictureInPictureEvent", + "Entity", + "EntityReference", + "Error", + "ErrorEvent", + "EvalError", + "Event", + "EventCounts", + "EventException", + "EventSource", + "EventTarget", + "Exception", + "ExtensionContext", + "ExtensionDisabledReason", + "ExtensionInfo", + "ExtensionInstallType", + "ExtensionType", + "External", + "EyeDropper", + "FASTEST", + "FIDOSDK", + "FILTER_ACCEPT", + "FILTER_INTERRUPT", + "FILTER_REJECT", + "FILTER_SKIP", + "FINISHED_STATE", + "FIRST_ORDERED_NODE_TYPE", + "FLOAT", + "FLOAT_32_UNSIGNED_INT_24_8_REV", + "FLOAT_MAT2", + "FLOAT_MAT2x3", + "FLOAT_MAT2x4", + "FLOAT_MAT3", + "FLOAT_MAT3x2", + "FLOAT_MAT3x4", + "FLOAT_MAT4", + "FLOAT_MAT4x2", + "FLOAT_MAT4x3", + "FLOAT_VEC2", + "FLOAT_VEC3", + "FLOAT_VEC4", + "FOCUS", + "FONT_FACE_RULE", + "FONT_FEATURE_VALUES_RULE", + "FRAGMENT", + "FRAGMENT_SHADER", + "FRAGMENT_SHADER_DERIVATIVE_HINT", + "FRAGMENT_SHADER_DERIVATIVE_HINT_OES", + "FRAMEBUFFER", + "FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE", + "FRAMEBUFFER_ATTACHMENT_BLUE_SIZE", + "FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING", + "FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE", + "FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE", + "FRAMEBUFFER_ATTACHMENT_GREEN_SIZE", + "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME", + "FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE", + "FRAMEBUFFER_ATTACHMENT_RED_SIZE", + "FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE", + "FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE", + "FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER", + "FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL", + "FRAMEBUFFER_BINDING", + "FRAMEBUFFER_COMPLETE", + "FRAMEBUFFER_DEFAULT", + "FRAMEBUFFER_INCOMPLETE_ATTACHMENT", + "FRAMEBUFFER_INCOMPLETE_DIMENSIONS", + "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT", + "FRAMEBUFFER_INCOMPLETE_MULTISAMPLE", + "FRAMEBUFFER_UNSUPPORTED", + "FRONT", + "FRONT_AND_BACK", + "FRONT_FACE", + "FUNC_ADD", + "FUNC_REVERSE_SUBTRACT", + "FUNC_SUBTRACT", + "FeaturePolicy", + "FeaturePolicyViolationReportBody", + "FederatedCredential", + "Feed", + "FeedEntry", + "Fence", + "FencedFrameConfig", + "File", + "FileError", + "FileList", + "FileReader", + "FileSystem", + "FileSystemDirectoryEntry", + "FileSystemDirectoryHandle", + "FileSystemDirectoryReader", + "FileSystemEntry", + "FileSystemFileEntry", + "FileSystemFileHandle", + "FileSystemHandle", + "FileSystemWritableFileStream", + "FinalizationRegistry", + "FindInPage", + "Float16Array", + "Float32Array", + "Float64Array", + "FocusEvent", + "FontData", + "FontFace", + "FontFaceSet", + "FontFaceSetLoadEvent", + "FormData", + "FormDataEvent", + "FragmentDirective", + "Function", + "GENERATE_MIPMAP_HINT", + "GEQUAL", + "GPU", + "GPUAdapter", + "GPUAdapterInfo", + "GPUBindGroup", + "GPUBindGroupLayout", + "GPUBuffer", + "GPUBufferUsage", + "GPUCanvasContext", + "GPUColorWrite", + "GPUCommandBuffer", + "GPUCommandEncoder", + "GPUCompilationInfo", + "GPUCompilationMessage", + "GPUComputePassEncoder", + "GPUComputePipeline", + "GPUDevice", + "GPUDeviceLostInfo", + "GPUError", + "GPUExternalTexture", + "GPUInternalError", + "GPUMapMode", + "GPUOutOfMemoryError", + "GPUPipelineError", + "GPUPipelineLayout", + "GPUQuerySet", + "GPUQueue", + "GPURenderBundle", + "GPURenderBundleEncoder", + "GPURenderPassEncoder", + "GPURenderPipeline", + "GPUSampler", + "GPUShaderModule", + "GPUShaderStage", + "GPUSupportedFeatures", + "GPUSupportedLimits", + "GPUTexture", + "GPUTextureUsage", + "GPUTextureView", + "GPUUncapturedErrorEvent", + "GPUValidationError", + "GREATER", + "GREEN", + "GREEN_BITS", + "GainNode", + "Gamepad", + "GamepadAxisMoveEvent", + "GamepadButton", + "GamepadButtonEvent", + "GamepadEvent", + "GamepadHapticActuator", + "GamepadPose", + "Geolocation", + "GeolocationCoordinates", + "GeolocationPosition", + "GeolocationPositionError", + "GestureEvent", + "GetInfo", + "Global", + "GravitySensor", + "Gyroscope", + "HALF_FLOAT", + "HAVE_CURRENT_DATA", + "HAVE_ENOUGH_DATA", + "HAVE_FUTURE_DATA", + "HAVE_METADATA", + "HAVE_NOTHING", + "HEADERS_RECEIVED", + "HID", + "HIDConnectionEvent", + "HIDDEN", + "HIDDevice", + "HIDInputReportEvent", + "HIERARCHY_REQUEST_ERR", + "HIGHPASS", + "HIGHSHELF", + "HIGH_FLOAT", + "HIGH_INT", + "HORIZONTAL", + "HORIZONTAL_AXIS", + "HRTF", + "HTMLAllCollection", + "HTMLAnchorElement", + "HTMLAppletElement", + "HTMLAreaElement", + "HTMLAudioElement", + "HTMLBRElement", + "HTMLBaseElement", + "HTMLBaseFontElement", + "HTMLBlockquoteElement", + "HTMLBodyElement", + "HTMLButtonElement", + "HTMLCanvasElement", + "HTMLCollection", + "HTMLCommandElement", + "HTMLContentElement", + "HTMLDListElement", + "HTMLDataElement", + "HTMLDataListElement", + "HTMLDetailsElement", + "HTMLDialogElement", + "HTMLDirectoryElement", + "HTMLDivElement", + "HTMLDocument", + "HTMLElement", + "HTMLEmbedElement", + "HTMLFencedFrameElement", + "HTMLFieldSetElement", + "HTMLFontElement", + "HTMLFormControlsCollection", + "HTMLFormElement", + "HTMLFrameElement", + "HTMLFrameSetElement", + "HTMLHRElement", + "HTMLHeadElement", + "HTMLHeadingElement", + "HTMLHtmlElement", + "HTMLIFrameElement", + "HTMLImageElement", + "HTMLInputElement", + "HTMLIsIndexElement", + "HTMLKeygenElement", + "HTMLLIElement", + "HTMLLabelElement", + "HTMLLegendElement", + "HTMLLinkElement", + "HTMLMapElement", + "HTMLMarqueeElement", + "HTMLMediaElement", + "HTMLMenuElement", + "HTMLMenuItemElement", + "HTMLMetaElement", + "HTMLMeterElement", + "HTMLModElement", + "HTMLOListElement", + "HTMLObjectElement", + "HTMLOptGroupElement", + "HTMLOptionElement", + "HTMLOptionsCollection", + "HTMLOutputElement", + "HTMLParagraphElement", + "HTMLParamElement", + "HTMLPictureElement", + "HTMLPreElement", + "HTMLProgressElement", + "HTMLPropertiesCollection", + "HTMLQuoteElement", + "HTMLScriptElement", + "HTMLSelectElement", + "HTMLShadowElement", + "HTMLSlotElement", + "HTMLSourceElement", + "HTMLSpanElement", + "HTMLStyleElement", + "HTMLTableCaptionElement", + "HTMLTableCellElement", + "HTMLTableColElement", + "HTMLTableElement", + "HTMLTableRowElement", + "HTMLTableSectionElement", + "HTMLTemplateElement", + "HTMLTextAreaElement", + "HTMLTimeElement", + "HTMLTitleElement", + "HTMLTrackElement", + "HTMLUListElement", + "HTMLUnknownElement", + "HTMLVideoElement", + "HashChangeEvent", + "Headers", + "Highlight", + "HighlightRegistry", + "History", + "Hz", + "ICE_CHECKING", + "ICE_CLOSED", + "ICE_COMPLETED", + "ICE_CONNECTED", + "ICE_FAILED", + "ICE_GATHERING", + "ICE_WAITING", + "IDBCursor", + "IDBCursorWithValue", + "IDBDatabase", + "IDBDatabaseException", + "IDBFactory", + "IDBFileHandle", + "IDBFileRequest", + "IDBIndex", + "IDBKeyRange", + "IDBMutableFile", + "IDBObjectStore", + "IDBOpenDBRequest", + "IDBRequest", + "IDBTransaction", + "IDBVersionChangeEvent", + "IDLE", + "IIRFilterNode", + "IMPLEMENTATION_COLOR_READ_FORMAT", + "IMPLEMENTATION_COLOR_READ_TYPE", + "IMPORT_RULE", + "INCR", + "INCR_WRAP", + "INDEX", + "INDEX_SIZE_ERR", + "INDIRECT", + "INT", + "INTERLEAVED_ATTRIBS", + "INT_2_10_10_10_REV", + "INT_SAMPLER_2D", + "INT_SAMPLER_2D_ARRAY", + "INT_SAMPLER_3D", + "INT_SAMPLER_CUBE", + "INT_VEC2", + "INT_VEC3", + "INT_VEC4", + "INUSE_ATTRIBUTE_ERR", + "INVALID_ACCESS_ERR", + "INVALID_CHARACTER_ERR", + "INVALID_ENUM", + "INVALID_EXPRESSION_ERR", + "INVALID_FRAMEBUFFER_OPERATION", + "INVALID_INDEX", + "INVALID_MODIFICATION_ERR", + "INVALID_NODE_TYPE_ERR", + "INVALID_OPERATION", + "INVALID_STATE_ERR", + "INVALID_VALUE", + "INVERSE_DISTANCE", + "INVERT", + "IceCandidate", + "IconInfo", + "IdentityCredential", + "IdentityCredentialError", + "IdentityProvider", + "IdleDeadline", + "IdleDetector", + "Image", + "ImageBitmap", + "ImageBitmapRenderingContext", + "ImageCapture", + "ImageData", + "ImageDataType", + "ImageDecoder", + "ImageTrack", + "ImageTrackList", + "Infinity", + "Ink", + "InputDeviceCapabilities", + "InputDeviceInfo", + "InputEvent", + "InputMethodContext", + "InstallTrigger", + "InstallTriggerImpl", + "Instance", + "Int16Array", + "Int32Array", + "Int8Array", + "Intent", + "InternalError", + "IntersectionObserver", + "IntersectionObserverEntry", + "Intl", + "IsSearchProviderInstalled", + "Iterator", + "JSON", + "JSTag", + "KEEP", + "KEYDOWN", + "KEYFRAMES_RULE", + "KEYFRAME_RULE", + "KEYPRESS", + "KEYUP", + "KeyEvent", + "Keyboard", + "KeyboardEvent", + "KeyboardLayoutMap", + "KeyframeEffect", + "LENGTHADJUST_SPACING", + "LENGTHADJUST_SPACINGANDGLYPHS", + "LENGTHADJUST_UNKNOWN", + "LEQUAL", + "LESS", + "LINEAR", + "LINEAR_DISTANCE", + "LINEAR_MIPMAP_LINEAR", + "LINEAR_MIPMAP_NEAREST", + "LINES", + "LINE_LOOP", + "LINE_STRIP", + "LINE_WIDTH", + "LINK_STATUS", + "LIVE", + "LN10", + "LN2", + "LOADED", + "LOADING", + "LOG10E", + "LOG2E", + "LOWPASS", + "LOWSHELF", + "LOW_FLOAT", + "LOW_INT", + "LSException", + "LSParserFilter", + "LUMINANCE", + "LUMINANCE_ALPHA", + "LanguageCode", + "LargestContentfulPaint", + "LaunchParams", + "LaunchQueue", + "LaunchType", + "LayoutShift", + "LayoutShiftAttribution", + "LinearAccelerationSensor", + "LinkError", + "ListFormat", + "LocalMediaStream", + "Locale", + "Location", + "Lock", + "LockManager", + "MAP_READ", + "MAP_WRITE", + "MARGIN_RULE", + "MAX", + "MAX_3D_TEXTURE_SIZE", + "MAX_ARRAY_TEXTURE_LAYERS", + "MAX_CAPTURE_VISIBLE_TAB_CALLS_PER_SECOND", + "MAX_CLIENT_WAIT_TIMEOUT_WEBGL", + "MAX_COLOR_ATTACHMENTS", + "MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS", + "MAX_COMBINED_TEXTURE_IMAGE_UNITS", + "MAX_COMBINED_UNIFORM_BLOCKS", + "MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS", + "MAX_CUBE_MAP_TEXTURE_SIZE", + "MAX_DRAW_BUFFERS", + "MAX_ELEMENTS_INDICES", + "MAX_ELEMENTS_VERTICES", + "MAX_ELEMENT_INDEX", + "MAX_FRAGMENT_INPUT_COMPONENTS", + "MAX_FRAGMENT_UNIFORM_BLOCKS", + "MAX_FRAGMENT_UNIFORM_COMPONENTS", + "MAX_FRAGMENT_UNIFORM_VECTORS", + "MAX_PROGRAM_TEXEL_OFFSET", + "MAX_RENDERBUFFER_SIZE", + "MAX_SAFE_INTEGER", + "MAX_SAMPLES", + "MAX_SERVER_WAIT_TIMEOUT", + "MAX_TEXTURE_IMAGE_UNITS", + "MAX_TEXTURE_LOD_BIAS", + "MAX_TEXTURE_MAX_ANISOTROPY_EXT", + "MAX_TEXTURE_SIZE", + "MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", + "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", + "MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS", + "MAX_UNIFORM_BLOCK_SIZE", + "MAX_UNIFORM_BUFFER_BINDINGS", + "MAX_VALUE", + "MAX_VARYING_COMPONENTS", + "MAX_VARYING_VECTORS", + "MAX_VERTEX_ATTRIBS", + "MAX_VERTEX_OUTPUT_COMPONENTS", + "MAX_VERTEX_TEXTURE_IMAGE_UNITS", + "MAX_VERTEX_UNIFORM_BLOCKS", + "MAX_VERTEX_UNIFORM_COMPONENTS", + "MAX_VERTEX_UNIFORM_VECTORS", + "MAX_VIEWPORT_DIMS", + "MEDIA_ERR_ABORTED", + "MEDIA_ERR_DECODE", + "MEDIA_ERR_ENCRYPTED", + "MEDIA_ERR_NETWORK", + "MEDIA_ERR_SRC_NOT_SUPPORTED", + "MEDIA_KEYERR_CLIENT", + "MEDIA_KEYERR_DOMAIN", + "MEDIA_KEYERR_HARDWARECHANGE", + "MEDIA_KEYERR_OUTPUT", + "MEDIA_KEYERR_SERVICE", + "MEDIA_KEYERR_UNKNOWN", + "MEDIA_RULE", + "MEDIUM_FLOAT", + "MEDIUM_INT", + "META_MASK", + "MIDIAccess", + "MIDIConnectionEvent", + "MIDIInput", + "MIDIInputMap", + "MIDIMessageEvent", + "MIDIOutput", + "MIDIOutputMap", + "MIDIPort", + "MIN", + "MIN_PROGRAM_TEXEL_OFFSET", + "MIN_SAFE_INTEGER", + "MIN_VALUE", + "MIRRORED_REPEAT", + "MODE_ASYNCHRONOUS", + "MODE_SYNCHRONOUS", + "MODIFICATION", + "MOUSEDOWN", + "MOUSEDRAG", + "MOUSEMOVE", + "MOUSEOUT", + "MOUSEOVER", + "MOUSEUP", + "MOZ_KEYFRAMES_RULE", + "MOZ_KEYFRAME_RULE", + "MOZ_SOURCE_CURSOR", + "MOZ_SOURCE_ERASER", + "MOZ_SOURCE_KEYBOARD", + "MOZ_SOURCE_MOUSE", + "MOZ_SOURCE_PEN", + "MOZ_SOURCE_TOUCH", + "MOZ_SOURCE_UNKNOWN", + "MSGESTURE_FLAG_BEGIN", + "MSGESTURE_FLAG_CANCEL", + "MSGESTURE_FLAG_END", + "MSGESTURE_FLAG_INERTIA", + "MSGESTURE_FLAG_NONE", + "MSPOINTER_TYPE_MOUSE", + "MSPOINTER_TYPE_PEN", + "MSPOINTER_TYPE_TOUCH", + "MS_ASYNC_CALLBACK_STATUS_ASSIGN_DELEGATE", + "MS_ASYNC_CALLBACK_STATUS_CANCEL", + "MS_ASYNC_CALLBACK_STATUS_CHOOSEANY", + "MS_ASYNC_CALLBACK_STATUS_ERROR", + "MS_ASYNC_CALLBACK_STATUS_JOIN", + "MS_ASYNC_OP_STATUS_CANCELED", + "MS_ASYNC_OP_STATUS_ERROR", + "MS_ASYNC_OP_STATUS_SUCCESS", + "MS_MANIPULATION_STATE_ACTIVE", + "MS_MANIPULATION_STATE_CANCELLED", + "MS_MANIPULATION_STATE_COMMITTED", + "MS_MANIPULATION_STATE_DRAGGING", + "MS_MANIPULATION_STATE_INERTIA", + "MS_MANIPULATION_STATE_PRESELECT", + "MS_MANIPULATION_STATE_SELECTING", + "MS_MANIPULATION_STATE_STOPPED", + "MS_MEDIA_ERR_ENCRYPTED", + "MS_MEDIA_KEYERR_CLIENT", + "MS_MEDIA_KEYERR_DOMAIN", + "MS_MEDIA_KEYERR_HARDWARECHANGE", + "MS_MEDIA_KEYERR_OUTPUT", + "MS_MEDIA_KEYERR_SERVICE", + "MS_MEDIA_KEYERR_UNKNOWN", + "Map", + "Math", + "MathMLElement", + "MediaCapabilities", + "MediaCapabilitiesInfo", + "MediaController", + "MediaDeviceInfo", + "MediaDevices", + "MediaElementAudioSourceNode", + "MediaEncryptedEvent", + "MediaError", + "MediaKeyError", + "MediaKeyEvent", + "MediaKeyMessageEvent", + "MediaKeyNeededEvent", + "MediaKeySession", + "MediaKeyStatusMap", + "MediaKeySystemAccess", + "MediaKeys", + "MediaList", + "MediaMetadata", + "MediaQueryList", + "MediaQueryListEvent", + "MediaRecorder", + "MediaRecorderErrorEvent", + "MediaSession", + "MediaSettingsRange", + "MediaSource", + "MediaSourceHandle", + "MediaStream", + "MediaStreamAudioDestinationNode", + "MediaStreamAudioSourceNode", + "MediaStreamEvent", + "MediaStreamTrack", + "MediaStreamTrackAudioSourceNode", + "MediaStreamTrackAudioStats", + "MediaStreamTrackEvent", + "MediaStreamTrackGenerator", + "MediaStreamTrackProcessor", + "MediaStreamTrackVideoStats", + "Memory", + "MessageChannel", + "MessageEvent", + "MessagePort", + "MessageSender", + "Methods", + "MimeType", + "MimeTypeArray", + "Module", + "MouseEvent", + "MouseScrollEvent", + "MozAnimation", + "MozAnimationDelay", + "MozAnimationDirection", + "MozAnimationDuration", + "MozAnimationFillMode", + "MozAnimationIterationCount", + "MozAnimationName", + "MozAnimationPlayState", + "MozAnimationTimingFunction", + "MozAppearance", + "MozBackfaceVisibility", + "MozBinding", + "MozBorderBottomColors", + "MozBorderEnd", + "MozBorderEndColor", + "MozBorderEndStyle", + "MozBorderEndWidth", + "MozBorderImage", + "MozBorderLeftColors", + "MozBorderRightColors", + "MozBorderStart", + "MozBorderStartColor", + "MozBorderStartStyle", + "MozBorderStartWidth", + "MozBorderTopColors", + "MozBoxAlign", + "MozBoxDirection", + "MozBoxFlex", + "MozBoxOrdinalGroup", + "MozBoxOrient", + "MozBoxPack", + "MozBoxSizing", + "MozCSSKeyframeRule", + "MozCSSKeyframesRule", + "MozColumnCount", + "MozColumnFill", + "MozColumnGap", + "MozColumnRule", + "MozColumnRuleColor", + "MozColumnRuleStyle", + "MozColumnRuleWidth", + "MozColumnWidth", + "MozColumns", + "MozContactChangeEvent", + "MozFloatEdge", + "MozFontFeatureSettings", + "MozFontLanguageOverride", + "MozForceBrokenImageIcon", + "MozHyphens", + "MozImageRegion", + "MozMarginEnd", + "MozMarginStart", + "MozMmsEvent", + "MozMmsMessage", + "MozMobileMessageThread", + "MozOSXFontSmoothing", + "MozOrient", + "MozOsxFontSmoothing", + "MozOutlineRadius", + "MozOutlineRadiusBottomleft", + "MozOutlineRadiusBottomright", + "MozOutlineRadiusTopleft", + "MozOutlineRadiusTopright", + "MozPaddingEnd", + "MozPaddingStart", + "MozPerspective", + "MozPerspectiveOrigin", + "MozPowerManager", + "MozSettingsEvent", + "MozSmsEvent", + "MozSmsMessage", + "MozStackSizing", + "MozTabSize", + "MozTextAlignLast", + "MozTextDecorationColor", + "MozTextDecorationLine", + "MozTextDecorationStyle", + "MozTextSizeAdjust", + "MozTransform", + "MozTransformOrigin", + "MozTransformStyle", + "MozTransition", + "MozTransitionDelay", + "MozTransitionDuration", + "MozTransitionProperty", + "MozTransitionTimingFunction", + "MozUserFocus", + "MozUserInput", + "MozUserModify", + "MozUserSelect", + "MozWindowDragging", + "MozWindowShadow", + "MutationEvent", + "MutationObserver", + "MutationRecord", + "MutedInfo", + "MutedInfoReason", + "NAMESPACE_ERR", + "NAMESPACE_RULE", + "NEAREST", + "NEAREST_MIPMAP_LINEAR", + "NEAREST_MIPMAP_NEAREST", + "NEGATIVE_INFINITY", + "NETWORK_EMPTY", + "NETWORK_ERR", + "NETWORK_IDLE", + "NETWORK_LOADED", + "NETWORK_LOADING", + "NETWORK_NO_SOURCE", + "NEVER", + "NEW", + "NEXT", + "NEXT_NO_DUPLICATE", + "NICEST", + "NODE_AFTER", + "NODE_BEFORE", + "NODE_BEFORE_AND_AFTER", + "NODE_INSIDE", + "NONE", + "NON_TRANSIENT_ERR", + "NOTATION_NODE", + "NOTCH", + "NOTEQUAL", + "NOT_ALLOWED_ERR", + "NOT_FOUND_ERR", + "NOT_READABLE_ERR", + "NOT_SUPPORTED_ERR", + "NO_DATA_ALLOWED_ERR", + "NO_ERR", + "NO_ERROR", + "NO_MODIFICATION_ALLOWED_ERR", + "NUMBER_TYPE", + "NUM_COMPRESSED_TEXTURE_FORMATS", + "NaN", + "NamedNodeMap", + "NavigateEvent", + "Navigation", + "NavigationActivation", + "NavigationCurrentEntryChangeEvent", + "NavigationDestination", + "NavigationHistoryEntry", + "NavigationPreloadManager", + "NavigationTransition", + "Navigator", + "NavigatorLogin", + "NavigatorManagedData", + "NavigatorUAData", + "NearbyLinks", + "NetworkInformation", + "Node", + "NodeFilter", + "NodeIterator", + "NodeList", + "NotRestoredReasonDetails", + "NotRestoredReasons", + "Notation", + "Notification", + "NotifyPaintEvent", + "Number", + "NumberFormat", + "OBJECT_TYPE", + "OBSOLETE", + "OK", + "ONE", + "ONE_MINUS_CONSTANT_ALPHA", + "ONE_MINUS_CONSTANT_COLOR", + "ONE_MINUS_DST_ALPHA", + "ONE_MINUS_DST_COLOR", + "ONE_MINUS_SRC_ALPHA", + "ONE_MINUS_SRC_COLOR", + "OPEN", + "OPENED", + "OPENING", + "ORDERED_NODE_ITERATOR_TYPE", + "ORDERED_NODE_SNAPSHOT_TYPE", + "OTHER_ERROR", + "OTPCredential", + "OUT_OF_MEMORY", + "Object", + "OfflineAudioCompletionEvent", + "OfflineAudioContext", + "OfflineResourceList", + "OffscreenCanvas", + "OffscreenCanvasRenderingContext2D", + "OnClickData", + "OnInstalledReason", + "OnPerformanceWarningCategory", + "OnPerformanceWarningSeverity", + "OnRestartRequiredReason", + "Option", + "OrientationSensor", + "OscillatorNode", + "OverconstrainedError", + "OverflowEvent", + "PACK_ALIGNMENT", + "PACK_ROW_LENGTH", + "PACK_SKIP_PIXELS", + "PACK_SKIP_ROWS", + "PAGE_RULE", + "PARSE_ERR", + "PATHSEG_ARC_ABS", + "PATHSEG_ARC_REL", + "PATHSEG_CLOSEPATH", + "PATHSEG_CURVETO_CUBIC_ABS", + "PATHSEG_CURVETO_CUBIC_REL", + "PATHSEG_CURVETO_CUBIC_SMOOTH_ABS", + "PATHSEG_CURVETO_CUBIC_SMOOTH_REL", + "PATHSEG_CURVETO_QUADRATIC_ABS", + "PATHSEG_CURVETO_QUADRATIC_REL", + "PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS", + "PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL", + "PATHSEG_LINETO_ABS", + "PATHSEG_LINETO_HORIZONTAL_ABS", + "PATHSEG_LINETO_HORIZONTAL_REL", + "PATHSEG_LINETO_REL", + "PATHSEG_LINETO_VERTICAL_ABS", + "PATHSEG_LINETO_VERTICAL_REL", + "PATHSEG_MOVETO_ABS", + "PATHSEG_MOVETO_REL", + "PATHSEG_UNKNOWN", + "PATH_EXISTS_ERR", + "PEAKING", + "PERMISSION_DENIED", + "PERSISTENT", + "PI", + "PIXEL_PACK_BUFFER", + "PIXEL_PACK_BUFFER_BINDING", + "PIXEL_UNPACK_BUFFER", + "PIXEL_UNPACK_BUFFER_BINDING", + "PLAYING_STATE", + "POINTS", + "POLYGON_OFFSET_FACTOR", + "POLYGON_OFFSET_FILL", + "POLYGON_OFFSET_UNITS", + "POSITION_UNAVAILABLE", + "POSITIVE_INFINITY", + "PREV", + "PREV_NO_DUPLICATE", + "PROCESSING_INSTRUCTION_NODE", + "PageChangeEvent", + "PageRevealEvent", + "PageSettings", + "PageSwapEvent", + "PageTransitionEvent", + "PaintRequest", + "PaintRequestList", + "PannerNode", + "PasswordCredential", + "Path2D", + "PaymentAddress", + "PaymentInstruments", + "PaymentManager", + "PaymentMethodChangeEvent", + "PaymentRequest", + "PaymentRequestUpdateEvent", + "PaymentResponse", + "Performance", + "PerformanceElementTiming", + "PerformanceEntry", + "PerformanceEventTiming", + "PerformanceLongAnimationFrameTiming", + "PerformanceLongTaskTiming", + "PerformanceMark", + "PerformanceMeasure", + "PerformanceNavigation", + "PerformanceNavigationTiming", + "PerformanceObserver", + "PerformanceObserverEntryList", + "PerformancePaintTiming", + "PerformanceResourceTiming", + "PerformanceScriptTiming", + "PerformanceServerTiming", + "PerformanceTiming", + "PeriodicSyncManager", + "PeriodicWave", + "PermissionStatus", + "Permissions", + "PhotoCapabilities", + "PictureInPictureEvent", + "PictureInPictureWindow", + "PlatformArch", + "PlatformInfo", + "PlatformNaclArch", + "PlatformOs", + "Plugin", + "PluginArray", + "PluralRules", + "PointerEvent", + "PopStateEvent", + "PopupBlockedEvent", + "Port", + "Presentation", + "PresentationAvailability", + "PresentationConnection", + "PresentationConnectionAvailableEvent", + "PresentationConnectionCloseEvent", + "PresentationConnectionList", + "PresentationReceiver", + "PresentationRequest", + "PressureObserver", + "PressureRecord", + "ProcessingInstruction", + "Profiler", + "ProgressEvent", + "Promise", + "PromiseRejectionEvent", + "PropertyNodeList", + "ProtectedAudience", + "Proxy", + "PublicKeyCredential", + "PushManager", + "PushSubscription", + "PushSubscriptionOptions", + "Q", + "QUERY_RESOLVE", + "QUERY_RESULT", + "QUERY_RESULT_AVAILABLE", + "QUOTA_ERR", + "QUOTA_EXCEEDED_ERR", + "QueryInterface", + "R11F_G11F_B10F", + "R16F", + "R16I", + "R16UI", + "R32F", + "R32I", + "R32UI", + "R8", + "R8I", + "R8UI", + "R8_SNORM", + "RASTERIZER_DISCARD", + "READ", + "READ_BUFFER", + "READ_FRAMEBUFFER", + "READ_FRAMEBUFFER_BINDING", + "READ_ONLY", + "READ_ONLY_ERR", + "READ_WRITE", + "RED", + "RED_BITS", + "RED_INTEGER", + "REMOVAL", + "RENDERBUFFER", + "RENDERBUFFER_ALPHA_SIZE", + "RENDERBUFFER_BINDING", + "RENDERBUFFER_BLUE_SIZE", + "RENDERBUFFER_DEPTH_SIZE", + "RENDERBUFFER_GREEN_SIZE", + "RENDERBUFFER_HEIGHT", + "RENDERBUFFER_INTERNAL_FORMAT", + "RENDERBUFFER_RED_SIZE", + "RENDERBUFFER_SAMPLES", + "RENDERBUFFER_STENCIL_SIZE", + "RENDERBUFFER_WIDTH", + "RENDERER", + "RENDERING_INTENT_ABSOLUTE_COLORIMETRIC", + "RENDERING_INTENT_AUTO", + "RENDERING_INTENT_PERCEPTUAL", + "RENDERING_INTENT_RELATIVE_COLORIMETRIC", + "RENDERING_INTENT_SATURATION", + "RENDERING_INTENT_UNKNOWN", + "RENDER_ATTACHMENT", + "REPEAT", + "REPLACE", + "RG", + "RG16F", + "RG16I", + "RG16UI", + "RG32F", + "RG32I", + "RG32UI", + "RG8", + "RG8I", + "RG8UI", + "RG8_SNORM", + "RGB", + "RGB10_A2", + "RGB10_A2UI", + "RGB16F", + "RGB16I", + "RGB16UI", + "RGB32F", + "RGB32I", + "RGB32UI", + "RGB565", + "RGB5_A1", + "RGB8", + "RGB8I", + "RGB8UI", + "RGB8_SNORM", + "RGB9_E5", + "RGBA", + "RGBA16F", + "RGBA16I", + "RGBA16UI", + "RGBA32F", + "RGBA32I", + "RGBA32UI", + "RGBA4", + "RGBA8", + "RGBA8I", + "RGBA8UI", + "RGBA8_SNORM", + "RGBA_INTEGER", + "RGBColor", + "RGB_INTEGER", + "RG_INTEGER", + "ROTATION_CLOCKWISE", + "ROTATION_COUNTERCLOCKWISE", + "RTCCertificate", + "RTCDTMFSender", + "RTCDTMFToneChangeEvent", + "RTCDataChannel", + "RTCDataChannelEvent", + "RTCDtlsTransport", + "RTCEncodedAudioFrame", + "RTCEncodedVideoFrame", + "RTCError", + "RTCErrorEvent", + "RTCIceCandidate", + "RTCIceTransport", + "RTCPeerConnection", + "RTCPeerConnectionIceErrorEvent", + "RTCPeerConnectionIceEvent", + "RTCRtpReceiver", + "RTCRtpScriptTransform", + "RTCRtpSender", + "RTCRtpTransceiver", + "RTCSctpTransport", + "RTCSessionDescription", + "RTCStatsReport", + "RTCTrackEvent", + "RadioNodeList", + "Range", + "RangeError", + "RangeException", + "ReadableByteStreamController", + "ReadableStream", + "ReadableStreamBYOBReader", + "ReadableStreamBYOBRequest", + "ReadableStreamDefaultController", + "ReadableStreamDefaultReader", + "RecordErrorEvent", + "Rect", + "ReferenceError", + "Reflect", + "RegExp", + "RelativeOrientationSensor", + "RelativeTimeFormat", + "RemotePlayback", + "Report", + "ReportBody", + "ReportingObserver", + "Request", + "RequestUpdateCheckStatus", + "ResizeObserver", + "ResizeObserverEntry", + "ResizeObserverSize", + "Response", + "RuntimeError", + "SAMPLER_2D", + "SAMPLER_2D_ARRAY", + "SAMPLER_2D_ARRAY_SHADOW", + "SAMPLER_2D_SHADOW", + "SAMPLER_3D", + "SAMPLER_BINDING", + "SAMPLER_CUBE", + "SAMPLER_CUBE_SHADOW", + "SAMPLES", + "SAMPLE_ALPHA_TO_COVERAGE", + "SAMPLE_BUFFERS", + "SAMPLE_COVERAGE", + "SAMPLE_COVERAGE_INVERT", + "SAMPLE_COVERAGE_VALUE", + "SAWTOOTH", + "SCHEDULED_STATE", + "SCISSOR_BOX", + "SCISSOR_TEST", + "SCROLL_PAGE_DOWN", + "SCROLL_PAGE_UP", + "SDP_ANSWER", + "SDP_OFFER", + "SDP_PRANSWER", + "SECURITY_ERR", + "SELECT", + "SEPARATE_ATTRIBS", + "SERIALIZE_ERR", + "SEVERITY_ERROR", + "SEVERITY_FATAL_ERROR", + "SEVERITY_WARNING", + "SHADER_COMPILER", + "SHADER_TYPE", + "SHADING_LANGUAGE_VERSION", + "SHIFT_MASK", + "SHORT", + "SHOWING", + "SHOW_ALL", + "SHOW_ATTRIBUTE", + "SHOW_CDATA_SECTION", + "SHOW_COMMENT", + "SHOW_DOCUMENT", + "SHOW_DOCUMENT_FRAGMENT", + "SHOW_DOCUMENT_TYPE", + "SHOW_ELEMENT", + "SHOW_ENTITY", + "SHOW_ENTITY_REFERENCE", + "SHOW_NOTATION", + "SHOW_PROCESSING_INSTRUCTION", + "SHOW_TEXT", + "SIGNALED", + "SIGNED_NORMALIZED", + "SINE", + "SOUNDFIELD", + "SQLException", + "SQRT1_2", + "SQRT2", + "SQUARE", + "SRC_ALPHA", + "SRC_ALPHA_SATURATE", + "SRC_COLOR", + "SRGB", + "SRGB8", + "SRGB8_ALPHA8", + "START_TO_END", + "START_TO_START", + "STATIC_COPY", + "STATIC_DRAW", + "STATIC_READ", + "STENCIL", + "STENCIL_ATTACHMENT", + "STENCIL_BACK_FAIL", + "STENCIL_BACK_FUNC", + "STENCIL_BACK_PASS_DEPTH_FAIL", + "STENCIL_BACK_PASS_DEPTH_PASS", + "STENCIL_BACK_REF", + "STENCIL_BACK_VALUE_MASK", + "STENCIL_BACK_WRITEMASK", + "STENCIL_BITS", + "STENCIL_BUFFER_BIT", + "STENCIL_CLEAR_VALUE", + "STENCIL_FAIL", + "STENCIL_FUNC", + "STENCIL_INDEX", + "STENCIL_INDEX8", + "STENCIL_PASS_DEPTH_FAIL", + "STENCIL_PASS_DEPTH_PASS", + "STENCIL_REF", + "STENCIL_TEST", + "STENCIL_VALUE_MASK", + "STENCIL_WRITEMASK", + "STORAGE", + "STORAGE_BINDING", + "STREAM_COPY", + "STREAM_DRAW", + "STREAM_READ", + "STRING_TYPE", + "STYLE_RULE", + "SUBPIXEL_BITS", + "SUPPORTS_RULE", + "SVGAElement", + "SVGAltGlyphDefElement", + "SVGAltGlyphElement", + "SVGAltGlyphItemElement", + "SVGAngle", + "SVGAnimateColorElement", + "SVGAnimateElement", + "SVGAnimateMotionElement", + "SVGAnimateTransformElement", + "SVGAnimatedAngle", + "SVGAnimatedBoolean", + "SVGAnimatedEnumeration", + "SVGAnimatedInteger", + "SVGAnimatedLength", + "SVGAnimatedLengthList", + "SVGAnimatedNumber", + "SVGAnimatedNumberList", + "SVGAnimatedPreserveAspectRatio", + "SVGAnimatedRect", + "SVGAnimatedString", + "SVGAnimatedTransformList", + "SVGAnimationElement", + "SVGCircleElement", + "SVGClipPathElement", + "SVGColor", + "SVGComponentTransferFunctionElement", + "SVGCursorElement", + "SVGDefsElement", + "SVGDescElement", + "SVGDiscardElement", + "SVGDocument", + "SVGElement", + "SVGElementInstance", + "SVGElementInstanceList", + "SVGEllipseElement", + "SVGException", + "SVGFEBlendElement", + "SVGFEColorMatrixElement", + "SVGFEComponentTransferElement", + "SVGFECompositeElement", + "SVGFEConvolveMatrixElement", + "SVGFEDiffuseLightingElement", + "SVGFEDisplacementMapElement", + "SVGFEDistantLightElement", + "SVGFEDropShadowElement", + "SVGFEFloodElement", + "SVGFEFuncAElement", + "SVGFEFuncBElement", + "SVGFEFuncGElement", + "SVGFEFuncRElement", + "SVGFEGaussianBlurElement", + "SVGFEImageElement", + "SVGFEMergeElement", + "SVGFEMergeNodeElement", + "SVGFEMorphologyElement", + "SVGFEOffsetElement", + "SVGFEPointLightElement", + "SVGFESpecularLightingElement", + "SVGFESpotLightElement", + "SVGFETileElement", + "SVGFETurbulenceElement", + "SVGFilterElement", + "SVGFontElement", + "SVGFontFaceElement", + "SVGFontFaceFormatElement", + "SVGFontFaceNameElement", + "SVGFontFaceSrcElement", + "SVGFontFaceUriElement", + "SVGForeignObjectElement", + "SVGGElement", + "SVGGeometryElement", + "SVGGlyphElement", + "SVGGlyphRefElement", + "SVGGradientElement", + "SVGGraphicsElement", + "SVGHKernElement", + "SVGImageElement", + "SVGLength", + "SVGLengthList", + "SVGLineElement", + "SVGLinearGradientElement", + "SVGMPathElement", + "SVGMarkerElement", + "SVGMaskElement", + "SVGMatrix", + "SVGMetadataElement", + "SVGMissingGlyphElement", + "SVGNumber", + "SVGNumberList", + "SVGPaint", + "SVGPathElement", + "SVGPathSeg", + "SVGPathSegArcAbs", + "SVGPathSegArcRel", + "SVGPathSegClosePath", + "SVGPathSegCurvetoCubicAbs", + "SVGPathSegCurvetoCubicRel", + "SVGPathSegCurvetoCubicSmoothAbs", + "SVGPathSegCurvetoCubicSmoothRel", + "SVGPathSegCurvetoQuadraticAbs", + "SVGPathSegCurvetoQuadraticRel", + "SVGPathSegCurvetoQuadraticSmoothAbs", + "SVGPathSegCurvetoQuadraticSmoothRel", + "SVGPathSegLinetoAbs", + "SVGPathSegLinetoHorizontalAbs", + "SVGPathSegLinetoHorizontalRel", + "SVGPathSegLinetoRel", + "SVGPathSegLinetoVerticalAbs", + "SVGPathSegLinetoVerticalRel", + "SVGPathSegList", + "SVGPathSegMovetoAbs", + "SVGPathSegMovetoRel", + "SVGPatternElement", + "SVGPoint", + "SVGPointList", + "SVGPolygonElement", + "SVGPolylineElement", + "SVGPreserveAspectRatio", + "SVGRadialGradientElement", + "SVGRect", + "SVGRectElement", + "SVGRenderingIntent", + "SVGSVGElement", + "SVGScriptElement", + "SVGSetElement", + "SVGStopElement", + "SVGStringList", + "SVGStyleElement", + "SVGSwitchElement", + "SVGSymbolElement", + "SVGTRefElement", + "SVGTSpanElement", + "SVGTextContentElement", + "SVGTextElement", + "SVGTextPathElement", + "SVGTextPositioningElement", + "SVGTitleElement", + "SVGTransform", + "SVGTransformList", + "SVGUnitTypes", + "SVGUseElement", + "SVGVKernElement", + "SVGViewElement", + "SVGViewSpec", + "SVGZoomAndPan", + "SVGZoomEvent", + "SVG_ANGLETYPE_DEG", + "SVG_ANGLETYPE_GRAD", + "SVG_ANGLETYPE_RAD", + "SVG_ANGLETYPE_UNKNOWN", + "SVG_ANGLETYPE_UNSPECIFIED", + "SVG_CHANNEL_A", + "SVG_CHANNEL_B", + "SVG_CHANNEL_G", + "SVG_CHANNEL_R", + "SVG_CHANNEL_UNKNOWN", + "SVG_COLORTYPE_CURRENTCOLOR", + "SVG_COLORTYPE_RGBCOLOR", + "SVG_COLORTYPE_RGBCOLOR_ICCCOLOR", + "SVG_COLORTYPE_UNKNOWN", + "SVG_EDGEMODE_DUPLICATE", + "SVG_EDGEMODE_NONE", + "SVG_EDGEMODE_UNKNOWN", + "SVG_EDGEMODE_WRAP", + "SVG_FEBLEND_MODE_COLOR", + "SVG_FEBLEND_MODE_COLOR_BURN", + "SVG_FEBLEND_MODE_COLOR_DODGE", + "SVG_FEBLEND_MODE_DARKEN", + "SVG_FEBLEND_MODE_DIFFERENCE", + "SVG_FEBLEND_MODE_EXCLUSION", + "SVG_FEBLEND_MODE_HARD_LIGHT", + "SVG_FEBLEND_MODE_HUE", + "SVG_FEBLEND_MODE_LIGHTEN", + "SVG_FEBLEND_MODE_LUMINOSITY", + "SVG_FEBLEND_MODE_MULTIPLY", + "SVG_FEBLEND_MODE_NORMAL", + "SVG_FEBLEND_MODE_OVERLAY", + "SVG_FEBLEND_MODE_SATURATION", + "SVG_FEBLEND_MODE_SCREEN", + "SVG_FEBLEND_MODE_SOFT_LIGHT", + "SVG_FEBLEND_MODE_UNKNOWN", + "SVG_FECOLORMATRIX_TYPE_HUEROTATE", + "SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA", + "SVG_FECOLORMATRIX_TYPE_MATRIX", + "SVG_FECOLORMATRIX_TYPE_SATURATE", + "SVG_FECOLORMATRIX_TYPE_UNKNOWN", + "SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE", + "SVG_FECOMPONENTTRANSFER_TYPE_GAMMA", + "SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY", + "SVG_FECOMPONENTTRANSFER_TYPE_LINEAR", + "SVG_FECOMPONENTTRANSFER_TYPE_TABLE", + "SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN", + "SVG_FECOMPOSITE_OPERATOR_ARITHMETIC", + "SVG_FECOMPOSITE_OPERATOR_ATOP", + "SVG_FECOMPOSITE_OPERATOR_IN", + "SVG_FECOMPOSITE_OPERATOR_LIGHTER", + "SVG_FECOMPOSITE_OPERATOR_OUT", + "SVG_FECOMPOSITE_OPERATOR_OVER", + "SVG_FECOMPOSITE_OPERATOR_UNKNOWN", + "SVG_FECOMPOSITE_OPERATOR_XOR", + "SVG_INVALID_VALUE_ERR", + "SVG_LENGTHTYPE_CM", + "SVG_LENGTHTYPE_EMS", + "SVG_LENGTHTYPE_EXS", + "SVG_LENGTHTYPE_IN", + "SVG_LENGTHTYPE_MM", + "SVG_LENGTHTYPE_NUMBER", + "SVG_LENGTHTYPE_PC", + "SVG_LENGTHTYPE_PERCENTAGE", + "SVG_LENGTHTYPE_PT", + "SVG_LENGTHTYPE_PX", + "SVG_LENGTHTYPE_UNKNOWN", + "SVG_MARKERUNITS_STROKEWIDTH", + "SVG_MARKERUNITS_UNKNOWN", + "SVG_MARKERUNITS_USERSPACEONUSE", + "SVG_MARKER_ORIENT_ANGLE", + "SVG_MARKER_ORIENT_AUTO", + "SVG_MARKER_ORIENT_AUTO_START_REVERSE", + "SVG_MARKER_ORIENT_UNKNOWN", + "SVG_MASKTYPE_ALPHA", + "SVG_MASKTYPE_LUMINANCE", + "SVG_MATRIX_NOT_INVERTABLE", + "SVG_MEETORSLICE_MEET", + "SVG_MEETORSLICE_SLICE", + "SVG_MEETORSLICE_UNKNOWN", + "SVG_MORPHOLOGY_OPERATOR_DILATE", + "SVG_MORPHOLOGY_OPERATOR_ERODE", + "SVG_MORPHOLOGY_OPERATOR_UNKNOWN", + "SVG_PAINTTYPE_CURRENTCOLOR", + "SVG_PAINTTYPE_NONE", + "SVG_PAINTTYPE_RGBCOLOR", + "SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR", + "SVG_PAINTTYPE_UNKNOWN", + "SVG_PAINTTYPE_URI", + "SVG_PAINTTYPE_URI_CURRENTCOLOR", + "SVG_PAINTTYPE_URI_NONE", + "SVG_PAINTTYPE_URI_RGBCOLOR", + "SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR", + "SVG_PRESERVEASPECTRATIO_NONE", + "SVG_PRESERVEASPECTRATIO_UNKNOWN", + "SVG_PRESERVEASPECTRATIO_XMAXYMAX", + "SVG_PRESERVEASPECTRATIO_XMAXYMID", + "SVG_PRESERVEASPECTRATIO_XMAXYMIN", + "SVG_PRESERVEASPECTRATIO_XMIDYMAX", + "SVG_PRESERVEASPECTRATIO_XMIDYMID", + "SVG_PRESERVEASPECTRATIO_XMIDYMIN", + "SVG_PRESERVEASPECTRATIO_XMINYMAX", + "SVG_PRESERVEASPECTRATIO_XMINYMID", + "SVG_PRESERVEASPECTRATIO_XMINYMIN", + "SVG_SPREADMETHOD_PAD", + "SVG_SPREADMETHOD_REFLECT", + "SVG_SPREADMETHOD_REPEAT", + "SVG_SPREADMETHOD_UNKNOWN", + "SVG_STITCHTYPE_NOSTITCH", + "SVG_STITCHTYPE_STITCH", + "SVG_STITCHTYPE_UNKNOWN", + "SVG_TRANSFORM_MATRIX", + "SVG_TRANSFORM_ROTATE", + "SVG_TRANSFORM_SCALE", + "SVG_TRANSFORM_SKEWX", + "SVG_TRANSFORM_SKEWY", + "SVG_TRANSFORM_TRANSLATE", + "SVG_TRANSFORM_UNKNOWN", + "SVG_TURBULENCE_TYPE_FRACTALNOISE", + "SVG_TURBULENCE_TYPE_TURBULENCE", + "SVG_TURBULENCE_TYPE_UNKNOWN", + "SVG_UNIT_TYPE_OBJECTBOUNDINGBOX", + "SVG_UNIT_TYPE_UNKNOWN", + "SVG_UNIT_TYPE_USERSPACEONUSE", + "SVG_WRONG_TYPE_ERR", + "SVG_ZOOMANDPAN_DISABLE", + "SVG_ZOOMANDPAN_MAGNIFY", + "SVG_ZOOMANDPAN_UNKNOWN", + "SYNC_CONDITION", + "SYNC_FENCE", + "SYNC_FLAGS", + "SYNC_FLUSH_COMMANDS_BIT", + "SYNC_GPU_COMMANDS_COMPLETE", + "SYNC_STATUS", + "SYNTAX_ERR", + "SavedPages", + "Scheduler", + "Scheduling", + "Screen", + "ScreenDetailed", + "ScreenDetails", + "ScreenOrientation", + "Script", + "ScriptProcessorNode", + "ScrollAreaEvent", + "ScrollTimeline", + "SecurityPolicyViolationEvent", + "Segmenter", + "Selection", + "Sensor", + "SensorErrorEvent", + "Serial", + "SerialPort", + "ServiceWorker", + "ServiceWorkerContainer", + "ServiceWorkerRegistration", + "SessionDescription", + "Set", + "ShadowRoot", + "SharedArrayBuffer", + "SharedStorage", + "SharedStorageWorklet", + "SharedWorker", + "SharingState", + "SimpleGestureEvent", + "SnapEvent", + "SourceBuffer", + "SourceBufferList", + "SpeechSynthesis", + "SpeechSynthesisErrorEvent", + "SpeechSynthesisEvent", + "SpeechSynthesisUtterance", + "SpeechSynthesisVoice", + "StaticRange", + "StereoPannerNode", + "StopIteration", + "Storage", + "StorageBucket", + "StorageBucketManager", + "StorageEvent", + "StorageManager", + "String", + "StructType", + "StylePropertyMap", + "StylePropertyMapReadOnly", + "StyleSheet", + "StyleSheetList", + "SubmitEvent", + "SubtleCrypto", + "Symbol", + "SyncManager", + "SyntaxError", + "TAB_ID_NONE", + "TAB_INDEX_NONE", + "TEMPORARY", + "TEXTPATH_METHODTYPE_ALIGN", + "TEXTPATH_METHODTYPE_STRETCH", + "TEXTPATH_METHODTYPE_UNKNOWN", + "TEXTPATH_SPACINGTYPE_AUTO", + "TEXTPATH_SPACINGTYPE_EXACT", + "TEXTPATH_SPACINGTYPE_UNKNOWN", + "TEXTURE", + "TEXTURE0", + "TEXTURE1", + "TEXTURE10", + "TEXTURE11", + "TEXTURE12", + "TEXTURE13", + "TEXTURE14", + "TEXTURE15", + "TEXTURE16", + "TEXTURE17", + "TEXTURE18", + "TEXTURE19", + "TEXTURE2", + "TEXTURE20", + "TEXTURE21", + "TEXTURE22", + "TEXTURE23", + "TEXTURE24", + "TEXTURE25", + "TEXTURE26", + "TEXTURE27", + "TEXTURE28", + "TEXTURE29", + "TEXTURE3", + "TEXTURE30", + "TEXTURE31", + "TEXTURE4", + "TEXTURE5", + "TEXTURE6", + "TEXTURE7", + "TEXTURE8", + "TEXTURE9", + "TEXTURE_2D", + "TEXTURE_2D_ARRAY", + "TEXTURE_3D", + "TEXTURE_BASE_LEVEL", + "TEXTURE_BINDING", + "TEXTURE_BINDING_2D", + "TEXTURE_BINDING_2D_ARRAY", + "TEXTURE_BINDING_3D", + "TEXTURE_BINDING_CUBE_MAP", + "TEXTURE_COMPARE_FUNC", + "TEXTURE_COMPARE_MODE", + "TEXTURE_CUBE_MAP", + "TEXTURE_CUBE_MAP_NEGATIVE_X", + "TEXTURE_CUBE_MAP_NEGATIVE_Y", + "TEXTURE_CUBE_MAP_NEGATIVE_Z", + "TEXTURE_CUBE_MAP_POSITIVE_X", + "TEXTURE_CUBE_MAP_POSITIVE_Y", + "TEXTURE_CUBE_MAP_POSITIVE_Z", + "TEXTURE_IMMUTABLE_FORMAT", + "TEXTURE_IMMUTABLE_LEVELS", + "TEXTURE_MAG_FILTER", + "TEXTURE_MAX_ANISOTROPY_EXT", + "TEXTURE_MAX_LEVEL", + "TEXTURE_MAX_LOD", + "TEXTURE_MIN_FILTER", + "TEXTURE_MIN_LOD", + "TEXTURE_WRAP_R", + "TEXTURE_WRAP_S", + "TEXTURE_WRAP_T", + "TEXT_NODE", + "TIMEOUT", + "TIMEOUT_ERR", + "TIMEOUT_EXPIRED", + "TIMEOUT_IGNORED", + "TOO_LARGE_ERR", + "TRANSACTION_INACTIVE_ERR", + "TRANSFORM_FEEDBACK", + "TRANSFORM_FEEDBACK_ACTIVE", + "TRANSFORM_FEEDBACK_BINDING", + "TRANSFORM_FEEDBACK_BUFFER", + "TRANSFORM_FEEDBACK_BUFFER_BINDING", + "TRANSFORM_FEEDBACK_BUFFER_MODE", + "TRANSFORM_FEEDBACK_BUFFER_SIZE", + "TRANSFORM_FEEDBACK_BUFFER_START", + "TRANSFORM_FEEDBACK_PAUSED", + "TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN", + "TRANSFORM_FEEDBACK_VARYINGS", + "TRIANGLE", + "TRIANGLES", + "TRIANGLE_FAN", + "TRIANGLE_STRIP", + "TYPE_BACK_FORWARD", + "TYPE_ERR", + "TYPE_MISMATCH_ERR", + "TYPE_NAVIGATE", + "TYPE_RELOAD", + "TYPE_RESERVED", + "Tab", + "TabStatus", + "Table", + "Tag", + "TaskAttributionTiming", + "TaskController", + "TaskPriorityChangeEvent", + "TaskSignal", + "Text", + "TextDecoder", + "TextDecoderStream", + "TextEncoder", + "TextEncoderStream", + "TextEvent", + "TextFormat", + "TextFormatUpdateEvent", + "TextMetrics", + "TextTrack", + "TextTrackCue", + "TextTrackCueList", + "TextTrackList", + "TextUpdateEvent", + "TimeEvent", + "TimeRanges", + "ToggleEvent", + "Touch", + "TouchEvent", + "TouchList", + "TrackEvent", + "TransformStream", + "TransformStreamDefaultController", + "TransitionEvent", + "TreeWalker", + "TrustedHTML", + "TrustedScript", + "TrustedScriptURL", + "TrustedTypePolicy", + "TrustedTypePolicyFactory", + "TypeError", + "TypedObject", + "U2F", + "UIEvent", + "UNCACHED", + "UNIFORM", + "UNIFORM_ARRAY_STRIDE", + "UNIFORM_BLOCK_ACTIVE_UNIFORMS", + "UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES", + "UNIFORM_BLOCK_BINDING", + "UNIFORM_BLOCK_DATA_SIZE", + "UNIFORM_BLOCK_INDEX", + "UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER", + "UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER", + "UNIFORM_BUFFER", + "UNIFORM_BUFFER_BINDING", + "UNIFORM_BUFFER_OFFSET_ALIGNMENT", + "UNIFORM_BUFFER_SIZE", + "UNIFORM_BUFFER_START", + "UNIFORM_IS_ROW_MAJOR", + "UNIFORM_MATRIX_STRIDE", + "UNIFORM_OFFSET", + "UNIFORM_SIZE", + "UNIFORM_TYPE", + "UNKNOWN_ERR", + "UNKNOWN_RULE", + "UNMASKED_RENDERER_WEBGL", + "UNMASKED_VENDOR_WEBGL", + "UNORDERED_NODE_ITERATOR_TYPE", + "UNORDERED_NODE_SNAPSHOT_TYPE", + "UNPACK_ALIGNMENT", + "UNPACK_COLORSPACE_CONVERSION_WEBGL", + "UNPACK_FLIP_Y_WEBGL", + "UNPACK_IMAGE_HEIGHT", + "UNPACK_PREMULTIPLY_ALPHA_WEBGL", + "UNPACK_ROW_LENGTH", + "UNPACK_SKIP_IMAGES", + "UNPACK_SKIP_PIXELS", + "UNPACK_SKIP_ROWS", + "UNSCHEDULED_STATE", + "UNSENT", + "UNSIGNALED", + "UNSIGNED_BYTE", + "UNSIGNED_INT", + "UNSIGNED_INT_10F_11F_11F_REV", + "UNSIGNED_INT_24_8", + "UNSIGNED_INT_2_10_10_10_REV", + "UNSIGNED_INT_5_9_9_9_REV", + "UNSIGNED_INT_SAMPLER_2D", + "UNSIGNED_INT_SAMPLER_2D_ARRAY", + "UNSIGNED_INT_SAMPLER_3D", + "UNSIGNED_INT_SAMPLER_CUBE", + "UNSIGNED_INT_VEC2", + "UNSIGNED_INT_VEC3", + "UNSIGNED_INT_VEC4", + "UNSIGNED_NORMALIZED", + "UNSIGNED_SHORT", + "UNSIGNED_SHORT_4_4_4_4", + "UNSIGNED_SHORT_5_5_5_1", + "UNSIGNED_SHORT_5_6_5", + "UNSPECIFIED_EVENT_TYPE_ERR", + "UPDATEREADY", + "URIError", + "URL", + "URLPattern", + "URLSearchParams", + "URLUnencoded", + "URL_MISMATCH_ERR", + "USB", + "USBAlternateInterface", + "USBConfiguration", + "USBConnectionEvent", + "USBDevice", + "USBEndpoint", + "USBInTransferResult", + "USBInterface", + "USBIsochronousInTransferPacket", + "USBIsochronousInTransferResult", + "USBIsochronousOutTransferPacket", + "USBIsochronousOutTransferResult", + "USBOutTransferResult", + "UTC", + "Uint16Array", + "Uint32Array", + "Uint8Array", + "Uint8ClampedArray", + "UpdateFilter", + "UpdatePropertyName", + "UserActivation", + "UserMessageHandler", + "UserMessageHandlersNamespace", + "UserProximityEvent", + "VALIDATE_STATUS", + "VALIDATION_ERR", + "VARIABLES_RULE", + "VENDOR", + "VERSION", + "VERSION_CHANGE", + "VERSION_ERR", + "VERTEX", + "VERTEX_ARRAY_BINDING", + "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING", + "VERTEX_ATTRIB_ARRAY_DIVISOR", + "VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE", + "VERTEX_ATTRIB_ARRAY_ENABLED", + "VERTEX_ATTRIB_ARRAY_INTEGER", + "VERTEX_ATTRIB_ARRAY_NORMALIZED", + "VERTEX_ATTRIB_ARRAY_POINTER", + "VERTEX_ATTRIB_ARRAY_SIZE", + "VERTEX_ATTRIB_ARRAY_STRIDE", + "VERTEX_ATTRIB_ARRAY_TYPE", + "VERTEX_SHADER", + "VERTICAL", + "VERTICAL_AXIS", + "VER_ERR", + "VIEWPORT", + "VIEWPORT_RULE", + "VRDisplay", + "VRDisplayCapabilities", + "VRDisplayEvent", + "VREyeParameters", + "VRFieldOfView", + "VRFrameData", + "VRPose", + "VRStageParameters", + "VTTCue", + "VTTRegion", + "ValidityState", + "VideoColorSpace", + "VideoDecoder", + "VideoEncoder", + "VideoFrame", + "VideoPlaybackQuality", + "VideoStreamTrack", + "ViewTimeline", + "ViewTransition", + "ViewTransitionTypeSet", + "ViewType", + "VirtualKeyboard", + "VirtualKeyboardGeometryChangeEvent", + "VisibilityStateEntry", + "VisualViewport", + "WAIT_FAILED", + "WEBKIT_FILTER_RULE", + "WEBKIT_KEYFRAMES_RULE", + "WEBKIT_KEYFRAME_RULE", + "WEBKIT_REGION_RULE", + "WGSLLanguageFeatures", + "WINDOW_ID_CURRENT", + "WINDOW_ID_NONE", + "WRITE", + "WRONG_DOCUMENT_ERR", + "WakeLock", + "WakeLockSentinel", + "WasmAnyRef", + "WaveShaperNode", + "WeakMap", + "WeakRef", + "WeakSet", + "WebAssembly", + "WebGL2RenderingContext", + "WebGLActiveInfo", + "WebGLBuffer", + "WebGLContextEvent", + "WebGLFramebuffer", + "WebGLObject", + "WebGLProgram", + "WebGLQuery", + "WebGLRenderbuffer", + "WebGLRenderingContext", + "WebGLSampler", + "WebGLShader", + "WebGLShaderPrecisionFormat", + "WebGLSync", + "WebGLTexture", + "WebGLTransformFeedback", + "WebGLUniformLocation", + "WebGLVertexArray", + "WebGLVertexArrayObject", + "WebKitAnimationEvent", + "WebKitBlobBuilder", + "WebKitCSSFilterRule", + "WebKitCSSFilterValue", + "WebKitCSSKeyframeRule", + "WebKitCSSKeyframesRule", + "WebKitCSSMatrix", + "WebKitCSSRegionRule", + "WebKitCSSTransformValue", + "WebKitDataCue", + "WebKitGamepad", + "WebKitMediaKeyError", + "WebKitMediaKeyMessageEvent", + "WebKitMediaKeySession", + "WebKitMediaKeys", + "WebKitMediaSource", + "WebKitMutationObserver", + "WebKitNamespace", + "WebKitPlaybackTargetAvailabilityEvent", + "WebKitPoint", + "WebKitShadowRoot", + "WebKitSourceBuffer", + "WebKitSourceBufferList", + "WebKitTransitionEvent", + "WebSocket", + "WebSocketError", + "WebSocketStream", + "WebTransport", + "WebTransportBidirectionalStream", + "WebTransportDatagramDuplexStream", + "WebTransportError", + "WebTransportReceiveStream", + "WebTransportSendStream", + "WebkitAlignContent", + "WebkitAlignItems", + "WebkitAlignSelf", + "WebkitAnimation", + "WebkitAnimationDelay", + "WebkitAnimationDirection", + "WebkitAnimationDuration", + "WebkitAnimationFillMode", + "WebkitAnimationIterationCount", + "WebkitAnimationName", + "WebkitAnimationPlayState", + "WebkitAnimationTimingFunction", + "WebkitAppearance", + "WebkitBackfaceVisibility", + "WebkitBackgroundClip", + "WebkitBackgroundOrigin", + "WebkitBackgroundSize", + "WebkitBorderBottomLeftRadius", + "WebkitBorderBottomRightRadius", + "WebkitBorderImage", + "WebkitBorderRadius", + "WebkitBorderTopLeftRadius", + "WebkitBorderTopRightRadius", + "WebkitBoxAlign", + "WebkitBoxDirection", + "WebkitBoxFlex", + "WebkitBoxOrdinalGroup", + "WebkitBoxOrient", + "WebkitBoxPack", + "WebkitBoxShadow", + "WebkitBoxSizing", + "WebkitClipPath", + "WebkitFilter", + "WebkitFlex", + "WebkitFlexBasis", + "WebkitFlexDirection", + "WebkitFlexFlow", + "WebkitFlexGrow", + "WebkitFlexShrink", + "WebkitFlexWrap", + "WebkitFontFeatureSettings", + "WebkitJustifyContent", + "WebkitLineClamp", + "WebkitMask", + "WebkitMaskClip", + "WebkitMaskComposite", + "WebkitMaskImage", + "WebkitMaskOrigin", + "WebkitMaskPosition", + "WebkitMaskPositionX", + "WebkitMaskPositionY", + "WebkitMaskRepeat", + "WebkitMaskSize", + "WebkitOrder", + "WebkitPerspective", + "WebkitPerspectiveOrigin", + "WebkitTextFillColor", + "WebkitTextSecurity", + "WebkitTextSizeAdjust", + "WebkitTextStroke", + "WebkitTextStrokeColor", + "WebkitTextStrokeWidth", + "WebkitTransform", + "WebkitTransformOrigin", + "WebkitTransformStyle", + "WebkitTransition", + "WebkitTransitionDelay", + "WebkitTransitionDuration", + "WebkitTransitionProperty", + "WebkitTransitionTimingFunction", + "WebkitUserSelect", + "WheelEvent", + "Window", + "WindowControlsOverlay", + "WindowControlsOverlayGeometryChangeEvent", + "WindowState", + "WindowType", + "Worker", + "Worklet", + "WritableStream", + "WritableStreamDefaultController", + "WritableStreamDefaultWriter", + "XMLDocument", + "XMLHttpRequest", + "XMLHttpRequestEventTarget", + "XMLHttpRequestException", + "XMLHttpRequestProgressEvent", + "XMLHttpRequestUpload", + "XMLSerializer", + "XMLStylesheetProcessingInstruction", + "XPathEvaluator", + "XPathException", + "XPathExpression", + "XPathNSResolver", + "XPathResult", + "XRAnchor", + "XRAnchorSet", + "XRBoundedReferenceSpace", + "XRCPUDepthInformation", + "XRCamera", + "XRDOMOverlayState", + "XRDepthInformation", + "XRFrame", + "XRHand", + "XRHitTestResult", + "XRHitTestSource", + "XRInputSource", + "XRInputSourceArray", + "XRInputSourceEvent", + "XRInputSourcesChangeEvent", + "XRJointPose", + "XRJointSpace", + "XRLayer", + "XRLightEstimate", + "XRLightProbe", + "XRPose", + "XRRay", + "XRReferenceSpace", + "XRReferenceSpaceEvent", + "XRRenderState", + "XRRigidTransform", + "XRSession", + "XRSessionEvent", + "XRSpace", + "XRSystem", + "XRTransientInputHitTestResult", + "XRTransientInputHitTestSource", + "XRView", + "XRViewerPose", + "XRViewport", + "XRWebGLBinding", + "XRWebGLDepthInformation", + "XRWebGLLayer", + "XSLTProcessor", + "ZERO", + "ZoomSettings", + "ZoomSettingsMode", + "ZoomSettingsScope", + "_XD0M_", + "_YD0M_", + "__REACT_DEVTOOLS_GLOBAL_HOOK__", + "__brand", + "__defineGetter__", + "__defineSetter__", + "__lookupGetter__", + "__lookupSetter__", + "__opera", + "__proto__", + "_browserjsran", + "a", + "aLink", + "abbr", + "abort", + "aborted", + "aboutConfigPrefs", + "abs", + "absolute", + "acceleration", + "accelerationIncludingGravity", + "accelerator", + "accent-color", + "accentColor", + "accept", + "acceptCharset", + "acceptNode", + "access", + "accessKey", + "accessKeyLabel", + "accuracy", + "acos", + "acosh", + "action", + "actionURL", + "actions", + "activated", + "activation", + "activationStart", + "active", + "activeCues", + "activeElement", + "activeSourceBuffers", + "activeSourceCount", + "activeTexture", + "activeVRDisplays", + "activityLog", + "actualBoundingBoxAscent", + "actualBoundingBoxDescent", + "actualBoundingBoxLeft", + "actualBoundingBoxRight", + "adAuctionComponents", + "adAuctionHeaders", + "add", + "addAll", + "addBehavior", + "addCandidate", + "addColorStop", + "addCue", + "addElement", + "addEventListener", + "addFilter", + "addFromString", + "addFromUri", + "addIceCandidate", + "addImport", + "addListener", + "addModule", + "addNamed", + "addPageRule", + "addPath", + "addPointer", + "addRange", + "addRegion", + "addRule", + "addSearchEngine", + "addSourceBuffer", + "addStream", + "addTextTrack", + "addTrack", + "addTransceiver", + "addWakeLockListener", + "added", + "addedNodes", + "additionalName", + "additiveSymbols", + "addons", + "address", + "addressLine", + "addressModeU", + "addressModeV", + "addressModeW", + "adoptNode", + "adoptedCallback", + "adoptedStyleSheets", + "adr", + "advance", + "after", + "alarms", + "album", + "alert", + "algorithm", + "align", + "align-content", + "align-items", + "align-self", + "alignContent", + "alignItems", + "alignSelf", + "alignmentBaseline", + "alinkColor", + "all", + "allSettled", + "allocationSize", + "allow", + "allowFullscreen", + "allowPaymentRequest", + "allowedDirections", + "allowedFeatures", + "allowedToPlay", + "allowsFeature", + "alpha", + "alphaMode", + "alphaToCoverageEnabled", + "alphabeticBaseline", + "alt", + "altGraphKey", + "altHtml", + "altKey", + "altLeft", + "alternate", + "alternateSetting", + "alternates", + "altitude", + "altitudeAccuracy", + "altitudeAngle", + "amplitude", + "ancestorOrigins", + "anchor", + "anchorNode", + "anchorOffset", + "anchorSpace", + "anchors", + "and", + "angle", + "angularAcceleration", + "angularVelocity", + "animVal", + "animate", + "animated", + "animatedInstanceRoot", + "animatedNormalizedPathSegList", + "animatedPathSegList", + "animatedPoints", + "animation", + "animation-composition", + "animation-delay", + "animation-direction", + "animation-duration", + "animation-fill-mode", + "animation-iteration-count", + "animation-name", + "animation-play-state", + "animation-timing-function", + "animationComposition", + "animationDelay", + "animationDirection", + "animationDuration", + "animationFillMode", + "animationIterationCount", + "animationName", + "animationPlayState", + "animationStartTime", + "animationTimingFunction", + "animationsPaused", + "anniversary", + "antialias", + "anticipatedRemoval", + "any", + "app", + "appCodeName", + "appMinorVersion", + "appName", + "appNotifications", + "appVersion", + "appearance", + "append", + "appendBuffer", + "appendChild", + "appendData", + "appendItem", + "appendMedium", + "appendNamed", + "appendRule", + "appendStream", + "appendWindowEnd", + "appendWindowStart", + "applets", + "applicationCache", + "applicationServerKey", + "apply", + "applyConstraints", + "applyElement", + "arc", + "arcTo", + "arch", + "architecture", + "archive", + "areas", + "arguments", + "ariaAtomic", + "ariaAutoComplete", + "ariaBrailleLabel", + "ariaBrailleRoleDescription", + "ariaBusy", + "ariaChecked", + "ariaColCount", + "ariaColIndex", + "ariaColIndexText", + "ariaColSpan", + "ariaCurrent", + "ariaDescription", + "ariaDisabled", + "ariaExpanded", + "ariaHasPopup", + "ariaHidden", + "ariaInvalid", + "ariaKeyShortcuts", + "ariaLabel", + "ariaLevel", + "ariaLive", + "ariaModal", + "ariaMultiLine", + "ariaMultiSelectable", + "ariaOrientation", + "ariaPlaceholder", + "ariaPosInSet", + "ariaPressed", + "ariaReadOnly", + "ariaRelevant", + "ariaRequired", + "ariaRoleDescription", + "ariaRowCount", + "ariaRowIndex", + "ariaRowIndexText", + "ariaRowSpan", + "ariaSelected", + "ariaSetSize", + "ariaSort", + "ariaValueMax", + "ariaValueMin", + "ariaValueNow", + "ariaValueText", + "arrayBuffer", + "arrayLayerCount", + "arrayStride", + "artist", + "artwork", + "as", + "asIntN", + "asUintN", + "ascentOverride", + "asin", + "asinh", + "aspect", + "aspect-ratio", + "aspectRatio", + "assert", + "assign", + "assignedElements", + "assignedNodes", + "assignedSlot", + "async", + "asyncDispose", + "asyncIterator", + "at", + "atEnd", + "atan", + "atan2", + "atanh", + "atob", + "attachEvent", + "attachInternals", + "attachShader", + "attachShadow", + "attachedElements", + "attachments", + "attack", + "attestationObject", + "attrChange", + "attrName", + "attributeChangedCallback", + "attributeFilter", + "attributeName", + "attributeNamespace", + "attributeOldValue", + "attributeStyleMap", + "attributes", + "attribution", + "attributionSrc", + "audioBitrateMode", + "audioBitsPerSecond", + "audioTracks", + "audioWorklet", + "authenticatedSignedWrites", + "authenticatorAttachment", + "authenticatorData", + "autoIncrement", + "autobuffer", + "autocapitalize", + "autocomplete", + "autocorrect", + "autofocus", + "automationRate", + "autoplay", + "availHeight", + "availLeft", + "availTop", + "availWidth", + "availability", + "available", + "averageLatency", + "aversion", + "ax", + "axes", + "axis", + "ay", + "azimuth", + "azimuthAngle", + "b", + "back", + "backdrop-filter", + "backdropFilter", + "backends", + "backface-visibility", + "backfaceVisibility", + "background", + "background-attachment", + "background-blend-mode", + "background-clip", + "background-color", + "background-image", + "background-origin", + "background-position", + "background-position-x", + "background-position-y", + "background-repeat", + "background-size", + "backgroundAttachment", + "backgroundBlendMode", + "backgroundClip", + "backgroundColor", + "backgroundFetch", + "backgroundImage", + "backgroundOrigin", + "backgroundPosition", + "backgroundPositionX", + "backgroundPositionY", + "backgroundRepeat", + "backgroundSize", + "badInput", + "badge", + "balance", + "baseArrayLayer", + "baseFrequencyX", + "baseFrequencyY", + "baseLatency", + "baseLayer", + "baseMipLevel", + "baseNode", + "baseOffset", + "basePalette", + "baseURI", + "baseVal", + "baseline-source", + "baselineShift", + "baselineSource", + "battery", + "bday", + "before", + "beginComputePass", + "beginElement", + "beginElementAt", + "beginOcclusionQuery", + "beginPath", + "beginQuery", + "beginRenderPass", + "beginTransformFeedback", + "beginningOfPassWriteIndex", + "behavior", + "behaviorCookie", + "behaviorPart", + "behaviorUrns", + "beta", + "bezierCurveTo", + "bgColor", + "bgProperties", + "bias", + "big", + "bigint64", + "biguint64", + "binaryType", + "bind", + "bindAttribLocation", + "bindBuffer", + "bindBufferBase", + "bindBufferRange", + "bindFramebuffer", + "bindGroupLayouts", + "bindRenderbuffer", + "bindSampler", + "bindTexture", + "bindTransformFeedback", + "bindVertexArray", + "binding", + "bitness", + "blend", + "blendColor", + "blendEquation", + "blendEquationSeparate", + "blendFunc", + "blendFuncSeparate", + "blink", + "blitFramebuffer", + "blob", + "block-size", + "blockDirection", + "blockSize", + "blockedURI", + "blocking", + "blockingDuration", + "blue", + "bluetooth", + "blur", + "body", + "bodyUsed", + "bold", + "bookmarks", + "booleanValue", + "border", + "border-block", + "border-block-color", + "border-block-end", + "border-block-end-color", + "border-block-end-style", + "border-block-end-width", + "border-block-start", + "border-block-start-color", + "border-block-start-style", + "border-block-start-width", + "border-block-style", + "border-block-width", + "border-bottom", + "border-bottom-color", + "border-bottom-left-radius", + "border-bottom-right-radius", + "border-bottom-style", + "border-bottom-width", + "border-collapse", + "border-color", + "border-end-end-radius", + "border-end-start-radius", + "border-image", + "border-image-outset", + "border-image-repeat", + "border-image-slice", + "border-image-source", + "border-image-width", + "border-inline", + "border-inline-color", + "border-inline-end", + "border-inline-end-color", + "border-inline-end-style", + "border-inline-end-width", + "border-inline-start", + "border-inline-start-color", + "border-inline-start-style", + "border-inline-start-width", + "border-inline-style", + "border-inline-width", + "border-left", + "border-left-color", + "border-left-style", + "border-left-width", + "border-radius", + "border-right", + "border-right-color", + "border-right-style", + "border-right-width", + "border-spacing", + "border-start-end-radius", + "border-start-start-radius", + "border-style", + "border-top", + "border-top-color", + "border-top-left-radius", + "border-top-right-radius", + "border-top-style", + "border-top-width", + "border-width", + "borderBlock", + "borderBlockColor", + "borderBlockEnd", + "borderBlockEndColor", + "borderBlockEndStyle", + "borderBlockEndWidth", + "borderBlockStart", + "borderBlockStartColor", + "borderBlockStartStyle", + "borderBlockStartWidth", + "borderBlockStyle", + "borderBlockWidth", + "borderBottom", + "borderBottomColor", + "borderBottomLeftRadius", + "borderBottomRightRadius", + "borderBottomStyle", + "borderBottomWidth", + "borderBoxSize", + "borderCollapse", + "borderColor", + "borderColorDark", + "borderColorLight", + "borderEndEndRadius", + "borderEndStartRadius", + "borderImage", + "borderImageOutset", + "borderImageRepeat", + "borderImageSlice", + "borderImageSource", + "borderImageWidth", + "borderInline", + "borderInlineColor", + "borderInlineEnd", + "borderInlineEndColor", + "borderInlineEndStyle", + "borderInlineEndWidth", + "borderInlineStart", + "borderInlineStartColor", + "borderInlineStartStyle", + "borderInlineStartWidth", + "borderInlineStyle", + "borderInlineWidth", + "borderLeft", + "borderLeftColor", + "borderLeftStyle", + "borderLeftWidth", + "borderRadius", + "borderRight", + "borderRightColor", + "borderRightStyle", + "borderRightWidth", + "borderSpacing", + "borderStartEndRadius", + "borderStartStartRadius", + "borderStyle", + "borderTop", + "borderTopColor", + "borderTopLeftRadius", + "borderTopRightRadius", + "borderTopStyle", + "borderTopWidth", + "borderWidth", + "bottom", + "bottomMargin", + "bound", + "boundElements", + "boundingClientRect", + "boundingHeight", + "boundingLeft", + "boundingRect", + "boundingTop", + "boundingWidth", + "bounds", + "boundsGeometry", + "box-decoration-break", + "box-shadow", + "box-sizing", + "boxDecorationBreak", + "boxShadow", + "boxSizing", + "brand", + "brands", + "break-after", + "break-before", + "break-inside", + "breakAfter", + "breakBefore", + "breakInside", + "broadcast", + "browser", + "browserLanguage", + "browserSettings", + "browsingData", + "browsingTopics", + "btoa", + "bubbles", + "buffer", + "bufferData", + "bufferDepth", + "bufferSize", + "bufferSubData", + "buffered", + "bufferedAmount", + "bufferedAmountLowThreshold", + "buffers", + "buildID", + "buildNumber", + "button", + "buttonID", + "buttons", + "byobRequest", + "byteLength", + "byteOffset", + "bytes", + "bytesPerRow", + "bytesWritten", + "c", + "cache", + "caches", + "call", + "caller", + "camera", + "canBeFormatted", + "canBeMounted", + "canBeShared", + "canConstructInDedicatedWorker", + "canGoBack", + "canGoForward", + "canHaveChildren", + "canHaveHTML", + "canInsertDTMF", + "canIntercept", + "canLoadAdAuctionFencedFrame", + "canLoadOpaqueURL", + "canMakePayment", + "canParse", + "canPlayType", + "canPresent", + "canShare", + "canTransition", + "canTrickleIceCandidates", + "cancel", + "cancelAndHoldAtTime", + "cancelAnimationFrame", + "cancelBubble", + "cancelIdleCallback", + "cancelScheduledValues", + "cancelVideoFrameCallback", + "cancelWatchAvailability", + "cancelable", + "candidate", + "canonicalUUID", + "canvas", + "cap", + "capabilities", + "caption", + "caption-side", + "captionSide", + "captivePortal", + "capture", + "captureEvents", + "captureStackTrace", + "captureStream", + "captureTab", + "captureVisibleTab", + "caret-color", + "caretBidiLevel", + "caretColor", + "caretPositionFromPoint", + "caretRangeFromPoint", + "cast", + "catch", + "category", + "cbrt", + "cd", + "ceil", + "cellIndex", + "cellPadding", + "cellSpacing", + "cells", + "ch", + "chOff", + "chain", + "challenge", + "changeType", + "changed", + "changedTouches", + "channel", + "channelCount", + "channelCountMode", + "channelInterpretation", + "chapterInfo", + "char", + "charAt", + "charCode", + "charCodeAt", + "charIndex", + "charLength", + "characterBounds", + "characterBoundsRangeStart", + "characterData", + "characterDataOldValue", + "characterSet", + "characteristic", + "charging", + "chargingTime", + "charset", + "check", + "checkDCE", + "checkEnclosure", + "checkFramebufferStatus", + "checkIntersection", + "checkValidity", + "checkVisibility", + "checked", + "childElementCount", + "childList", + "childNodes", + "children", + "chrome", + "ciphertext", + "cite", + "city", + "claimInterface", + "claimed", + "classList", + "className", + "classid", + "clear", + "clearAppBadge", + "clearAttributes", + "clearBuffer", + "clearBufferfi", + "clearBufferfv", + "clearBufferiv", + "clearBufferuiv", + "clearColor", + "clearData", + "clearDepth", + "clearHalt", + "clearImmediate", + "clearInterval", + "clearLiveSeekableRange", + "clearMarks", + "clearMaxGCPauseAccumulator", + "clearMeasures", + "clearOriginJoinedAdInterestGroups", + "clearParameters", + "clearRect", + "clearResourceTimings", + "clearShadow", + "clearStencil", + "clearTimeout", + "clearValue", + "clearWatch", + "click", + "clickCount", + "clientDataJSON", + "clientHeight", + "clientInformation", + "clientLeft", + "clientRect", + "clientRects", + "clientTop", + "clientWaitSync", + "clientWidth", + "clientX", + "clientY", + "clip", + "clip-path", + "clip-rule", + "clipBottom", + "clipLeft", + "clipPath", + "clipPathUnits", + "clipRight", + "clipRule", + "clipTop", + "clipboard", + "clipboardData", + "clonable", + "clone", + "cloneContents", + "cloneNode", + "cloneRange", + "close", + "closeCode", + "closePath", + "closed", + "closest", + "clz", + "clz32", + "cm", + "cmp", + "code", + "codeBase", + "codePointAt", + "codeType", + "codedHeight", + "codedRect", + "codedWidth", + "colSpan", + "collapse", + "collapseToEnd", + "collapseToStart", + "collapsed", + "collect", + "collections", + "colno", + "color", + "color-adjust", + "color-interpolation", + "color-interpolation-filters", + "color-scheme", + "colorAdjust", + "colorAttachments", + "colorDepth", + "colorFormats", + "colorInterpolation", + "colorInterpolationFilters", + "colorMask", + "colorScheme", + "colorSpace", + "colorType", + "cols", + "column-count", + "column-fill", + "column-gap", + "column-rule", + "column-rule-color", + "column-rule-style", + "column-rule-width", + "column-span", + "column-width", + "columnCount", + "columnFill", + "columnGap", + "columnNumber", + "columnRule", + "columnRuleColor", + "columnRuleStyle", + "columnRuleWidth", + "columnSpan", + "columnWidth", + "columns", + "command", + "commands", + "commit", + "commitLoadTime", + "commitPreferences", + "commitStyles", + "commonAncestorContainer", + "compact", + "compare", + "compareBoundaryPoints", + "compareDocumentPosition", + "compareEndPoints", + "compareExchange", + "compareNode", + "comparePoint", + "compatMode", + "compatible", + "compile", + "compileShader", + "compileStreaming", + "complete", + "completed", + "component", + "componentFromPoint", + "composed", + "composedPath", + "composite", + "compositionEndOffset", + "compositionStartOffset", + "compressedTexImage2D", + "compressedTexImage3D", + "compressedTexSubImage2D", + "compressedTexSubImage3D", + "compute", + "computedStyleMap", + "concat", + "conditionText", + "coneInnerAngle", + "coneOuterAngle", + "coneOuterGain", + "config", + "configurable", + "configuration", + "configurationName", + "configurationValue", + "configurations", + "configure", + "confirm", + "confirmComposition", + "confirmSiteSpecificTrackingException", + "confirmWebWideTrackingException", + "congestionControl", + "connect", + "connectEnd", + "connectNative", + "connectShark", + "connectStart", + "connected", + "connectedCallback", + "connection", + "connectionInfo", + "connectionList", + "connectionSpeed", + "connectionState", + "connections", + "console", + "consolidate", + "constants", + "constraint", + "constrictionActive", + "construct", + "constructor", + "contactID", + "contain", + "contain-intrinsic-block-size", + "contain-intrinsic-height", + "contain-intrinsic-inline-size", + "contain-intrinsic-size", + "contain-intrinsic-width", + "containIntrinsicBlockSize", + "containIntrinsicHeight", + "containIntrinsicInlineSize", + "containIntrinsicSize", + "containIntrinsicWidth", + "container", + "container-name", + "container-type", + "containerId", + "containerName", + "containerQuery", + "containerSrc", + "containerType", + "contains", + "containsNode", + "content", + "content-visibility", + "contentBoxSize", + "contentDocument", + "contentEditable", + "contentHint", + "contentOverflow", + "contentRect", + "contentScriptType", + "contentStyleType", + "contentType", + "contentVisibility", + "contentWindow", + "context", + "contextId", + "contextIds", + "contextMenu", + "contextMenus", + "contextType", + "contextTypes", + "contextmenu", + "contextualIdentities", + "continue", + "continuePrimaryKey", + "continuous", + "control", + "controlTransferIn", + "controlTransferOut", + "controller", + "controls", + "controlsList", + "convertPointFromNode", + "convertQuadFromNode", + "convertRectFromNode", + "convertToBlob", + "convertToSpecifiedUnits", + "cookie", + "cookieEnabled", + "cookieStore", + "cookies", + "coords", + "copyBufferSubData", + "copyBufferToBuffer", + "copyBufferToTexture", + "copyExternalImageToTexture", + "copyFromChannel", + "copyTexImage2D", + "copyTexSubImage2D", + "copyTexSubImage3D", + "copyTextureToBuffer", + "copyTextureToTexture", + "copyTo", + "copyToChannel", + "copyWithin", + "correspondingElement", + "correspondingUseElement", + "corruptedVideoFrames", + "cos", + "cosh", + "count", + "countReset", + "counter-increment", + "counter-reset", + "counter-set", + "counterIncrement", + "counterReset", + "counterSet", + "country", + "cpuClass", + "cpuSleepAllowed", + "cqb", + "cqh", + "cqi", + "cqmax", + "cqmin", + "cqw", + "create", + "createAnalyser", + "createAnchor", + "createAnswer", + "createAttribute", + "createAttributeNS", + "createAuctionNonce", + "createBidirectionalStream", + "createBindGroup", + "createBindGroupLayout", + "createBiquadFilter", + "createBuffer", + "createBufferSource", + "createCDATASection", + "createCSSStyleSheet", + "createCaption", + "createChannelMerger", + "createChannelSplitter", + "createCommandEncoder", + "createComment", + "createComputePipeline", + "createComputePipelineAsync", + "createConicGradient", + "createConstantSource", + "createContextualFragment", + "createControlRange", + "createConvolver", + "createDTMFSender", + "createDataChannel", + "createDelay", + "createDelayNode", + "createDocument", + "createDocumentFragment", + "createDocumentType", + "createDynamicsCompressor", + "createElement", + "createElementNS", + "createEncodedStreams", + "createEntityReference", + "createEvent", + "createEventObject", + "createExpression", + "createFramebuffer", + "createFunction", + "createGain", + "createGainNode", + "createHTML", + "createHTMLDocument", + "createIIRFilter", + "createImageBitmap", + "createImageData", + "createIndex", + "createJavaScriptNode", + "createLinearGradient", + "createMediaElementSource", + "createMediaKeys", + "createMediaStreamDestination", + "createMediaStreamSource", + "createMediaStreamTrackSource", + "createMutableFile", + "createNSResolver", + "createNodeIterator", + "createNotification", + "createObjectStore", + "createObjectURL", + "createOffer", + "createOscillator", + "createPanner", + "createPattern", + "createPeriodicWave", + "createPipelineLayout", + "createPolicy", + "createPopup", + "createProcessingInstruction", + "createProgram", + "createQuery", + "createQuerySet", + "createRadialGradient", + "createRange", + "createRangeCollection", + "createReader", + "createRenderBundleEncoder", + "createRenderPipeline", + "createRenderPipelineAsync", + "createRenderbuffer", + "createSVGAngle", + "createSVGLength", + "createSVGMatrix", + "createSVGNumber", + "createSVGPathSegArcAbs", + "createSVGPathSegArcRel", + "createSVGPathSegClosePath", + "createSVGPathSegCurvetoCubicAbs", + "createSVGPathSegCurvetoCubicRel", + "createSVGPathSegCurvetoCubicSmoothAbs", + "createSVGPathSegCurvetoCubicSmoothRel", + "createSVGPathSegCurvetoQuadraticAbs", + "createSVGPathSegCurvetoQuadraticRel", + "createSVGPathSegCurvetoQuadraticSmoothAbs", + "createSVGPathSegCurvetoQuadraticSmoothRel", + "createSVGPathSegLinetoAbs", + "createSVGPathSegLinetoHorizontalAbs", + "createSVGPathSegLinetoHorizontalRel", + "createSVGPathSegLinetoRel", + "createSVGPathSegLinetoVerticalAbs", + "createSVGPathSegLinetoVerticalRel", + "createSVGPathSegMovetoAbs", + "createSVGPathSegMovetoRel", + "createSVGPoint", + "createSVGRect", + "createSVGTransform", + "createSVGTransformFromMatrix", + "createSampler", + "createScript", + "createScriptProcessor", + "createScriptURL", + "createSession", + "createShader", + "createShaderModule", + "createShadowRoot", + "createStereoPanner", + "createStyleSheet", + "createTBody", + "createTFoot", + "createTHead", + "createTask", + "createTextNode", + "createTextRange", + "createTexture", + "createTouch", + "createTouchList", + "createTransformFeedback", + "createTreeWalker", + "createUnidirectionalStream", + "createVertexArray", + "createView", + "createWaveShaper", + "createWorklet", + "createWritable", + "creationTime", + "credentialless", + "credentials", + "criticalCHRestart", + "cropTo", + "crossOrigin", + "crossOriginIsolated", + "crypto", + "csi", + "csp", + "cssFloat", + "cssRules", + "cssText", + "cssValueType", + "ctrlKey", + "ctrlLeft", + "cues", + "cullFace", + "cullMode", + "currentCSSZoom", + "currentDirection", + "currentEntry", + "currentLocalDescription", + "currentNode", + "currentPage", + "currentRect", + "currentRemoteDescription", + "currentScale", + "currentScreen", + "currentScript", + "currentSrc", + "currentState", + "currentStyle", + "currentTarget", + "currentTime", + "currentTranslate", + "currentView", + "cursor", + "curve", + "customElements", + "customError", + "cx", + "cy", + "d", + "data", + "dataFld", + "dataFormatAs", + "dataLoss", + "dataLossMessage", + "dataPageSize", + "dataSrc", + "dataTransfer", + "database", + "databases", + "datagrams", + "dataset", + "dateTime", + "db", + "debug", + "debuggerEnabled", + "declarativeNetRequest", + "declare", + "decode", + "decodeAudioData", + "decodeQueueSize", + "decodeURI", + "decodeURIComponent", + "decodedBodySize", + "decoding", + "decodingInfo", + "decrypt", + "default", + "defaultCharset", + "defaultChecked", + "defaultMuted", + "defaultPlaybackRate", + "defaultPolicy", + "defaultPrevented", + "defaultQueue", + "defaultRequest", + "defaultSelected", + "defaultStatus", + "defaultURL", + "defaultValue", + "defaultView", + "defaultstatus", + "defer", + "define", + "defineMagicFunction", + "defineMagicVariable", + "defineProperties", + "defineProperty", + "deg", + "delay", + "delayTime", + "delegatesFocus", + "delete", + "deleteBuffer", + "deleteCaption", + "deleteCell", + "deleteContents", + "deleteData", + "deleteDatabase", + "deleteFramebuffer", + "deleteFromDocument", + "deleteIndex", + "deleteMedium", + "deleteObjectStore", + "deleteProgram", + "deleteProperty", + "deleteQuery", + "deleteRenderbuffer", + "deleteRow", + "deleteRule", + "deleteSampler", + "deleteShader", + "deleteSync", + "deleteTFoot", + "deleteTHead", + "deleteTexture", + "deleteTransformFeedback", + "deleteVertexArray", + "deleted", + "deliverChangeRecords", + "deliveredFrames", + "deliveredFramesDuration", + "delivery", + "deliveryInfo", + "deliveryStatus", + "deliveryTimestamp", + "deliveryType", + "delta", + "deltaMode", + "deltaX", + "deltaY", + "deltaZ", + "dependentLocality", + "deprecatedReplaceInURN", + "deprecatedRunAdAuctionEnforcesKAnonymity", + "deprecatedURNToURL", + "depthBias", + "depthBiasClamp", + "depthBiasSlopeScale", + "depthClearValue", + "depthCompare", + "depthDataFormat", + "depthFailOp", + "depthFar", + "depthFunc", + "depthLoadOp", + "depthMask", + "depthNear", + "depthOrArrayLayers", + "depthRange", + "depthReadOnly", + "depthStencil", + "depthStencilAttachment", + "depthStencilFormat", + "depthStoreOp", + "depthUsage", + "depthWriteEnabled", + "deref", + "deriveBits", + "deriveKey", + "descentOverride", + "description", + "deselectAll", + "designMode", + "desiredSize", + "destination", + "destinationURL", + "destroy", + "detach", + "detachEvent", + "detachShader", + "detached", + "detail", + "details", + "detect", + "detectLanguage", + "detune", + "device", + "deviceClass", + "deviceId", + "deviceMemory", + "devicePixelContentBoxSize", + "devicePixelRatio", + "deviceProtocol", + "deviceSubclass", + "deviceVersionMajor", + "deviceVersionMinor", + "deviceVersionSubminor", + "deviceXDPI", + "deviceYDPI", + "devtools", + "devtools_panels", + "didTimeout", + "difference", + "diffuseConstant", + "digest", + "dimension", + "dimensions", + "dir", + "dirName", + "direction", + "dirxml", + "disable", + "disablePictureInPicture", + "disableRemotePlayback", + "disableVertexAttribArray", + "disabled", + "discard", + "discardedFrames", + "dischargingTime", + "disconnect", + "disconnectShark", + "disconnectedCallback", + "dispatchEvent", + "dispatchWorkgroups", + "dispatchWorkgroupsIndirect", + "display", + "displayHeight", + "displayId", + "displayName", + "displayWidth", + "dispose", + "disposition", + "distanceModel", + "div", + "divisor", + "djsapi", + "djsproxy", + "dns", + "doImport", + "doNotTrack", + "doScroll", + "doctype", + "document", + "documentElement", + "documentId", + "documentIds", + "documentLifecycle", + "documentMode", + "documentOrigin", + "documentOrigins", + "documentPictureInPicture", + "documentURI", + "documentUrl", + "documentUrls", + "dolphin", + "dolphinGameCenter", + "dolphininfo", + "dolphinmeta", + "dom", + "domComplete", + "domContentLoadedEventEnd", + "domContentLoadedEventStart", + "domInteractive", + "domLoading", + "domOverlayState", + "domain", + "domainLookupEnd", + "domainLookupStart", + "dominant-baseline", + "dominantBaseline", + "done", + "dopplerFactor", + "dotAll", + "downDegrees", + "downlink", + "download", + "downloadRequest", + "downloadTotal", + "downloaded", + "downloads", + "dpcm", + "dpi", + "dppx", + "dragDrop", + "draggable", + "draw", + "drawArrays", + "drawArraysInstanced", + "drawArraysInstancedANGLE", + "drawBuffers", + "drawCustomFocusRing", + "drawElements", + "drawElementsInstanced", + "drawElementsInstancedANGLE", + "drawFocusIfNeeded", + "drawImage", + "drawImageFromRect", + "drawIndexed", + "drawIndexedIndirect", + "drawIndirect", + "drawRangeElements", + "drawSystemFocusRing", + "drawingBufferColorSpace", + "drawingBufferFormat", + "drawingBufferHeight", + "drawingBufferStorage", + "drawingBufferWidth", + "drop", + "dropEffect", + "droppedVideoFrames", + "dropzone", + "dstFactor", + "dtmf", + "dump", + "dumpProfile", + "duplex", + "duplicate", + "durability", + "duration", + "dvb", + "dvh", + "dvi", + "dvmax", + "dvmin", + "dvname", + "dvnum", + "dvw", + "dx", + "dy", + "dynamicId", + "dynsrc", + "e", + "edgeMode", + "editContext", + "effect", + "effectAllowed", + "effectiveDirective", + "effectiveType", + "effects", + "elapsedTime", + "element", + "elementFromPoint", + "elementTiming", + "elements", + "elementsFromPoint", + "elevation", + "ellipse", + "em", + "emHeightAscent", + "emHeightDescent", + "email", + "embeds", + "emit", + "emma", + "empty", + "empty-cells", + "emptyCells", + "emptyHTML", + "emptyScript", + "emulatedPosition", + "enable", + "enableBackground", + "enableDelegations", + "enableStyleSheetsForSet", + "enableVertexAttribArray", + "enabled", + "enabledFeatures", + "enabledPlugin", + "encode", + "encodeInto", + "encodeQueueSize", + "encodeURI", + "encodeURIComponent", + "encodedBodySize", + "encoding", + "encodingInfo", + "encrypt", + "enctype", + "end", + "endContainer", + "endElement", + "endElementAt", + "endOcclusionQuery", + "endOfPassWriteIndex", + "endOfStream", + "endOffset", + "endQuery", + "endTime", + "endTransformFeedback", + "ended", + "endpoint", + "endpointNumber", + "endpoints", + "endsWith", + "enqueue", + "enterKeyHint", + "entities", + "entries", + "entry", + "entryPoint", + "entryType", + "enumerable", + "enumerate", + "enumerateDevices", + "enumerateEditable", + "environmentBlendMode", + "equals", + "error", + "errorCode", + "errorDetail", + "errorText", + "escape", + "estimate", + "eval", + "evaluate", + "event", + "eventCounts", + "eventPhase", + "events", + "every", + "ex", + "exception", + "exchange", + "exec", + "execCommand", + "execCommandShowHelp", + "execScript", + "executeBundles", + "executionStart", + "exitFullscreen", + "exitPictureInPicture", + "exitPointerLock", + "exitPresent", + "exp", + "expand", + "expandEntityReferences", + "expando", + "expansion", + "expectedImprovement", + "experiments", + "expiration", + "expirationTime", + "expires", + "expiryDate", + "explicitOriginalTarget", + "expm1", + "exponent", + "exponentialRampToValueAtTime", + "exportKey", + "exports", + "extend", + "extension", + "extensionTypes", + "extensions", + "extentNode", + "extentOffset", + "external", + "externalResourcesRequired", + "externalTexture", + "extractContents", + "extractable", + "eye", + "f", + "f16round", + "face", + "factoryReset", + "failOp", + "failureReason", + "fallback", + "family", + "familyName", + "farthestViewportElement", + "fastSeek", + "fatal", + "featureId", + "featurePolicy", + "featureSettings", + "features", + "fence", + "fenceSync", + "fetch", + "fetchPriority", + "fetchStart", + "fftSize", + "fgColor", + "fieldOfView", + "file", + "fileCreatedDate", + "fileHandle", + "fileModifiedDate", + "fileName", + "fileSize", + "fileUpdatedDate", + "filename", + "files", + "filesystem", + "fill", + "fill-opacity", + "fill-rule", + "fillJointRadii", + "fillLightMode", + "fillOpacity", + "fillPoses", + "fillRect", + "fillRule", + "fillStyle", + "fillText", + "filter", + "filterResX", + "filterResY", + "filterUnits", + "filters", + "finally", + "find", + "findIndex", + "findLast", + "findLastIndex", + "findRule", + "findText", + "finish", + "finishDocumentLoadTime", + "finishLoadTime", + "finished", + "fireEvent", + "firesTouchEvents", + "firstChild", + "firstElementChild", + "firstInterimResponseStart", + "firstPage", + "firstPaintAfterLoadTime", + "firstPaintTime", + "firstUIEventTimestamp", + "fixed", + "flags", + "flat", + "flatMap", + "flex", + "flex-basis", + "flex-direction", + "flex-flow", + "flex-grow", + "flex-shrink", + "flex-wrap", + "flexBasis", + "flexDirection", + "flexFlow", + "flexGrow", + "flexShrink", + "flexWrap", + "flipX", + "flipY", + "float", + "float32", + "float64", + "flood-color", + "flood-opacity", + "floodColor", + "floodOpacity", + "floor", + "flush", + "focus", + "focusNode", + "focusOffset", + "font", + "font-family", + "font-feature-settings", + "font-kerning", + "font-language-override", + "font-optical-sizing", + "font-palette", + "font-size", + "font-size-adjust", + "font-stretch", + "font-style", + "font-synthesis", + "font-synthesis-position", + "font-synthesis-small-caps", + "font-synthesis-style", + "font-synthesis-weight", + "font-variant", + "font-variant-alternates", + "font-variant-caps", + "font-variant-east-asian", + "font-variant-ligatures", + "font-variant-numeric", + "font-variant-position", + "font-variation-settings", + "font-weight", + "fontBoundingBoxAscent", + "fontBoundingBoxDescent", + "fontFamily", + "fontFeatureSettings", + "fontKerning", + "fontLanguageOverride", + "fontOpticalSizing", + "fontPalette", + "fontSize", + "fontSizeAdjust", + "fontSmoothingEnabled", + "fontStretch", + "fontStyle", + "fontSynthesis", + "fontSynthesisPosition", + "fontSynthesisSmallCaps", + "fontSynthesisStyle", + "fontSynthesisWeight", + "fontVariant", + "fontVariantAlternates", + "fontVariantCaps", + "fontVariantEastAsian", + "fontVariantLigatures", + "fontVariantNumeric", + "fontVariantPosition", + "fontVariationSettings", + "fontWeight", + "fontcolor", + "fontfaces", + "fonts", + "fontsize", + "for", + "forEach", + "force", + "forceFallbackAdapter", + "forceRedraw", + "forced-color-adjust", + "forcedColorAdjust", + "forcedStyleAndLayoutDuration", + "forget", + "form", + "formAction", + "formData", + "formEnctype", + "formMethod", + "formNoValidate", + "formTarget", + "format", + "formatToParts", + "forms", + "forward", + "forwardX", + "forwardY", + "forwardZ", + "foundation", + "fr", + "fragment", + "fragmentDirective", + "frame", + "frameBorder", + "frameCount", + "frameElement", + "frameId", + "frameIds", + "frameSpacing", + "framebuffer", + "framebufferHeight", + "framebufferRenderbuffer", + "framebufferTexture2D", + "framebufferTextureLayer", + "framebufferWidth", + "frames", + "freeSpace", + "freeze", + "frequency", + "frequencyBinCount", + "from", + "fromAsync", + "fromBase64", + "fromCharCode", + "fromCodePoint", + "fromElement", + "fromEntries", + "fromFloat32Array", + "fromFloat64Array", + "fromHex", + "fromMatrix", + "fromPoint", + "fromQuad", + "fromRect", + "frontFace", + "fround", + "fullName", + "fullPath", + "fullRange", + "fullScreen", + "fullVersionList", + "fullscreen", + "fullscreenElement", + "fullscreenEnabled", + "fx", + "fy", + "g", + "gain", + "gamepad", + "gamma", + "gap", + "gatheringState", + "gatt", + "geckoProfiler", + "genderIdentity", + "generateCertificate", + "generateKey", + "generateMipmap", + "generateRequest", + "geolocation", + "gestureObject", + "get", + "getAcceptLanguages", + "getActiveAttrib", + "getActiveUniform", + "getActiveUniformBlockName", + "getActiveUniformBlockParameter", + "getActiveUniforms", + "getAdjacentText", + "getAll", + "getAllKeys", + "getAllResponseHeaders", + "getAllowlistForFeature", + "getAnimations", + "getAsFile", + "getAsFileSystemHandle", + "getAsString", + "getAttachedShaders", + "getAttribLocation", + "getAttribute", + "getAttributeNS", + "getAttributeNames", + "getAttributeNode", + "getAttributeNodeNS", + "getAttributeType", + "getAudioTracks", + "getAuthenticatorData", + "getAutoplayPolicy", + "getAvailability", + "getBBox", + "getBackgroundPage", + "getBadgeBackgroundColor", + "getBadgeText", + "getBadgeTextColor", + "getBattery", + "getBigInt64", + "getBigUint64", + "getBindGroupLayout", + "getBlob", + "getBookmark", + "getBoundingClientRect", + "getBounds", + "getBoxQuads", + "getBrowserInfo", + "getBufferParameter", + "getBufferSubData", + "getByteFrequencyData", + "getByteTimeDomainData", + "getCSSCanvasContext", + "getCTM", + "getCameraImage", + "getCandidateWindowClientRect", + "getCanonicalLocales", + "getCapabilities", + "getCaptureHandle", + "getChannelData", + "getCharNumAtPosition", + "getCharacteristic", + "getCharacteristics", + "getClientExtensionResults", + "getClientRect", + "getClientRects", + "getCoalescedEvents", + "getCompilationInfo", + "getCompositionAlternatives", + "getComputedStyle", + "getComputedTextLength", + "getComputedTiming", + "getConfiguration", + "getConstraints", + "getContext", + "getContextAttributes", + "getContexts", + "getContributingSources", + "getCounterValue", + "getCueAsHTML", + "getCueById", + "getCurrent", + "getCurrentPosition", + "getCurrentTexture", + "getCurrentTime", + "getData", + "getDatabaseNames", + "getDate", + "getDay", + "getDefaultComputedStyle", + "getDepthInMeters", + "getDepthInformation", + "getDescriptor", + "getDescriptors", + "getDestinationInsertionPoints", + "getDevices", + "getDirectory", + "getDirectoryHandle", + "getDisplayMedia", + "getDistributedNodes", + "getEditable", + "getElementById", + "getElementsByClassName", + "getElementsByName", + "getElementsByTagName", + "getElementsByTagNameNS", + "getEnclosureList", + "getEndPositionOfChar", + "getEntries", + "getEntriesByName", + "getEntriesByType", + "getError", + "getExtension", + "getExtentOfChar", + "getEyeParameters", + "getFeature", + "getFiberRoots", + "getFile", + "getFileHandle", + "getFiles", + "getFilesAndDirectories", + "getFingerprints", + "getFloat16", + "getFloat32", + "getFloat64", + "getFloatFrequencyData", + "getFloatTimeDomainData", + "getFloatValue", + "getFragDataLocation", + "getFrameData", + "getFrameId", + "getFramebufferAttachmentParameter", + "getFrequencyResponse", + "getFullYear", + "getGamepads", + "getHTML", + "getHeaderExtensionsToNegotiate", + "getHighEntropyValues", + "getHitTestResults", + "getHitTestResultsForTransientInput", + "getHours", + "getIdentityAssertion", + "getIds", + "getImageData", + "getIndexedParameter", + "getInfo", + "getInnerHTML", + "getInstalledRelatedApps", + "getInt16", + "getInt32", + "getInt8", + "getInterestGroupAdAuctionData", + "getInternalModuleRanges", + "getInternalformatParameter", + "getIntersectionList", + "getItem", + "getItems", + "getJointPose", + "getKey", + "getKeyframes", + "getLastFocused", + "getLayers", + "getLayoutMap", + "getLightEstimate", + "getLineDash", + "getLocalCandidates", + "getLocalParameters", + "getLocalStreams", + "getManagedConfiguration", + "getManifest", + "getMappedRange", + "getMarks", + "getMatchedCSSRules", + "getMaxGCPauseSinceClear", + "getMeasures", + "getMessage", + "getMetadata", + "getMilliseconds", + "getMinutes", + "getModifierState", + "getMonth", + "getName", + "getNamedItem", + "getNamedItemNS", + "getNativeFramebufferScaleFactor", + "getNegotiatedHeaderExtensions", + "getNestedConfigs", + "getNotifications", + "getNotifier", + "getNumberOfChars", + "getOffsetReferenceSpace", + "getOutputTimestamp", + "getOverrideHistoryNavigationMode", + "getOverrideStyle", + "getOwnPropertyDescriptor", + "getOwnPropertyDescriptors", + "getOwnPropertyNames", + "getOwnPropertySymbols", + "getPackageDirectoryEntry", + "getParameter", + "getParameters", + "getParent", + "getPathSegAtLength", + "getPermissionWarningsByManifest", + "getPhotoCapabilities", + "getPhotoSettings", + "getPlatformInfo", + "getPointAtLength", + "getPopup", + "getPorts", + "getPose", + "getPredictedEvents", + "getPreference", + "getPreferenceDefault", + "getPreferredCanvasFormat", + "getPresentationAttribute", + "getPreventDefault", + "getPrimaryService", + "getPrimaryServices", + "getProgramInfoLog", + "getProgramParameter", + "getPropertyCSSValue", + "getPropertyPriority", + "getPropertyShorthand", + "getPropertyType", + "getPropertyValue", + "getPrototypeOf", + "getPublicKey", + "getPublicKeyAlgorithm", + "getQuery", + "getQueryParameter", + "getRGBColorValue", + "getRandomValues", + "getRangeAt", + "getReader", + "getReceivers", + "getRectValue", + "getReflectionCubeMap", + "getRegistration", + "getRegistrations", + "getRemoteCandidates", + "getRemoteCertificates", + "getRemoteParameters", + "getRemoteStreams", + "getRenderbufferParameter", + "getResponseHeader", + "getRoot", + "getRootNode", + "getRotationOfChar", + "getSVGDocument", + "getSamplerParameter", + "getScreenCTM", + "getScreenDetails", + "getSeconds", + "getSelectedCandidatePair", + "getSelection", + "getSelf", + "getSenders", + "getService", + "getSetCookie", + "getSettings", + "getShaderInfoLog", + "getShaderParameter", + "getShaderPrecisionFormat", + "getShaderSource", + "getSignals", + "getSimpleDuration", + "getSiteIcons", + "getSources", + "getSpeculativeParserUrls", + "getStartPositionOfChar", + "getStartTime", + "getState", + "getStats", + "getStatusForPolicy", + "getStorageUpdates", + "getStreamById", + "getStringValue", + "getSubStringLength", + "getSubscription", + "getSubscriptions", + "getSupportedConstraints", + "getSupportedExtensions", + "getSupportedFormats", + "getSyncParameter", + "getSynchronizationSources", + "getTags", + "getTargetRanges", + "getTexParameter", + "getTextFormats", + "getTime", + "getTimezoneOffset", + "getTiming", + "getTitle", + "getTitlebarAreaRect", + "getTotalLength", + "getTrackById", + "getTracks", + "getTransceivers", + "getTransform", + "getTransformFeedbackVarying", + "getTransformToElement", + "getTransports", + "getType", + "getTypeMapping", + "getUILanguage", + "getURL", + "getUTCDate", + "getUTCDay", + "getUTCFullYear", + "getUTCHours", + "getUTCMilliseconds", + "getUTCMinutes", + "getUTCMonth", + "getUTCSeconds", + "getUint16", + "getUint32", + "getUint8", + "getUniform", + "getUniformBlockIndex", + "getUniformIndices", + "getUniformLocation", + "getUserInfo", + "getUserMedia", + "getUserSettings", + "getVRDisplays", + "getValues", + "getVarDate", + "getVariableValue", + "getVertexAttrib", + "getVertexAttribOffset", + "getVideoPlaybackQuality", + "getVideoTracks", + "getViewerPose", + "getViewport", + "getViews", + "getVoices", + "getWakeLockState", + "getWriter", + "getYear", + "getZoom", + "getZoomSettings", + "givenName", + "global", + "globalAlpha", + "globalCompositeOperation", + "globalPrivacyControl", + "globalThis", + "glyphOrientationHorizontal", + "glyphOrientationVertical", + "glyphRef", + "go", + "goBack", + "goForward", + "gpu", + "grabFrame", + "grad", + "gradientTransform", + "gradientUnits", + "grammars", + "green", + "grid", + "grid-area", + "grid-auto-columns", + "grid-auto-flow", + "grid-auto-rows", + "grid-column", + "grid-column-end", + "grid-column-gap", + "grid-column-start", + "grid-gap", + "grid-row", + "grid-row-end", + "grid-row-gap", + "grid-row-start", + "grid-template", + "grid-template-areas", + "grid-template-columns", + "grid-template-rows", + "gridArea", + "gridAutoColumns", + "gridAutoFlow", + "gridAutoRows", + "gridColumn", + "gridColumnEnd", + "gridColumnGap", + "gridColumnStart", + "gridGap", + "gridRow", + "gridRowEnd", + "gridRowGap", + "gridRowStart", + "gridTemplate", + "gridTemplateAreas", + "gridTemplateColumns", + "gridTemplateRows", + "gripSpace", + "group", + "groupBy", + "groupCollapsed", + "groupEnd", + "groupId", + "groups", + "grow", + "growable", + "guestProcessId", + "guestRenderFrameRoutingId", + "hadRecentInput", + "hand", + "handedness", + "hangingBaseline", + "hapticActuators", + "hardwareConcurrency", + "has", + "hasAttribute", + "hasAttributeNS", + "hasAttributes", + "hasBeenActive", + "hasChildNodes", + "hasComposition", + "hasDynamicOffset", + "hasEnrolledInstrument", + "hasExtension", + "hasExternalDisplay", + "hasFeature", + "hasFocus", + "hasIndices", + "hasInstance", + "hasLayout", + "hasOrientation", + "hasOwn", + "hasOwnProperty", + "hasPointerCapture", + "hasPosition", + "hasPrivateToken", + "hasReading", + "hasRedemptionRecord", + "hasRegExpGroups", + "hasStorageAccess", + "hasUAVisualTransition", + "hasUnpartitionedCookieAccess", + "hash", + "hashChange", + "head", + "headers", + "heading", + "height", + "hid", + "hidden", + "hide", + "hideFocus", + "hidePopover", + "high", + "highWaterMark", + "highlight", + "highlights", + "hint", + "hints", + "history", + "honorificPrefix", + "honorificSuffix", + "horizontalOverflow", + "host", + "hostCandidate", + "hostname", + "href", + "hrefTranslate", + "hreflang", + "hspace", + "html5TagCheckInerface", + "htmlFor", + "htmlText", + "httpEquiv", + "httpRequestStatusCode", + "hwTimestamp", + "hyphenate-character", + "hyphenateCharacter", + "hyphens", + "hypot", + "i18n", + "ic", + "iccId", + "iceConnectionState", + "iceGatheringState", + "iceTransport", + "icon", + "iconURL", + "id", + "identifier", + "identity", + "ideographicBaseline", + "idle", + "idpLoginUrl", + "ignoreBOM", + "ignoreCase", + "ignoreDepthValues", + "image", + "image-orientation", + "image-rendering", + "imageHeight", + "imageOrientation", + "imageRendering", + "imageSizes", + "imageSmoothingEnabled", + "imageSmoothingQuality", + "imageSrcset", + "imageWidth", + "images", + "ime-mode", + "imeMode", + "implementation", + "importExternalTexture", + "importKey", + "importNode", + "importStylesheet", + "imports", + "impp", + "imul", + "in", + "in1", + "in2", + "inBandMetadataTrackDispatchType", + "inIncognitoContext", + "inRange", + "includes", + "incognito", + "incomingBidirectionalStreams", + "incomingHighWaterMark", + "incomingMaxAge", + "incomingUnidirectionalStreams", + "incremental", + "indeterminate", + "index", + "indexNames", + "indexOf", + "indexedDB", + "indicate", + "indices", + "inert", + "inertiaDestinationX", + "inertiaDestinationY", + "info", + "inherits", + "init", + "initAnimationEvent", + "initBeforeLoadEvent", + "initClipboardEvent", + "initCloseEvent", + "initCommandEvent", + "initCompositionEvent", + "initCustomEvent", + "initData", + "initDataType", + "initDeviceMotionEvent", + "initDeviceOrientationEvent", + "initDragEvent", + "initErrorEvent", + "initEvent", + "initFocusEvent", + "initGestureEvent", + "initHashChangeEvent", + "initKeyEvent", + "initKeyboardEvent", + "initMSManipulationEvent", + "initMessageEvent", + "initMouseEvent", + "initMouseScrollEvent", + "initMouseWheelEvent", + "initMutationEvent", + "initNSMouseEvent", + "initOverflowEvent", + "initPageEvent", + "initPageTransitionEvent", + "initPointerEvent", + "initPopStateEvent", + "initProgressEvent", + "initScrollAreaEvent", + "initSimpleGestureEvent", + "initStorageEvent", + "initTextEvent", + "initTimeEvent", + "initTouchEvent", + "initTransitionEvent", + "initUIEvent", + "initWebKitAnimationEvent", + "initWebKitTransitionEvent", + "initWebKitWheelEvent", + "initWheelEvent", + "initialTime", + "initialValue", + "initialize", + "initiatorType", + "inject", + "ink", + "inline-size", + "inlineSize", + "inlineVerticalFieldOfView", + "inner", + "innerHTML", + "innerHeight", + "innerText", + "innerWidth", + "input", + "inputBuffer", + "inputEncoding", + "inputMethod", + "inputMode", + "inputSource", + "inputSources", + "inputType", + "inputs", + "insertAdjacentElement", + "insertAdjacentHTML", + "insertAdjacentText", + "insertBefore", + "insertCell", + "insertDTMF", + "insertData", + "insertDebugMarker", + "insertItemBefore", + "insertNode", + "insertRow", + "insertRule", + "inset", + "inset-block", + "inset-block-end", + "inset-block-start", + "inset-inline", + "inset-inline-end", + "inset-inline-start", + "insetBlock", + "insetBlockEnd", + "insetBlockStart", + "insetInline", + "insetInlineEnd", + "insetInlineStart", + "install", + "installing", + "instanceRoot", + "instantiate", + "instantiateStreaming", + "instruments", + "int16", + "int32", + "int8", + "integrity", + "interactionId", + "interactionMode", + "intercept", + "interfaceClass", + "interfaceName", + "interfaceNumber", + "interfaceProtocol", + "interfaceSubclass", + "interfaces", + "interimResults", + "internalSubset", + "interpretation", + "intersection", + "intersectionRatio", + "intersectionRect", + "intersectsNode", + "interval", + "invalidIteratorState", + "invalidateFramebuffer", + "invalidateSubFramebuffer", + "inverse", + "invertSelf", + "invoker", + "invokerType", + "is", + "is2D", + "isActive", + "isAllowedFileSchemeAccess", + "isAllowedIncognitoAccess", + "isAlternate", + "isArray", + "isAutoSelected", + "isBingCurrentSearchDefault", + "isBuffer", + "isCandidateWindowVisible", + "isChar", + "isCollapsed", + "isComposing", + "isConcatSpreadable", + "isConditionalMediationAvailable", + "isConfigSupported", + "isConnected", + "isContentEditable", + "isContentHandlerRegistered", + "isContextLost", + "isDefaultNamespace", + "isDirectory", + "isDisabled", + "isDisjointFrom", + "isEnabled", + "isEqual", + "isEqualNode", + "isExtended", + "isExtensible", + "isExternalCTAP2SecurityKeySupported", + "isFallbackAdapter", + "isFile", + "isFinite", + "isFirstPersonObserver", + "isFramebuffer", + "isFrozen", + "isGenerator", + "isHTML", + "isHistoryNavigation", + "isId", + "isIdentity", + "isInjected", + "isInputPending", + "isInteger", + "isInternal", + "isIntersecting", + "isLockFree", + "isMap", + "isMultiLine", + "isNaN", + "isOpen", + "isPointInFill", + "isPointInPath", + "isPointInRange", + "isPointInStroke", + "isPrefAlternate", + "isPresenting", + "isPrimary", + "isProgram", + "isPropertyImplicit", + "isProtocolHandlerRegistered", + "isPrototypeOf", + "isQuery", + "isRawJSON", + "isRenderbuffer", + "isSafeInteger", + "isSameEntry", + "isSameNode", + "isSampler", + "isScript", + "isScriptURL", + "isSealed", + "isSecureContext", + "isSessionSupported", + "isShader", + "isSubsetOf", + "isSupersetOf", + "isSupported", + "isSync", + "isTextEdit", + "isTexture", + "isTransformFeedback", + "isTrusted", + "isTypeSupported", + "isUserVerifyingPlatformAuthenticatorAvailable", + "isVertexArray", + "isView", + "isVisible", + "isWellFormed", + "isochronousTransferIn", + "isochronousTransferOut", + "isolation", + "italics", + "item", + "itemId", + "itemProp", + "itemRef", + "itemScope", + "itemType", + "itemValue", + "items", + "iterateNext", + "iterationComposite", + "iterator", + "javaEnabled", + "jitterBufferTarget", + "jobTitle", + "join", + "joinAdInterestGroup", + "jointName", + "json", + "justify-content", + "justify-items", + "justify-self", + "justifyContent", + "justifyItems", + "justifySelf", + "k1", + "k2", + "k3", + "k4", + "kHz", + "keepalive", + "kernelMatrix", + "kernelUnitLengthX", + "kernelUnitLengthY", + "kerning", + "key", + "keyCode", + "keyFor", + "keyIdentifier", + "keyLightEnabled", + "keyLocation", + "keyPath", + "keyStatuses", + "keySystem", + "keyText", + "keyUsage", + "keyboard", + "keys", + "keytype", + "kind", + "knee", + "knownSources", + "label", + "labels", + "lang", + "language", + "languages", + "largeArcFlag", + "lastChild", + "lastElementChild", + "lastError", + "lastEventId", + "lastIndex", + "lastIndexOf", + "lastInputTime", + "lastMatch", + "lastMessageSubject", + "lastMessageType", + "lastModified", + "lastModifiedDate", + "lastPage", + "lastParen", + "lastState", + "lastStyleSheetSet", + "latency", + "latitude", + "launchQueue", + "layerName", + "layerX", + "layerY", + "layout", + "layoutFlow", + "layoutGrid", + "layoutGridChar", + "layoutGridLine", + "layoutGridMode", + "layoutGridType", + "lbound", + "leaveAdInterestGroup", + "left", + "leftContext", + "leftDegrees", + "leftMargin", + "leftProjectionMatrix", + "leftViewMatrix", + "length", + "lengthAdjust", + "lengthComputable", + "letter-spacing", + "letterSpacing", + "level", + "lh", + "lighting-color", + "lightingColor", + "limitingConeAngle", + "limits", + "line", + "line-break", + "line-height", + "lineAlign", + "lineBreak", + "lineCap", + "lineDashOffset", + "lineGapOverride", + "lineHeight", + "lineJoin", + "lineNum", + "lineNumber", + "linePos", + "lineTo", + "lineWidth", + "linearAcceleration", + "linearRampToValueAtTime", + "linearVelocity", + "lineno", + "lines", + "link", + "linkColor", + "linkProgram", + "links", + "list", + "list-style", + "list-style-image", + "list-style-position", + "list-style-type", + "listStyle", + "listStyleImage", + "listStylePosition", + "listStyleType", + "listener", + "listeners", + "load", + "loadEventEnd", + "loadEventStart", + "loadOp", + "loadTime", + "loadTimes", + "loaded", + "loading", + "localDescription", + "localName", + "localService", + "localStorage", + "locale", + "localeCompare", + "location", + "locationbar", + "lock", + "locked", + "lockedFile", + "locks", + "lodMaxClamp", + "lodMinClamp", + "log", + "log10", + "log1p", + "log2", + "logicalXDPI", + "logicalYDPI", + "login", + "loglevel", + "longDesc", + "longitude", + "lookupNamespaceURI", + "lookupPrefix", + "loop", + "loopEnd", + "loopStart", + "looping", + "lost", + "low", + "lower", + "lowerBound", + "lowerOpen", + "lowsrc", + "lvb", + "lvh", + "lvi", + "lvmax", + "lvmin", + "lvw", + "m11", + "m12", + "m13", + "m14", + "m21", + "m22", + "m23", + "m24", + "m31", + "m32", + "m33", + "m34", + "m41", + "m42", + "m43", + "m44", + "magFilter", + "makeXRCompatible", + "managed", + "management", + "manifest", + "manufacturer", + "manufacturerName", + "map", + "mapAsync", + "mapState", + "mappedAtCreation", + "mapping", + "margin", + "margin-block", + "margin-block-end", + "margin-block-start", + "margin-bottom", + "margin-inline", + "margin-inline-end", + "margin-inline-start", + "margin-left", + "margin-right", + "margin-top", + "marginBlock", + "marginBlockEnd", + "marginBlockStart", + "marginBottom", + "marginHeight", + "marginInline", + "marginInlineEnd", + "marginInlineStart", + "marginLeft", + "marginRight", + "marginTop", + "marginWidth", + "mark", + "marker", + "marker-end", + "marker-mid", + "marker-offset", + "marker-start", + "markerEnd", + "markerHeight", + "markerMid", + "markerOffset", + "markerStart", + "markerUnits", + "markerWidth", + "marks", + "mask", + "mask-clip", + "mask-composite", + "mask-image", + "mask-mode", + "mask-origin", + "mask-position", + "mask-position-x", + "mask-position-y", + "mask-repeat", + "mask-size", + "mask-type", + "maskClip", + "maskComposite", + "maskContentUnits", + "maskImage", + "maskMode", + "maskOrigin", + "maskPosition", + "maskPositionX", + "maskPositionY", + "maskRepeat", + "maskSize", + "maskType", + "maskUnits", + "match", + "matchAll", + "matchMedia", + "matchMedium", + "matchPatterns", + "matches", + "math-depth", + "math-style", + "mathDepth", + "mathStyle", + "matrix", + "matrixTransform", + "max", + "max-block-size", + "max-height", + "max-inline-size", + "max-width", + "maxActions", + "maxAlternatives", + "maxAnisotropy", + "maxBindGroups", + "maxBindGroupsPlusVertexBuffers", + "maxBindingsPerBindGroup", + "maxBlockSize", + "maxBufferSize", + "maxByteLength", + "maxChannelCount", + "maxChannels", + "maxColorAttachmentBytesPerSample", + "maxColorAttachments", + "maxComputeInvocationsPerWorkgroup", + "maxComputeWorkgroupSizeX", + "maxComputeWorkgroupSizeY", + "maxComputeWorkgroupSizeZ", + "maxComputeWorkgroupStorageSize", + "maxComputeWorkgroupsPerDimension", + "maxConnectionsPerServer", + "maxDatagramSize", + "maxDecibels", + "maxDistance", + "maxDrawCount", + "maxDynamicStorageBuffersPerPipelineLayout", + "maxDynamicUniformBuffersPerPipelineLayout", + "maxHeight", + "maxInlineSize", + "maxInterStageShaderComponents", + "maxInterStageShaderVariables", + "maxLayers", + "maxLength", + "maxMessageSize", + "maxPacketLifeTime", + "maxRetransmits", + "maxSampledTexturesPerShaderStage", + "maxSamplersPerShaderStage", + "maxStorageBufferBindingSize", + "maxStorageBuffersPerShaderStage", + "maxStorageTexturesPerShaderStage", + "maxTextureArrayLayers", + "maxTextureDimension1D", + "maxTextureDimension2D", + "maxTextureDimension3D", + "maxTouchPoints", + "maxUniformBufferBindingSize", + "maxUniformBuffersPerShaderStage", + "maxValue", + "maxVertexAttributes", + "maxVertexBufferArrayStride", + "maxVertexBuffers", + "maxWidth", + "maximumLatency", + "measure", + "measureText", + "media", + "mediaCapabilities", + "mediaDevices", + "mediaElement", + "mediaGroup", + "mediaKeys", + "mediaSession", + "mediaStream", + "mediaText", + "meetOrSlice", + "memory", + "menubar", + "menus", + "menusChild", + "menusInternal", + "mergeAttributes", + "message", + "messageClass", + "messageHandlers", + "messageType", + "messages", + "metaKey", + "metadata", + "method", + "methodDetails", + "methodName", + "mid", + "mimeType", + "mimeTypes", + "min", + "min-block-size", + "min-height", + "min-inline-size", + "min-width", + "minBindingSize", + "minBlockSize", + "minDecibels", + "minFilter", + "minHeight", + "minInlineSize", + "minLength", + "minStorageBufferOffsetAlignment", + "minUniformBufferOffsetAlignment", + "minValue", + "minWidth", + "minimumLatency", + "mipLevel", + "mipLevelCount", + "mipmapFilter", + "miterLimit", + "mix-blend-mode", + "mixBlendMode", + "mm", + "mobile", + "mode", + "model", + "modify", + "module", + "mount", + "move", + "moveBy", + "moveEnd", + "moveFirst", + "moveFocusDown", + "moveFocusLeft", + "moveFocusRight", + "moveFocusUp", + "moveInSuccession", + "moveNext", + "moveRow", + "moveStart", + "moveTo", + "moveToBookmark", + "moveToElementText", + "moveToPoint", + "movementX", + "movementY", + "mozAdd", + "mozAnimationStartTime", + "mozAnon", + "mozApps", + "mozAudioCaptured", + "mozAudioChannelType", + "mozAutoplayEnabled", + "mozCancelAnimationFrame", + "mozCancelFullScreen", + "mozCancelRequestAnimationFrame", + "mozCaptureStream", + "mozCaptureStreamUntilEnded", + "mozClearDataAt", + "mozContact", + "mozContacts", + "mozCreateFileHandle", + "mozCurrentTransform", + "mozCurrentTransformInverse", + "mozCursor", + "mozDash", + "mozDashOffset", + "mozDecodedFrames", + "mozExitPointerLock", + "mozFillRule", + "mozFragmentEnd", + "mozFrameDelay", + "mozFullScreen", + "mozFullScreenElement", + "mozFullScreenEnabled", + "mozGetAll", + "mozGetAllKeys", + "mozGetAsFile", + "mozGetDataAt", + "mozGetMetadata", + "mozGetUserMedia", + "mozHasAudio", + "mozHasItem", + "mozHidden", + "mozImageSmoothingEnabled", + "mozIndexedDB", + "mozInnerScreenX", + "mozInnerScreenY", + "mozInputSource", + "mozIsTextField", + "mozItem", + "mozItemCount", + "mozItems", + "mozLength", + "mozLockOrientation", + "mozMatchesSelector", + "mozMovementX", + "mozMovementY", + "mozOpaque", + "mozOrientation", + "mozPaintCount", + "mozPaintedFrames", + "mozParsedFrames", + "mozPay", + "mozPointerLockElement", + "mozPresentedFrames", + "mozPreservesPitch", + "mozPressure", + "mozPrintCallback", + "mozRTCIceCandidate", + "mozRTCPeerConnection", + "mozRTCSessionDescription", + "mozRemove", + "mozRequestAnimationFrame", + "mozRequestFullScreen", + "mozRequestPointerLock", + "mozSetDataAt", + "mozSetImageElement", + "mozSourceNode", + "mozSrcObject", + "mozSystem", + "mozTCPSocket", + "mozTextStyle", + "mozTypesAt", + "mozUnlockOrientation", + "mozUserCancelled", + "mozVisibilityState", + "ms", + "msAnimation", + "msAnimationDelay", + "msAnimationDirection", + "msAnimationDuration", + "msAnimationFillMode", + "msAnimationIterationCount", + "msAnimationName", + "msAnimationPlayState", + "msAnimationStartTime", + "msAnimationTimingFunction", + "msBackfaceVisibility", + "msBlockProgression", + "msCSSOMElementFloatMetrics", + "msCaching", + "msCachingEnabled", + "msCancelRequestAnimationFrame", + "msCapsLockWarningOff", + "msClearImmediate", + "msClose", + "msContentZoomChaining", + "msContentZoomFactor", + "msContentZoomLimit", + "msContentZoomLimitMax", + "msContentZoomLimitMin", + "msContentZoomSnap", + "msContentZoomSnapPoints", + "msContentZoomSnapType", + "msContentZooming", + "msConvertURL", + "msCrypto", + "msDoNotTrack", + "msElementsFromPoint", + "msElementsFromRect", + "msExitFullscreen", + "msExtendedCode", + "msFillRule", + "msFirstPaint", + "msFlex", + "msFlexAlign", + "msFlexDirection", + "msFlexFlow", + "msFlexItemAlign", + "msFlexLinePack", + "msFlexNegative", + "msFlexOrder", + "msFlexPack", + "msFlexPositive", + "msFlexPreferredSize", + "msFlexWrap", + "msFlowFrom", + "msFlowInto", + "msFontFeatureSettings", + "msFullscreenElement", + "msFullscreenEnabled", + "msGetInputContext", + "msGetRegionContent", + "msGetUntransformedBounds", + "msGraphicsTrustStatus", + "msGridColumn", + "msGridColumnAlign", + "msGridColumnSpan", + "msGridColumns", + "msGridRow", + "msGridRowAlign", + "msGridRowSpan", + "msGridRows", + "msHidden", + "msHighContrastAdjust", + "msHyphenateLimitChars", + "msHyphenateLimitLines", + "msHyphenateLimitZone", + "msHyphens", + "msImageSmoothingEnabled", + "msImeAlign", + "msIndexedDB", + "msInterpolationMode", + "msIsStaticHTML", + "msKeySystem", + "msKeys", + "msLaunchUri", + "msLockOrientation", + "msManipulationViewsEnabled", + "msMatchMedia", + "msMatchesSelector", + "msMaxTouchPoints", + "msOrientation", + "msOverflowStyle", + "msPerspective", + "msPerspectiveOrigin", + "msPlayToDisabled", + "msPlayToPreferredSourceUri", + "msPlayToPrimary", + "msPointerEnabled", + "msRegionOverflow", + "msReleasePointerCapture", + "msRequestAnimationFrame", + "msRequestFullscreen", + "msSaveBlob", + "msSaveOrOpenBlob", + "msScrollChaining", + "msScrollLimit", + "msScrollLimitXMax", + "msScrollLimitXMin", + "msScrollLimitYMax", + "msScrollLimitYMin", + "msScrollRails", + "msScrollSnapPointsX", + "msScrollSnapPointsY", + "msScrollSnapType", + "msScrollSnapX", + "msScrollSnapY", + "msScrollTranslation", + "msSetImmediate", + "msSetMediaKeys", + "msSetPointerCapture", + "msTextCombineHorizontal", + "msTextSizeAdjust", + "msToBlob", + "msTouchAction", + "msTouchSelect", + "msTraceAsyncCallbackCompleted", + "msTraceAsyncCallbackStarting", + "msTraceAsyncOperationCompleted", + "msTraceAsyncOperationStarting", + "msTransform", + "msTransformOrigin", + "msTransformStyle", + "msTransition", + "msTransitionDelay", + "msTransitionDuration", + "msTransitionProperty", + "msTransitionTimingFunction", + "msUnlockOrientation", + "msUpdateAsyncCallbackRelation", + "msUserSelect", + "msVisibilityState", + "msWrapFlow", + "msWrapMargin", + "msWrapThrough", + "msWriteProfilerMark", + "msZoom", + "msZoomTo", + "mt", + "mul", + "multiEntry", + "multiSelectionObj", + "multiline", + "multiple", + "multiply", + "multiplySelf", + "multisample", + "multisampled", + "mutableFile", + "muted", + "n", + "nacl_arch", + "name", + "nameList", + "nameProp", + "namedItem", + "namedRecordset", + "names", + "namespaceURI", + "namespaces", + "nativeApplication", + "nativeMap", + "nativeObjectCreate", + "nativeSet", + "nativeWeakMap", + "naturalHeight", + "naturalWidth", + "navigate", + "navigation", + "navigationMode", + "navigationPreload", + "navigationStart", + "navigationType", + "navigator", + "near", + "nearestViewportElement", + "negative", + "negotiated", + "netscape", + "networkState", + "networkStatus", + "newScale", + "newState", + "newTranslate", + "newURL", + "newValue", + "newValueSpecifiedUnits", + "newVersion", + "newhome", + "next", + "nextElementSibling", + "nextHopProtocol", + "nextNode", + "nextPage", + "nextSibling", + "nickname", + "noHref", + "noModule", + "noResize", + "noShade", + "noValidate", + "noWrap", + "node", + "nodeName", + "nodeType", + "nodeValue", + "nonce", + "normDepthBufferFromNormView", + "normalize", + "normalizedPathSegList", + "normandyAddonStudy", + "notRestoredReasons", + "notationName", + "notations", + "note", + "noteGrainOn", + "noteOff", + "noteOn", + "notifications", + "notify", + "now", + "npnNegotiatedProtocol", + "numOctaves", + "number", + "numberOfChannels", + "numberOfFrames", + "numberOfInputs", + "numberOfItems", + "numberOfOutputs", + "numberValue", + "oMatchesSelector", + "object", + "object-fit", + "object-position", + "objectFit", + "objectPosition", + "objectStore", + "objectStoreNames", + "objectType", + "observe", + "occlusionQuerySet", + "of", + "off", + "offscreenBuffering", + "offset", + "offset-anchor", + "offset-distance", + "offset-path", + "offset-position", + "offset-rotate", + "offsetAnchor", + "offsetDistance", + "offsetHeight", + "offsetLeft", + "offsetNode", + "offsetParent", + "offsetPath", + "offsetPosition", + "offsetRotate", + "offsetTop", + "offsetWidth", + "offsetX", + "offsetY", + "ok", + "oldState", + "oldURL", + "oldValue", + "oldVersion", + "olderShadowRoot", + "omnibox", + "on", + "onActivated", + "onAdded", + "onAttached", + "onBoundsChanged", + "onBrowserUpdateAvailable", + "onClicked", + "onCommitFiberRoot", + "onCommitFiberUnmount", + "onConnect", + "onConnectExternal", + "onConnectNative", + "onCreated", + "onDetached", + "onDisabled", + "onEnabled", + "onFocusChanged", + "onHighlighted", + "onInstalled", + "onLine", + "onMessage", + "onMessageExternal", + "onMoved", + "onPerformanceWarning", + "onPostCommitFiberRoot", + "onRemoved", + "onReplaced", + "onRestartRequired", + "onStartup", + "onSubmittedWorkDone", + "onSuspend", + "onSuspendCanceled", + "onUninstalled", + "onUpdateAvailable", + "onUpdated", + "onUserScriptConnect", + "onUserScriptMessage", + "onUserSettingsChanged", + "onZoomChange", + "onabort", + "onabsolutedeviceorientation", + "onactivate", + "onactive", + "onaddsourcebuffer", + "onaddstream", + "onaddtrack", + "onafterprint", + "onafterscriptexecute", + "onafterupdate", + "onanimationcancel", + "onanimationend", + "onanimationiteration", + "onanimationstart", + "onappinstalled", + "onaudioend", + "onaudioprocess", + "onaudiostart", + "onautocomplete", + "onautocompleteerror", + "onauxclick", + "onbeforeactivate", + "onbeforecopy", + "onbeforecut", + "onbeforedeactivate", + "onbeforeeditfocus", + "onbeforeinput", + "onbeforeinstallprompt", + "onbeforematch", + "onbeforepaste", + "onbeforeprint", + "onbeforescriptexecute", + "onbeforetoggle", + "onbeforeunload", + "onbeforeupdate", + "onbeforexrselect", + "onbegin", + "onblocked", + "onblur", + "onbounce", + "onboundary", + "onbufferedamountlow", + "oncached", + "oncancel", + "oncandidatewindowhide", + "oncandidatewindowshow", + "oncandidatewindowupdate", + "oncanplay", + "oncanplaythrough", + "oncapturehandlechange", + "once", + "oncellchange", + "onchange", + "oncharacterboundsupdate", + "oncharacteristicvaluechanged", + "onchargingchange", + "onchargingtimechange", + "onchecking", + "onclick", + "onclose", + "onclosing", + "oncompassneedscalibration", + "oncomplete", + "oncompositionend", + "oncompositionstart", + "onconnect", + "onconnecting", + "onconnectionavailable", + "onconnectionstatechange", + "oncontentvisibilityautostatechange", + "oncontextlost", + "oncontextmenu", + "oncontextrestored", + "oncontrollerchange", + "oncontrolselect", + "oncopy", + "oncuechange", + "oncurrententrychange", + "oncurrentscreenchange", + "oncut", + "ondataavailable", + "ondatachannel", + "ondatasetchanged", + "ondatasetcomplete", + "ondblclick", + "ondeactivate", + "ondequeue", + "ondevicechange", + "ondevicelight", + "ondevicemotion", + "ondeviceorientation", + "ondeviceorientationabsolute", + "ondeviceproximity", + "ondischargingtimechange", + "ondisconnect", + "ondisplay", + "ondispose", + "ondownloading", + "ondrag", + "ondragend", + "ondragenter", + "ondragexit", + "ondragleave", + "ondragover", + "ondragstart", + "ondrop", + "ondurationchange", + "onemptied", + "onencrypted", + "onend", + "onended", + "onenter", + "onenterpictureinpicture", + "onerror", + "onerrorupdate", + "onexit", + "onfencedtreeclick", + "onfilterchange", + "onfinish", + "onfocus", + "onfocusin", + "onfocusout", + "onformdata", + "onfreeze", + "onfullscreenchange", + "onfullscreenerror", + "ongamepadconnected", + "ongamepaddisconnected", + "ongatheringstatechange", + "ongattserverdisconnected", + "ongeometrychange", + "ongesturechange", + "ongestureend", + "ongesturestart", + "ongotpointercapture", + "onhashchange", + "onhelp", + "onicecandidate", + "onicecandidateerror", + "oniceconnectionstatechange", + "onicegatheringstatechange", + "oninactive", + "oninput", + "oninputreport", + "oninputsourceschange", + "oninvalid", + "onkeydown", + "onkeypress", + "onkeystatuseschange", + "onkeyup", + "onlanguagechange", + "onlayoutcomplete", + "onleavepictureinpicture", + "onlevelchange", + "onload", + "onloadT", + "onloadeddata", + "onloadedmetadata", + "onloadend", + "onloading", + "onloadingdone", + "onloadingerror", + "onloadstart", + "onlosecapture", + "onlostpointercapture", + "only", + "onmanagedconfigurationchange", + "onmark", + "onmessage", + "onmessageerror", + "onmidimessage", + "onmousedown", + "onmouseenter", + "onmouseleave", + "onmousemove", + "onmouseout", + "onmouseover", + "onmouseup", + "onmousewheel", + "onmove", + "onmoveend", + "onmovestart", + "onmozfullscreenchange", + "onmozfullscreenerror", + "onmozorientationchange", + "onmozpointerlockchange", + "onmozpointerlockerror", + "onmscontentzoom", + "onmsfullscreenchange", + "onmsfullscreenerror", + "onmsgesturechange", + "onmsgesturedoubletap", + "onmsgestureend", + "onmsgesturehold", + "onmsgesturestart", + "onmsgesturetap", + "onmsgotpointercapture", + "onmsinertiastart", + "onmslostpointercapture", + "onmsmanipulationstatechanged", + "onmsneedkey", + "onmsorientationchange", + "onmspointercancel", + "onmspointerdown", + "onmspointerenter", + "onmspointerhover", + "onmspointerleave", + "onmspointermove", + "onmspointerout", + "onmspointerover", + "onmspointerup", + "onmssitemodejumplistitemremoved", + "onmsthumbnailclick", + "onmute", + "onnavigate", + "onnavigateerror", + "onnavigatesuccess", + "onnegotiationneeded", + "onnomatch", + "onnoupdate", + "onobsolete", + "onoffline", + "ononline", + "onopen", + "onorientationchange", + "onpagechange", + "onpagehide", + "onpagereveal", + "onpageshow", + "onpageswap", + "onpaste", + "onpause", + "onpayerdetailchange", + "onpaymentmethodchange", + "onplay", + "onplaying", + "onpluginstreamstart", + "onpointercancel", + "onpointerdown", + "onpointerenter", + "onpointerleave", + "onpointerlockchange", + "onpointerlockerror", + "onpointermove", + "onpointerout", + "onpointerover", + "onpointerrawupdate", + "onpointerup", + "onpopstate", + "onprerenderingchange", + "onprioritychange", + "onprocessorerror", + "onprogress", + "onpropertychange", + "onratechange", + "onreading", + "onreadystatechange", + "onreflectionchange", + "onrejectionhandled", + "onrelease", + "onremove", + "onremovesourcebuffer", + "onremovestream", + "onremovetrack", + "onrepeat", + "onreset", + "onresize", + "onresizeend", + "onresizestart", + "onresourcetimingbufferfull", + "onresult", + "onresume", + "onrowenter", + "onrowexit", + "onrowsdelete", + "onrowsinserted", + "onscreenschange", + "onscroll", + "onscrollend", + "onscrollsnapchange", + "onscrollsnapchanging", + "onsearch", + "onsecuritypolicyviolation", + "onseeked", + "onseeking", + "onselect", + "onselectedcandidatepairchange", + "onselectend", + "onselectionchange", + "onselectstart", + "onshippingaddresschange", + "onshippingoptionchange", + "onshow", + "onsignalingstatechange", + "onsinkchange", + "onslotchange", + "onsoundend", + "onsoundstart", + "onsourceclose", + "onsourceclosed", + "onsourceended", + "onsourceopen", + "onspeechend", + "onspeechstart", + "onsqueeze", + "onsqueezeend", + "onsqueezestart", + "onstalled", + "onstart", + "onstatechange", + "onstop", + "onstorage", + "onstoragecommit", + "onsubmit", + "onsuccess", + "onsuspend", + "onterminate", + "ontextformatupdate", + "ontextinput", + "ontextupdate", + "ontimeout", + "ontimeupdate", + "ontoggle", + "ontonechange", + "ontouchcancel", + "ontouchend", + "ontouchmove", + "ontouchstart", + "ontrack", + "ontransitioncancel", + "ontransitionend", + "ontransitionrun", + "ontransitionstart", + "onuncapturederror", + "onunhandledrejection", + "onunload", + "onunmute", + "onupdate", + "onupdateend", + "onupdatefound", + "onupdateready", + "onupdatestart", + "onupgradeneeded", + "onuserproximity", + "onversionchange", + "onvisibilitychange", + "onvoiceschanged", + "onvolumechange", + "onvrdisplayactivate", + "onvrdisplayconnect", + "onvrdisplaydeactivate", + "onvrdisplaydisconnect", + "onvrdisplaypresentchange", + "onwaiting", + "onwaitingforkey", + "onwarning", + "onwebkitanimationend", + "onwebkitanimationiteration", + "onwebkitanimationstart", + "onwebkitcurrentplaybacktargetiswirelesschanged", + "onwebkitfullscreenchange", + "onwebkitfullscreenerror", + "onwebkitkeyadded", + "onwebkitkeyerror", + "onwebkitkeymessage", + "onwebkitneedkey", + "onwebkitorientationchange", + "onwebkitplaybacktargetavailabilitychanged", + "onwebkitpointerlockchange", + "onwebkitpointerlockerror", + "onwebkitresourcetimingbufferfull", + "onwebkittransitionend", + "onwheel", + "onzoom", + "opacity", + "open", + "openCursor", + "openDatabase", + "openKeyCursor", + "openOptionsPage", + "openOrClosedShadowRoot", + "openPopup", + "opened", + "opener", + "opera", + "operation", + "operationType", + "operator", + "opr", + "optimum", + "options", + "or", + "order", + "orderX", + "orderY", + "ordered", + "org", + "organization", + "orient", + "orientAngle", + "orientType", + "orientation", + "orientationX", + "orientationY", + "orientationZ", + "origin", + "originAgentCluster", + "originalPolicy", + "originalTarget", + "orphans", + "os", + "oscpu", + "outerHTML", + "outerHeight", + "outerText", + "outerWidth", + "outgoingHighWaterMark", + "outgoingMaxAge", + "outline", + "outline-color", + "outline-offset", + "outline-style", + "outline-width", + "outlineColor", + "outlineOffset", + "outlineStyle", + "outlineWidth", + "outputBuffer", + "outputChannelCount", + "outputLatency", + "outputs", + "overflow", + "overflow-anchor", + "overflow-block", + "overflow-clip-margin", + "overflow-inline", + "overflow-wrap", + "overflow-x", + "overflow-y", + "overflowAnchor", + "overflowBlock", + "overflowClipMargin", + "overflowInline", + "overflowWrap", + "overflowX", + "overflowY", + "overlaysContent", + "overrideColors", + "overrideMimeType", + "oversample", + "overscroll-behavior", + "overscroll-behavior-block", + "overscroll-behavior-inline", + "overscroll-behavior-x", + "overscroll-behavior-y", + "overscrollBehavior", + "overscrollBehaviorBlock", + "overscrollBehaviorInline", + "overscrollBehaviorX", + "overscrollBehaviorY", + "ownKeys", + "ownerDocument", + "ownerElement", + "ownerNode", + "ownerRule", + "ownerSVGElement", + "owningElement", + "p1", + "p2", + "p3", + "p4", + "packetSize", + "packets", + "pad", + "padEnd", + "padStart", + "padding", + "padding-block", + "padding-block-end", + "padding-block-start", + "padding-bottom", + "padding-inline", + "padding-inline-end", + "padding-inline-start", + "padding-left", + "padding-right", + "padding-top", + "paddingBlock", + "paddingBlockEnd", + "paddingBlockStart", + "paddingBottom", + "paddingInline", + "paddingInlineEnd", + "paddingInlineStart", + "paddingLeft", + "paddingRight", + "paddingTop", + "page", + "page-break-after", + "page-break-before", + "page-break-inside", + "page-orientation", + "pageAction", + "pageBreakAfter", + "pageBreakBefore", + "pageBreakInside", + "pageCount", + "pageLeft", + "pageOrientation", + "pageT", + "pageTop", + "pageX", + "pageXOffset", + "pageY", + "pageYOffset", + "pages", + "paint-order", + "paintOrder", + "paintRequests", + "paintType", + "paintWorklet", + "palette", + "pan", + "panningModel", + "parameterData", + "parameters", + "parent", + "parentElement", + "parentNode", + "parentRule", + "parentStyleSheet", + "parentTextEdit", + "parentWindow", + "parse", + "parseAll", + "parseCreationOptionsFromJSON", + "parseFloat", + "parseFromString", + "parseHTMLUnsafe", + "parseInt", + "parseRequestOptionsFromJSON", + "part", + "participants", + "passOp", + "passive", + "password", + "pasteHTML", + "path", + "pathLength", + "pathSegList", + "pathSegType", + "pathSegTypeAsLetter", + "pathname", + "pattern", + "patternContentUnits", + "patternMismatch", + "patternTransform", + "patternUnits", + "pause", + "pauseAnimations", + "pauseDuration", + "pauseOnExit", + "pauseProfilers", + "pauseTransformFeedback", + "paused", + "payerEmail", + "payerName", + "payerPhone", + "paymentManager", + "pc", + "pdfViewerEnabled", + "peerIdentity", + "pending", + "pendingLocalDescription", + "pendingRemoteDescription", + "percent", + "performance", + "periodicSync", + "permission", + "permissionState", + "permissions", + "persist", + "persisted", + "persistentDeviceId", + "personalbar", + "perspective", + "perspective-origin", + "perspectiveOrigin", + "phone", + "phoneticFamilyName", + "phoneticGivenName", + "photo", + "pictureInPictureChild", + "pictureInPictureElement", + "pictureInPictureEnabled", + "pictureInPictureWindow", + "ping", + "pipeThrough", + "pipeTo", + "pitch", + "pixelBottom", + "pixelDepth", + "pixelHeight", + "pixelLeft", + "pixelRight", + "pixelStorei", + "pixelTop", + "pixelUnitToMillimeterX", + "pixelUnitToMillimeterY", + "pixelWidth", + "pkcs11", + "place-content", + "place-items", + "place-self", + "placeContent", + "placeItems", + "placeSelf", + "placeholder", + "platform", + "platformVersion", + "platforms", + "play", + "playEffect", + "playState", + "playbackRate", + "playbackState", + "playbackTime", + "played", + "playoutDelayHint", + "playsInline", + "plugins", + "pluginspage", + "pname", + "pointer-events", + "pointerBeforeReferenceNode", + "pointerEnabled", + "pointerEvents", + "pointerId", + "pointerLockElement", + "pointerType", + "points", + "pointsAtX", + "pointsAtY", + "pointsAtZ", + "polygonOffset", + "pop", + "popDebugGroup", + "popErrorScope", + "popover", + "popoverTargetAction", + "popoverTargetElement", + "populateMatrix", + "popupWindowFeatures", + "popupWindowName", + "popupWindowURI", + "port", + "port1", + "port2", + "ports", + "posBottom", + "posHeight", + "posLeft", + "posRight", + "posTop", + "posWidth", + "pose", + "position", + "position-anchor", + "position-area", + "positionAlign", + "positionAnchor", + "positionArea", + "positionX", + "positionY", + "positionZ", + "postError", + "postMessage", + "postTask", + "postalCode", + "poster", + "postscriptName", + "pow", + "powerEfficient", + "powerOff", + "powerPreference", + "preMultiplySelf", + "precision", + "preferredReflectionFormat", + "preferredStyleSheetSet", + "preferredStylesheetSet", + "prefix", + "preload", + "premultipliedAlpha", + "prepend", + "prerendering", + "presentation", + "presentationArea", + "presentationStyle", + "preserveAlpha", + "preserveAspectRatio", + "preserveAspectRatioString", + "preservesPitch", + "pressed", + "pressure", + "prevValue", + "preventDefault", + "preventExtensions", + "preventSilentAccess", + "previousElementSibling", + "previousNode", + "previousPage", + "previousPriority", + "previousRect", + "previousScale", + "previousSibling", + "previousTranslate", + "primaries", + "primaryKey", + "primaryLightDirection", + "primaryLightIntensity", + "primitive", + "primitiveType", + "primitiveUnits", + "principals", + "print", + "print-color-adjust", + "printColorAdjust", + "printPreview", + "priority", + "privacy", + "privateKey", + "privateToken", + "probablySupportsContext", + "probeSpace", + "process", + "processIceMessage", + "processingEnd", + "processingStart", + "processorOptions", + "product", + "productId", + "productName", + "productSub", + "profile", + "profileEnd", + "profiles", + "projectionMatrix", + "promise", + "prompt", + "properties", + "propertyIsEnumerable", + "propertyName", + "protectedAudience", + "protocol", + "protocolLong", + "prototype", + "provider", + "proxy", + "pseudoClass", + "pseudoElement", + "pt", + "publicId", + "publicKey", + "published", + "pulse", + "push", + "pushDebugGroup", + "pushErrorScope", + "pushManager", + "pushNotification", + "pushState", + "put", + "putImageData", + "px", + "quadraticCurveTo", + "qualifier", + "quaternion", + "query", + "queryCommandEnabled", + "queryCommandIndeterm", + "queryCommandState", + "queryCommandSupported", + "queryCommandText", + "queryCommandValue", + "queryFeatureSupport", + "queryLocalFonts", + "queryPermission", + "querySelector", + "querySelectorAll", + "querySet", + "queue", + "queueMicrotask", + "quote", + "quotes", + "r", + "r1", + "r2", + "race", + "rad", + "radiogroup", + "radius", + "radiusX", + "radiusY", + "random", + "randomUUID", + "range", + "rangeCount", + "rangeEnd", + "rangeMax", + "rangeMin", + "rangeOffset", + "rangeOverflow", + "rangeParent", + "rangeStart", + "rangeUnderflow", + "rate", + "ratio", + "raw", + "rawId", + "rawJSON", + "rawValueToMeters", + "rcap", + "rch", + "read", + "readAsArrayBuffer", + "readAsBinaryString", + "readAsBlob", + "readAsDataURL", + "readAsText", + "readBuffer", + "readEntries", + "readOnly", + "readPixels", + "readReportRequested", + "readText", + "readValue", + "readable", + "ready", + "readyState", + "reason", + "reasons", + "reboot", + "receiveFeatureReport", + "receivedAlert", + "receiver", + "receivers", + "recipient", + "recommendedViewportScale", + "reconnect", + "recordNumber", + "recordsAvailable", + "recordset", + "rect", + "red", + "redEyeReduction", + "redirect", + "redirectCount", + "redirectEnd", + "redirectStart", + "redirected", + "reduce", + "reduceRight", + "reduction", + "refDistance", + "refX", + "refY", + "referenceNode", + "referenceSpace", + "referrer", + "referrerPolicy", + "refresh", + "region", + "regionAnchorX", + "regionAnchorY", + "regionId", + "regions", + "register", + "registerContentHandler", + "registerElement", + "registerInternalModuleStart", + "registerInternalModuleStop", + "registerProperty", + "registerProtocolHandler", + "reject", + "rel", + "relList", + "relatedAddress", + "relatedNode", + "relatedPort", + "relatedTarget", + "relayProtocol", + "release", + "releaseCapture", + "releaseEvents", + "releaseInterface", + "releaseLock", + "releasePointerCapture", + "releaseShaderCompiler", + "released", + "reliability", + "reliable", + "reliableWrite", + "reload", + "rem", + "remainingSpace", + "remote", + "remoteDescription", + "remove", + "removeAllRanges", + "removeAttribute", + "removeAttributeNS", + "removeAttributeNode", + "removeBehavior", + "removeChild", + "removeCue", + "removeEntry", + "removeEventListener", + "removeFilter", + "removeImport", + "removeItem", + "removeListener", + "removeNamedItem", + "removeNamedItemNS", + "removeNode", + "removeParameter", + "removeProperty", + "removeRange", + "removeRegion", + "removeRule", + "removeSiteSpecificTrackingException", + "removeSourceBuffer", + "removeStream", + "removeTrack", + "removeVariable", + "removeWakeLockListener", + "removeWebWideTrackingException", + "removed", + "removedNodes", + "renderBlockingStatus", + "renderHeight", + "renderStart", + "renderState", + "renderTime", + "renderWidth", + "renderbufferStorage", + "renderbufferStorageMultisample", + "renderedBuffer", + "rendererInterfaces", + "renderers", + "renderingMode", + "renotify", + "repeat", + "repetitionCount", + "replace", + "replaceAdjacentText", + "replaceAll", + "replaceChild", + "replaceChildren", + "replaceData", + "replaceId", + "replaceItem", + "replaceNode", + "replaceState", + "replaceSync", + "replaceTrack", + "replaceWholeText", + "replaceWith", + "reportError", + "reportEvent", + "reportId", + "reportValidity", + "request", + "requestAdapter", + "requestAdapterInfo", + "requestAnimationFrame", + "requestAutocomplete", + "requestClose", + "requestData", + "requestDevice", + "requestFrame", + "requestFullscreen", + "requestHitTestSource", + "requestHitTestSourceForTransientInput", + "requestId", + "requestIdleCallback", + "requestLightProbe", + "requestMIDIAccess", + "requestMediaKeySystemAccess", + "requestPermission", + "requestPictureInPicture", + "requestPointerLock", + "requestPort", + "requestPresent", + "requestPresenter", + "requestReferenceSpace", + "requestSession", + "requestStart", + "requestStorageAccess", + "requestStorageAccessFor", + "requestSubmit", + "requestTime", + "requestUpdateCheck", + "requestVideoFrameCallback", + "requestViewportScale", + "requestWindow", + "requestingWindow", + "requireInteraction", + "required", + "requiredExtensions", + "requiredFeatures", + "requiredLimits", + "reset", + "resetLatency", + "resetPose", + "resetTransform", + "resizable", + "resize", + "resizeBy", + "resizeTo", + "resolve", + "resolveQuerySet", + "resolveTarget", + "resource", + "respond", + "respondWithNewView", + "response", + "responseBody", + "responseEnd", + "responseReady", + "responseStart", + "responseStatus", + "responseText", + "responseType", + "responseURL", + "responseXML", + "restart", + "restartAfterDelay", + "restartIce", + "restore", + "result", + "resultIndex", + "resultType", + "results", + "resume", + "resumeProfilers", + "resumeTransformFeedback", + "retry", + "returnValue", + "rev", + "reverse", + "reversed", + "revocable", + "revokeObjectURL", + "rex", + "rgbColor", + "ric", + "right", + "rightContext", + "rightDegrees", + "rightMargin", + "rightProjectionMatrix", + "rightViewMatrix", + "rlh", + "role", + "rolloffFactor", + "root", + "rootBounds", + "rootElement", + "rootMargin", + "rotate", + "rotateAxisAngle", + "rotateAxisAngleSelf", + "rotateFromVector", + "rotateFromVectorSelf", + "rotateSelf", + "rotation", + "rotationAngle", + "rotationRate", + "round", + "roundRect", + "row-gap", + "rowGap", + "rowIndex", + "rowSpan", + "rows", + "rowsPerImage", + "rtcpTransport", + "rtt", + "ruby-align", + "ruby-position", + "rubyAlign", + "rubyOverhang", + "rubyPosition", + "rules", + "run", + "runAdAuction", + "runtime", + "runtimeStyle", + "rx", + "ry", + "s", + "safari", + "sameDocument", + "sample", + "sampleCount", + "sampleCoverage", + "sampleInterval", + "sampleRate", + "sampleType", + "sampler", + "samplerParameterf", + "samplerParameteri", + "sandbox", + "save", + "saveAsPDF", + "saveData", + "scale", + "scale3d", + "scale3dSelf", + "scaleNonUniform", + "scaleNonUniformSelf", + "scaleSelf", + "scheduler", + "scheduling", + "scheme", + "scissor", + "scope", + "scopeName", + "scoped", + "screen", + "screenBrightness", + "screenEnabled", + "screenLeft", + "screenPixelToMillimeterX", + "screenPixelToMillimeterY", + "screenState", + "screenTop", + "screenX", + "screenY", + "screens", + "scriptURL", + "scripting", + "scripts", + "scroll", + "scroll-behavior", + "scroll-margin", + "scroll-margin-block", + "scroll-margin-block-end", + "scroll-margin-block-start", + "scroll-margin-bottom", + "scroll-margin-inline", + "scroll-margin-inline-end", + "scroll-margin-inline-start", + "scroll-margin-left", + "scroll-margin-right", + "scroll-margin-top", + "scroll-padding", + "scroll-padding-block", + "scroll-padding-block-end", + "scroll-padding-block-start", + "scroll-padding-bottom", + "scroll-padding-inline", + "scroll-padding-inline-end", + "scroll-padding-inline-start", + "scroll-padding-left", + "scroll-padding-right", + "scroll-padding-top", + "scroll-snap-align", + "scroll-snap-stop", + "scroll-snap-type", + "scrollAmount", + "scrollBehavior", + "scrollBy", + "scrollByLines", + "scrollByPages", + "scrollDelay", + "scrollHeight", + "scrollIntoView", + "scrollIntoViewIfNeeded", + "scrollLeft", + "scrollLeftMax", + "scrollMargin", + "scrollMarginBlock", + "scrollMarginBlockEnd", + "scrollMarginBlockStart", + "scrollMarginBottom", + "scrollMarginInline", + "scrollMarginInlineEnd", + "scrollMarginInlineStart", + "scrollMarginLeft", + "scrollMarginRight", + "scrollMarginTop", + "scrollMaxX", + "scrollMaxY", + "scrollPadding", + "scrollPaddingBlock", + "scrollPaddingBlockEnd", + "scrollPaddingBlockStart", + "scrollPaddingBottom", + "scrollPaddingInline", + "scrollPaddingInlineEnd", + "scrollPaddingInlineStart", + "scrollPaddingLeft", + "scrollPaddingRight", + "scrollPaddingTop", + "scrollRestoration", + "scrollSnapAlign", + "scrollSnapStop", + "scrollSnapType", + "scrollTo", + "scrollTop", + "scrollTopMax", + "scrollWidth", + "scrollX", + "scrollY", + "scrollbar-color", + "scrollbar-gutter", + "scrollbar-width", + "scrollbar3dLightColor", + "scrollbarArrowColor", + "scrollbarBaseColor", + "scrollbarColor", + "scrollbarDarkShadowColor", + "scrollbarFaceColor", + "scrollbarGutter", + "scrollbarHighlightColor", + "scrollbarShadowColor", + "scrollbarTrackColor", + "scrollbarWidth", + "scrollbars", + "scrolling", + "scrollingElement", + "sctp", + "sctpCauseCode", + "sdp", + "sdpLineNumber", + "sdpMLineIndex", + "sdpMid", + "seal", + "search", + "searchBox", + "searchBoxJavaBridge_", + "searchParams", + "sectionRowIndex", + "secureConnectionStart", + "security", + "seed", + "seek", + "seekToNextFrame", + "seekable", + "seeking", + "select", + "selectAllChildren", + "selectAlternateInterface", + "selectAudioOutput", + "selectConfiguration", + "selectNode", + "selectNodeContents", + "selectNodes", + "selectSingleNode", + "selectSubString", + "selectURL", + "selected", + "selectedIndex", + "selectedOptions", + "selectedStyleSheetSet", + "selectedStylesheetSet", + "selectedTrack", + "selection", + "selectionDirection", + "selectionEnd", + "selectionStart", + "selector", + "selectorText", + "self", + "send", + "sendAsBinary", + "sendBeacon", + "sendFeatureReport", + "sendMessage", + "sendNativeMessage", + "sendOrder", + "sendReport", + "sender", + "sentAlert", + "sentTimestamp", + "separator", + "serial", + "serialNumber", + "serializable", + "serializeToString", + "serverTiming", + "service", + "serviceWorker", + "session", + "sessionId", + "sessionStorage", + "sessions", + "set", + "setActionHandler", + "setActive", + "setAlpha", + "setAppBadge", + "setAttribute", + "setAttributeNS", + "setAttributeNode", + "setAttributeNodeNS", + "setAttributionReporting", + "setBadgeBackgroundColor", + "setBadgeText", + "setBadgeTextColor", + "setBaseAndExtent", + "setBigInt64", + "setBigUint64", + "setBindGroup", + "setBingCurrentSearchDefault", + "setBlendConstant", + "setCameraActive", + "setCapture", + "setCaptureHandleConfig", + "setCodecPreferences", + "setColor", + "setCompositeOperation", + "setConfiguration", + "setConsumer", + "setCurrentTime", + "setCustomValidity", + "setData", + "setDate", + "setDragImage", + "setEnabled", + "setEnd", + "setEndAfter", + "setEndBefore", + "setEndPoint", + "setExpires", + "setFillColor", + "setFilterRes", + "setFloat16", + "setFloat32", + "setFloat64", + "setFloatValue", + "setFocusBehavior", + "setFormValue", + "setFromBase64", + "setFromHex", + "setFullYear", + "setHTMLUnsafe", + "setHeaderExtensionsToNegotiate", + "setHeaderValue", + "setHours", + "setIcon", + "setIdentityProvider", + "setImmediate", + "setIndexBuffer", + "setInt16", + "setInt32", + "setInt8", + "setInterval", + "setItem", + "setKeyframes", + "setLineCap", + "setLineDash", + "setLineJoin", + "setLineWidth", + "setLiveSeekableRange", + "setLocalDescription", + "setMatrix", + "setMatrixValue", + "setMediaKeys", + "setMicrophoneActive", + "setMilliseconds", + "setMinutes", + "setMiterLimit", + "setMonth", + "setNamedItem", + "setNamedItemNS", + "setNonUserCodeExceptions", + "setOrientToAngle", + "setOrientToAuto", + "setOrientation", + "setOverrideHistoryNavigationMode", + "setPaint", + "setParameter", + "setParameters", + "setPeriodicWave", + "setPipeline", + "setPointerCapture", + "setPopup", + "setPosition", + "setPositionState", + "setPreference", + "setPriority", + "setPrivateToken", + "setProperty", + "setPrototypeOf", + "setRGBColor", + "setRGBColorICCColor", + "setRadius", + "setRangeText", + "setRemoteDescription", + "setReportEventDataForAutomaticBeacons", + "setRequestHeader", + "setResizable", + "setResourceTimingBufferSize", + "setRotate", + "setScale", + "setScissorRect", + "setSeconds", + "setSelectionRange", + "setServerCertificate", + "setShadow", + "setSharedStorageContext", + "setSignals", + "setSinkId", + "setSkewX", + "setSkewY", + "setStart", + "setStartAfter", + "setStartBefore", + "setStatus", + "setStdDeviation", + "setStencilReference", + "setStreams", + "setStrictMode", + "setStringValue", + "setStrokeColor", + "setSuggestResult", + "setTargetAtTime", + "setTargetValueAtTime", + "setTime", + "setTimeout", + "setTitle", + "setTransform", + "setTranslate", + "setUTCDate", + "setUTCFullYear", + "setUTCHours", + "setUTCMilliseconds", + "setUTCMinutes", + "setUTCMonth", + "setUTCSeconds", + "setUint16", + "setUint32", + "setUint8", + "setUninstallURL", + "setUpdateUrlData", + "setUri", + "setValidity", + "setValueAtTime", + "setValueCurveAtTime", + "setVariable", + "setVelocity", + "setVersion", + "setVertexBuffer", + "setViewport", + "setYear", + "setZoom", + "setZoomSettings", + "settingName", + "settingValue", + "sex", + "shaderLocation", + "shaderSource", + "shadowBlur", + "shadowColor", + "shadowOffsetX", + "shadowOffsetY", + "shadowRoot", + "shadowRootClonable", + "shadowRootDelegatesFocus", + "shadowRootMode", + "shadowRootSerializable", + "shape", + "shape-image-threshold", + "shape-margin", + "shape-outside", + "shape-rendering", + "shapeImageThreshold", + "shapeMargin", + "shapeOutside", + "shapeRendering", + "share", + "sharedStorage", + "sharedStorageWritable", + "sheet", + "shift", + "shiftKey", + "shiftLeft", + "shippingAddress", + "shippingOption", + "shippingType", + "show", + "showDirectoryPicker", + "showHelp", + "showModal", + "showModalDialog", + "showModelessDialog", + "showNotification", + "showOpenFilePicker", + "showPicker", + "showPopover", + "showSaveFilePicker", + "sidebar", + "sidebarAction", + "sign", + "signal", + "signalingState", + "signature", + "silent", + "sin", + "singleNodeValue", + "sinh", + "sinkId", + "sittingToStandingTransform", + "size", + "sizeAdjust", + "sizeToContent", + "sizeX", + "sizeZ", + "sizes", + "skewX", + "skewXSelf", + "skewY", + "skewYSelf", + "skipTransition", + "skipped", + "slice", + "slope", + "slot", + "slotAssignment", + "small", + "smil", + "smooth", + "smoothingTimeConstant", + "snapTargetBlock", + "snapTargetInline", + "snapToLines", + "snapshotItem", + "snapshotLength", + "some", + "sort", + "sortingCode", + "source", + "sourceBuffer", + "sourceBuffers", + "sourceCapabilities", + "sourceCharPosition", + "sourceFile", + "sourceFunctionName", + "sourceIndex", + "sourceMap", + "sourceURL", + "sources", + "spacing", + "span", + "speak", + "speakAs", + "speaking", + "species", + "specified", + "specularConstant", + "specularExponent", + "speechSynthesis", + "speed", + "speedOfSound", + "spellcheck", + "sphericalHarmonicsCoefficients", + "splice", + "split", + "splitText", + "spreadMethod", + "sqrt", + "src", + "srcElement", + "srcFactor", + "srcFilter", + "srcObject", + "srcUrn", + "srcdoc", + "srclang", + "srcset", + "stack", + "stackTraceLimit", + "stacktrace", + "stageParameters", + "standalone", + "standby", + "start", + "startContainer", + "startE", + "startIce", + "startLoadTime", + "startMessages", + "startNotifications", + "startOffset", + "startProfiling", + "startRendering", + "startShark", + "startTime", + "startViewTransition", + "startsWith", + "state", + "states", + "stats", + "status", + "statusCode", + "statusMessage", + "statusText", + "statusbar", + "stdDeviationX", + "stdDeviationY", + "stencilBack", + "stencilClearValue", + "stencilFront", + "stencilFunc", + "stencilFuncSeparate", + "stencilLoadOp", + "stencilMask", + "stencilMaskSeparate", + "stencilOp", + "stencilOpSeparate", + "stencilReadMask", + "stencilReadOnly", + "stencilStoreOp", + "stencilWriteMask", + "step", + "stepDown", + "stepMismatch", + "stepMode", + "stepUp", + "sticky", + "stitchTiles", + "stop", + "stop-color", + "stop-opacity", + "stopColor", + "stopImmediatePropagation", + "stopNotifications", + "stopOpacity", + "stopProfiling", + "stopPropagation", + "stopShark", + "stopped", + "storage", + "storageArea", + "storageBuckets", + "storageName", + "storageStatus", + "storageTexture", + "store", + "storeOp", + "storeSiteSpecificTrackingException", + "storeWebWideTrackingException", + "stpVersion", + "stream", + "streamErrorCode", + "streams", + "stretch", + "strike", + "string", + "stringValue", + "stringify", + "stripIndexFormat", + "stroke", + "stroke-dasharray", + "stroke-dashoffset", + "stroke-linecap", + "stroke-linejoin", + "stroke-miterlimit", + "stroke-opacity", + "stroke-width", + "strokeDasharray", + "strokeDashoffset", + "strokeLinecap", + "strokeLinejoin", + "strokeMiterlimit", + "strokeOpacity", + "strokeRect", + "strokeStyle", + "strokeText", + "strokeWidth", + "structuredClone", + "style", + "styleAndLayoutStart", + "styleFloat", + "styleMap", + "styleMedia", + "styleSheet", + "styleSheetSets", + "styleSheets", + "sub", + "subarray", + "subject", + "submit", + "submitFrame", + "submitter", + "subscribe", + "substr", + "substring", + "substringData", + "subtle", + "subtree", + "suffix", + "suffixes", + "summary", + "sup", + "supported", + "supportedContentEncodings", + "supportedEntryTypes", + "supportedValuesOf", + "supports", + "supportsFiber", + "supportsSession", + "supportsText", + "surfaceScale", + "surroundContents", + "suspend", + "suspendRedraw", + "svb", + "svh", + "svi", + "svmax", + "svmin", + "svw", + "swapCache", + "swapNode", + "sweepFlag", + "symbols", + "symmetricDifference", + "sync", + "syntax", + "sysexEnabled", + "system", + "systemCode", + "systemId", + "systemLanguage", + "systemXDPI", + "systemYDPI", + "tBodies", + "tFoot", + "tHead", + "tab", + "tab-size", + "tabId", + "tabIds", + "tabIndex", + "tabSize", + "table", + "table-layout", + "tableLayout", + "tableValues", + "tabs", + "tag", + "tagName", + "tagUrn", + "tags", + "taintEnabled", + "take", + "takePhoto", + "takeRecords", + "tan", + "tangentialPressure", + "tanh", + "target", + "targetAddressSpace", + "targetElement", + "targetRayMode", + "targetRaySpace", + "targetTouches", + "targetURL", + "targetX", + "targetY", + "targets", + "tcpType", + "tee", + "tel", + "telemetry", + "terminate", + "test", + "texImage2D", + "texImage3D", + "texParameterf", + "texParameteri", + "texStorage2D", + "texStorage3D", + "texSubImage2D", + "texSubImage3D", + "text", + "text-align", + "text-align-last", + "text-anchor", + "text-combine-upright", + "text-decoration", + "text-decoration-color", + "text-decoration-line", + "text-decoration-skip-ink", + "text-decoration-style", + "text-decoration-thickness", + "text-emphasis", + "text-emphasis-color", + "text-emphasis-position", + "text-emphasis-style", + "text-indent", + "text-justify", + "text-orientation", + "text-overflow", + "text-rendering", + "text-shadow", + "text-transform", + "text-underline-offset", + "text-underline-position", + "text-wrap", + "text-wrap-mode", + "text-wrap-style", + "textAlign", + "textAlignLast", + "textAnchor", + "textAutospace", + "textBaseline", + "textCombineUpright", + "textContent", + "textDecoration", + "textDecorationBlink", + "textDecorationColor", + "textDecorationLine", + "textDecorationLineThrough", + "textDecorationNone", + "textDecorationOverline", + "textDecorationSkipInk", + "textDecorationStyle", + "textDecorationThickness", + "textDecorationUnderline", + "textEmphasis", + "textEmphasisColor", + "textEmphasisPosition", + "textEmphasisStyle", + "textIndent", + "textJustify", + "textJustifyTrim", + "textKashida", + "textKashidaSpace", + "textLength", + "textOrientation", + "textOverflow", + "textRendering", + "textShadow", + "textTracks", + "textTransform", + "textUnderlineOffset", + "textUnderlinePosition", + "textWrap", + "textWrapMode", + "textWrapStyle", + "texture", + "theme", + "then", + "threadId", + "threshold", + "thresholds", + "throwIfAborted", + "tiltX", + "tiltY", + "time", + "timeEnd", + "timeLog", + "timeOrigin", + "timeRemaining", + "timeStamp", + "timecode", + "timeline", + "timelineTime", + "timeout", + "timestamp", + "timestampOffset", + "timestampWrites", + "timing", + "title", + "titlebarAreaRect", + "tlsChannelId", + "to", + "toArray", + "toBase64", + "toBlob", + "toDataURL", + "toDateString", + "toElement", + "toExponential", + "toFixed", + "toFloat32Array", + "toFloat64Array", + "toGMTString", + "toHex", + "toISOString", + "toJSON", + "toLocaleDateString", + "toLocaleFormat", + "toLocaleLowerCase", + "toLocaleString", + "toLocaleTimeString", + "toLocaleUpperCase", + "toLowerCase", + "toMatrix", + "toMethod", + "toPrecision", + "toPrimitive", + "toReversed", + "toSdp", + "toSorted", + "toSource", + "toSpliced", + "toStaticHTML", + "toString", + "toStringTag", + "toSum", + "toTimeString", + "toUTCString", + "toUpperCase", + "toWellFormed", + "toggle", + "toggleAttribute", + "toggleLongPressEnabled", + "togglePopover", + "toggleReaderMode", + "token", + "tone", + "toneBuffer", + "tooLong", + "tooShort", + "toolbar", + "top", + "topMargin", + "topSites", + "topology", + "total", + "totalFrameDelay", + "totalFrames", + "totalFramesDuration", + "totalVideoFrames", + "touch-action", + "touchAction", + "touched", + "touches", + "trace", + "track", + "trackVisibility", + "trackedAnchors", + "tracks", + "tran", + "transaction", + "transactions", + "transceiver", + "transfer", + "transferControlToOffscreen", + "transferFromImageBitmap", + "transferImageBitmap", + "transferIn", + "transferOut", + "transferSize", + "transferToFixedLength", + "transferToImageBitmap", + "transform", + "transform-box", + "transform-origin", + "transform-style", + "transformBox", + "transformFeedbackVaryings", + "transformOrigin", + "transformPoint", + "transformString", + "transformStyle", + "transformToDocument", + "transformToFragment", + "transition", + "transition-behavior", + "transition-delay", + "transition-duration", + "transition-property", + "transition-timing-function", + "transitionBehavior", + "transitionDelay", + "transitionDuration", + "transitionProperty", + "transitionTimingFunction", + "translate", + "translateSelf", + "translationX", + "translationY", + "transport", + "traverseTo", + "trim", + "trimEnd", + "trimLeft", + "trimRight", + "trimStart", + "trueSpeed", + "trunc", + "truncate", + "trustedTypes", + "try", + "turn", + "twist", + "type", + "typeDetail", + "typeMismatch", + "typeMustMatch", + "types", + "u2f", + "ubound", + "uint16", + "uint32", + "uint8", + "uint8Clamped", + "unadjustedMovement", + "unclippedDepth", + "unconfigure", + "undefined", + "underlineStyle", + "underlineThickness", + "unescape", + "uneval", + "ungroup", + "unicode", + "unicode-bidi", + "unicodeBidi", + "unicodeRange", + "unicodeSets", + "uniform1f", + "uniform1fv", + "uniform1i", + "uniform1iv", + "uniform1ui", + "uniform1uiv", + "uniform2f", + "uniform2fv", + "uniform2i", + "uniform2iv", + "uniform2ui", + "uniform2uiv", + "uniform3f", + "uniform3fv", + "uniform3i", + "uniform3iv", + "uniform3ui", + "uniform3uiv", + "uniform4f", + "uniform4fv", + "uniform4i", + "uniform4iv", + "uniform4ui", + "uniform4uiv", + "uniformBlockBinding", + "uniformMatrix2fv", + "uniformMatrix2x3fv", + "uniformMatrix2x4fv", + "uniformMatrix3fv", + "uniformMatrix3x2fv", + "uniformMatrix3x4fv", + "uniformMatrix4fv", + "uniformMatrix4x2fv", + "uniformMatrix4x3fv", + "uninstallSelf", + "union", + "unique", + "uniqueID", + "uniqueNumber", + "unit", + "unitType", + "units", + "unloadEventEnd", + "unloadEventStart", + "unlock", + "unmap", + "unmount", + "unobserve", + "unpackColorSpace", + "unpause", + "unpauseAnimations", + "unreadCount", + "unregister", + "unregisterContentHandler", + "unregisterProtocolHandler", + "unscopables", + "unselectable", + "unshift", + "unsubscribe", + "unsuspendRedraw", + "unsuspendRedrawAll", + "unwatch", + "unwrapKey", + "upDegrees", + "upX", + "upY", + "upZ", + "update", + "updateAdInterestGroups", + "updateCallbackDone", + "updateCharacterBounds", + "updateCommands", + "updateControlBounds", + "updateCurrentEntry", + "updateIce", + "updateInkTrailStartPoint", + "updateInterval", + "updatePlaybackRate", + "updateRangeEnd", + "updateRangeStart", + "updateRenderState", + "updateSelection", + "updateSelectionBounds", + "updateSettings", + "updateText", + "updateTiming", + "updateViaCache", + "updateWith", + "updated", + "updating", + "upgrade", + "upload", + "uploadTotal", + "uploaded", + "upper", + "upperBound", + "upperOpen", + "uri", + "url", + "urn", + "urns", + "usage", + "usages", + "usb", + "usbVersionMajor", + "usbVersionMinor", + "usbVersionSubminor", + "useCurrentView", + "useMap", + "useProgram", + "usedSpace", + "user-select", + "userActivation", + "userAgent", + "userAgentData", + "userChoice", + "userHandle", + "userHint", + "userInitiated", + "userLanguage", + "userSelect", + "userState", + "userVisibleOnly", + "username", + "usernameFragment", + "utterance", + "uuid", + "v8BreakIterator", + "vAlign", + "vLink", + "valid", + "validate", + "validateProgram", + "validationMessage", + "validity", + "value", + "valueAsDate", + "valueAsNumber", + "valueAsString", + "valueInSpecifiedUnits", + "valueMissing", + "valueOf", + "valueText", + "valueType", + "values", + "variable", + "variant", + "variationSettings", + "vb", + "vector-effect", + "vectorEffect", + "velocityAngular", + "velocityExpansion", + "velocityX", + "velocityY", + "vendor", + "vendorId", + "vendorSub", + "verify", + "version", + "vertex", + "vertexAttrib1f", + "vertexAttrib1fv", + "vertexAttrib2f", + "vertexAttrib2fv", + "vertexAttrib3f", + "vertexAttrib3fv", + "vertexAttrib4f", + "vertexAttrib4fv", + "vertexAttribDivisor", + "vertexAttribDivisorANGLE", + "vertexAttribI4i", + "vertexAttribI4iv", + "vertexAttribI4ui", + "vertexAttribI4uiv", + "vertexAttribIPointer", + "vertexAttribPointer", + "vertical", + "vertical-align", + "verticalAlign", + "verticalOverflow", + "vh", + "vi", + "vibrate", + "vibrationActuator", + "videoBitsPerSecond", + "videoHeight", + "videoTracks", + "videoWidth", + "view", + "viewBox", + "viewBoxString", + "viewDimension", + "viewFormats", + "viewTarget", + "viewTargetString", + "viewTransition", + "viewport", + "viewportAnchorX", + "viewportAnchorY", + "viewportElement", + "views", + "violatedDirective", + "virtualKeyboard", + "virtualKeyboardPolicy", + "visibility", + "visibilityState", + "visible", + "visibleRect", + "visualViewport", + "vlinkColor", + "vmax", + "vmin", + "voice", + "voiceURI", + "volume", + "vrml", + "vspace", + "vw", + "w", + "wait", + "waitAsync", + "waitSync", + "waiting", + "wake", + "wakeLock", + "wand", + "warmup", + "warn", + "wasAlternateProtocolAvailable", + "wasClean", + "wasDiscarded", + "wasFetchedViaSpdy", + "wasNpnNegotiated", + "watch", + "watchAvailability", + "watchPosition", + "webNavigation", + "webRequest", + "webdriver", + "webkitAddKey", + "webkitAlignContent", + "webkitAlignItems", + "webkitAlignSelf", + "webkitAnimation", + "webkitAnimationDelay", + "webkitAnimationDirection", + "webkitAnimationDuration", + "webkitAnimationFillMode", + "webkitAnimationIterationCount", + "webkitAnimationName", + "webkitAnimationPlayState", + "webkitAnimationTimingFunction", + "webkitAppearance", + "webkitAudioContext", + "webkitAudioDecodedByteCount", + "webkitAudioPannerNode", + "webkitBackfaceVisibility", + "webkitBackground", + "webkitBackgroundAttachment", + "webkitBackgroundClip", + "webkitBackgroundColor", + "webkitBackgroundImage", + "webkitBackgroundOrigin", + "webkitBackgroundPosition", + "webkitBackgroundPositionX", + "webkitBackgroundPositionY", + "webkitBackgroundRepeat", + "webkitBackgroundSize", + "webkitBackingStorePixelRatio", + "webkitBorderBottomLeftRadius", + "webkitBorderBottomRightRadius", + "webkitBorderImage", + "webkitBorderImageOutset", + "webkitBorderImageRepeat", + "webkitBorderImageSlice", + "webkitBorderImageSource", + "webkitBorderImageWidth", + "webkitBorderRadius", + "webkitBorderTopLeftRadius", + "webkitBorderTopRightRadius", + "webkitBoxAlign", + "webkitBoxDirection", + "webkitBoxFlex", + "webkitBoxOrdinalGroup", + "webkitBoxOrient", + "webkitBoxPack", + "webkitBoxShadow", + "webkitBoxSizing", + "webkitCancelAnimationFrame", + "webkitCancelFullScreen", + "webkitCancelKeyRequest", + "webkitCancelRequestAnimationFrame", + "webkitClearResourceTimings", + "webkitClipPath", + "webkitClosedCaptionsVisible", + "webkitConvertPointFromNodeToPage", + "webkitConvertPointFromPageToNode", + "webkitCreateShadowRoot", + "webkitCurrentFullScreenElement", + "webkitCurrentPlaybackTargetIsWireless", + "webkitDecodedFrameCount", + "webkitDirectionInvertedFromDevice", + "webkitDisplayingFullscreen", + "webkitDroppedFrameCount", + "webkitEnterFullScreen", + "webkitEnterFullscreen", + "webkitEntries", + "webkitExitFullScreen", + "webkitExitFullscreen", + "webkitExitPointerLock", + "webkitFilter", + "webkitFlex", + "webkitFlexBasis", + "webkitFlexDirection", + "webkitFlexFlow", + "webkitFlexGrow", + "webkitFlexShrink", + "webkitFlexWrap", + "webkitFontFeatureSettings", + "webkitFullScreenKeyboardInputAllowed", + "webkitFullscreenElement", + "webkitFullscreenEnabled", + "webkitGenerateKeyRequest", + "webkitGetAsEntry", + "webkitGetDatabaseNames", + "webkitGetEntries", + "webkitGetEntriesByName", + "webkitGetEntriesByType", + "webkitGetFlowByName", + "webkitGetGamepads", + "webkitGetImageDataHD", + "webkitGetNamedFlows", + "webkitGetRegionFlowRanges", + "webkitGetUserMedia", + "webkitHasClosedCaptions", + "webkitHidden", + "webkitIDBCursor", + "webkitIDBDatabase", + "webkitIDBDatabaseError", + "webkitIDBDatabaseException", + "webkitIDBFactory", + "webkitIDBIndex", + "webkitIDBKeyRange", + "webkitIDBObjectStore", + "webkitIDBRequest", + "webkitIDBTransaction", + "webkitImageSmoothingEnabled", + "webkitIndexedDB", + "webkitInitMessageEvent", + "webkitIsFullScreen", + "webkitJustifyContent", + "webkitKeys", + "webkitLineClamp", + "webkitLineDashOffset", + "webkitLockOrientation", + "webkitMask", + "webkitMaskClip", + "webkitMaskComposite", + "webkitMaskImage", + "webkitMaskOrigin", + "webkitMaskPosition", + "webkitMaskPositionX", + "webkitMaskPositionY", + "webkitMaskRepeat", + "webkitMaskSize", + "webkitMatchesSelector", + "webkitMediaStream", + "webkitNotifications", + "webkitOfflineAudioContext", + "webkitOrder", + "webkitOrientation", + "webkitPeerConnection00", + "webkitPersistentStorage", + "webkitPerspective", + "webkitPerspectiveOrigin", + "webkitPointerLockElement", + "webkitPostMessage", + "webkitPreservesPitch", + "webkitPutImageDataHD", + "webkitRTCPeerConnection", + "webkitRegionOverset", + "webkitRelativePath", + "webkitRequestAnimationFrame", + "webkitRequestFileSystem", + "webkitRequestFullScreen", + "webkitRequestFullscreen", + "webkitRequestPointerLock", + "webkitResolveLocalFileSystemURL", + "webkitSetMediaKeys", + "webkitSetResourceTimingBufferSize", + "webkitShadowRoot", + "webkitShowPlaybackTargetPicker", + "webkitSlice", + "webkitSpeechGrammar", + "webkitSpeechGrammarList", + "webkitSpeechRecognition", + "webkitSpeechRecognitionError", + "webkitSpeechRecognitionEvent", + "webkitStorageInfo", + "webkitSupportsFullscreen", + "webkitTemporaryStorage", + "webkitTextFillColor", + "webkitTextSecurity", + "webkitTextSizeAdjust", + "webkitTextStroke", + "webkitTextStrokeColor", + "webkitTextStrokeWidth", + "webkitTransform", + "webkitTransformOrigin", + "webkitTransformStyle", + "webkitTransition", + "webkitTransitionDelay", + "webkitTransitionDuration", + "webkitTransitionProperty", + "webkitTransitionTimingFunction", + "webkitURL", + "webkitUnlockOrientation", + "webkitUserSelect", + "webkitVideoDecodedByteCount", + "webkitVisibilityState", + "webkitWirelessVideoPlaybackDisabled", + "webkitdirectory", + "webkitdropzone", + "webstore", + "weight", + "wgslLanguageFeatures", + "whatToShow", + "wheelDelta", + "wheelDeltaX", + "wheelDeltaY", + "whenDefined", + "which", + "white-space", + "white-space-collapse", + "whiteSpace", + "whiteSpaceCollapse", + "wholeText", + "widows", + "width", + "will-change", + "willChange", + "willValidate", + "window", + "windowAttribution", + "windowControlsOverlay", + "windowId", + "windowIds", + "windows", + "with", + "withCredentials", + "withResolvers", + "word-break", + "word-spacing", + "word-wrap", + "wordBreak", + "wordSpacing", + "wordWrap", + "workerStart", + "worklet", + "wow64", + "wrap", + "wrapKey", + "writable", + "writableAuxiliaries", + "write", + "writeBuffer", + "writeMask", + "writeText", + "writeTexture", + "writeTimestamp", + "writeValue", + "writeValueWithResponse", + "writeValueWithoutResponse", + "writeWithoutResponse", + "writeln", + "writing-mode", + "writingMode", + "writingSuggestions", + "x", + "x1", + "x2", + "xChannelSelector", + "xmlEncoding", + "xmlStandalone", + "xmlVersion", + "xmlbase", + "xmllang", + "xmlspace", + "xor", + "xr", + "y", + "y1", + "y2", + "yChannelSelector", + "yandex", + "yield", + "z", + "z-index", + "zIndex", + "zoom", + "zoomAndPan", + "zoomRectScreen", +]; + +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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 find_builtins(reserved) { + domprops.forEach(add); + + // Compatibility fix for some standard defined globals not defined on every js environment + var new_globals = ["Symbol", "Map", "Promise", "Proxy", "Reflect", "Set", "WeakMap", "WeakSet"]; + var objects = {}; + var global_ref = typeof global === "object" ? global : self; + + new_globals.forEach(function (new_global) { + objects[new_global] = global_ref[new_global] || function() {}; + }); + + [ + "null", + "true", + "false", + "NaN", + "Infinity", + "-Infinity", + "undefined", + ].forEach(add); + [ Object, Array, Function, Number, + String, Boolean, Error, Math, + Date, RegExp, objects.Symbol, ArrayBuffer, + DataView, decodeURI, decodeURIComponent, + encodeURI, encodeURIComponent, eval, EvalError, + Float32Array, Float64Array, Int8Array, Int16Array, + Int32Array, isFinite, isNaN, JSON, objects.Map, parseFloat, + parseInt, objects.Promise, objects.Proxy, RangeError, ReferenceError, + objects.Reflect, objects.Set, SyntaxError, TypeError, Uint8Array, + Uint8ClampedArray, Uint16Array, Uint32Array, URIError, + objects.WeakMap, objects.WeakSet + ].forEach(function(ctor) { + Object.getOwnPropertyNames(ctor).map(add); + if (ctor.prototype) { + Object.getOwnPropertyNames(ctor.prototype).map(add); + } + }); + function add(name) { + reserved.add(name); + } +} + +function reserve_quoted_keys(ast, reserved) { + function add(name) { + push_uniq(reserved, name); + } + + ast.walk(new TreeWalker(function(node) { + if (node instanceof AST_ObjectKeyVal && node.quote) { + add(node.key); + } else if (node instanceof AST_ObjectProperty && node.quote) { + add(node.key.name); + } else if (node instanceof AST_Sub) { + addStrings(node.property, add); + } + })); +} + +function addStrings(node, add) { + node.walk(new TreeWalker(function(node) { + if (node instanceof AST_Sequence) { + addStrings(node.tail_node(), add); + } else if (node instanceof AST_String) { + add(node.value); + } else if (node instanceof AST_Conditional) { + addStrings(node.consequent, add); + addStrings(node.alternative, add); + } + return true; + })); +} + +function mangle_private_properties(ast, options) { + var cprivate = -1; + var private_cache = new Map(); + var nth_identifier = options.nth_identifier || base54; + + ast = ast.transform(new TreeTransformer(function(node) { + if ( + node instanceof AST_ClassPrivateProperty + || node instanceof AST_PrivateMethod + || node instanceof AST_PrivateGetter + || node instanceof AST_PrivateSetter + || node instanceof AST_PrivateIn + ) { + node.key.name = mangle_private(node.key.name); + } else if (node instanceof AST_DotHash) { + node.property = mangle_private(node.property); + } + })); + return ast; + + function mangle_private(name) { + let mangled = private_cache.get(name); + if (!mangled) { + mangled = nth_identifier.get(++cprivate); + private_cache.set(name, mangled); + } + + return mangled; + } +} + +function find_annotated_props(ast) { + var annotated_props = new Set(); + walk(ast, node => { + if ( + node instanceof AST_ClassPrivateProperty + || node instanceof AST_PrivateMethod + || node instanceof AST_PrivateGetter + || node instanceof AST_PrivateSetter + || node instanceof AST_DotHash + ) ; else if (node instanceof AST_ObjectKeyVal) { + if (typeof node.key == "string" && has_annotation(node, _MANGLEPROP)) { + annotated_props.add(node.key); + } + } else if (node instanceof AST_ObjectProperty) { + // setter or getter, since KeyVal is handled above + if (has_annotation(node, _MANGLEPROP)) { + annotated_props.add(node.key.name); + } + } else if (node instanceof AST_Dot) { + if (has_annotation(node, _MANGLEPROP)) { + annotated_props.add(node.property); + } + } else if (node instanceof AST_Sub) { + if (node.property instanceof AST_String && has_annotation(node, _MANGLEPROP)) { + annotated_props.add(node.property.value); + } + } + }); + return annotated_props; +} + +function mangle_properties(ast, options, annotated_props = find_annotated_props(ast)) { + options = defaults(options, { + builtins: false, + cache: null, + debug: false, + keep_quoted: false, + nth_identifier: base54, + only_cache: false, + regex: null, + reserved: null, + undeclared: false, + only_annotated: false, + }, true); + + var nth_identifier = options.nth_identifier; + + var reserved_option = options.reserved; + if (!Array.isArray(reserved_option)) reserved_option = [reserved_option]; + var reserved = new Set(reserved_option); + if (!options.builtins) find_builtins(reserved); + + var cname = -1; + + var cache; + if (options.cache) { + cache = options.cache.props; + } else { + cache = new Map(); + } + + var only_annotated = options.only_annotated; + var regex = options.regex && new RegExp(options.regex); + + // note debug is either false (disabled), or a string of the debug suffix to use (enabled). + // note debug may be enabled as an empty string, which is falsey. Also treat passing 'true' + // the same as passing an empty string. + var debug = options.debug !== false; + var debug_name_suffix; + if (debug) { + debug_name_suffix = (options.debug === true ? "" : options.debug); + } + + var names_to_mangle = new Set(); + var unmangleable = new Set(); + // Track each already-mangled name to prevent nth_identifier from generating + // the same name. + cache.forEach((mangled_name) => unmangleable.add(mangled_name)); + + var keep_quoted = !!options.keep_quoted; + + // step 1: find candidates to mangle + ast.walk(new TreeWalker(function(node) { + if ( + node instanceof AST_ClassPrivateProperty + || node instanceof AST_PrivateMethod + || node instanceof AST_PrivateGetter + || node instanceof AST_PrivateSetter + || node instanceof AST_DotHash + ) ; else if (node instanceof AST_ObjectKeyVal) { + if (typeof node.key == "string" && (!keep_quoted || !node.quote)) { + add(node.key); + } + } else if (node instanceof AST_ObjectProperty) { + // setter or getter, since KeyVal is handled above + if (!keep_quoted || !node.quote) { + add(node.key.name); + } + } else if (node instanceof AST_Dot) { + var declared = !!options.undeclared; + if (!declared) { + var root = node; + while (root.expression) { + root = root.expression; + } + declared = !(root.thedef && root.thedef.undeclared); + } + if (declared && + (!keep_quoted || !node.quote)) { + add(node.property); + } + } else if (node instanceof AST_Sub) { + if (!keep_quoted) { + addStrings(node.property, add); + } + } else if (node instanceof AST_Call + && node.expression.print_to_string() == "Object.defineProperty") { + addStrings(node.args[1], add); + } else if (node instanceof AST_Binary && node.operator === "in") { + addStrings(node.left, add); + } else if (node instanceof AST_String && has_annotation(node, _KEY)) { + add(node.value); + } + })); + + // step 2: transform the tree, renaming properties + return ast.transform(new TreeTransformer(function(node) { + if ( + node instanceof AST_ClassPrivateProperty + || node instanceof AST_PrivateMethod + || node instanceof AST_PrivateGetter + || node instanceof AST_PrivateSetter + || node instanceof AST_DotHash + ) ; else if (node instanceof AST_ObjectKeyVal) { + if (typeof node.key == "string" && (!keep_quoted || !node.quote)) { + node.key = mangle(node.key); + } + } else if (node instanceof AST_ObjectProperty) { + // setter, getter, method or class field + if (!keep_quoted || !node.quote) { + if (!node.computed_key()) { + node.key.name = mangle(node.key.name); + } + } + } else if (node instanceof AST_Dot) { + if (!keep_quoted || !node.quote) { + node.property = mangle(node.property); + } + } else if (!keep_quoted && node instanceof AST_Sub) { + node.property = mangleStrings(node.property); + } else if (node instanceof AST_Call + && node.expression.print_to_string() == "Object.defineProperty") { + node.args[1] = mangleStrings(node.args[1]); + } else if (node instanceof AST_Binary && node.operator === "in") { + node.left = mangleStrings(node.left); + } else if (node instanceof AST_String && has_annotation(node, _KEY)) { + // Clear _KEY annotation to prevent double mangling + clear_annotation(node, _KEY); + node.value = mangle(node.value); + } + })); + + // only function declarations after this line + + function can_mangle(name) { + if (unmangleable.has(name)) return false; + if (reserved.has(name)) return false; + if (options.only_cache) { + return cache.has(name); + } + if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false; + return true; + } + + function should_mangle(name) { + if (only_annotated && !annotated_props.has(name)) return false; + if (regex && !regex.test(name)) { + return annotated_props.has(name); + } + if (reserved.has(name)) return false; + return cache.has(name) + || names_to_mangle.has(name); + } + + function add(name) { + if (can_mangle(name)) { + names_to_mangle.add(name); + } + + if (!should_mangle(name)) { + unmangleable.add(name); + } + } + + function mangle(name) { + if (!should_mangle(name)) { + return name; + } + + var mangled = cache.get(name); + if (!mangled) { + if (debug) { + // debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_. + var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_"; + + if (can_mangle(debug_mangled)) { + mangled = debug_mangled; + } + } + + // either debug mode is off, or it is on and we could not use the mangled name + if (!mangled) { + do { + mangled = nth_identifier.get(++cname); + } while (!can_mangle(mangled)); + } + + cache.set(name, mangled); + } + return mangled; + } + + function mangleStrings(node) { + return node.transform(new TreeTransformer(function(node) { + if (node instanceof AST_Sequence) { + var last = node.expressions.length - 1; + node.expressions[last] = mangleStrings(node.expressions[last]); + } else if (node instanceof AST_String) { + // Clear _KEY annotation to prevent double mangling + clear_annotation(node, _KEY); + node.value = mangle(node.value); + } else if (node instanceof AST_Conditional) { + node.consequent = mangleStrings(node.consequent); + node.alternative = mangleStrings(node.alternative); + } + return node; + })); + } +} + +// to/from base64 functions +// Prefer built-in Buffer, if available, then use hack +// https://developer.mozilla.org/en-US/docs/Glossary/Base64#The_Unicode_Problem +var to_ascii = typeof Buffer !== "undefined" + ? (b64) => Buffer.from(b64, "base64").toString() + : (b64) => decodeURIComponent(escape(atob(b64))); +var to_base64 = typeof Buffer !== "undefined" + ? (str) => Buffer.from(str).toString("base64") + : (str) => btoa(unescape(encodeURIComponent(str))); + +function read_source_map(code) { + var match = /(?:^|[^.])\/\/# sourceMappingURL=data:application\/json(;[\w=-]*)?;base64,([+/0-9A-Za-z]*=*)\s*$/.exec(code); + if (!match) { + console.warn("inline source map not found"); + return null; + } + return to_ascii(match[2]); +} + +function set_shorthand(name, options, keys) { + if (options[name]) { + keys.forEach(function(key) { + if (options[key]) { + if (typeof options[key] != "object") options[key] = {}; + if (!(name in options[key])) options[key][name] = options[name]; + } + }); + } +} + +function init_cache(cache) { + if (!cache) return; + if (!("props" in cache)) { + cache.props = new Map(); + } else if (!(cache.props instanceof Map)) { + cache.props = map_from_object(cache.props); + } +} + +function cache_to_json(cache) { + return { + props: map_to_object(cache.props) + }; +} + +function log_input(files, options, fs, debug_folder) { + if (!(fs && fs.writeFileSync && fs.mkdirSync)) { + return; + } + + try { + fs.mkdirSync(debug_folder); + } catch (e) { + if (e.code !== "EEXIST") throw e; + } + + const log_path = `${debug_folder}/terser-debug-${(Math.random() * 9999999) | 0}.log`; + + options = options || {}; + + const options_str = JSON.stringify(options, (_key, thing) => { + if (typeof thing === "function") return "[Function " + thing.toString() + "]"; + if (thing instanceof RegExp) return "[RegExp " + thing.toString() + "]"; + return thing; + }, 4); + + const files_str = (file) => { + if (typeof file === "object" && options.parse && options.parse.spidermonkey) { + return JSON.stringify(file, null, 2); + } else if (typeof file === "object") { + return Object.keys(file) + .map((key) => key + ": " + files_str(file[key])) + .join("\n\n"); + } else if (typeof file === "string") { + return "```\n" + file + "\n```"; + } else { + return file; // What do? + } + }; + + fs.writeFileSync(log_path, "Options: \n" + options_str + "\n\nInput files:\n\n" + files_str(files) + "\n"); +} + +function* minify_sync_or_async(files, options, _fs_module) { + if ( + _fs_module + && typeof process === "object" + && process.env + && typeof process.env.TERSER_DEBUG_DIR === "string" + ) { + log_input(files, options, _fs_module, process.env.TERSER_DEBUG_DIR); + } + + options = defaults(options, { + compress: {}, + ecma: undefined, + enclose: false, + ie8: false, + keep_classnames: undefined, + keep_fnames: false, + mangle: {}, + module: false, + nameCache: null, + output: null, + format: null, + parse: {}, + rename: undefined, + safari10: false, + sourceMap: false, + spidermonkey: false, + timings: false, + toplevel: false, + warnings: false, + wrap: false, + }, true); + + var timings = options.timings && { + start: Date.now() + }; + if (options.keep_classnames === undefined) { + options.keep_classnames = options.keep_fnames; + } + if (options.rename === undefined) { + options.rename = options.compress && options.mangle; + } + if (options.output && options.format) { + throw new Error("Please only specify either output or format option, preferrably format."); + } + options.format = options.format || options.output || {}; + set_shorthand("ecma", options, [ "parse", "compress", "format" ]); + set_shorthand("ie8", options, [ "compress", "mangle", "format" ]); + set_shorthand("keep_classnames", options, [ "compress", "mangle" ]); + set_shorthand("keep_fnames", options, [ "compress", "mangle" ]); + set_shorthand("module", options, [ "parse", "compress", "mangle" ]); + set_shorthand("safari10", options, [ "mangle", "format" ]); + set_shorthand("toplevel", options, [ "compress", "mangle" ]); + set_shorthand("warnings", options, [ "compress" ]); // legacy + var quoted_props; + if (options.mangle) { + options.mangle = defaults(options.mangle, { + cache: options.nameCache && (options.nameCache.vars || {}), + eval: false, + ie8: false, + keep_classnames: false, + keep_fnames: false, + module: false, + nth_identifier: base54, + properties: false, + reserved: [], + safari10: false, + toplevel: false, + }, true); + if (options.mangle.properties) { + if (typeof options.mangle.properties != "object") { + options.mangle.properties = {}; + } + if (options.mangle.properties.keep_quoted) { + quoted_props = options.mangle.properties.reserved; + if (!Array.isArray(quoted_props)) quoted_props = []; + options.mangle.properties.reserved = quoted_props; + } + if (options.nameCache && !("cache" in options.mangle.properties)) { + options.mangle.properties.cache = options.nameCache.props || {}; + } + } + init_cache(options.mangle.cache); + init_cache(options.mangle.properties.cache); + } + if (options.sourceMap) { + options.sourceMap = defaults(options.sourceMap, { + asObject: false, + content: null, + filename: null, + includeSources: false, + root: null, + url: null, + }, true); + } + + // -- Parse phase -- + if (timings) timings.parse = Date.now(); + var toplevel; + if (files instanceof AST_Toplevel) { + toplevel = files; + } else { + if (typeof files == "string" || (options.parse.spidermonkey && !Array.isArray(files))) { + files = [ files ]; + } + options.parse = options.parse || {}; + options.parse.toplevel = null; + + if (options.parse.spidermonkey) { + options.parse.toplevel = AST_Node.from_mozilla_ast(Object.keys(files).reduce(function(toplevel, name) { + if (!toplevel) return files[name]; + toplevel.body = toplevel.body.concat(files[name].body); + return toplevel; + }, null)); + } else { + delete options.parse.spidermonkey; + + for (var name in files) if (HOP(files, name)) { + options.parse.filename = name; + options.parse.toplevel = parse(files[name], options.parse); + if (options.sourceMap && options.sourceMap.content == "inline") { + if (Object.keys(files).length > 1) + throw new Error("inline source map only works with singular input"); + options.sourceMap.content = read_source_map(files[name]); + } + } + } + if (options.parse.toplevel === null) { + throw new Error("no source file given"); + } + + toplevel = options.parse.toplevel; + } + if (quoted_props && options.mangle.properties.keep_quoted !== "strict") { + reserve_quoted_keys(toplevel, quoted_props); + } + var annotated_props; + if (options.mangle && options.mangle.properties) { + annotated_props = find_annotated_props(toplevel); + } + if (options.wrap) { + toplevel = toplevel.wrap_commonjs(options.wrap); + } + if (options.enclose) { + toplevel = toplevel.wrap_enclose(options.enclose); + } + if (timings) timings.rename = Date.now(); + + // -- Compress phase -- + if (timings) timings.compress = Date.now(); + if (options.compress) { + toplevel = new Compressor(options.compress, { + mangle_options: options.mangle + }).compress(toplevel); + } + + // -- Mangle phase -- + if (timings) timings.scope = Date.now(); + if (options.mangle) toplevel.figure_out_scope(options.mangle); + if (timings) timings.mangle = Date.now(); + if (options.mangle) { + toplevel.compute_char_frequency(options.mangle); + toplevel.mangle_names(options.mangle); + toplevel = mangle_private_properties(toplevel, options.mangle); + } + if (timings) timings.properties = Date.now(); + if (options.mangle && options.mangle.properties) { + toplevel = mangle_properties(toplevel, options.mangle.properties, annotated_props); + } + + // Format phase + if (timings) timings.format = Date.now(); + var result = {}; + if (options.format.ast) { + result.ast = toplevel; + } + if (options.format.spidermonkey) { + result.ast = toplevel.to_mozilla_ast(); + } + let format_options; + if (!HOP(options.format, "code") || options.format.code) { + // Make a shallow copy so that we can modify without mutating the user's input. + format_options = {...options.format}; + if (!format_options.ast) { + // Destroy stuff to save RAM. (unless the deprecated `ast` option is on) + format_options._destroy_ast = true; + + walk(toplevel, node => { + if (node instanceof AST_Scope) { + node.variables = undefined; + node.enclosed = undefined; + node.parent_scope = undefined; + } + if (node.block_scope) { + node.block_scope.variables = undefined; + node.block_scope.enclosed = undefined; + node.block_scope.parent_scope = undefined; + } + }); + } + + if (options.sourceMap) { + if (options.sourceMap.includeSources && files instanceof AST_Toplevel) { + throw new Error("original source content unavailable"); + } + format_options.source_map = yield* SourceMap({ + file: options.sourceMap.filename, + orig: options.sourceMap.content, + root: options.sourceMap.root, + files: options.sourceMap.includeSources ? files : null, + }); + } + delete format_options.ast; + delete format_options.code; + delete format_options.spidermonkey; + var stream = OutputStream(format_options); + toplevel.print(stream); + result.code = stream.get(); + if (options.sourceMap) { + Object.defineProperty(result, "map", { + configurable: true, + enumerable: true, + get() { + const map = format_options.source_map.getEncoded(); + return (result.map = options.sourceMap.asObject ? map : JSON.stringify(map)); + }, + set(value) { + Object.defineProperty(result, "map", { + value, + writable: true, + }); + } + }); + result.decoded_map = format_options.source_map.getDecoded(); + if (options.sourceMap.url == "inline") { + var sourceMap = typeof result.map === "object" ? JSON.stringify(result.map) : result.map; + result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(sourceMap); + } else if (options.sourceMap.url) { + result.code += "\n//# sourceMappingURL=" + options.sourceMap.url; + } + } + } + if (options.nameCache && options.mangle) { + if (options.mangle.cache) options.nameCache.vars = cache_to_json(options.mangle.cache); + if (options.mangle.properties && options.mangle.properties.cache) { + options.nameCache.props = cache_to_json(options.mangle.properties.cache); + } + } + if (format_options && format_options.source_map) { + format_options.source_map.destroy(); + } + if (timings) { + timings.end = Date.now(); + result.timings = { + parse: 1e-3 * (timings.rename - timings.parse), + rename: 1e-3 * (timings.compress - timings.rename), + compress: 1e-3 * (timings.scope - timings.compress), + scope: 1e-3 * (timings.mangle - timings.scope), + mangle: 1e-3 * (timings.properties - timings.mangle), + properties: 1e-3 * (timings.format - timings.properties), + format: 1e-3 * (timings.end - timings.format), + total: 1e-3 * (timings.end - timings.start) + }; + } + return result; +} + +async function minify(files, options, _fs_module) { + const gen = minify_sync_or_async(files, options, _fs_module); + + let yielded; + let val; + do { + val = gen.next(await yielded); + yielded = val.value; + } while (!val.done); + + return val.value; +} + +function minify_sync(files, options, _fs_module) { + const gen = minify_sync_or_async(files, options, _fs_module); + + let yielded; + let val; + do { + if (yielded && typeof yielded.then === "function") { + throw new Error("minify_sync cannot be used with the legacy source-map module"); + } + val = gen.next(yielded); + yielded = val.value; + } while (!val.done); + + return val.value; +} + +async function run_cli({ program, packageJson, fs, path }) { + const skip_keys = new Set([ "cname", "parent_scope", "scope", "uses_eval", "uses_with" ]); + var files = {}; + var options = { + compress: false, + mangle: false + }; + const default_options = await _default_options(); + program.version(packageJson.name + " " + packageJson.version); + program.parseArgv = program.parse; + program.parse = undefined; + + if (process.argv.includes("ast")) program.helpInformation = describe_ast; + else if (process.argv.includes("options")) program.helpInformation = function() { + var text = []; + for (var option in default_options) { + text.push("--" + (option === "sourceMap" ? "source-map" : option) + " options:"); + text.push(format_object(default_options[option])); + text.push(""); + } + return text.join("\n"); + }; + + program.option("-p, --parse ", "Specify parser options.", parse_js()); + program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js()); + program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js()); + program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js()); + program.option("-f, --format [options]", "Format options.", parse_js()); + program.option("-b, --beautify [options]", "Alias for --format.", parse_js()); + program.option("-o, --output ", "Output file (default STDOUT)."); + program.option("--comments [filter]", "Preserve copyright comments in the output."); + program.option("--config-file ", "Read minify() options from JSON file."); + program.option("-d, --define [=value]", "Global definitions.", parse_js("define")); + program.option("--ecma ", "Specify ECMAScript release: 5, 2015, 2016 or 2017..."); + program.option("-e, --enclose [arg[,...][:value[,...]]]", "Embed output in a big function with configurable arguments and values."); + program.option("--ie8", "Support non-standard Internet Explorer 8."); + program.option("--keep-classnames", "Do not mangle/drop class names."); + program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name."); + program.option("--module", "Input is an ES6 module"); + program.option("--name-cache ", "File to hold mangled name mappings."); + program.option("--rename", "Force symbol expansion."); + program.option("--no-rename", "Disable symbol expansion."); + program.option("--safari10", "Support non-standard Safari 10."); + program.option("--source-map [options]", "Enable source map/specify source map options.", parse_js()); + program.option("--timings", "Display operations run time on STDERR."); + program.option("--toplevel", "Compress and/or mangle variables in toplevel scope."); + program.option("--wrap ", "Embed everything as a function with “exports” corresponding to “name” globally."); + program.arguments("[files...]").parseArgv(process.argv); + if (program.configFile) { + options = JSON.parse(read_file(program.configFile)); + } + if (!program.output && program.sourceMap && program.sourceMap.url != "inline") { + fatal("ERROR: cannot write source map to STDOUT"); + } + + [ + "compress", + "enclose", + "ie8", + "mangle", + "module", + "safari10", + "sourceMap", + "toplevel", + "wrap" + ].forEach(function(name) { + if (name in program) { + options[name] = program[name]; + } + }); + + if ("ecma" in program) { + if (program.ecma != (program.ecma | 0)) fatal("ERROR: ecma must be an integer"); + const ecma = program.ecma | 0; + if (ecma > 5 && ecma < 2015) + options.ecma = ecma + 2009; + else + options.ecma = ecma; + } + if (program.format || program.beautify) { + const chosenOption = program.format || program.beautify; + options.format = typeof chosenOption === "object" ? chosenOption : {}; + } + if (program.comments) { + if (typeof options.format != "object") options.format = {}; + options.format.comments = typeof program.comments == "string" ? (program.comments == "false" ? false : program.comments) : "some"; + } + if (program.define) { + if (typeof options.compress != "object") options.compress = {}; + if (typeof options.compress.global_defs != "object") options.compress.global_defs = {}; + for (var expr in program.define) { + options.compress.global_defs[expr] = program.define[expr]; + } + } + if (program.keepClassnames) { + options.keep_classnames = true; + } + if (program.keepFnames) { + options.keep_fnames = true; + } + if (program.mangleProps) { + if (program.mangleProps.domprops) { + delete program.mangleProps.domprops; + } else { + if (typeof program.mangleProps != "object") program.mangleProps = {}; + if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = []; + } + if (typeof options.mangle != "object") options.mangle = {}; + options.mangle.properties = program.mangleProps; + } + if (program.nameCache) { + options.nameCache = JSON.parse(read_file(program.nameCache, "{}")); + } + if (program.output == "ast") { + options.format = { + ast: true, + code: false + }; + } + if (program.parse) { + if (!program.parse.acorn && !program.parse.spidermonkey) { + options.parse = program.parse; + } else if (program.sourceMap && program.sourceMap.content == "inline") { + fatal("ERROR: inline source map only works with built-in parser"); + } + } + if (~program.rawArgs.indexOf("--rename")) { + options.rename = true; + } else if (!program.rename) { + options.rename = false; + } + + let convert_path = name => name; + if (typeof program.sourceMap == "object" && "base" in program.sourceMap) { + convert_path = function() { + var base = program.sourceMap.base; + delete options.sourceMap.base; + return function(name) { + return path.relative(base, name); + }; + }(); + } + + let filesList; + if (options.files && options.files.length) { + filesList = options.files; + + delete options.files; + } else if (program.args.length) { + filesList = program.args; + } + + if (filesList) { + simple_glob(filesList).forEach(function(name) { + files[convert_path(name)] = read_file(name); + }); + } else { + await new Promise((resolve) => { + var chunks = []; + process.stdin.setEncoding("utf8"); + process.stdin.on("data", function(chunk) { + chunks.push(chunk); + }).on("end", function() { + files = [ chunks.join("") ]; + resolve(); + }); + process.stdin.resume(); + }); + } + + await run_cli(); + + function convert_ast(fn) { + return AST_Node.from_mozilla_ast(Object.keys(files).reduce(fn, null)); + } + + async function run_cli() { + var content = program.sourceMap && program.sourceMap.content; + if (content && content !== "inline") { + options.sourceMap.content = read_file(content, content); + } + if (program.timings) options.timings = true; + + try { + if (program.parse) { + if (program.parse.acorn) { + files = convert_ast(function(toplevel, name) { + return require("acorn").parse(files[name], { + ecmaVersion: 2024, + locations: true, + program: toplevel, + sourceFile: name, + sourceType: options.module || program.parse.module ? "module" : "script" + }); + }); + } else if (program.parse.spidermonkey) { + files = convert_ast(function(toplevel, name) { + var obj = JSON.parse(files[name]); + if (!toplevel) return obj; + toplevel.body = toplevel.body.concat(obj.body); + return toplevel; + }); + } + } + } catch (ex) { + fatal(ex); + } + + let result; + try { + result = await minify(files, options, fs); + } catch (ex) { + if (ex.name == "SyntaxError") { + print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col); + var col = ex.col; + var lines = files[ex.filename].split(/\r?\n/); + var line = lines[ex.line - 1]; + if (!line && !col) { + line = lines[ex.line - 2]; + col = line.length; + } + if (line) { + var limit = 70; + if (col > limit) { + line = line.slice(col - limit); + col = limit; + } + print_error(line.slice(0, 80)); + print_error(line.slice(0, col).replace(/\S/g, " ") + "^"); + } + } + if (ex.defs) { + print_error("Supported options:"); + print_error(format_object(ex.defs)); + } + fatal(ex); + return; + } + + if (program.output == "ast") { + if (!options.compress && !options.mangle) { + result.ast.figure_out_scope({}); + } + console.log(JSON.stringify(result.ast, function(key, value) { + if (value) switch (key) { + case "thedef": + return symdef(value); + case "enclosed": + return value.length ? value.map(symdef) : undefined; + case "variables": + case "globals": + return value.size ? collect_from_map(value, symdef) : undefined; + } + if (skip_keys.has(key)) return; + if (value instanceof AST_Token) return; + if (value instanceof Map) return; + if (value instanceof AST_Node) { + var result = { + _class: "AST_" + value.TYPE + }; + if (value.block_scope) { + result.variables = value.block_scope.variables; + result.enclosed = value.block_scope.enclosed; + } + value.CTOR.PROPS.forEach(function(prop) { + if (prop !== "block_scope") { + result[prop] = value[prop]; + } + }); + return result; + } + return value; + }, 2)); + } else if (program.output == "spidermonkey") { + try { + const minified = await minify( + result.code, + { + compress: false, + mangle: false, + format: { + ast: true, + code: false + } + }, + fs + ); + console.log(JSON.stringify(minified.ast.to_mozilla_ast(), null, 2)); + } catch (ex) { + fatal(ex); + return; + } + } else if (program.output) { + fs.mkdirSync(path.dirname(program.output), { recursive: true }); + fs.writeFileSync(program.output, result.code); + if (options.sourceMap && options.sourceMap.url !== "inline" && result.map) { + fs.writeFileSync(program.output + ".map", result.map); + } + } else { + console.log(result.code); + } + if (program.nameCache) { + fs.writeFileSync(program.nameCache, JSON.stringify(options.nameCache)); + } + if (result.timings) for (var phase in result.timings) { + print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s"); + } + } + + function fatal(message) { + if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:"); + print_error(message); + process.exit(1); + } + + // A file glob function that only supports "*" and "?" wildcards in the basename. + // Example: "foo/bar/*baz??.*.js" + // Argument `glob` may be a string or an array of strings. + // Returns an array of strings. Garbage in, garbage out. + function simple_glob(glob) { + if (Array.isArray(glob)) { + return [].concat.apply([], glob.map(simple_glob)); + } + if (glob && glob.match(/[*?]/)) { + var dir = path.dirname(glob); + try { + var entries = fs.readdirSync(dir); + } catch (ex) {} + if (entries) { + var pattern = "^" + path.basename(glob) + .replace(/[.+^$[\]\\(){}]/g, "\\$&") + .replace(/\*/g, "[^/\\\\]*") + .replace(/\?/g, "[^/\\\\]") + "$"; + var mod = process.platform === "win32" ? "i" : ""; + var rx = new RegExp(pattern, mod); + var results = entries.filter(function(name) { + return rx.test(name); + }).map(function(name) { + return path.join(dir, name); + }); + if (results.length) return results; + } + } + return [ glob ]; + } + + function read_file(path, default_value) { + try { + return fs.readFileSync(path, "utf8"); + } catch (ex) { + if ((ex.code == "ENOENT" || ex.code == "ENAMETOOLONG") && default_value != null) return default_value; + fatal(ex); + } + } + + function parse_js(flag) { + return function(value, options) { + options = options || {}; + try { + walk(parse(value, { expression: true }), node => { + if (node instanceof AST_Assign) { + var name = node.left.print_to_string(); + var value = node.right; + if (flag) { + options[name] = value; + } else if (value instanceof AST_Array) { + options[name] = value.elements.map(to_string); + } else if (value instanceof AST_RegExp) { + value = value.value; + options[name] = new RegExp(value.source, value.flags); + } else { + options[name] = to_string(value); + } + return true; + } + if (node instanceof AST_Symbol || node instanceof AST_PropAccess) { + var name = node.print_to_string(); + options[name] = true; + return true; + } + if (!(node instanceof AST_Sequence)) throw node; + + function to_string(value) { + return value instanceof AST_Constant ? value.getValue() : value.print_to_string({ + quote_keys: true + }); + } + }); + } catch(ex) { + if (flag) { + fatal("Error parsing arguments for '" + flag + "': " + value); + } else { + options[value] = null; + } + } + return options; + }; + } + + function symdef(def) { + var ret = (1e6 + def.id) + " " + def.name; + if (def.mangled_name) ret += " " + def.mangled_name; + return ret; + } + + function collect_from_map(map, callback) { + var result = []; + map.forEach(function (def) { + result.push(callback(def)); + }); + return result; + } + + function format_object(obj) { + var lines = []; + var padding = ""; + Object.keys(obj).map(function(name) { + if (padding.length < name.length) padding = Array(name.length + 1).join(" "); + return [ name, JSON.stringify(obj[name]) ]; + }).forEach(function(tokens) { + lines.push(" " + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]); + }); + return lines.join("\n"); + } + + function print_error(msg) { + process.stderr.write(msg); + process.stderr.write("\n"); + } + + function describe_ast() { + var out = OutputStream({ beautify: true }); + function doitem(ctor) { + out.print("AST_" + ctor.TYPE); + const props = ctor.SELF_PROPS.filter(prop => !/^\$/.test(prop)); + + if (props.length > 0) { + out.space(); + out.with_parens(function() { + props.forEach(function(prop, i) { + if (i) out.space(); + out.print(prop); + }); + }); + } + + if (ctor.documentation) { + out.space(); + out.print_string(ctor.documentation); + } + + if (ctor.SUBCLASSES.length > 0) { + out.space(); + out.with_block(function() { + ctor.SUBCLASSES.forEach(function(ctor) { + out.indent(); + doitem(ctor); + out.newline(); + }); + }); + } + } + doitem(AST_Node); + return out + "\n"; + } +} + +async function _default_options() { + const defs = {}; + + Object.keys(infer_options({ 0: 0 })).forEach((component) => { + const options = infer_options({ + [component]: {0: 0} + }); + + if (options) defs[component] = options; + }); + return defs; +} + +async function infer_options(options) { + try { + await minify("", options); + } catch (error) { + return error.defs; + } +} + +exports._default_options = _default_options; +exports._run_cli = run_cli; +exports.minify = minify; +exports.minify_sync = minify_sync; + +})); diff --git a/node_modules/terser/dist/package.json b/node_modules/terser/dist/package.json new file mode 100644 index 0000000..a4cb7d1 --- /dev/null +++ b/node_modules/terser/dist/package.json @@ -0,0 +1,10 @@ +{ + "name": "dist", + "private": true, + "version": "1.0.0", + "main": "bundle.min.js", + "type": "commonjs", + "author": "", + "license": "BSD-2-Clause", + "description": "A package to hold the Terser dist bundle as commonjs while keeping the rest of it ESM. Nothing to see here." +} diff --git a/node_modules/terser/lib/ast.js b/node_modules/terser/lib/ast.js new file mode 100644 index 0000000..096c8d6 --- /dev/null +++ b/node_modules/terser/lib/ast.js @@ -0,0 +1,3475 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +import { + HOP, + MAP, + noop +} from "./utils/index.js"; +import { parse } from "./parse.js"; + +function DEFNODE(type, props, ctor, methods, base = AST_Node) { + if (!props) props = []; + else props = props.split(/\s+/); + var self_props = props; + if (base && base.PROPS) + props = props.concat(base.PROPS); + const proto = base && Object.create(base.prototype); + if (proto) { + ctor.prototype = proto; + ctor.BASE = base; + } + if (base) base.SUBCLASSES.push(ctor); + ctor.prototype.CTOR = ctor; + ctor.prototype.constructor = ctor; + ctor.PROPS = props || null; + ctor.SELF_PROPS = self_props; + ctor.SUBCLASSES = []; + if (type) { + ctor.prototype.TYPE = ctor.TYPE = type; + } + if (methods) for (let i in methods) if (HOP(methods, i)) { + if (i[0] === "$") { + ctor[i.substr(1)] = methods[i]; + } else { + ctor.prototype[i] = methods[i]; + } + } + ctor.DEFMETHOD = function(name, method) { + this.prototype[name] = method; + }; + return ctor; +} + +const has_tok_flag = (tok, flag) => Boolean(tok.flags & flag); +const set_tok_flag = (tok, flag, truth) => { + if (truth) { + tok.flags |= flag; + } else { + tok.flags &= ~flag; + } +}; + +const TOK_FLAG_NLB = 0b0001; +const TOK_FLAG_QUOTE_SINGLE = 0b0010; +const TOK_FLAG_QUOTE_EXISTS = 0b0100; +const TOK_FLAG_TEMPLATE_END = 0b1000; + +class AST_Token { + constructor(type, value, line, col, pos, nlb, comments_before, comments_after, file) { + this.flags = (nlb ? 1 : 0); + + this.type = type; + this.value = value; + this.line = line; + this.col = col; + this.pos = pos; + this.comments_before = comments_before; + this.comments_after = comments_after; + this.file = file; + + Object.seal(this); + } + + // Return a string summary of the token for node.js console.log + [Symbol.for("nodejs.util.inspect.custom")](_depth, options) { + const special = str => options.stylize(str, "special"); + const quote = typeof this.value === "string" && this.value.includes("`") ? "'" : "`"; + const value = `${quote}${this.value}${quote}`; + return `${special("[AST_Token")} ${value} at ${this.line}:${this.col}${special("]")}`; + } + + get nlb() { + return has_tok_flag(this, TOK_FLAG_NLB); + } + + set nlb(new_nlb) { + set_tok_flag(this, TOK_FLAG_NLB, new_nlb); + } + + get quote() { + return !has_tok_flag(this, TOK_FLAG_QUOTE_EXISTS) + ? "" + : (has_tok_flag(this, TOK_FLAG_QUOTE_SINGLE) ? "'" : '"'); + } + + set quote(quote_type) { + set_tok_flag(this, TOK_FLAG_QUOTE_SINGLE, quote_type === "'"); + set_tok_flag(this, TOK_FLAG_QUOTE_EXISTS, !!quote_type); + } + + get template_end() { + return has_tok_flag(this, TOK_FLAG_TEMPLATE_END); + } + + set template_end(new_template_end) { + set_tok_flag(this, TOK_FLAG_TEMPLATE_END, new_template_end); + } +} + +var AST_Node = DEFNODE("Node", "start end", function AST_Node(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + _clone: function(deep) { + if (deep) { + var self = this.clone(); + return self.transform(new TreeTransformer(function(node) { + if (node !== self) { + return node.clone(true); + } + })); + } + return new this.CTOR(this); + }, + clone: function(deep) { + return this._clone(deep); + }, + $documentation: "Base class of all AST nodes", + $propdoc: { + start: "[AST_Token] The first token of this node", + end: "[AST_Token] The last token of this node" + }, + _walk: function(visitor) { + return visitor._visit(this); + }, + walk: function(visitor) { + return this._walk(visitor); // not sure the indirection will be any help + }, + _children_backwards: () => {} +}, null); + +/* -----[ statements ]----- */ + +var AST_Statement = DEFNODE("Statement", null, function AST_Statement(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class of all statements", +}); + +var AST_Debugger = DEFNODE("Debugger", null, function AST_Debugger(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Represents a debugger statement", +}, AST_Statement); + +var AST_Directive = DEFNODE("Directive", "value quote", function AST_Directive(props) { + if (props) { + this.value = props.value; + this.quote = props.quote; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Represents a directive, like \"use strict\";", + $propdoc: { + value: "[string] The value of this directive as a plain string (it's not an AST_String!)", + quote: "[string] the original quote character" + }, +}, AST_Statement); + +var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", function AST_SimpleStatement(props) { + if (props) { + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A statement consisting of an expression, i.e. a = 1 + 2", + $propdoc: { + body: "[AST_Node] an expression node (should not be instanceof AST_Statement)" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.body._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.body); + } +}, AST_Statement); + +function walk_body(node, visitor) { + const body = node.body; + for (var i = 0, len = body.length; i < len; i++) { + body[i]._walk(visitor); + } +} + +function clone_block_scope(deep) { + var clone = this._clone(deep); + if (this.block_scope) { + clone.block_scope = this.block_scope.clone(); + } + return clone; +} + +var AST_Block = DEFNODE("Block", "body block_scope", function AST_Block(props) { + if (props) { + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A body of statements (usually braced)", + $propdoc: { + body: "[AST_Statement*] an array of statements", + block_scope: "[AST_Scope] the block scope" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + walk_body(this, visitor); + }); + }, + _children_backwards(push) { + let i = this.body.length; + while (i--) push(this.body[i]); + }, + clone: clone_block_scope +}, AST_Statement); + +var AST_BlockStatement = DEFNODE("BlockStatement", null, function AST_BlockStatement(props) { + if (props) { + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A block statement", +}, AST_Block); + +var AST_EmptyStatement = DEFNODE("EmptyStatement", null, function AST_EmptyStatement(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The empty statement (empty block or simply a semicolon)" +}, AST_Statement); + +var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", function AST_StatementWithBody(props) { + if (props) { + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`", + $propdoc: { + body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement" + } +}, AST_Statement); + +var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", function AST_LabeledStatement(props) { + if (props) { + this.label = props.label; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Statement with a label", + $propdoc: { + label: "[AST_Label] a label definition" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.label._walk(visitor); + this.body._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.body); + push(this.label); + }, + clone: function(deep) { + var node = this._clone(deep); + if (deep) { + var label = node.label; + var def = this.label; + node.walk(new TreeWalker(function(node) { + if (node instanceof AST_LoopControl + && node.label && node.label.thedef === def) { + node.label.thedef = label; + label.references.push(node); + } + })); + } + return node; + } +}, AST_StatementWithBody); + +var AST_IterationStatement = DEFNODE( + "IterationStatement", + "block_scope", + function AST_IterationStatement(props) { + if (props) { + this.block_scope = props.block_scope; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "Internal class. All loops inherit from it.", + $propdoc: { + block_scope: "[AST_Scope] the block scope for this iteration statement." + }, + clone: clone_block_scope + }, + AST_StatementWithBody +); + +var AST_DWLoop = DEFNODE("DWLoop", "condition", function AST_DWLoop(props) { + if (props) { + this.condition = props.condition; + this.block_scope = props.block_scope; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for do/while statements", + $propdoc: { + condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement" + } +}, AST_IterationStatement); + +var AST_Do = DEFNODE("Do", null, function AST_Do(props) { + if (props) { + this.condition = props.condition; + this.block_scope = props.block_scope; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `do` statement", + _walk: function(visitor) { + return visitor._visit(this, function() { + this.body._walk(visitor); + this.condition._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.condition); + push(this.body); + } +}, AST_DWLoop); + +var AST_While = DEFNODE("While", null, function AST_While(props) { + if (props) { + this.condition = props.condition; + this.block_scope = props.block_scope; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `while` statement", + _walk: function(visitor) { + return visitor._visit(this, function() { + this.condition._walk(visitor); + this.body._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.body); + push(this.condition); + }, +}, AST_DWLoop); + +var AST_For = DEFNODE("For", "init condition step", function AST_For(props) { + if (props) { + this.init = props.init; + this.condition = props.condition; + this.step = props.step; + this.block_scope = props.block_scope; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `for` statement", + $propdoc: { + init: "[AST_Node?] the `for` initialization code, or null if empty", + condition: "[AST_Node?] the `for` termination clause, or null if empty", + step: "[AST_Node?] the `for` update clause, or null if empty" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + if (this.init) this.init._walk(visitor); + if (this.condition) this.condition._walk(visitor); + if (this.step) this.step._walk(visitor); + this.body._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.body); + if (this.step) push(this.step); + if (this.condition) push(this.condition); + if (this.init) push(this.init); + }, +}, AST_IterationStatement); + +var AST_ForIn = DEFNODE("ForIn", "init object", function AST_ForIn(props) { + if (props) { + this.init = props.init; + this.object = props.object; + this.block_scope = props.block_scope; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `for ... in` statement", + $propdoc: { + init: "[AST_Node] the `for/in` initialization code", + object: "[AST_Node] the object that we're looping through" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.init._walk(visitor); + this.object._walk(visitor); + this.body._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.body); + if (this.object) push(this.object); + if (this.init) push(this.init); + }, +}, AST_IterationStatement); + +var AST_ForOf = DEFNODE("ForOf", "await", function AST_ForOf(props) { + if (props) { + this.await = props.await; + this.init = props.init; + this.object = props.object; + this.block_scope = props.block_scope; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `for ... of` statement", +}, AST_ForIn); + +var AST_With = DEFNODE("With", "expression", function AST_With(props) { + if (props) { + this.expression = props.expression; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `with` statement", + $propdoc: { + expression: "[AST_Node] the `with` expression" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + this.body._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.body); + push(this.expression); + }, +}, AST_StatementWithBody); + +/* -----[ scope and functions ]----- */ + +var AST_Scope = DEFNODE( + "Scope", + "variables uses_with uses_eval parent_scope enclosed cname", + function AST_Scope(props) { + if (props) { + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "Base class for all statements introducing a lexical scope", + $propdoc: { + variables: "[Map/S] a map of name -> SymbolDef for all variables/functions defined in this scope", + uses_with: "[boolean/S] tells whether this scope uses the `with` statement", + uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`", + parent_scope: "[AST_Scope?/S] link to the parent scope", + enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes", + cname: "[integer/S] current index for mangling variables (used internally by the mangler)", + }, + get_defun_scope: function() { + var self = this; + while (self.is_block_scope()) { + self = self.parent_scope; + } + return self; + }, + clone: function(deep, toplevel) { + var node = this._clone(deep); + if (deep && this.variables && toplevel && !this._block_scope) { + node.figure_out_scope({}, { + toplevel: toplevel, + parent_scope: this.parent_scope + }); + } else { + if (this.variables) node.variables = new Map(this.variables); + if (this.enclosed) node.enclosed = this.enclosed.slice(); + if (this._block_scope) node._block_scope = this._block_scope; + } + return node; + }, + pinned: function() { + return this.uses_eval || this.uses_with; + } + }, + AST_Block +); + +var AST_Toplevel = DEFNODE("Toplevel", "globals", function AST_Toplevel(props) { + if (props) { + this.globals = props.globals; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The toplevel scope", + $propdoc: { + globals: "[Map/S] a map of name -> SymbolDef for all undeclared names", + }, + wrap_commonjs: function(name) { + var body = this.body; + var wrapped_tl = "(function(exports){'$ORIG';})(typeof " + name + "=='undefined'?(" + name + "={}):" + name + ");"; + wrapped_tl = parse(wrapped_tl); + wrapped_tl = wrapped_tl.transform(new TreeTransformer(function(node) { + if (node instanceof AST_Directive && node.value == "$ORIG") { + return MAP.splice(body); + } + })); + return wrapped_tl; + }, + wrap_enclose: function(args_values) { + if (typeof args_values != "string") args_values = ""; + var index = args_values.indexOf(":"); + if (index < 0) index = args_values.length; + var body = this.body; + return parse([ + "(function(", + args_values.slice(0, index), + '){"$ORIG"})(', + args_values.slice(index + 1), + ")" + ].join("")).transform(new TreeTransformer(function(node) { + if (node instanceof AST_Directive && node.value == "$ORIG") { + return MAP.splice(body); + } + })); + } +}, AST_Scope); + +var AST_Expansion = DEFNODE("Expansion", "expression", function AST_Expansion(props) { + if (props) { + this.expression = props.expression; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "An expandible argument, such as ...rest, a splat, such as [1,2,...all], or an expansion in a variable declaration, such as var [first, ...rest] = list", + $propdoc: { + expression: "[AST_Node] the thing to be expanded" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression.walk(visitor); + }); + }, + _children_backwards(push) { + push(this.expression); + }, +}); + +var AST_Lambda = DEFNODE( + "Lambda", + "name argnames uses_arguments is_generator async", + function AST_Lambda(props) { + if (props) { + this.name = props.name; + this.argnames = props.argnames; + this.uses_arguments = props.uses_arguments; + this.is_generator = props.is_generator; + this.async = props.async; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "Base class for functions", + $propdoc: { + name: "[AST_SymbolDeclaration?] the name of this function", + argnames: "[AST_SymbolFunarg|AST_Destructuring|AST_Expansion|AST_DefaultAssign*] array of function arguments, destructurings, or expanding arguments", + uses_arguments: "[boolean/S] tells whether this function accesses the arguments array", + is_generator: "[boolean] is this a generator method", + async: "[boolean] is this method async", + }, + args_as_names: function () { + var out = []; + for (var i = 0; i < this.argnames.length; i++) { + if (this.argnames[i] instanceof AST_Destructuring) { + out.push(...this.argnames[i].all_symbols()); + } else { + out.push(this.argnames[i]); + } + } + return out; + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + if (this.name) this.name._walk(visitor); + var argnames = this.argnames; + for (var i = 0, len = argnames.length; i < len; i++) { + argnames[i]._walk(visitor); + } + walk_body(this, visitor); + }); + }, + _children_backwards(push) { + let i = this.body.length; + while (i--) push(this.body[i]); + + i = this.argnames.length; + while (i--) push(this.argnames[i]); + + if (this.name) push(this.name); + }, + is_braceless() { + return this.body[0] instanceof AST_Return && this.body[0].value; + }, + // Default args and expansion don't count, so .argnames.length doesn't cut it + length_property() { + let length = 0; + + for (const arg of this.argnames) { + if (arg instanceof AST_SymbolFunarg || arg instanceof AST_Destructuring) { + length++; + } + } + + return length; + } + }, + AST_Scope +); + +var AST_Accessor = DEFNODE("Accessor", null, function AST_Accessor(props) { + if (props) { + this.name = props.name; + this.argnames = props.argnames; + this.uses_arguments = props.uses_arguments; + this.is_generator = props.is_generator; + this.async = props.async; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A setter/getter function. The `name` property is always null." +}, AST_Lambda); + +var AST_Function = DEFNODE("Function", null, function AST_Function(props) { + if (props) { + this.name = props.name; + this.argnames = props.argnames; + this.uses_arguments = props.uses_arguments; + this.is_generator = props.is_generator; + this.async = props.async; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A function expression" +}, AST_Lambda); + +var AST_Arrow = DEFNODE("Arrow", null, function AST_Arrow(props) { + if (props) { + this.name = props.name; + this.argnames = props.argnames; + this.uses_arguments = props.uses_arguments; + this.is_generator = props.is_generator; + this.async = props.async; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "An ES6 Arrow function ((a) => b)" +}, AST_Lambda); + +var AST_Defun = DEFNODE("Defun", null, function AST_Defun(props) { + if (props) { + this.name = props.name; + this.argnames = props.argnames; + this.uses_arguments = props.uses_arguments; + this.is_generator = props.is_generator; + this.async = props.async; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A function definition" +}, AST_Lambda); + +/* -----[ DESTRUCTURING ]----- */ +var AST_Destructuring = DEFNODE("Destructuring", "names is_array", function AST_Destructuring(props) { + if (props) { + this.names = props.names; + this.is_array = props.is_array; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A destructuring of several names. Used in destructuring assignment and with destructuring function argument names", + $propdoc: { + "names": "[AST_Node*] Array of properties or elements", + "is_array": "[Boolean] Whether the destructuring represents an object or array" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.names.forEach(function(name) { + name._walk(visitor); + }); + }); + }, + _children_backwards(push) { + let i = this.names.length; + while (i--) push(this.names[i]); + }, + all_symbols: function() { + var out = []; + walk(this, node => { + if (node instanceof AST_SymbolDeclaration) { + out.push(node); + } + if (node instanceof AST_Lambda) { + return true; + } + }); + return out; + } +}); + +var AST_PrefixedTemplateString = DEFNODE( + "PrefixedTemplateString", + "template_string prefix", + function AST_PrefixedTemplateString(props) { + if (props) { + this.template_string = props.template_string; + this.prefix = props.prefix; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "A templatestring with a prefix, such as String.raw`foobarbaz`", + $propdoc: { + template_string: "[AST_TemplateString] The template string", + prefix: "[AST_Node] The prefix, which will get called." + }, + _walk: function(visitor) { + return visitor._visit(this, function () { + this.prefix._walk(visitor); + this.template_string._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.template_string); + push(this.prefix); + }, + } +); + +var AST_TemplateString = DEFNODE("TemplateString", "segments", function AST_TemplateString(props) { + if (props) { + this.segments = props.segments; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A template string literal", + $propdoc: { + segments: "[AST_Node*] One or more segments, starting with AST_TemplateSegment. AST_Node may follow AST_TemplateSegment, but each AST_Node must be followed by AST_TemplateSegment." + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.segments.forEach(function(seg) { + seg._walk(visitor); + }); + }); + }, + _children_backwards(push) { + let i = this.segments.length; + while (i--) push(this.segments[i]); + } +}); + +var AST_TemplateSegment = DEFNODE("TemplateSegment", "value raw", function AST_TemplateSegment(props) { + if (props) { + this.value = props.value; + this.raw = props.raw; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A segment of a template string literal", + $propdoc: { + value: "Content of the segment", + raw: "Raw source of the segment", + } +}); + +/* -----[ JUMPS ]----- */ + +var AST_Jump = DEFNODE("Jump", null, function AST_Jump(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)" +}, AST_Statement); + +/** Base class for “exits” (`return` and `throw`) */ +var AST_Exit = DEFNODE("Exit", "value", function AST_Exit(props) { + if (props) { + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for “exits” (`return` and `throw`)", + $propdoc: { + value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return" + }, + _walk: function(visitor) { + return visitor._visit(this, this.value && function() { + this.value._walk(visitor); + }); + }, + _children_backwards(push) { + if (this.value) push(this.value); + }, +}, AST_Jump); + +var AST_Return = DEFNODE("Return", null, function AST_Return(props) { + if (props) { + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `return` statement" +}, AST_Exit); + +var AST_Throw = DEFNODE("Throw", null, function AST_Throw(props) { + if (props) { + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `throw` statement" +}, AST_Exit); + +var AST_LoopControl = DEFNODE("LoopControl", "label", function AST_LoopControl(props) { + if (props) { + this.label = props.label; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for loop control statements (`break` and `continue`)", + $propdoc: { + label: "[AST_LabelRef?] the label, or null if none", + }, + _walk: function(visitor) { + return visitor._visit(this, this.label && function() { + this.label._walk(visitor); + }); + }, + _children_backwards(push) { + if (this.label) push(this.label); + }, +}, AST_Jump); + +var AST_Break = DEFNODE("Break", null, function AST_Break(props) { + if (props) { + this.label = props.label; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `break` statement" +}, AST_LoopControl); + +var AST_Continue = DEFNODE("Continue", null, function AST_Continue(props) { + if (props) { + this.label = props.label; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `continue` statement" +}, AST_LoopControl); + +var AST_Await = DEFNODE("Await", "expression", function AST_Await(props) { + if (props) { + this.expression = props.expression; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "An `await` statement", + $propdoc: { + expression: "[AST_Node] the mandatory expression being awaited", + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.expression); + }, +}); + +var AST_Yield = DEFNODE("Yield", "expression is_star", function AST_Yield(props) { + if (props) { + this.expression = props.expression; + this.is_star = props.is_star; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `yield` statement", + $propdoc: { + expression: "[AST_Node?] the value returned or thrown by this statement; could be null (representing undefined) but only when is_star is set to false", + is_star: "[Boolean] Whether this is a yield or yield* statement" + }, + _walk: function(visitor) { + return visitor._visit(this, this.expression && function() { + this.expression._walk(visitor); + }); + }, + _children_backwards(push) { + if (this.expression) push(this.expression); + } +}); + +/* -----[ IF ]----- */ + +var AST_If = DEFNODE("If", "condition alternative", function AST_If(props) { + if (props) { + this.condition = props.condition; + this.alternative = props.alternative; + this.body = props.body; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `if` statement", + $propdoc: { + condition: "[AST_Node] the `if` condition", + alternative: "[AST_Statement?] the `else` part, or null if not present" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.condition._walk(visitor); + this.body._walk(visitor); + if (this.alternative) this.alternative._walk(visitor); + }); + }, + _children_backwards(push) { + if (this.alternative) { + push(this.alternative); + } + push(this.body); + push(this.condition); + } +}, AST_StatementWithBody); + +/* -----[ SWITCH ]----- */ + +var AST_Switch = DEFNODE("Switch", "expression", function AST_Switch(props) { + if (props) { + this.expression = props.expression; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `switch` statement", + $propdoc: { + expression: "[AST_Node] the `switch` “discriminant”" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + walk_body(this, visitor); + }); + }, + _children_backwards(push) { + let i = this.body.length; + while (i--) push(this.body[i]); + push(this.expression); + } +}, AST_Block); + +var AST_SwitchBranch = DEFNODE("SwitchBranch", null, function AST_SwitchBranch(props) { + if (props) { + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for `switch` branches", +}, AST_Block); + +var AST_Default = DEFNODE("Default", null, function AST_Default(props) { + if (props) { + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `default` switch branch", +}, AST_SwitchBranch); + +var AST_Case = DEFNODE("Case", "expression", function AST_Case(props) { + if (props) { + this.expression = props.expression; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `case` switch branch", + $propdoc: { + expression: "[AST_Node] the `case` expression" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + walk_body(this, visitor); + }); + }, + _children_backwards(push) { + let i = this.body.length; + while (i--) push(this.body[i]); + push(this.expression); + }, +}, AST_SwitchBranch); + +/* -----[ EXCEPTIONS ]----- */ + +var AST_Try = DEFNODE("Try", "body bcatch bfinally", function AST_Try(props) { + if (props) { + this.body = props.body; + this.bcatch = props.bcatch; + this.bfinally = props.bfinally; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `try` statement", + $propdoc: { + body: "[AST_TryBlock] the try block", + bcatch: "[AST_Catch?] the catch block, or null if not present", + bfinally: "[AST_Finally?] the finally block, or null if not present" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.body._walk(visitor); + if (this.bcatch) this.bcatch._walk(visitor); + if (this.bfinally) this.bfinally._walk(visitor); + }); + }, + _children_backwards(push) { + if (this.bfinally) push(this.bfinally); + if (this.bcatch) push(this.bcatch); + push(this.body); + }, +}, AST_Statement); + +var AST_TryBlock = DEFNODE("TryBlock", null, function AST_TryBlock(props) { + if (props) { + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The `try` block of a try statement" +}, AST_Block); + +var AST_Catch = DEFNODE("Catch", "argname", function AST_Catch(props) { + if (props) { + this.argname = props.argname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `catch` node; only makes sense as part of a `try` statement", + $propdoc: { + argname: "[AST_SymbolCatch|AST_Destructuring|AST_Expansion|AST_DefaultAssign] symbol for the exception" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + if (this.argname) this.argname._walk(visitor); + walk_body(this, visitor); + }); + }, + _children_backwards(push) { + let i = this.body.length; + while (i--) push(this.body[i]); + if (this.argname) push(this.argname); + }, +}, AST_Block); + +var AST_Finally = DEFNODE("Finally", null, function AST_Finally(props) { + if (props) { + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `finally` node; only makes sense as part of a `try` statement" +}, AST_Block); + +/* -----[ VAR/CONST ]----- */ + +var AST_DefinitionsLike = DEFNODE("DefinitionsLike", "definitions", function AST_DefinitionsLike(props) { + if (props) { + this.definitions = props.definitions; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for variable definitions and `using`", + $propdoc: { + definitions: "[AST_VarDef*|AST_UsingDef*] array of variable definitions" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + var definitions = this.definitions; + for (var i = 0, len = definitions.length; i < len; i++) { + definitions[i]._walk(visitor); + } + }); + }, + _children_backwards(push) { + let i = this.definitions.length; + while (i--) push(this.definitions[i]); + }, +}, AST_Statement); + +var AST_Definitions = DEFNODE("Definitions", null, function AST_Definitions(props) { + if (props) { + this.definitions = props.definitions; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)", +}, AST_DefinitionsLike); + +var AST_Var = DEFNODE("Var", null, function AST_Var(props) { + if (props) { + this.definitions = props.definitions; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `var` statement" +}, AST_Definitions); + +var AST_Let = DEFNODE("Let", null, function AST_Let(props) { + if (props) { + this.definitions = props.definitions; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `let` statement" +}, AST_Definitions); + +var AST_Const = DEFNODE("Const", null, function AST_Const(props) { + if (props) { + this.definitions = props.definitions; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `const` statement" +}, AST_Definitions); + +var AST_Using = DEFNODE("Using", "await", function AST_Using(props) { + if (props) { + this.await = props.await; + this.definitions = props.definitions; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `using` statement", + $propdoc: { + await: "[boolean] Whether it's `await using`" + }, +}, AST_DefinitionsLike); + +var AST_VarDefLike = DEFNODE("VarDefLike", "name value", function AST_VarDefLike(props) { + if (props) { + this.name = props.name; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A name=value pair in a variable definition statement or `using`", + $propdoc: { + name: "[AST_Destructuring|AST_SymbolDeclaration] name of the variable", + value: "[AST_Node?] initializer, or null of there's no initializer" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.name._walk(visitor); + if (this.value) this.value._walk(visitor); + }); + }, + _children_backwards(push) { + if (this.value) push(this.value); + push(this.name); + }, + declarations_as_names() { + if (this.name instanceof AST_SymbolDeclaration) { + return [this.name]; + } else { + return this.name.all_symbols(); + } + } +}); + +var AST_VarDef = DEFNODE("VarDef", null, function AST_VarDef(props) { + if (props) { + this.name = props.name; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A variable declaration; only appears in a AST_Definitions node", +}, AST_VarDefLike); + +var AST_UsingDef = DEFNODE("UsingDef", null, function AST_UsingDef(props) { + if (props) { + this.name = props.name; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Like VarDef but specific to AST_Using", +}, AST_VarDefLike); + +var AST_NameMapping = DEFNODE("NameMapping", "foreign_name name", function AST_NameMapping(props) { + if (props) { + this.foreign_name = props.foreign_name; + this.name = props.name; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The part of the export/import statement that declare names from a module.", + $propdoc: { + foreign_name: "[AST_SymbolExportForeign|AST_SymbolImportForeign] The name being exported/imported (as specified in the module)", + name: "[AST_SymbolExport|AST_SymbolImport] The name as it is visible to this module." + }, + _walk: function (visitor) { + return visitor._visit(this, function() { + this.foreign_name._walk(visitor); + this.name._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.name); + push(this.foreign_name); + }, +}); + +var AST_Import = DEFNODE( + "Import", + "imported_name imported_names module_name attributes", + function AST_Import(props) { + if (props) { + this.imported_name = props.imported_name; + this.imported_names = props.imported_names; + this.module_name = props.module_name; + this.attributes = props.attributes; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "An `import` statement", + $propdoc: { + imported_name: "[AST_SymbolImport] The name of the variable holding the module's default export.", + imported_names: "[AST_NameMapping*] The names of non-default imported variables", + module_name: "[AST_String] String literal describing where this module came from", + attributes: "[AST_Object?] The import attributes (with {...})" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + if (this.imported_name) { + this.imported_name._walk(visitor); + } + if (this.imported_names) { + this.imported_names.forEach(function(name_import) { + name_import._walk(visitor); + }); + } + this.module_name._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.module_name); + if (this.imported_names) { + let i = this.imported_names.length; + while (i--) push(this.imported_names[i]); + } + if (this.imported_name) push(this.imported_name); + }, + } +); + +var AST_ImportMeta = DEFNODE("ImportMeta", null, function AST_ImportMeta(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A reference to import.meta", +}); + +var AST_Export = DEFNODE( + "Export", + "exported_definition exported_value is_default exported_names module_name attributes", + function AST_Export(props) { + if (props) { + this.exported_definition = props.exported_definition; + this.exported_value = props.exported_value; + this.is_default = props.is_default; + this.exported_names = props.exported_names; + this.module_name = props.module_name; + this.attributes = props.attributes; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "An `export` statement", + $propdoc: { + exported_definition: "[AST_Defun|AST_Definitions|AST_DefClass?] An exported definition", + exported_value: "[AST_Node?] An exported value", + exported_names: "[AST_NameMapping*?] List of exported names", + module_name: "[AST_String?] Name of the file to load exports from", + is_default: "[Boolean] Whether this is the default exported value of this module", + attributes: "[AST_Object?] The import attributes" + }, + _walk: function (visitor) { + return visitor._visit(this, function () { + if (this.exported_definition) { + this.exported_definition._walk(visitor); + } + if (this.exported_value) { + this.exported_value._walk(visitor); + } + if (this.exported_names) { + this.exported_names.forEach(function(name_export) { + name_export._walk(visitor); + }); + } + if (this.module_name) { + this.module_name._walk(visitor); + } + }); + }, + _children_backwards(push) { + if (this.module_name) push(this.module_name); + if (this.exported_names) { + let i = this.exported_names.length; + while (i--) push(this.exported_names[i]); + } + if (this.exported_value) push(this.exported_value); + if (this.exported_definition) push(this.exported_definition); + } + }, + AST_Statement +); + +/* -----[ OTHER ]----- */ + +var AST_Call = DEFNODE( + "Call", + "expression args optional _annotations", + function AST_Call(props) { + if (props) { + this.expression = props.expression; + this.args = props.args; + this.optional = props.optional; + this._annotations = props._annotations; + this.start = props.start; + this.end = props.end; + this.initialize(); + } + + this.flags = 0; + }, + { + $documentation: "A function call expression", + $propdoc: { + expression: "[AST_Node] expression to invoke as function", + args: "[AST_Node*] array of arguments", + optional: "[boolean] whether this is an optional call (IE ?.() )", + _annotations: "[number] bitfield containing information about the call" + }, + initialize() { + if (this._annotations == null) this._annotations = 0; + }, + _walk(visitor) { + return visitor._visit(this, function() { + var args = this.args; + for (var i = 0, len = args.length; i < len; i++) { + args[i]._walk(visitor); + } + this.expression._walk(visitor); // TODO why do we need to crawl this last? + }); + }, + _children_backwards(push) { + let i = this.args.length; + while (i--) push(this.args[i]); + push(this.expression); + }, + } +); + +var AST_New = DEFNODE("New", null, function AST_New(props) { + if (props) { + this.expression = props.expression; + this.args = props.args; + this.optional = props.optional; + this._annotations = props._annotations; + this.start = props.start; + this.end = props.end; + this.initialize(); + } + + this.flags = 0; +}, { + $documentation: "An object instantiation. Derives from a function call since it has exactly the same properties" +}, AST_Call); + +var AST_Sequence = DEFNODE("Sequence", "expressions", function AST_Sequence(props) { + if (props) { + this.expressions = props.expressions; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A sequence expression (comma-separated expressions)", + $propdoc: { + expressions: "[AST_Node*] array of expressions (at least two)" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expressions.forEach(function(node) { + node._walk(visitor); + }); + }); + }, + _children_backwards(push) { + let i = this.expressions.length; + while (i--) push(this.expressions[i]); + }, +}); + +var AST_PropAccess = DEFNODE( + "PropAccess", + "expression property optional", + function AST_PropAccess(props) { + if (props) { + this.expression = props.expression; + this.property = props.property; + this.optional = props.optional; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`", + $propdoc: { + expression: "[AST_Node] the “container” expression", + property: "[AST_Node|string] the property to access. For AST_Dot & AST_DotHash this is always a plain string, while for AST_Sub it's an arbitrary AST_Node", + + optional: "[boolean] whether this is an optional property access (IE ?.)" + } + } +); + +var AST_Dot = DEFNODE("Dot", "quote", function AST_Dot(props) { + if (props) { + this.quote = props.quote; + this.expression = props.expression; + this.property = props.property; + this.optional = props.optional; + this._annotations = props._annotations; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A dotted property access expression", + $propdoc: { + quote: "[string] the original quote character when transformed from AST_Sub", + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.expression); + }, +}, AST_PropAccess); + +var AST_DotHash = DEFNODE("DotHash", "", function AST_DotHash(props) { + if (props) { + this.expression = props.expression; + this.property = props.property; + this.optional = props.optional; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A dotted property access to a private property", + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.expression); + }, +}, AST_PropAccess); + +var AST_Sub = DEFNODE("Sub", null, function AST_Sub(props) { + if (props) { + this.expression = props.expression; + this.property = props.property; + this.optional = props.optional; + this._annotations = props._annotations; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Index-style property access, i.e. `a[\"foo\"]`", + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + this.property._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.property); + push(this.expression); + }, +}, AST_PropAccess); + +var AST_Chain = DEFNODE("Chain", "expression", function AST_Chain(props) { + if (props) { + this.expression = props.expression; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A chain expression like a?.b?.(c)?.[d]", + $propdoc: { + expression: "[AST_Call|AST_Dot|AST_DotHash|AST_Sub] chain element." + }, + _walk: function (visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.expression); + }, +}); + +var AST_Unary = DEFNODE("Unary", "operator expression", function AST_Unary(props) { + if (props) { + this.operator = props.operator; + this.expression = props.expression; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for unary expressions", + $propdoc: { + operator: "[string] the operator", + expression: "[AST_Node] expression that this unary operator applies to" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.expression._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.expression); + }, +}); + +var AST_UnaryPrefix = DEFNODE("UnaryPrefix", null, function AST_UnaryPrefix(props) { + if (props) { + this.operator = props.operator; + this.expression = props.expression; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Unary prefix expression, i.e. `typeof i` or `++i`" +}, AST_Unary); + +var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, function AST_UnaryPostfix(props) { + if (props) { + this.operator = props.operator; + this.expression = props.expression; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Unary postfix expression, i.e. `i++`" +}, AST_Unary); + +var AST_Binary = DEFNODE("Binary", "operator left right", function AST_Binary(props) { + if (props) { + this.operator = props.operator; + this.left = props.left; + this.right = props.right; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Binary expression, i.e. `a + b`", + $propdoc: { + left: "[AST_Node] left-hand side expression", + operator: "[string] the operator", + right: "[AST_Node] right-hand side expression" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.left._walk(visitor); + this.right._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.right); + push(this.left); + }, +}); + +var AST_Conditional = DEFNODE( + "Conditional", + "condition consequent alternative", + function AST_Conditional(props) { + if (props) { + this.condition = props.condition; + this.consequent = props.consequent; + this.alternative = props.alternative; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "Conditional expression using the ternary operator, i.e. `a ? b : c`", + $propdoc: { + condition: "[AST_Node]", + consequent: "[AST_Node]", + alternative: "[AST_Node]" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + this.condition._walk(visitor); + this.consequent._walk(visitor); + this.alternative._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.alternative); + push(this.consequent); + push(this.condition); + }, + } +); + +var AST_Assign = DEFNODE("Assign", "logical", function AST_Assign(props) { + if (props) { + this.logical = props.logical; + this.operator = props.operator; + this.left = props.left; + this.right = props.right; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "An assignment expression — `a = b + 5`", + $propdoc: { + logical: "Whether it's a logical assignment" + } +}, AST_Binary); + +var AST_DefaultAssign = DEFNODE("DefaultAssign", null, function AST_DefaultAssign(props) { + if (props) { + this.operator = props.operator; + this.left = props.left; + this.right = props.right; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A default assignment expression like in `(a = 3) => a`" +}, AST_Binary); + +/* -----[ LITERALS ]----- */ + +var AST_Array = DEFNODE("Array", "elements", function AST_Array(props) { + if (props) { + this.elements = props.elements; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "An array literal", + $propdoc: { + elements: "[AST_Node*] array of elements" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + var elements = this.elements; + for (var i = 0, len = elements.length; i < len; i++) { + elements[i]._walk(visitor); + } + }); + }, + _children_backwards(push) { + let i = this.elements.length; + while (i--) push(this.elements[i]); + }, +}); + +var AST_Object = DEFNODE("Object", "properties", function AST_Object(props) { + if (props) { + this.properties = props.properties; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "An object literal", + $propdoc: { + properties: "[AST_ObjectProperty*] array of properties" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + var properties = this.properties; + for (var i = 0, len = properties.length; i < len; i++) { + properties[i]._walk(visitor); + } + }); + }, + _children_backwards(push) { + let i = this.properties.length; + while (i--) push(this.properties[i]); + }, +}); + +/* -----[ OBJECT/CLASS PROPERTIES ]----- */ + +/** + * Everything inside the curly braces of an object/class is a subclass of AST_ObjectProperty, except for AST_ClassStaticBlock. + **/ +var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", function AST_ObjectProperty(props) { + if (props) { + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + this._annotations = props._annotations; + } + + this.flags = 0; +}, { + $documentation: "Base class for literal object properties", + $propdoc: { + key: "[string|AST_Node] property name. For ObjectKeyVal this is a string. For getters, setters and computed property this is an AST_Node.", + value: "[AST_Node] property value. For getters, setters and methods this is an AST_Accessor." + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + if (this.key instanceof AST_Node) + this.key._walk(visitor); + this.value._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.value); + if (this.key instanceof AST_Node) push(this.key); + }, +}); + +var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", "quote", function AST_ObjectKeyVal(props) { + if (props) { + this.quote = props.quote; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + this._annotations = props._annotations; + } + + this.flags = 0; +}, { + $documentation: "A key: value object property", + $propdoc: { + quote: "[string] the original quote character" + }, + computed_key() { + return this.key instanceof AST_Node; + } +}, AST_ObjectProperty); + +var AST_PrivateSetter = DEFNODE("PrivateSetter", "static", function AST_PrivateSetter(props) { + if (props) { + this.static = props.static; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $propdoc: { + static: "[boolean] whether this is a static private setter" + }, + $documentation: "A private setter property", + computed_key() { + return false; + } +}, AST_ObjectProperty); + +var AST_PrivateGetter = DEFNODE("PrivateGetter", "static", function AST_PrivateGetter(props) { + if (props) { + this.static = props.static; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $propdoc: { + static: "[boolean] whether this is a static private getter" + }, + $documentation: "A private getter property", + computed_key() { + return false; + } +}, AST_ObjectProperty); + +var AST_ObjectSetter = DEFNODE("ObjectSetter", "quote static", function AST_ObjectSetter(props) { + if (props) { + this.quote = props.quote; + this.static = props.static; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + this._annotations = props._annotations; + } + + this.flags = 0; +}, { + $propdoc: { + quote: "[string|undefined] the original quote character, if any", + static: "[boolean] whether this is a static setter (classes only)" + }, + $documentation: "An object setter property", + computed_key() { + return !(this.key instanceof AST_SymbolMethod); + } +}, AST_ObjectProperty); + +var AST_ObjectGetter = DEFNODE("ObjectGetter", "quote static", function AST_ObjectGetter(props) { + if (props) { + this.quote = props.quote; + this.static = props.static; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + this._annotations = props._annotations; + } + + this.flags = 0; +}, { + $propdoc: { + quote: "[string|undefined] the original quote character, if any", + static: "[boolean] whether this is a static getter (classes only)" + }, + $documentation: "An object getter property", + computed_key() { + return !(this.key instanceof AST_SymbolMethod); + } +}, AST_ObjectProperty); + +var AST_ConciseMethod = DEFNODE("ConciseMethod", "quote static", function AST_ConciseMethod(props) { + if (props) { + this.quote = props.quote; + this.static = props.static; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + this._annotations = props._annotations; + } + + this.flags = 0; +}, { + $propdoc: { + quote: "[string|undefined] the original quote character, if any", + static: "[boolean] is this method static (classes only)", + }, + $documentation: "An ES6 concise method inside an object or class", + computed_key() { + return !(this.key instanceof AST_SymbolMethod); + } +}, AST_ObjectProperty); + +var AST_PrivateMethod = DEFNODE("PrivateMethod", "static", function AST_PrivateMethod(props) { + if (props) { + this.static = props.static; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A private class method inside a class", + $propdoc: { + static: "[boolean] is this a static private method", + }, + computed_key() { + return false; + }, +}, AST_ObjectProperty); + +var AST_Class = DEFNODE("Class", "name extends properties", function AST_Class(props) { + if (props) { + this.name = props.name; + this.extends = props.extends; + this.properties = props.properties; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $propdoc: { + name: "[AST_SymbolClass|AST_SymbolDefClass?] optional class name.", + extends: "[AST_Node]? optional parent class", + properties: "[AST_ObjectProperty|AST_ClassStaticBlock]* array of properties or static blocks" + }, + $documentation: "An ES6 class", + _walk: function(visitor) { + return visitor._visit(this, function() { + if (this.name) { + this.name._walk(visitor); + } + if (this.extends) { + this.extends._walk(visitor); + } + this.properties.forEach((prop) => prop._walk(visitor)); + }); + }, + _children_backwards(push) { + let i = this.properties.length; + while (i--) push(this.properties[i]); + if (this.extends) push(this.extends); + if (this.name) push(this.name); + }, + /** go through the bits that are executed instantly, not when the class is `new`'d. Doesn't walk the name. */ + visit_nondeferred_class_parts(visitor) { + if (this.extends) { + this.extends._walk(visitor); + } + this.properties.forEach((prop) => { + if (prop instanceof AST_ClassStaticBlock) { + prop._walk(visitor); + return; + } + if (prop.computed_key()) { + visitor.push(prop); + prop.key._walk(visitor); + visitor.pop(); + } + if ( + prop instanceof AST_ClassPrivateProperty && prop.static && prop.value + || prop instanceof AST_ClassProperty && prop.static && prop.value + ) { + visitor.push(prop); + prop.value._walk(visitor); + visitor.pop(); + } + }); + }, + /** go through the bits that are executed later, when the class is `new`'d or a static method is called */ + visit_deferred_class_parts(visitor) { + this.properties.forEach((prop) => { + if ( + prop instanceof AST_ConciseMethod + || prop instanceof AST_PrivateMethod + ) { + prop.walk(visitor); + } else if ( + prop instanceof AST_ClassProperty && !prop.static && prop.value + || prop instanceof AST_ClassPrivateProperty && !prop.static && prop.value + ) { + visitor.push(prop); + prop.value._walk(visitor); + visitor.pop(); + } + }); + }, + is_self_referential: function() { + const this_id = this.name && this.name.definition().id; + let found = false; + let class_this = true; + this.visit_nondeferred_class_parts(new TreeWalker((node, descend) => { + if (found) return true; + if (node instanceof AST_This) return (found = class_this); + if (node instanceof AST_SymbolRef) return (found = node.definition().id === this_id); + if (node instanceof AST_Lambda && !(node instanceof AST_Arrow)) { + const class_this_save = class_this; + class_this = false; + descend(); + class_this = class_this_save; + return true; + } + })); + return found; + }, +}, AST_Scope /* TODO a class might have a scope but it's not a scope */); + +var AST_ClassProperty = DEFNODE("ClassProperty", "static quote", function AST_ClassProperty(props) { + if (props) { + this.static = props.static; + this.quote = props.quote; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + this._annotations = props._annotations; + } + + this.flags = 0; +}, { + $documentation: "A class property", + $propdoc: { + static: "[boolean] whether this is a static key", + quote: "[string] which quote is being used" + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + if (this.key instanceof AST_Node) + this.key._walk(visitor); + if (this.value instanceof AST_Node) + this.value._walk(visitor); + }); + }, + _children_backwards(push) { + if (this.value instanceof AST_Node) push(this.value); + if (this.key instanceof AST_Node) push(this.key); + }, + computed_key() { + return !(this.key instanceof AST_SymbolClassProperty); + } +}, AST_ObjectProperty); + +var AST_ClassPrivateProperty = DEFNODE("ClassPrivateProperty", "", function AST_ClassPrivateProperty(props) { + if (props) { + this.static = props.static; + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A class property for a private property", + _walk: function(visitor) { + return visitor._visit(this, function() { + if (this.value instanceof AST_Node) + this.value._walk(visitor); + }); + }, + _children_backwards(push) { + if (this.value instanceof AST_Node) push(this.value); + }, + computed_key() { + return false; + }, +}, AST_ObjectProperty); + +var AST_PrivateIn = DEFNODE("PrivateIn", "key value", function AST_PrivateIn(props) { + if (props) { + this.key = props.key; + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "An `in` binop when the key is private, eg #x in this", + _walk: function(visitor) { + return visitor._visit(this, function() { + this.key._walk(visitor); + this.value._walk(visitor); + }); + }, + _children_backwards(push) { + push(this.value); + push(this.key); + }, +}); + +var AST_DefClass = DEFNODE("DefClass", null, function AST_DefClass(props) { + if (props) { + this.name = props.name; + this.extends = props.extends; + this.properties = props.properties; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A class definition", +}, AST_Class); + +var AST_ClassStaticBlock = DEFNODE("ClassStaticBlock", "body block_scope", function AST_ClassStaticBlock (props) { + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; +}, { + $documentation: "A block containing statements to be executed in the context of the class", + $propdoc: { + body: "[AST_Statement*] an array of statements", + }, + _walk: function(visitor) { + return visitor._visit(this, function() { + walk_body(this, visitor); + }); + }, + _children_backwards(push) { + let i = this.body.length; + while (i--) push(this.body[i]); + }, + clone: clone_block_scope, + computed_key() { + return false; + }, +}, AST_Scope); + +var AST_ClassExpression = DEFNODE("ClassExpression", null, function AST_ClassExpression(props) { + if (props) { + this.name = props.name; + this.extends = props.extends; + this.properties = props.properties; + this.variables = props.variables; + this.uses_with = props.uses_with; + this.uses_eval = props.uses_eval; + this.parent_scope = props.parent_scope; + this.enclosed = props.enclosed; + this.cname = props.cname; + this.body = props.body; + this.block_scope = props.block_scope; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A class expression." +}, AST_Class); + +var AST_Symbol = DEFNODE("Symbol", "scope name thedef", function AST_Symbol(props) { + if (props) { + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $propdoc: { + name: "[string] name of this symbol", + scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)", + thedef: "[SymbolDef/S] the definition of this symbol" + }, + $documentation: "Base class for all symbols" +}); + +var AST_NewTarget = DEFNODE("NewTarget", null, function AST_NewTarget(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A reference to new.target" +}); + +var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", function AST_SymbolDeclaration(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)", +}, AST_Symbol); + +var AST_SymbolVar = DEFNODE("SymbolVar", null, function AST_SymbolVar(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol defining a variable", +}, AST_SymbolDeclaration); + +var AST_SymbolBlockDeclaration = DEFNODE( + "SymbolBlockDeclaration", + null, + function AST_SymbolBlockDeclaration(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; + }, + { + $documentation: "Base class for block-scoped declaration symbols" + }, + AST_SymbolDeclaration +); + +var AST_SymbolConst = DEFNODE("SymbolConst", null, function AST_SymbolConst(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A constant declaration" +}, AST_SymbolBlockDeclaration); + +var AST_SymbolUsing = DEFNODE("SymbolUsing", null, function AST_SymbolUsing(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A `using` declaration" +}, AST_SymbolBlockDeclaration); + +var AST_SymbolLet = DEFNODE("SymbolLet", null, function AST_SymbolLet(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A block-scoped `let` declaration" +}, AST_SymbolBlockDeclaration); + +var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, function AST_SymbolFunarg(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol naming a function argument", +}, AST_SymbolVar); + +var AST_SymbolDefun = DEFNODE("SymbolDefun", null, function AST_SymbolDefun(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol defining a function", +}, AST_SymbolDeclaration); + +var AST_SymbolMethod = DEFNODE("SymbolMethod", null, function AST_SymbolMethod(props) { + if (props) { + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol in an object defining a method", +}, AST_Symbol); + +var AST_SymbolClassProperty = DEFNODE("SymbolClassProperty", null, function AST_SymbolClassProperty(props) { + if (props) { + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol for a class property", +}, AST_Symbol); + +var AST_SymbolLambda = DEFNODE("SymbolLambda", null, function AST_SymbolLambda(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol naming a function expression", +}, AST_SymbolDeclaration); + +var AST_SymbolDefClass = DEFNODE("SymbolDefClass", null, function AST_SymbolDefClass(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol naming a class's name in a class declaration. Lexically scoped to its containing scope, and accessible within the class." +}, AST_SymbolBlockDeclaration); + +var AST_SymbolClass = DEFNODE("SymbolClass", null, function AST_SymbolClass(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol naming a class's name. Lexically scoped to the class." +}, AST_SymbolDeclaration); + +var AST_SymbolCatch = DEFNODE("SymbolCatch", null, function AST_SymbolCatch(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol naming the exception in catch", +}, AST_SymbolBlockDeclaration); + +var AST_SymbolImport = DEFNODE("SymbolImport", null, function AST_SymbolImport(props) { + if (props) { + this.init = props.init; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol referring to an imported name", +}, AST_SymbolBlockDeclaration); + +var AST_SymbolImportForeign = DEFNODE("SymbolImportForeign", "quote", function AST_SymbolImportForeign(props) { + if (props) { + this.quote = props.quote; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A symbol imported from a module, but it is defined in the other module, and its real name is irrelevant for this module's purposes", +}, AST_Symbol); + +var AST_Label = DEFNODE("Label", "references", function AST_Label(props) { + if (props) { + this.references = props.references; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + this.initialize(); + } + + this.flags = 0; +}, { + $documentation: "Symbol naming a label (declaration)", + $propdoc: { + references: "[AST_LoopControl*] a list of nodes referring to this label" + }, + initialize: function() { + this.references = []; + this.thedef = this; + } +}, AST_Symbol); + +var AST_SymbolRef = DEFNODE("SymbolRef", null, function AST_SymbolRef(props) { + if (props) { + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Reference to some symbol (not definition/declaration)", +}, AST_Symbol); + +var AST_SymbolExport = DEFNODE("SymbolExport", "quote", function AST_SymbolExport(props) { + if (props) { + this.quote = props.quote; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Symbol referring to a name to export", +}, AST_SymbolRef); + +var AST_SymbolExportForeign = DEFNODE("SymbolExportForeign", "quote", function AST_SymbolExportForeign(props) { + if (props) { + this.quote = props.quote; + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A symbol exported from this module, but it is used in the other module, and its real name is irrelevant for this module's purposes", +}, AST_Symbol); + +var AST_LabelRef = DEFNODE("LabelRef", null, function AST_LabelRef(props) { + if (props) { + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Reference to a label symbol", +}, AST_Symbol); + +var AST_SymbolPrivateProperty = DEFNODE("SymbolPrivateProperty", null, function AST_SymbolPrivateProperty(props) { + if (props) { + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A symbol that refers to a private property", +}, AST_Symbol); + +var AST_This = DEFNODE("This", null, function AST_This(props) { + if (props) { + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The `this` symbol", +}, AST_Symbol); + +var AST_Super = DEFNODE("Super", null, function AST_Super(props) { + if (props) { + this.scope = props.scope; + this.name = props.name; + this.thedef = props.thedef; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The `super` symbol", +}, AST_This); + +var AST_Constant = DEFNODE("Constant", null, function AST_Constant(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for all constants", + getValue: function() { + return this.value; + } +}); + +var AST_String = DEFNODE("String", "value quote", function AST_String(props) { + if (props) { + this.value = props.value; + this.quote = props.quote; + this.start = props.start; + this.end = props.end; + this._annotations = props._annotations; + } + + this.flags = 0; +}, { + $documentation: "A string literal", + $propdoc: { + value: "[string] the contents of this string", + quote: "[string] the original quote character" + } +}, AST_Constant); + +var AST_Number = DEFNODE("Number", "value raw", function AST_Number(props) { + if (props) { + this.value = props.value; + this.raw = props.raw; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A number literal", + $propdoc: { + value: "[number] the numeric value", + raw: "[string] numeric value as string" + } +}, AST_Constant); + +var AST_BigInt = DEFNODE("BigInt", "value raw", function AST_BigInt(props) { + if (props) { + this.value = props.value; + this.raw = props.raw; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A big int literal", + $propdoc: { + value: "[string] big int value, represented as a string", + raw: "[string] the original format preserved" + } +}, AST_Constant); + +var AST_RegExp = DEFNODE("RegExp", "value", function AST_RegExp(props) { + if (props) { + this.value = props.value; + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A regexp literal", + $propdoc: { + value: "[RegExp] the actual regexp", + } +}, AST_Constant); + +var AST_Atom = DEFNODE("Atom", null, function AST_Atom(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for atoms", +}, AST_Constant); + +var AST_Null = DEFNODE("Null", null, function AST_Null(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The `null` atom", + value: null +}, AST_Atom); + +var AST_NaN = DEFNODE("NaN", null, function AST_NaN(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The impossible value", + value: 0/0 +}, AST_Atom); + +var AST_Undefined = DEFNODE("Undefined", null, function AST_Undefined(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The `undefined` value", + value: (function() {}()) +}, AST_Atom); + +var AST_Hole = DEFNODE("Hole", null, function AST_Hole(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "A hole in an array", + value: (function() {}()) +}, AST_Atom); + +var AST_Infinity = DEFNODE("Infinity", null, function AST_Infinity(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The `Infinity` value", + value: 1/0 +}, AST_Atom); + +var AST_Boolean = DEFNODE("Boolean", null, function AST_Boolean(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "Base class for booleans", +}, AST_Atom); + +var AST_False = DEFNODE("False", null, function AST_False(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The `false` atom", + value: false +}, AST_Boolean); + +var AST_True = DEFNODE("True", null, function AST_True(props) { + if (props) { + this.start = props.start; + this.end = props.end; + } + + this.flags = 0; +}, { + $documentation: "The `true` atom", + value: true +}, AST_Boolean); + +/* -----[ Walk function ]---- */ + +/** + * Walk nodes in depth-first search fashion. + * Callback can return `walk_abort` symbol to stop iteration. + * It can also return `true` to stop iteration just for child nodes. + * Iteration can be stopped and continued by passing the `to_visit` argument, + * which is given to the callback in the second argument. + **/ +function walk(node, cb, to_visit = [node]) { + const push = to_visit.push.bind(to_visit); + while (to_visit.length) { + const node = to_visit.pop(); + const ret = cb(node, to_visit); + + if (ret) { + if (ret === walk_abort) return true; + continue; + } + + node._children_backwards(push); + } + return false; +} + +/** + * Walks an AST node and its children. + * + * {cb} can return `walk_abort` to interrupt the walk. + * + * @param node + * @param cb {(node, info: { parent: (nth) => any }) => (boolean | undefined)} + * + * @returns {boolean} whether the walk was aborted + * + * @example + * const found_some_cond = walk_parent(my_ast_node, (node, { parent }) => { + * if (some_cond(node, parent())) return walk_abort + * }); + */ +function walk_parent(node, cb, initial_stack) { + const to_visit = [node]; + const push = to_visit.push.bind(to_visit); + const stack = initial_stack ? initial_stack.slice() : []; + const parent_pop_indices = []; + + let current; + + const info = { + parent: (n = 0) => { + if (n === -1) { + return current; + } + + // [ p1 p0 ] [ 1 0 ] + if (initial_stack && n >= stack.length) { + n -= stack.length; + return initial_stack[ + initial_stack.length - (n + 1) + ]; + } + + return stack[stack.length - (1 + n)]; + }, + }; + + while (to_visit.length) { + current = to_visit.pop(); + + while ( + parent_pop_indices.length && + to_visit.length == parent_pop_indices[parent_pop_indices.length - 1] + ) { + stack.pop(); + parent_pop_indices.pop(); + } + + const ret = cb(current, info); + + if (ret) { + if (ret === walk_abort) return true; + continue; + } + + const visit_length = to_visit.length; + + current._children_backwards(push); + + // Push only if we're going to traverse the children + if (to_visit.length > visit_length) { + stack.push(current); + parent_pop_indices.push(visit_length - 1); + } + } + + return false; +} + +const walk_abort = Symbol("abort walk"); + +/* -----[ TreeWalker ]----- */ + +class TreeWalker { + constructor(callback) { + this.visit = callback; + this.stack = []; + this.directives = Object.create(null); + } + + _visit(node, descend) { + this.push(node); + var ret = this.visit(node, descend ? function() { + descend.call(node); + } : noop); + if (!ret && descend) { + descend.call(node); + } + this.pop(); + return ret; + } + + parent(n) { + return this.stack[this.stack.length - 2 - (n || 0)]; + } + + push(node) { + if (node instanceof AST_Lambda) { + this.directives = Object.create(this.directives); + } else if (node instanceof AST_Directive && !this.directives[node.value]) { + this.directives[node.value] = node; + } else if (node instanceof AST_Class) { + this.directives = Object.create(this.directives); + if (!this.directives["use strict"]) { + this.directives["use strict"] = node; + } + } + this.stack.push(node); + } + + pop() { + var node = this.stack.pop(); + if (node instanceof AST_Lambda || node instanceof AST_Class) { + this.directives = Object.getPrototypeOf(this.directives); + } + } + + self() { + return this.stack[this.stack.length - 1]; + } + + find_parent(type) { + var stack = this.stack; + for (var i = stack.length; --i >= 0;) { + var x = stack[i]; + if (x instanceof type) return x; + } + } + + is_within_loop() { + let i = this.stack.length - 1; + let child = this.stack[i]; + while (i--) { + const node = this.stack[i]; + + if (node instanceof AST_Lambda) return false; + if ( + node instanceof AST_IterationStatement + // exclude for-loop bits that only run once + && !((node instanceof AST_For) && child === node.init) + && !((node instanceof AST_ForIn || node instanceof AST_ForOf) && child === node.object) + ) { + return true; + } + + child = node; + } + + return false; + } + + find_scope() { + var stack = this.stack; + for (var i = stack.length; --i >= 0;) { + const p = stack[i]; + if (p instanceof AST_Toplevel) return p; + if (p instanceof AST_Lambda) return p; + if (p.block_scope) return p.block_scope; + } + } + + has_directive(type) { + var dir = this.directives[type]; + if (dir) return dir; + var node = this.stack[this.stack.length - 1]; + if (node instanceof AST_Scope && node.body) { + for (var i = 0; i < node.body.length; ++i) { + var st = node.body[i]; + if (!(st instanceof AST_Directive)) break; + if (st.value == type) return st; + } + } + } + + loopcontrol_target(node) { + var stack = this.stack; + if (node.label) for (var i = stack.length; --i >= 0;) { + var x = stack[i]; + if (x instanceof AST_LabeledStatement && x.label.name == node.label.name) + return x.body; + } else for (var i = stack.length; --i >= 0;) { + var x = stack[i]; + if (x instanceof AST_IterationStatement + || node instanceof AST_Break && x instanceof AST_Switch) + return x; + } + } +} + +// Tree transformer helpers. +class TreeTransformer extends TreeWalker { + constructor(before, after) { + super(); + this.before = before; + this.after = after; + } +} + +const _PURE = 0b00000001; +const _INLINE = 0b00000010; +const _NOINLINE = 0b00000100; +const _KEY = 0b00001000; +const _MANGLEPROP = 0b00010000; + +export { + AST_Accessor, + AST_Array, + AST_Arrow, + AST_Assign, + AST_Atom, + AST_Await, + AST_BigInt, + AST_Binary, + AST_Block, + AST_BlockStatement, + AST_Boolean, + AST_Break, + AST_Call, + AST_Case, + AST_Catch, + AST_Chain, + AST_Class, + AST_ClassExpression, + AST_ClassPrivateProperty, + AST_PrivateIn, + AST_ClassProperty, + AST_ClassStaticBlock, + AST_ConciseMethod, + AST_Conditional, + AST_Const, + AST_Constant, + AST_Continue, + AST_Debugger, + AST_Default, + AST_DefaultAssign, + AST_DefClass, + AST_Definitions, + AST_DefinitionsLike, + AST_Defun, + AST_Destructuring, + AST_Directive, + AST_Do, + AST_Dot, + AST_DotHash, + AST_DWLoop, + AST_EmptyStatement, + AST_Exit, + AST_Expansion, + AST_Export, + AST_False, + AST_Finally, + AST_For, + AST_ForIn, + AST_ForOf, + AST_Function, + AST_Hole, + AST_If, + AST_Import, + AST_ImportMeta, + AST_Infinity, + AST_IterationStatement, + AST_Jump, + AST_Label, + AST_LabeledStatement, + AST_LabelRef, + AST_Lambda, + AST_Let, + AST_LoopControl, + AST_NameMapping, + AST_NaN, + AST_New, + AST_NewTarget, + AST_Node, + AST_Null, + AST_Number, + AST_Object, + AST_ObjectGetter, + AST_ObjectKeyVal, + AST_ObjectProperty, + AST_ObjectSetter, + AST_PrefixedTemplateString, + AST_PrivateGetter, + AST_PrivateMethod, + AST_PrivateSetter, + AST_PropAccess, + AST_RegExp, + AST_Return, + AST_Scope, + AST_Sequence, + AST_SimpleStatement, + AST_Statement, + AST_StatementWithBody, + AST_String, + AST_Sub, + AST_Super, + AST_Switch, + AST_SwitchBranch, + AST_Symbol, + AST_SymbolBlockDeclaration, + AST_SymbolCatch, + AST_SymbolClass, + AST_SymbolClassProperty, + AST_SymbolConst, + AST_SymbolDeclaration, + AST_SymbolDefClass, + AST_SymbolDefun, + AST_SymbolExport, + AST_SymbolExportForeign, + AST_SymbolFunarg, + AST_SymbolImport, + AST_SymbolImportForeign, + AST_SymbolLambda, + AST_SymbolLet, + AST_SymbolMethod, + AST_SymbolRef, + AST_SymbolUsing, + AST_SymbolVar, + AST_TemplateSegment, + AST_TemplateString, + AST_SymbolPrivateProperty, + AST_This, + AST_Throw, + AST_Token, + AST_Toplevel, + AST_True, + AST_Try, + AST_TryBlock, + AST_Unary, + AST_UnaryPostfix, + AST_UnaryPrefix, + AST_Undefined, + AST_Using, + AST_UsingDef, + AST_Var, + AST_VarDef, + AST_VarDefLike, + AST_While, + AST_With, + AST_Yield, + + // Walkers + TreeTransformer, + TreeWalker, + walk, + walk_abort, + walk_body, + walk_parent, + + // annotations + _INLINE, + _NOINLINE, + _PURE, + _KEY, + _MANGLEPROP, +}; diff --git a/node_modules/terser/lib/cli.js b/node_modules/terser/lib/cli.js new file mode 100644 index 0000000..56be24f --- /dev/null +++ b/node_modules/terser/lib/cli.js @@ -0,0 +1,482 @@ +import { minify, _default_options } from "../main.js"; +import { parse } from "./parse.js"; +import { + AST_Assign, + AST_Array, + AST_Constant, + AST_Node, + AST_PropAccess, + AST_RegExp, + AST_Sequence, + AST_Symbol, + AST_Token, + walk +} from "./ast.js"; +import { OutputStream } from "./output.js"; + +export async function run_cli({ program, packageJson, fs, path }) { + const skip_keys = new Set([ "cname", "parent_scope", "scope", "uses_eval", "uses_with" ]); + var files = {}; + var options = { + compress: false, + mangle: false + }; + const default_options = await _default_options(); + program.version(packageJson.name + " " + packageJson.version); + program.parseArgv = program.parse; + program.parse = undefined; + + if (process.argv.includes("ast")) program.helpInformation = describe_ast; + else if (process.argv.includes("options")) program.helpInformation = function() { + var text = []; + for (var option in default_options) { + text.push("--" + (option === "sourceMap" ? "source-map" : option) + " options:"); + text.push(format_object(default_options[option])); + text.push(""); + } + return text.join("\n"); + }; + + program.option("-p, --parse ", "Specify parser options.", parse_js()); + program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js()); + program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js()); + program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js()); + program.option("-f, --format [options]", "Format options.", parse_js()); + program.option("-b, --beautify [options]", "Alias for --format.", parse_js()); + program.option("-o, --output ", "Output file (default STDOUT)."); + program.option("--comments [filter]", "Preserve copyright comments in the output."); + program.option("--config-file ", "Read minify() options from JSON file."); + program.option("-d, --define [=value]", "Global definitions.", parse_js("define")); + program.option("--ecma ", "Specify ECMAScript release: 5, 2015, 2016 or 2017..."); + program.option("-e, --enclose [arg[,...][:value[,...]]]", "Embed output in a big function with configurable arguments and values."); + program.option("--ie8", "Support non-standard Internet Explorer 8."); + program.option("--keep-classnames", "Do not mangle/drop class names."); + program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name."); + program.option("--module", "Input is an ES6 module"); + program.option("--name-cache ", "File to hold mangled name mappings."); + program.option("--rename", "Force symbol expansion."); + program.option("--no-rename", "Disable symbol expansion."); + program.option("--safari10", "Support non-standard Safari 10."); + program.option("--source-map [options]", "Enable source map/specify source map options.", parse_js()); + program.option("--timings", "Display operations run time on STDERR."); + program.option("--toplevel", "Compress and/or mangle variables in toplevel scope."); + program.option("--wrap ", "Embed everything as a function with “exports” corresponding to “name” globally."); + program.arguments("[files...]").parseArgv(process.argv); + if (program.configFile) { + options = JSON.parse(read_file(program.configFile)); + } + if (!program.output && program.sourceMap && program.sourceMap.url != "inline") { + fatal("ERROR: cannot write source map to STDOUT"); + } + + [ + "compress", + "enclose", + "ie8", + "mangle", + "module", + "safari10", + "sourceMap", + "toplevel", + "wrap" + ].forEach(function(name) { + if (name in program) { + options[name] = program[name]; + } + }); + + if ("ecma" in program) { + if (program.ecma != (program.ecma | 0)) fatal("ERROR: ecma must be an integer"); + const ecma = program.ecma | 0; + if (ecma > 5 && ecma < 2015) + options.ecma = ecma + 2009; + else + options.ecma = ecma; + } + if (program.format || program.beautify) { + const chosenOption = program.format || program.beautify; + options.format = typeof chosenOption === "object" ? chosenOption : {}; + } + if (program.comments) { + if (typeof options.format != "object") options.format = {}; + options.format.comments = typeof program.comments == "string" ? (program.comments == "false" ? false : program.comments) : "some"; + } + if (program.define) { + if (typeof options.compress != "object") options.compress = {}; + if (typeof options.compress.global_defs != "object") options.compress.global_defs = {}; + for (var expr in program.define) { + options.compress.global_defs[expr] = program.define[expr]; + } + } + if (program.keepClassnames) { + options.keep_classnames = true; + } + if (program.keepFnames) { + options.keep_fnames = true; + } + if (program.mangleProps) { + if (program.mangleProps.domprops) { + delete program.mangleProps.domprops; + } else { + if (typeof program.mangleProps != "object") program.mangleProps = {}; + if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = []; + } + if (typeof options.mangle != "object") options.mangle = {}; + options.mangle.properties = program.mangleProps; + } + if (program.nameCache) { + options.nameCache = JSON.parse(read_file(program.nameCache, "{}")); + } + if (program.output == "ast") { + options.format = { + ast: true, + code: false + }; + } + if (program.parse) { + if (!program.parse.acorn && !program.parse.spidermonkey) { + options.parse = program.parse; + } else if (program.sourceMap && program.sourceMap.content == "inline") { + fatal("ERROR: inline source map only works with built-in parser"); + } + } + if (~program.rawArgs.indexOf("--rename")) { + options.rename = true; + } else if (!program.rename) { + options.rename = false; + } + + let convert_path = name => name; + if (typeof program.sourceMap == "object" && "base" in program.sourceMap) { + convert_path = function() { + var base = program.sourceMap.base; + delete options.sourceMap.base; + return function(name) { + return path.relative(base, name); + }; + }(); + } + + let filesList; + if (options.files && options.files.length) { + filesList = options.files; + + delete options.files; + } else if (program.args.length) { + filesList = program.args; + } + + if (filesList) { + simple_glob(filesList).forEach(function(name) { + files[convert_path(name)] = read_file(name); + }); + } else { + await new Promise((resolve) => { + var chunks = []; + process.stdin.setEncoding("utf8"); + process.stdin.on("data", function(chunk) { + chunks.push(chunk); + }).on("end", function() { + files = [ chunks.join("") ]; + resolve(); + }); + process.stdin.resume(); + }); + } + + await run_cli(); + + function convert_ast(fn) { + return AST_Node.from_mozilla_ast(Object.keys(files).reduce(fn, null)); + } + + async function run_cli() { + var content = program.sourceMap && program.sourceMap.content; + if (content && content !== "inline") { + options.sourceMap.content = read_file(content, content); + } + if (program.timings) options.timings = true; + + try { + if (program.parse) { + if (program.parse.acorn) { + files = convert_ast(function(toplevel, name) { + return require("acorn").parse(files[name], { + ecmaVersion: 2024, + locations: true, + program: toplevel, + sourceFile: name, + sourceType: options.module || program.parse.module ? "module" : "script" + }); + }); + } else if (program.parse.spidermonkey) { + files = convert_ast(function(toplevel, name) { + var obj = JSON.parse(files[name]); + if (!toplevel) return obj; + toplevel.body = toplevel.body.concat(obj.body); + return toplevel; + }); + } + } + } catch (ex) { + fatal(ex); + } + + let result; + try { + result = await minify(files, options, fs); + } catch (ex) { + if (ex.name == "SyntaxError") { + print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col); + var col = ex.col; + var lines = files[ex.filename].split(/\r?\n/); + var line = lines[ex.line - 1]; + if (!line && !col) { + line = lines[ex.line - 2]; + col = line.length; + } + if (line) { + var limit = 70; + if (col > limit) { + line = line.slice(col - limit); + col = limit; + } + print_error(line.slice(0, 80)); + print_error(line.slice(0, col).replace(/\S/g, " ") + "^"); + } + } + if (ex.defs) { + print_error("Supported options:"); + print_error(format_object(ex.defs)); + } + fatal(ex); + return; + } + + if (program.output == "ast") { + if (!options.compress && !options.mangle) { + result.ast.figure_out_scope({}); + } + console.log(JSON.stringify(result.ast, function(key, value) { + if (value) switch (key) { + case "thedef": + return symdef(value); + case "enclosed": + return value.length ? value.map(symdef) : undefined; + case "variables": + case "globals": + return value.size ? collect_from_map(value, symdef) : undefined; + } + if (skip_keys.has(key)) return; + if (value instanceof AST_Token) return; + if (value instanceof Map) return; + if (value instanceof AST_Node) { + var result = { + _class: "AST_" + value.TYPE + }; + if (value.block_scope) { + result.variables = value.block_scope.variables; + result.enclosed = value.block_scope.enclosed; + } + value.CTOR.PROPS.forEach(function(prop) { + if (prop !== "block_scope") { + result[prop] = value[prop]; + } + }); + return result; + } + return value; + }, 2)); + } else if (program.output == "spidermonkey") { + try { + const minified = await minify( + result.code, + { + compress: false, + mangle: false, + format: { + ast: true, + code: false + } + }, + fs + ); + console.log(JSON.stringify(minified.ast.to_mozilla_ast(), null, 2)); + } catch (ex) { + fatal(ex); + return; + } + } else if (program.output) { + fs.mkdirSync(path.dirname(program.output), { recursive: true }); + fs.writeFileSync(program.output, result.code); + if (options.sourceMap && options.sourceMap.url !== "inline" && result.map) { + fs.writeFileSync(program.output + ".map", result.map); + } + } else { + console.log(result.code); + } + if (program.nameCache) { + fs.writeFileSync(program.nameCache, JSON.stringify(options.nameCache)); + } + if (result.timings) for (var phase in result.timings) { + print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s"); + } + } + + function fatal(message) { + if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:"); + print_error(message); + process.exit(1); + } + + // A file glob function that only supports "*" and "?" wildcards in the basename. + // Example: "foo/bar/*baz??.*.js" + // Argument `glob` may be a string or an array of strings. + // Returns an array of strings. Garbage in, garbage out. + function simple_glob(glob) { + if (Array.isArray(glob)) { + return [].concat.apply([], glob.map(simple_glob)); + } + if (glob && glob.match(/[*?]/)) { + var dir = path.dirname(glob); + try { + var entries = fs.readdirSync(dir); + } catch (ex) {} + if (entries) { + var pattern = "^" + path.basename(glob) + .replace(/[.+^$[\]\\(){}]/g, "\\$&") + .replace(/\*/g, "[^/\\\\]*") + .replace(/\?/g, "[^/\\\\]") + "$"; + var mod = process.platform === "win32" ? "i" : ""; + var rx = new RegExp(pattern, mod); + var results = entries.filter(function(name) { + return rx.test(name); + }).map(function(name) { + return path.join(dir, name); + }); + if (results.length) return results; + } + } + return [ glob ]; + } + + function read_file(path, default_value) { + try { + return fs.readFileSync(path, "utf8"); + } catch (ex) { + if ((ex.code == "ENOENT" || ex.code == "ENAMETOOLONG") && default_value != null) return default_value; + fatal(ex); + } + } + + function parse_js(flag) { + return function(value, options) { + options = options || {}; + try { + walk(parse(value, { expression: true }), node => { + if (node instanceof AST_Assign) { + var name = node.left.print_to_string(); + var value = node.right; + if (flag) { + options[name] = value; + } else if (value instanceof AST_Array) { + options[name] = value.elements.map(to_string); + } else if (value instanceof AST_RegExp) { + value = value.value; + options[name] = new RegExp(value.source, value.flags); + } else { + options[name] = to_string(value); + } + return true; + } + if (node instanceof AST_Symbol || node instanceof AST_PropAccess) { + var name = node.print_to_string(); + options[name] = true; + return true; + } + if (!(node instanceof AST_Sequence)) throw node; + + function to_string(value) { + return value instanceof AST_Constant ? value.getValue() : value.print_to_string({ + quote_keys: true + }); + } + }); + } catch(ex) { + if (flag) { + fatal("Error parsing arguments for '" + flag + "': " + value); + } else { + options[value] = null; + } + } + return options; + }; + } + + function symdef(def) { + var ret = (1e6 + def.id) + " " + def.name; + if (def.mangled_name) ret += " " + def.mangled_name; + return ret; + } + + function collect_from_map(map, callback) { + var result = []; + map.forEach(function (def) { + result.push(callback(def)); + }); + return result; + } + + function format_object(obj) { + var lines = []; + var padding = ""; + Object.keys(obj).map(function(name) { + if (padding.length < name.length) padding = Array(name.length + 1).join(" "); + return [ name, JSON.stringify(obj[name]) ]; + }).forEach(function(tokens) { + lines.push(" " + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]); + }); + return lines.join("\n"); + } + + function print_error(msg) { + process.stderr.write(msg); + process.stderr.write("\n"); + } + + function describe_ast() { + var out = OutputStream({ beautify: true }); + function doitem(ctor) { + out.print("AST_" + ctor.TYPE); + const props = ctor.SELF_PROPS.filter(prop => !/^\$/.test(prop)); + + if (props.length > 0) { + out.space(); + out.with_parens(function() { + props.forEach(function(prop, i) { + if (i) out.space(); + out.print(prop); + }); + }); + } + + if (ctor.documentation) { + out.space(); + out.print_string(ctor.documentation); + } + + if (ctor.SUBCLASSES.length > 0) { + out.space(); + out.with_block(function() { + ctor.SUBCLASSES.forEach(function(ctor) { + out.indent(); + doitem(ctor); + out.newline(); + }); + }); + } + } + doitem(AST_Node); + return out + "\n"; + } +} diff --git a/node_modules/terser/lib/compress/common.js b/node_modules/terser/lib/compress/common.js new file mode 100644 index 0000000..3e432a6 --- /dev/null +++ b/node_modules/terser/lib/compress/common.js @@ -0,0 +1,375 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +import { + AST_Array, + AST_Arrow, + AST_BigInt, + AST_BlockStatement, + AST_Call, + AST_Chain, + AST_Class, + AST_Const, + AST_Constant, + AST_DefClass, + AST_Defun, + AST_EmptyStatement, + AST_Export, + AST_False, + AST_Function, + AST_Import, + AST_Infinity, + AST_LabeledStatement, + AST_Lambda, + AST_Let, + AST_LoopControl, + AST_NaN, + AST_Node, + AST_Null, + AST_Number, + AST_Object, + AST_ObjectKeyVal, + AST_PropAccess, + AST_RegExp, + AST_Scope, + AST_Sequence, + AST_SimpleStatement, + AST_Statement, + AST_String, + AST_SymbolRef, + AST_True, + AST_UnaryPrefix, + AST_Undefined, + AST_Using, + + TreeWalker, + walk, + walk_abort, + walk_parent, +} from "../ast.js"; +import { make_node, regexp_source_fix, string_template, makePredicate } from "../utils/index.js"; +import { first_in_statement } from "../utils/first_in_statement.js"; +import { has_flag, TOP } from "./compressor-flags.js"; + +export function merge_sequence(array, node) { + if (node instanceof AST_Sequence) { + array.push(...node.expressions); + } else { + array.push(node); + } + return array; +} + +export function make_sequence(orig, expressions) { + if (expressions.length == 1) return expressions[0]; + if (expressions.length == 0) throw new Error("trying to create a sequence with length zero!"); + return make_node(AST_Sequence, orig, { + expressions: expressions.reduce(merge_sequence, []) + }); +} + +export function make_empty_function(self) { + return make_node(AST_Function, self, { + uses_arguments: false, + argnames: [], + body: [], + is_generator: false, + async: false, + variables: new Map(), + uses_with: false, + uses_eval: false, + parent_scope: null, + enclosed: [], + cname: 0, + block_scope: undefined, + }); +} + +export function make_node_from_constant(val, orig) { + switch (typeof val) { + case "string": + return make_node(AST_String, orig, { + value: val + }); + case "number": + if (isNaN(val)) return make_node(AST_NaN, orig); + if (isFinite(val)) { + return 1 / val < 0 ? make_node(AST_UnaryPrefix, orig, { + operator: "-", + expression: make_node(AST_Number, orig, { value: -val }) + }) : make_node(AST_Number, orig, { value: val }); + } + return val < 0 ? make_node(AST_UnaryPrefix, orig, { + operator: "-", + expression: make_node(AST_Infinity, orig) + }) : make_node(AST_Infinity, orig); + case "bigint": + return make_node(AST_BigInt, orig, { value: val.toString() }); + case "boolean": + return make_node(val ? AST_True : AST_False, orig); + case "undefined": + return make_node(AST_Undefined, orig); + default: + if (val === null) { + return make_node(AST_Null, orig, { value: null }); + } + if (val instanceof RegExp) { + return make_node(AST_RegExp, orig, { + value: { + source: regexp_source_fix(val.source), + flags: val.flags + } + }); + } + throw new Error(string_template("Can't handle constant of type: {type}", { + type: typeof val + })); + } +} + +export function best_of_expression(ast1, ast2) { + return ast1.size() > ast2.size() ? ast2 : ast1; +} + +export function best_of_statement(ast1, ast2) { + return best_of_expression( + make_node(AST_SimpleStatement, ast1, { + body: ast1 + }), + make_node(AST_SimpleStatement, ast2, { + body: ast2 + }) + ).body; +} + +/** Find which node is smaller, and return that */ +export function best_of(compressor, ast1, ast2) { + if (first_in_statement(compressor)) { + return best_of_statement(ast1, ast2); + } else { + return best_of_expression(ast1, ast2); + } +} + +/** Simplify an object property's key, if possible */ +export function get_simple_key(key) { + if (key instanceof AST_Constant) { + return key.getValue(); + } + if (key instanceof AST_UnaryPrefix + && key.operator == "void" + && key.expression instanceof AST_Constant) { + return undefined; + } + return key; +} + +export function read_property(obj, key) { + key = get_simple_key(key); + if (key instanceof AST_Node) return; + + var value; + if (obj instanceof AST_Array) { + var elements = obj.elements; + if (key == "length") return make_node_from_constant(elements.length, obj); + if (typeof key == "number" && key in elements) value = elements[key]; + } else if (obj instanceof AST_Object) { + key = "" + key; + var props = obj.properties; + for (var i = props.length; --i >= 0;) { + var prop = props[i]; + if (!(prop instanceof AST_ObjectKeyVal)) return; + if (!value && props[i].key === key) value = props[i].value; + } + } + + return value instanceof AST_SymbolRef && value.fixed_value() || value; +} + +export function has_break_or_continue(loop, parent) { + var found = false; + var tw = new TreeWalker(function(node) { + if (found || node instanceof AST_Scope) return true; + if (node instanceof AST_LoopControl && tw.loopcontrol_target(node) === loop) { + return found = true; + } + }); + if (parent instanceof AST_LabeledStatement) tw.push(parent); + tw.push(loop); + loop.body.walk(tw); + return found; +} + +// we shouldn't compress (1,func)(something) to +// func(something) because that changes the meaning of +// the func (becomes lexical instead of global). +export function maintain_this_binding(parent, orig, val) { + if (requires_sequence_to_maintain_binding(parent, orig, val)) { + const zero = make_node(AST_Number, orig, { value: 0 }); + return make_sequence(orig, [ zero, val ]); + } else { + return val; + } +} + +/** Detect (1, x.noThis)(), (0, eval)(), which need sequences */ +export function requires_sequence_to_maintain_binding(parent, orig, val) { + return ( + parent instanceof AST_UnaryPrefix && parent.operator == "delete" + || parent instanceof AST_Call && parent.expression === orig + && ( + val instanceof AST_Chain + || val instanceof AST_PropAccess + || val instanceof AST_SymbolRef && val.name == "eval" + ) + ); +} + +export function is_func_expr(node) { + return node instanceof AST_Arrow || node instanceof AST_Function; +} + +/** + * Used to determine whether the node can benefit from negation. + * Not the case with arrow functions (you need an extra set of parens). */ +export function is_iife_call(node) { + if (node.TYPE != "Call") return false; + return node.expression instanceof AST_Function || is_iife_call(node.expression); +} + +export function is_empty(thing) { + if (thing === null) return true; + if (thing instanceof AST_EmptyStatement) return true; + if (thing instanceof AST_BlockStatement) return thing.body.length == 0; + return false; +} + +export const identifier_atom = makePredicate("Infinity NaN undefined"); +export function is_identifier_atom(node) { + return node instanceof AST_Infinity + || node instanceof AST_NaN + || node instanceof AST_Undefined; +} + +/** Check if this is a SymbolRef node which has one def of a certain AST type */ +export function is_ref_of(ref, type) { + if (!(ref instanceof AST_SymbolRef)) return false; + var orig = ref.definition().orig; + for (var i = orig.length; --i >= 0;) { + if (orig[i] instanceof type) return true; + } +} + +/**Can we turn { block contents... } into just the block contents ? + * Not if one of these is inside. + **/ +export function can_be_evicted_from_block(node) { + return !( + node instanceof AST_DefClass || + node instanceof AST_Defun || + node instanceof AST_Let || + node instanceof AST_Const || + node instanceof AST_Using || + node instanceof AST_Export || + node instanceof AST_Import + ); +} + +export function as_statement_array(thing) { + if (thing === null) return []; + if (thing instanceof AST_BlockStatement) return thing.body; + if (thing instanceof AST_EmptyStatement) return []; + if (thing instanceof AST_Statement) return [ thing ]; + throw new Error("Can't convert thing to statement array"); +} + +export function is_reachable(scope_node, defs) { + const find_ref = node => { + if (node instanceof AST_SymbolRef && defs.includes(node.definition())) { + return walk_abort; + } + }; + + return walk_parent(scope_node, (node, info) => { + if (node instanceof AST_Scope && node !== scope_node) { + var parent = info.parent(); + + if ( + parent instanceof AST_Call + && parent.expression === node + // Async/Generators aren't guaranteed to sync evaluate all of + // their body steps, so it's possible they close over the variable. + && !(node.async || node.is_generator) + ) { + return; + } + + if (walk(node, find_ref)) return walk_abort; + + return true; + } + }); +} + +/** Check if a ref refers to the name of a function/class it's defined within */ +export function is_recursive_ref(tw, def) { + var node; + for (var i = 0; node = tw.parent(i); i++) { + if (node instanceof AST_Lambda || node instanceof AST_Class) { + var name = node.name; + if (name && name.definition() === def) { + return true; + } + } + } + return false; +} + +// TODO this only works with AST_Defun, shouldn't it work for other ways of defining functions? +export function retain_top_func(fn, compressor) { + return compressor.top_retain + && fn instanceof AST_Defun + && has_flag(fn, TOP) + && fn.name + && compressor.top_retain(fn.name.definition()); +} diff --git a/node_modules/terser/lib/compress/compressor-flags.js b/node_modules/terser/lib/compress/compressor-flags.js new file mode 100644 index 0000000..fc13273 --- /dev/null +++ b/node_modules/terser/lib/compress/compressor-flags.js @@ -0,0 +1,62 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +// bitfield flags to be stored in node.flags. +// These are set and unset during compression, and store information in the node without requiring multiple fields. +export const UNUSED = 0b00000001; +export const TRUTHY = 0b00000010; +export const FALSY = 0b00000100; +export const UNDEFINED = 0b00001000; +export const INLINED = 0b00010000; +// Nodes to which values are ever written. Used when keep_assign is part of the unused option string. +export const WRITE_ONLY = 0b00100000; + +// information specific to a single compression pass +export const SQUEEZED = 0b0000000100000000; +export const OPTIMIZED = 0b0000001000000000; +export const TOP = 0b0000010000000000; +export const CLEAR_BETWEEN_PASSES = SQUEEZED | OPTIMIZED | TOP; + +export const has_flag = (node, flag) => node.flags & flag; +export const set_flag = (node, flag) => { node.flags |= flag; }; +export const clear_flag = (node, flag) => { node.flags &= ~flag; }; diff --git a/node_modules/terser/lib/compress/drop-side-effect-free.js b/node_modules/terser/lib/compress/drop-side-effect-free.js new file mode 100644 index 0000000..787d5b4 --- /dev/null +++ b/node_modules/terser/lib/compress/drop-side-effect-free.js @@ -0,0 +1,387 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +import { + AST_Accessor, + AST_Array, + AST_Arrow, + AST_Assign, + AST_Binary, + AST_Call, + AST_Chain, + AST_Class, + AST_ClassPrivateProperty, + AST_ClassProperty, + AST_ClassStaticBlock, + AST_ConciseMethod, + AST_Conditional, + AST_Constant, + AST_DefClass, + AST_Dot, + AST_Expansion, + AST_Function, + AST_Node, + AST_Number, + AST_Object, + AST_ObjectGetter, + AST_ObjectKeyVal, + AST_ObjectSetter, + AST_PrivateGetter, + AST_PrivateSetter, + AST_PrivateMethod, + AST_PropAccess, + AST_Scope, + AST_Sequence, + AST_SimpleStatement, + AST_Sub, + AST_SymbolRef, + AST_TemplateSegment, + AST_TemplateString, + AST_This, + AST_Unary, +} from "../ast.js"; +import { make_node, return_null, return_this } from "../utils/index.js"; +import { first_in_statement } from "../utils/first_in_statement.js"; + +import { pure_prop_access_globals } from "./native-objects.js"; +import { lazy_op, unary_side_effects, is_nullish_shortcircuited } from "./inference.js"; +import { WRITE_ONLY, set_flag, clear_flag } from "./compressor-flags.js"; +import { make_sequence, is_func_expr, is_iife_call } from "./common.js"; + +// AST_Node#drop_side_effect_free() gets called when we don't care about the value, +// only about side effects. We'll be defining this method for each node type in this module +// +// Examples: +// foo++ -> foo++ +// 1 + func() -> func() +// 10 -> (nothing) +// knownPureFunc(foo++) -> foo++ + +function def_drop_side_effect_free(node_or_nodes, func) { + for (const node of [].concat(node_or_nodes)) { + node.DEFMETHOD("drop_side_effect_free", func); + } +} + +// Drop side-effect-free elements from an array of expressions. +// Returns an array of expressions with side-effects or null +// if all elements were dropped. Note: original array may be +// returned if nothing changed. +function trim(nodes, compressor, first_in_statement) { + var len = nodes.length; + if (!len) return null; + + var ret = [], changed = false; + for (var i = 0; i < len; i++) { + var node = nodes[i].drop_side_effect_free(compressor, first_in_statement); + changed |= node !== nodes[i]; + if (node) { + ret.push(node); + first_in_statement = false; + } + } + return changed ? ret.length ? ret : null : nodes; +} + +def_drop_side_effect_free(AST_Node, return_this); +def_drop_side_effect_free(AST_Constant, return_null); +def_drop_side_effect_free(AST_This, return_null); + +def_drop_side_effect_free(AST_Call, function (compressor, first_in_statement) { + if (is_nullish_shortcircuited(this, compressor)) { + return this.expression.drop_side_effect_free(compressor, first_in_statement); + } + + if (!this.is_callee_pure(compressor)) { + if (this.expression.is_call_pure(compressor)) { + var exprs = this.args.slice(); + exprs.unshift(this.expression.expression); + exprs = trim(exprs, compressor, first_in_statement); + return exprs && make_sequence(this, exprs); + } + if (is_func_expr(this.expression) + && (!this.expression.name || !this.expression.name.definition().references.length)) { + var node = this.clone(); + node.expression.process_expression(false, compressor); + return node; + } + return this; + } + + var args = trim(this.args, compressor, first_in_statement); + return args && make_sequence(this, args); +}); + +def_drop_side_effect_free(AST_Accessor, return_null); + +def_drop_side_effect_free(AST_Function, return_null); + +def_drop_side_effect_free(AST_Arrow, return_null); + +def_drop_side_effect_free(AST_Class, function (compressor) { + const with_effects = []; + + if (this.is_self_referential() && this.has_side_effects(compressor)) { + return this; + } + + const trimmed_extends = this.extends && this.extends.drop_side_effect_free(compressor); + if (trimmed_extends) with_effects.push(trimmed_extends); + + for (const prop of this.properties) { + if (prop instanceof AST_ClassStaticBlock) { + if (prop.has_side_effects(compressor)) { + return this; // Be cautious about these + } + } else { + const trimmed_prop = prop.drop_side_effect_free(compressor); + if (trimmed_prop) with_effects.push(trimmed_prop); + } + } + + if (!with_effects.length) + return null; + + const exprs = make_sequence(this, with_effects); + if (this instanceof AST_DefClass) { + // We want a statement + return make_node(AST_SimpleStatement, this, { body: exprs }); + } else { + return exprs; + } +}); + +def_drop_side_effect_free([ + AST_ClassProperty, + AST_ClassPrivateProperty, +], function (compressor) { + const key = this.computed_key() && this.key.drop_side_effect_free(compressor); + + const value = this.static && this.value + && this.value.drop_side_effect_free(compressor); + + if (key && value) + return make_sequence(this, [key, value]); + return key || value || null; +}); + +def_drop_side_effect_free(AST_Binary, function (compressor, first_in_statement) { + var right = this.right.drop_side_effect_free(compressor); + if (!right) + return this.left.drop_side_effect_free(compressor, first_in_statement); + if (lazy_op.has(this.operator)) { + if (right === this.right) + return this; + var node = this.clone(); + node.right = right; + return node; + } else { + var left = this.left.drop_side_effect_free(compressor, first_in_statement); + if (!left) + return this.right.drop_side_effect_free(compressor, first_in_statement); + return make_sequence(this, [left, right]); + } +}); + +def_drop_side_effect_free(AST_Assign, function (compressor) { + if (this.logical) + return this; + + var left = this.left; + if (left.has_side_effects(compressor) + || compressor.has_directive("use strict") + && left instanceof AST_PropAccess + && left.expression.is_constant()) { + return this; + } + set_flag(this, WRITE_ONLY); + while (left instanceof AST_PropAccess) { + left = left.expression; + } + if (left.is_constant_expression(compressor.find_parent(AST_Scope))) { + return this.right.drop_side_effect_free(compressor); + } + return this; +}); + +def_drop_side_effect_free(AST_Conditional, function (compressor) { + var consequent = this.consequent.drop_side_effect_free(compressor); + var alternative = this.alternative.drop_side_effect_free(compressor); + if (consequent === this.consequent && alternative === this.alternative) + return this; + if (!consequent) + return alternative ? make_node(AST_Binary, this, { + operator: "||", + left: this.condition, + right: alternative + }) : this.condition.drop_side_effect_free(compressor); + if (!alternative) + return make_node(AST_Binary, this, { + operator: "&&", + left: this.condition, + right: consequent + }); + var node = this.clone(); + node.consequent = consequent; + node.alternative = alternative; + return node; +}); + +def_drop_side_effect_free(AST_Unary, function (compressor, first_in_statement) { + if (unary_side_effects.has(this.operator)) { + if (!this.expression.has_side_effects(compressor)) { + set_flag(this, WRITE_ONLY); + } else { + clear_flag(this, WRITE_ONLY); + } + return this; + } + if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef) + return null; + var expression = this.expression.drop_side_effect_free(compressor, first_in_statement); + if (first_in_statement && expression && is_iife_call(expression)) { + if (expression === this.expression && this.operator == "!") + return this; + return expression.negate(compressor, first_in_statement); + } + return expression; +}); + +def_drop_side_effect_free(AST_SymbolRef, function (compressor) { + const safe_access = this.is_declared(compressor) + || pure_prop_access_globals.has(this.name); + return safe_access ? null : this; +}); + +def_drop_side_effect_free(AST_Object, function (compressor, first_in_statement) { + var values = trim(this.properties, compressor, first_in_statement); + return values && make_sequence(this, values); +}); + +def_drop_side_effect_free(AST_ObjectKeyVal, function (compressor, first_in_statement) { + const computed_key = this.key instanceof AST_Node; + const key = computed_key && this.key.drop_side_effect_free(compressor, first_in_statement); + const value = this.value.drop_side_effect_free(compressor, first_in_statement); + if (key && value) { + return make_sequence(this, [key, value]); + } + return key || value; +}); + +def_drop_side_effect_free([ + AST_ConciseMethod, + AST_ObjectGetter, + AST_ObjectSetter, +], function () { + return this.computed_key() ? this.key : null; +}); + +def_drop_side_effect_free([ + AST_PrivateMethod, + AST_PrivateGetter, + AST_PrivateSetter, +], function () { + return null; +}); + +def_drop_side_effect_free(AST_Array, function (compressor, first_in_statement) { + var values = trim(this.elements, compressor, first_in_statement); + return values && make_sequence(this, values); +}); + +def_drop_side_effect_free(AST_Dot, function (compressor, first_in_statement) { + if (is_nullish_shortcircuited(this, compressor)) { + return this.expression.drop_side_effect_free(compressor, first_in_statement); + } + if (!this.optional && this.expression.may_throw_on_access(compressor)) { + return this; + } + + return this.expression.drop_side_effect_free(compressor, first_in_statement); +}); + +def_drop_side_effect_free(AST_Sub, function (compressor, first_in_statement) { + if (is_nullish_shortcircuited(this, compressor)) { + return this.expression.drop_side_effect_free(compressor, first_in_statement); + } + if (!this.optional && this.expression.may_throw_on_access(compressor)) { + return this; + } + + var property = this.property.drop_side_effect_free(compressor); + if (property && this.optional) return this; + + var expression = this.expression.drop_side_effect_free(compressor, first_in_statement); + + if (expression && property) return make_sequence(this, [expression, property]); + return expression || property; +}); + +def_drop_side_effect_free(AST_Chain, function (compressor, first_in_statement) { + return this.expression.drop_side_effect_free(compressor, first_in_statement); +}); + +def_drop_side_effect_free(AST_Sequence, function (compressor) { + var last = this.tail_node(); + var expr = last.drop_side_effect_free(compressor); + if (expr === last) + return this; + var expressions = this.expressions.slice(0, -1); + if (expr) + expressions.push(expr); + if (!expressions.length) { + return make_node(AST_Number, this, { value: 0 }); + } + return make_sequence(this, expressions); +}); + +def_drop_side_effect_free(AST_Expansion, function (compressor, first_in_statement) { + return this.expression.drop_side_effect_free(compressor, first_in_statement); +}); + +def_drop_side_effect_free(AST_TemplateSegment, return_null); + +def_drop_side_effect_free(AST_TemplateString, function (compressor) { + var values = trim(this.segments, compressor, first_in_statement); + return values && make_sequence(this, values); +}); diff --git a/node_modules/terser/lib/compress/drop-unused.js b/node_modules/terser/lib/compress/drop-unused.js new file mode 100644 index 0000000..47a6f28 --- /dev/null +++ b/node_modules/terser/lib/compress/drop-unused.js @@ -0,0 +1,505 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +import { + AST_Accessor, + AST_Assign, + AST_BlockStatement, + AST_Call, + AST_Class, + AST_ClassExpression, + AST_ClassStaticBlock, + AST_DefaultAssign, + AST_DefClass, + AST_Definitions, + AST_Defun, + AST_Destructuring, + AST_EmptyStatement, + AST_Expansion, + AST_Export, + AST_For, + AST_ForIn, + AST_Function, + AST_LabeledStatement, + AST_Lambda, + AST_Number, + AST_Scope, + AST_Sequence, + AST_SimpleStatement, + AST_SymbolBlockDeclaration, + AST_SymbolCatch, + AST_SymbolDeclaration, + AST_SymbolFunarg, + AST_SymbolRef, + AST_SymbolVar, + AST_Toplevel, + AST_Unary, + AST_Var, + + TreeTransformer, + TreeWalker, + walk, +} from "../ast.js"; +import { + keep_name, + make_node, + map_add, + MAP, + remove, + return_false, +} from "../utils/index.js"; +import { SymbolDef } from "../scope.js"; + +import { + WRITE_ONLY, + UNUSED, + + has_flag, + set_flag, +} from "./compressor-flags.js"; +import { + make_sequence, + maintain_this_binding, + is_empty, + is_ref_of, + can_be_evicted_from_block, +} from "./common.js"; +import { is_used_in_expression } from "./inference.js"; + +const r_keep_assign = /keep_assign/; + +/** Drop unused variables from this scope */ +AST_Scope.DEFMETHOD("drop_unused", function(compressor) { + if (!compressor.option("unused")) return; + if (compressor.has_directive("use asm")) return; + if (!this.variables) return; // not really a scope (eg: AST_Class) + + var self = this; + if (self.pinned()) return; + var drop_funcs = !(self instanceof AST_Toplevel) || compressor.toplevel.funcs; + var drop_vars = !(self instanceof AST_Toplevel) || compressor.toplevel.vars; + const assign_as_unused = r_keep_assign.test(compressor.option("unused")) ? return_false : function(node) { + if (node instanceof AST_Assign + && !node.logical + && (has_flag(node, WRITE_ONLY) || node.operator == "=") + ) { + return node.left; + } + if (node instanceof AST_Unary && has_flag(node, WRITE_ONLY)) { + return node.expression; + } + }; + var in_use_ids = new Map(); + var fixed_ids = new Map(); + if (self instanceof AST_Toplevel && compressor.top_retain) { + self.variables.forEach(function(def) { + if (compressor.top_retain(def)) { + in_use_ids.set(def.id, def); + } + }); + } + var var_defs_by_id = new Map(); + var initializations = new Map(); + + // pass 1: find out which symbols are directly used in + // this scope (not in nested scopes). + var scope = this; + var tw = new TreeWalker(function(node, descend) { + if (node instanceof AST_Lambda && node.uses_arguments && !tw.has_directive("use strict")) { + node.argnames.forEach(function(argname) { + if (!(argname instanceof AST_SymbolDeclaration)) return; + var def = argname.definition(); + in_use_ids.set(def.id, def); + }); + } + if (node === self) return; + if (node instanceof AST_Class && node.has_side_effects(compressor)) { + if (node.is_self_referential()) { + descend(); + } else { + node.visit_nondeferred_class_parts(tw); + } + } + if (node instanceof AST_Defun || node instanceof AST_DefClass) { + var node_def = node.name.definition(); + const in_export = tw.parent() instanceof AST_Export; + if (in_export || !drop_funcs && scope === self) { + if (node_def.global) { + in_use_ids.set(node_def.id, node_def); + } + } + + map_add(initializations, node_def.id, node); + return true; // don't go in nested scopes + } + // In the root scope, we drop things. In inner scopes, we just check for uses. + const in_root_scope = scope === self; + if (node instanceof AST_SymbolFunarg && in_root_scope) { + map_add(var_defs_by_id, node.definition().id, node); + } + if (node instanceof AST_Definitions && in_root_scope) { + const in_export = tw.parent() instanceof AST_Export; + node.definitions.forEach(function(def) { + if (def.name instanceof AST_SymbolVar) { + map_add(var_defs_by_id, def.name.definition().id, def); + } + if (in_export || !drop_vars) { + walk(def.name, node => { + if (node instanceof AST_SymbolDeclaration) { + const def = node.definition(); + if (def.global) { + in_use_ids.set(def.id, def); + } + } + }); + } + if (def.name instanceof AST_Destructuring) { + def.walk(tw); + } + if (def.name instanceof AST_SymbolDeclaration && def.value) { + var node_def = def.name.definition(); + map_add(initializations, node_def.id, def.value); + if (!node_def.chained && def.name.fixed_value() === def.value) { + fixed_ids.set(node_def.id, def); + } + if (def.value.has_side_effects(compressor)) { + def.value.walk(tw); + } + } + }); + return true; + } + return scan_ref_scoped(node, descend); + }); + self.walk(tw); + // pass 2: for every used symbol we need to walk its + // initialization code to figure out if it uses other + // symbols (that may not be in_use). + tw = new TreeWalker(scan_ref_scoped); + in_use_ids.forEach(function (def) { + var init = initializations.get(def.id); + if (init) init.forEach(function(init) { + init.walk(tw); + }); + }); + // pass 3: we should drop declarations not in_use + var tt = new TreeTransformer( + function before(node, descend, in_list) { + var parent = tt.parent(); + if (drop_vars) { + const sym = assign_as_unused(node); + if (sym instanceof AST_SymbolRef) { + var def = sym.definition(); + var in_use = in_use_ids.has(def.id); + if (node instanceof AST_Assign) { + if (!in_use || fixed_ids.has(def.id) && fixed_ids.get(def.id) !== node) { + const assignee = node.right.transform(tt); + if (!in_use && !assignee.has_side_effects(compressor) && !is_used_in_expression(tt)) { + return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 }); + } + return maintain_this_binding(parent, node, assignee); + } + } else if (!in_use) { + return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 }); + } + } + } + if (scope !== self) return; + var def; + if (node.name + && (node instanceof AST_ClassExpression + && !keep_name(compressor.option("keep_classnames"), (def = node.name.definition()).name) + || node instanceof AST_Function + && !keep_name(compressor.option("keep_fnames"), (def = node.name.definition()).name))) { + // any declarations with same name will overshadow + // name of this anonymous function and can therefore + // never be used anywhere + if (!in_use_ids.has(def.id) || def.orig.length > 1) node.name = null; + } + if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) { + var trim = + !compressor.option("keep_fargs") + // Is this an IIFE that won't refer to its name? + || parent instanceof AST_Call + && parent.expression === node + && !node.pinned() + && (!node.name || node.name.unreferenced()); + for (var a = node.argnames, i = a.length; --i >= 0;) { + var sym = a[i]; + if (sym instanceof AST_Expansion) { + sym = sym.expression; + } + if (sym instanceof AST_DefaultAssign) { + sym = sym.left; + } + // Do not drop destructuring arguments. + // They constitute a type assertion of sorts + if ( + !(sym instanceof AST_Destructuring) + && !in_use_ids.has(sym.definition().id) + ) { + set_flag(sym, UNUSED); + if (trim) { + a.pop(); + } + } else { + trim = false; + } + } + } + if (node instanceof AST_DefClass && node !== self) { + const def = node.name.definition(); + descend(node, this); + const keep_class = def.global && !drop_funcs || in_use_ids.has(def.id); + if (!keep_class) { + const kept = node.drop_side_effect_free(compressor); + if (kept == null) { + def.eliminated++; + return in_list ? MAP.skip : make_node(AST_EmptyStatement, node); + } + return kept; + } + return node; + } + if (node instanceof AST_Defun && node !== self) { + const def = node.name.definition(); + const keep = def.global && !drop_funcs || in_use_ids.has(def.id); + if (!keep) { + def.eliminated++; + return in_list ? MAP.skip : make_node(AST_EmptyStatement, node); + } + } + if (node instanceof AST_Definitions && !(parent instanceof AST_ForIn && parent.init === node)) { + var drop_block = !(parent instanceof AST_Toplevel) && !(node instanceof AST_Var); + // place uninitialized names at the start + var body = [], head = [], tail = []; + // for unused names whose initialization has + // side effects, we can cascade the init. code + // into the next one, or next statement. + var side_effects = []; + node.definitions.forEach(function(def) { + if (def.value) def.value = def.value.transform(tt); + var is_destructure = def.name instanceof AST_Destructuring; + var sym = is_destructure + ? new SymbolDef(null, { name: "" }) /* fake SymbolDef */ + : def.name.definition(); + if (drop_block && sym.global) return tail.push(def); + if (!(drop_vars || drop_block) + || is_destructure + && (def.name.names.length + || def.name.is_array + || compressor.option("pure_getters") != true) + || in_use_ids.has(sym.id) + ) { + if (def.value && fixed_ids.has(sym.id) && fixed_ids.get(sym.id) !== def) { + def.value = def.value.drop_side_effect_free(compressor); + } + if (def.name instanceof AST_SymbolVar) { + var var_defs = var_defs_by_id.get(sym.id); + if (var_defs.length > 1 && (!def.value || sym.orig.indexOf(def.name) > sym.eliminated)) { + if (def.value) { + var ref = make_node(AST_SymbolRef, def.name, def.name); + sym.references.push(ref); + var assign = make_node(AST_Assign, def, { + operator: "=", + logical: false, + left: ref, + right: def.value + }); + if (fixed_ids.get(sym.id) === def) { + fixed_ids.set(sym.id, assign); + } + side_effects.push(assign.transform(tt)); + } + remove(var_defs, def); + sym.eliminated++; + return; + } + } + if (def.value) { + if (side_effects.length > 0) { + if (tail.length > 0) { + side_effects.push(def.value); + def.value = make_sequence(def.value, side_effects); + } else { + body.push(make_node(AST_SimpleStatement, node, { + body: make_sequence(node, side_effects) + })); + } + side_effects = []; + } + tail.push(def); + } else { + head.push(def); + } + } else if (sym.orig[0] instanceof AST_SymbolCatch) { + var value = def.value && def.value.drop_side_effect_free(compressor); + if (value) side_effects.push(value); + def.value = null; + head.push(def); + } else { + var value = def.value && def.value.drop_side_effect_free(compressor); + if (value) { + side_effects.push(value); + } + sym.eliminated++; + } + }); + if (head.length > 0 || tail.length > 0) { + node.definitions = head.concat(tail); + body.push(node); + } + if (side_effects.length > 0) { + body.push(make_node(AST_SimpleStatement, node, { + body: make_sequence(node, side_effects) + })); + } + switch (body.length) { + case 0: + return in_list ? MAP.skip : make_node(AST_EmptyStatement, node); + case 1: + return body[0]; + default: + return in_list ? MAP.splice(body) : make_node(AST_BlockStatement, node, { body }); + } + } + // certain combination of unused name + side effect leads to: + // https://github.com/mishoo/UglifyJS2/issues/44 + // https://github.com/mishoo/UglifyJS2/issues/1830 + // https://github.com/mishoo/UglifyJS2/issues/1838 + // that's an invalid AST. + // We fix it at this stage by moving the `var` outside the `for`. + if (node instanceof AST_For) { + descend(node, this); + var block; + if (node.init instanceof AST_BlockStatement) { + block = node.init; + node.init = block.body.pop(); + block.body.push(node); + } + if (node.init instanceof AST_SimpleStatement) { + node.init = node.init.body; + } else if (is_empty(node.init)) { + node.init = null; + } + return !block ? node : in_list ? MAP.splice(block.body) : block; + } + if (node instanceof AST_LabeledStatement + && node.body instanceof AST_For + ) { + descend(node, this); + if (node.body instanceof AST_BlockStatement) { + var block = node.body; + node.body = block.body.pop(); + block.body.push(node); + return in_list ? MAP.splice(block.body) : block; + } + return node; + } + if (node instanceof AST_BlockStatement) { + descend(node, this); + if (in_list && node.body.every(can_be_evicted_from_block)) { + return MAP.splice(node.body); + } + return node; + } + if (node instanceof AST_Scope && !(node instanceof AST_ClassStaticBlock)) { + const save_scope = scope; + scope = node; + descend(node, this); + scope = save_scope; + return node; + } + }, + function after(node, in_list) { + if (node instanceof AST_Sequence) { + switch (node.expressions.length) { + case 0: return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 }); + case 1: return node.expressions[0]; + } + } + } + ); + + self.transform(tt); + + function scan_ref_scoped(node, descend) { + var node_def; + const sym = assign_as_unused(node); + if (sym instanceof AST_SymbolRef + && !is_ref_of(node.left, AST_SymbolBlockDeclaration) + && self.variables.get(sym.name) === (node_def = sym.definition()) + ) { + if (node instanceof AST_Assign) { + node.right.walk(tw); + if (!node_def.chained && node.left.fixed_value() === node.right) { + fixed_ids.set(node_def.id, node); + } + } + return true; + } + if (node instanceof AST_SymbolRef) { + node_def = node.definition(); + if (!in_use_ids.has(node_def.id)) { + in_use_ids.set(node_def.id, node_def); + if (node_def.orig[0] instanceof AST_SymbolCatch) { + const redef = node_def.scope.is_block_scope() + && node_def.scope.get_defun_scope().variables.get(node_def.name); + if (redef) in_use_ids.set(redef.id, redef); + } + } + return true; + } + if (node instanceof AST_Class) { + descend(); + return true; + } + if (node instanceof AST_Scope && !(node instanceof AST_ClassStaticBlock)) { + var save_scope = scope; + scope = node; + descend(); + scope = save_scope; + return true; + } + } +}); diff --git a/node_modules/terser/lib/compress/evaluate.js b/node_modules/terser/lib/compress/evaluate.js new file mode 100644 index 0000000..f658dff --- /dev/null +++ b/node_modules/terser/lib/compress/evaluate.js @@ -0,0 +1,521 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +import { + HOP, + makePredicate, + return_this, + string_template, + regexp_source_fix, + regexp_is_safe, +} from "../utils/index.js"; +import { + AST_Array, + AST_BigInt, + AST_Binary, + AST_Call, + AST_Chain, + AST_Class, + AST_Conditional, + AST_Constant, + AST_Dot, + AST_Expansion, + AST_Function, + AST_Lambda, + AST_New, + AST_Node, + AST_Object, + AST_PropAccess, + AST_RegExp, + AST_Statement, + AST_Symbol, + AST_SymbolRef, + AST_TemplateString, + AST_UnaryPrefix, + AST_With, +} from "../ast.js"; +import { is_undeclared_ref} from "./inference.js"; +import { is_pure_native_value, is_pure_native_fn, is_pure_native_method } from "./native-objects.js"; + +// methods to evaluate a constant expression + +function def_eval(node, func) { + node.DEFMETHOD("_eval", func); +} + +// Used to propagate a nullish short-circuit signal upwards through the chain. +export const nullish = Symbol("This AST_Chain is nullish"); + +// If the node has been successfully reduced to a constant, +// then its value is returned; otherwise the element itself +// is returned. +// They can be distinguished as constant value is never a +// descendant of AST_Node. +AST_Node.DEFMETHOD("evaluate", function (compressor) { + if (!compressor.option("evaluate")) + return this; + var val = this._eval(compressor, 1); + if (!val || val instanceof RegExp) + return val; + if (typeof val == "function" || typeof val == "object" || val == nullish) + return this; + + // Evaluated strings can be larger than the original expression + if (typeof val === "string") { + const unevaluated_size = this.size(compressor); + if (val.length + 2 > unevaluated_size) return this; + } + + return val; +}); + +var unaryPrefix = makePredicate("! ~ - + void"); +AST_Node.DEFMETHOD("is_constant", function () { + // Accomodate when compress option evaluate=false + // as well as the common constant expressions !0 and -1 + if (this instanceof AST_Constant) { + return !(this instanceof AST_RegExp); + } else { + return this instanceof AST_UnaryPrefix + && unaryPrefix.has(this.operator) + && ( + // `this.expression` may be an `AST_RegExp`, + // so not only `.is_constant()`. + this.expression instanceof AST_Constant + || this.expression.is_constant() + ); + } +}); + +def_eval(AST_Statement, function () { + throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start)); +}); + +def_eval(AST_Lambda, return_this); +def_eval(AST_Class, return_this); +def_eval(AST_Node, return_this); +def_eval(AST_Constant, function () { + return this.getValue(); +}); + +const supports_bigint = typeof BigInt === "function"; +def_eval(AST_BigInt, function () { + if (supports_bigint) { + return BigInt(this.value); + } else { + return this; + } +}); + +def_eval(AST_RegExp, function (compressor) { + let evaluated = compressor.evaluated_regexps.get(this.value); + if (evaluated === undefined && regexp_is_safe(this.value.source)) { + try { + const { source, flags } = this.value; + evaluated = new RegExp(source, flags); + } catch (e) { + evaluated = null; + } + compressor.evaluated_regexps.set(this.value, evaluated); + } + return evaluated || this; +}); + +def_eval(AST_TemplateString, function () { + if (this.segments.length !== 1) return this; + return this.segments[0].value; +}); + +def_eval(AST_Function, function (compressor) { + if (compressor.option("unsafe")) { + var fn = function () { }; + fn.node = this; + fn.toString = () => this.print_to_string(); + return fn; + } + return this; +}); + +def_eval(AST_Array, function (compressor, depth) { + if (compressor.option("unsafe")) { + var elements = []; + for (var i = 0, len = this.elements.length; i < len; i++) { + var element = this.elements[i]; + var value = element._eval(compressor, depth); + if (element === value) + return this; + elements.push(value); + } + return elements; + } + return this; +}); + +def_eval(AST_Object, function (compressor, depth) { + if (compressor.option("unsafe")) { + var val = {}; + for (var i = 0, len = this.properties.length; i < len; i++) { + var prop = this.properties[i]; + if (prop instanceof AST_Expansion) + return this; + var key = prop.key; + if (key instanceof AST_Symbol) { + key = key.name; + } else if (key instanceof AST_Node) { + key = key._eval(compressor, depth); + if (key === prop.key) + return this; + } + if (typeof Object.prototype[key] === "function") { + return this; + } + if (prop.value instanceof AST_Function) + continue; + val[key] = prop.value._eval(compressor, depth); + if (val[key] === prop.value) + return this; + } + return val; + } + return this; +}); + +var non_converting_unary = makePredicate("! typeof void"); +def_eval(AST_UnaryPrefix, function (compressor, depth) { + var e = this.expression; + if (compressor.option("typeofs") + && this.operator == "typeof") { + // Function would be evaluated to an array and so typeof would + // incorrectly return 'object'. Hence making is a special case. + if (e instanceof AST_Lambda + || e instanceof AST_SymbolRef + && e.fixed_value() instanceof AST_Lambda) { + return typeof function () { }; + } + if ( + (e instanceof AST_Object + || e instanceof AST_Array + || (e instanceof AST_SymbolRef + && (e.fixed_value() instanceof AST_Object + || e.fixed_value() instanceof AST_Array))) + && !e.has_side_effects(compressor) + ) { + return typeof {}; + } + } + if (!non_converting_unary.has(this.operator)) + depth++; + e = e._eval(compressor, depth); + if (e === this.expression) + return this; + switch (this.operator) { + case "!": return !e; + case "typeof": + // typeof returns "object" or "function" on different platforms + // so cannot evaluate reliably + if (e instanceof RegExp) + return this; + return typeof e; + case "void": return void e; + case "~": return ~e; + case "-": return -e; + case "+": return +e; + } + return this; +}); + +var non_converting_binary = makePredicate("&& || ?? === !=="); +const identity_comparison = makePredicate("== != === !=="); +const has_identity = value => typeof value === "object" + || typeof value === "function" + || typeof value === "symbol"; + +def_eval(AST_Binary, function (compressor, depth) { + if (!non_converting_binary.has(this.operator)) + depth++; + + var left = this.left._eval(compressor, depth); + if (left === this.left) + return this; + var right = this.right._eval(compressor, depth); + if (right === this.right) + return this; + + if (left != null + && right != null + && identity_comparison.has(this.operator) + && has_identity(left) + && has_identity(right) + && typeof left === typeof right) { + // Do not compare by reference + return this; + } + + // Do not mix BigInt and Number; Don't use `>>>` on BigInt or `/ 0n` + if ( + (typeof left === "bigint") !== (typeof right === "bigint") + || typeof left === "bigint" + && (this.operator === ">>>" + || this.operator === "/" && Number(right) === 0) + ) { + return this; + } + + var result; + switch (this.operator) { + case "&&": result = left && right; break; + case "||": result = left || right; break; + case "??": result = left != null ? left : right; break; + case "|": result = left | right; break; + case "&": result = left & right; break; + case "^": result = left ^ right; break; + case "+": result = left + right; break; + case "*": result = left * right; break; + case "**": result = left ** right; break; + case "/": result = left / right; break; + case "%": result = left % right; break; + case "-": result = left - right; break; + case "<<": result = left << right; break; + case ">>": result = left >> right; break; + case ">>>": result = left >>> right; break; + case "==": result = left == right; break; + case "===": result = left === right; break; + case "!=": result = left != right; break; + case "!==": result = left !== right; break; + case "<": result = left < right; break; + case "<=": result = left <= right; break; + case ">": result = left > right; break; + case ">=": result = left >= right; break; + default: + return this; + } + if (typeof result === "number" && isNaN(result) && compressor.find_parent(AST_With)) { + // leave original expression as is + return this; + } + return result; +}); + +def_eval(AST_Conditional, function (compressor, depth) { + var condition = this.condition._eval(compressor, depth); + if (condition === this.condition) + return this; + var node = condition ? this.consequent : this.alternative; + var value = node._eval(compressor, depth); + return value === node ? this : value; +}); + +// Set of AST_SymbolRef which are currently being evaluated. +// Avoids infinite recursion of ._eval() +const reentrant_ref_eval = new Set(); +def_eval(AST_SymbolRef, function (compressor, depth) { + if (reentrant_ref_eval.has(this)) + return this; + + var fixed = this.fixed_value(); + if (!fixed) + return this; + + reentrant_ref_eval.add(this); + const value = fixed._eval(compressor, depth); + reentrant_ref_eval.delete(this); + + if (value === fixed) + return this; + + if (value && typeof value == "object") { + var escaped = this.definition().escaped; + if (escaped && depth > escaped) + return this; + } + return value; +}); + +const global_objs = { Array, Math, Number, Object, String }; + +const regexp_flags = new Set([ + "dotAll", + "global", + "ignoreCase", + "multiline", + "sticky", + "unicode", +]); + +def_eval(AST_PropAccess, function (compressor, depth) { + let obj = this.expression._eval(compressor, depth + 1); + if (obj === nullish || (this.optional && obj == null)) return nullish; + + // `.length` of strings and arrays is always safe + if (this.property === "length") { + if (typeof obj === "string") { + return obj.length; + } + + const is_spreadless_array = + obj instanceof AST_Array + && obj.elements.every(el => !(el instanceof AST_Expansion)); + + if ( + is_spreadless_array + && obj.elements.every(el => !el.has_side_effects(compressor)) + ) { + return obj.elements.length; + } + } + + if (compressor.option("unsafe")) { + var key = this.property; + if (key instanceof AST_Node) { + key = key._eval(compressor, depth); + if (key === this.property) + return this; + } + + var exp = this.expression; + if (is_undeclared_ref(exp)) { + var aa; + var first_arg = exp.name === "hasOwnProperty" + && key === "call" + && (aa = compressor.parent() && compressor.parent().args) + && (aa && aa[0] + && aa[0].evaluate(compressor)); + + first_arg = first_arg instanceof AST_Dot ? first_arg.expression : first_arg; + + if (first_arg == null || first_arg.thedef && first_arg.thedef.undeclared) { + return this.clone(); + } + if (!is_pure_native_value(exp.name, key)) + return this; + obj = global_objs[exp.name]; + } else { + if (obj instanceof RegExp) { + if (key == "source") { + return regexp_source_fix(obj.source); + } else if (key == "flags" || regexp_flags.has(key)) { + return obj[key]; + } + } + if (!obj || obj === exp || !HOP(obj, key)) + return this; + + if (typeof obj == "function") + switch (key) { + case "name": + return obj.node.name ? obj.node.name.name : ""; + case "length": + return obj.node.length_property(); + default: + return this; + } + } + return obj[key]; + } + return this; +}); + +def_eval(AST_Chain, function (compressor, depth) { + const evaluated = this.expression._eval(compressor, depth); + return evaluated === nullish + ? undefined + : evaluated === this.expression + ? this + : evaluated; +}); + +def_eval(AST_Call, function (compressor, depth) { + var exp = this.expression; + + const callee = exp._eval(compressor, depth); + if (callee === nullish || (this.optional && callee == null)) return nullish; + + if (compressor.option("unsafe") && exp instanceof AST_PropAccess) { + var key = exp.property; + if (key instanceof AST_Node) { + key = key._eval(compressor, depth); + if (key === exp.property) + return this; + } + var val; + var e = exp.expression; + if (is_undeclared_ref(e)) { + var first_arg = e.name === "hasOwnProperty" && + key === "call" && + (this.args[0] && this.args[0].evaluate(compressor)); + + first_arg = first_arg instanceof AST_Dot ? first_arg.expression : first_arg; + + if ((first_arg == null || first_arg.thedef && first_arg.thedef.undeclared)) { + return this.clone(); + } + if (!is_pure_native_fn(e.name, key)) return this; + val = global_objs[e.name]; + } else { + val = e._eval(compressor, depth + 1); + if (val === e || !val) + return this; + if (!is_pure_native_method(val.constructor.name, key)) + return this; + } + var args = []; + for (var i = 0, len = this.args.length; i < len; i++) { + var arg = this.args[i]; + var value = arg._eval(compressor, depth); + if (arg === value) + return this; + if (arg instanceof AST_Lambda) + return this; + args.push(value); + } + try { + return val[key].apply(val, args); + } catch (ex) { + // We don't really care + } + } + return this; +}); + +// Also a subclass of AST_Call +def_eval(AST_New, return_this); diff --git a/node_modules/terser/lib/compress/global-defs.js b/node_modules/terser/lib/compress/global-defs.js new file mode 100644 index 0000000..e9eb7f5 --- /dev/null +++ b/node_modules/terser/lib/compress/global-defs.js @@ -0,0 +1,92 @@ +import { + AST_Array, + AST_Chain, + AST_Constant, + AST_Dot, + AST_ImportMeta, + AST_Node, + AST_Object, + AST_ObjectKeyVal, + AST_PropAccess, + AST_SymbolDeclaration, + AST_SymbolRef, + AST_Toplevel, + TreeTransformer, +} from "../ast.js"; +import { make_node, noop, HOP } from "../utils/index.js"; +import { make_node_from_constant } from "./common.js"; +import { is_lhs } from "./inference.js"; + +(function(def_find_defs) { + function to_node(value, orig) { + if (value instanceof AST_Node) { + if (!(value instanceof AST_Constant)) { + // Value may be a function, an array including functions and even a complex assign / block expression, + // so it should never be shared in different places. + // Otherwise wrong information may be used in the compression phase + value = value.clone(true); + } + return make_node(value.CTOR, orig, value); + } + if (Array.isArray(value)) return make_node(AST_Array, orig, { + elements: value.map(function(value) { + return to_node(value, orig); + }) + }); + if (value && typeof value == "object") { + var props = []; + for (var key in value) if (HOP(value, key)) { + props.push(make_node(AST_ObjectKeyVal, orig, { + key: key, + value: to_node(value[key], orig) + })); + } + return make_node(AST_Object, orig, { + properties: props + }); + } + return make_node_from_constant(value, orig); + } + + AST_Toplevel.DEFMETHOD("resolve_defines", function(compressor) { + if (!compressor.option("global_defs")) return this; + this.figure_out_scope({ ie8: compressor.option("ie8") }); + return this.transform(new TreeTransformer(function(node) { + var def = node._find_defs(compressor, ""); + if (!def) return; + var level = 0, child = node, parent; + while (parent = this.parent(level++)) { + if (!(parent instanceof AST_PropAccess)) break; + if (parent.expression !== child) break; + child = parent; + } + if (is_lhs(child, parent)) { + return; + } + return def; + })); + }); + def_find_defs(AST_Node, noop); + def_find_defs(AST_Chain, function(compressor, suffix) { + return this.expression._find_defs(compressor, suffix); + }); + def_find_defs(AST_Dot, function(compressor, suffix) { + return this.expression._find_defs(compressor, "." + this.property + suffix); + }); + def_find_defs(AST_SymbolDeclaration, function() { + if (!this.global()) return; + }); + def_find_defs(AST_SymbolRef, function(compressor, suffix) { + if (!this.global()) return; + var defines = compressor.option("global_defs"); + var name = this.name + suffix; + if (HOP(defines, name)) return to_node(defines[name], this); + }); + def_find_defs(AST_ImportMeta, function(compressor, suffix) { + var defines = compressor.option("global_defs"); + var name = "import.meta" + suffix; + if (HOP(defines, name)) return to_node(defines[name], this); + }); +})(function(node, func) { + node.DEFMETHOD("_find_defs", func); +}); diff --git a/node_modules/terser/lib/compress/index.js b/node_modules/terser/lib/compress/index.js new file mode 100644 index 0000000..ce7dc70 --- /dev/null +++ b/node_modules/terser/lib/compress/index.js @@ -0,0 +1,4115 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +import { + AST_Accessor, + AST_Array, + AST_Arrow, + AST_Assign, + AST_BigInt, + AST_Binary, + AST_Block, + AST_BlockStatement, + AST_Boolean, + AST_Break, + AST_Call, + AST_Catch, + AST_Chain, + AST_Class, + AST_ClassProperty, + AST_ClassStaticBlock, + AST_ConciseMethod, + AST_Conditional, + AST_Const, + AST_Constant, + AST_Debugger, + AST_Default, + AST_DefaultAssign, + AST_Definitions, + AST_Defun, + AST_Destructuring, + AST_Directive, + AST_Do, + AST_Dot, + AST_DotHash, + AST_DWLoop, + AST_EmptyStatement, + AST_Exit, + AST_Expansion, + AST_Export, + AST_False, + AST_For, + AST_ForIn, + AST_Function, + AST_Hole, + AST_If, + AST_Import, + AST_Infinity, + AST_LabeledStatement, + AST_Lambda, + AST_Let, + AST_NaN, + AST_New, + AST_Node, + AST_Null, + AST_Number, + AST_Object, + AST_ObjectKeyVal, + AST_ObjectProperty, + AST_PrefixedTemplateString, + AST_PropAccess, + AST_RegExp, + AST_Return, + AST_Scope, + AST_Sequence, + AST_SimpleStatement, + AST_Statement, + AST_String, + AST_Sub, + AST_Switch, + AST_SwitchBranch, + AST_Symbol, + AST_SymbolClassProperty, + AST_SymbolDeclaration, + AST_SymbolDefun, + AST_SymbolExport, + AST_SymbolFunarg, + AST_SymbolLambda, + AST_SymbolLet, + AST_SymbolMethod, + AST_SymbolRef, + AST_SymbolUsing, + AST_TemplateString, + AST_This, + AST_Toplevel, + AST_True, + AST_Try, + AST_Unary, + AST_UnaryPostfix, + AST_UnaryPrefix, + AST_Undefined, + AST_Using, + AST_Var, + AST_VarDef, + AST_While, + AST_With, + AST_Yield, + + TreeTransformer, + TreeWalker, + walk, + walk_abort, + + _NOINLINE, +} from "../ast.js"; +import { + defaults, + HOP, + make_node, + makePredicate, + MAP, + remove, + return_false, + return_true, + regexp_source_fix, + has_annotation, + regexp_is_safe, +} from "../utils/index.js"; +import { first_in_statement } from "../utils/first_in_statement.js"; +import { equivalent_to } from "../equivalent-to.js"; +import { + is_basic_identifier_string, + JS_Parse_Error, + parse, + PRECEDENCE, +} from "../parse.js"; +import { OutputStream } from "../output.js"; +import { base54, format_mangler_options } from "../scope.js"; +import "../size.js"; + +import "./evaluate.js"; +import "./drop-side-effect-free.js"; +import "./drop-unused.js"; +import "./reduce-vars.js"; +import { + is_undeclared_ref, + bitwise_binop, + lazy_op, + is_nullish, + is_undefined, + is_lhs, + aborts, + is_used_in_expression, +} from "./inference.js"; +import { + SQUEEZED, + OPTIMIZED, + CLEAR_BETWEEN_PASSES, + TOP, + UNDEFINED, + UNUSED, + TRUTHY, + FALSY, + has_flag, + set_flag, + clear_flag, +} from "./compressor-flags.js"; +import { + make_sequence, + best_of, + best_of_expression, + make_empty_function, + make_node_from_constant, + merge_sequence, + get_simple_key, + has_break_or_continue, + maintain_this_binding, + is_empty, + is_identifier_atom, + is_reachable, + can_be_evicted_from_block, + as_statement_array, + is_func_expr, +} from "./common.js"; +import { tighten_body, trim_unreachable_code } from "./tighten-body.js"; +import { inline_into_symbolref, inline_into_call } from "./inline.js"; +import "./global-defs.js"; + +class Compressor extends TreeWalker { + constructor(options, { false_by_default = false, mangle_options = false }) { + super(); + if (options.defaults !== undefined && !options.defaults) false_by_default = true; + this.options = defaults(options, { + arguments : false, + arrows : !false_by_default, + booleans : !false_by_default, + booleans_as_integers : false, + collapse_vars : !false_by_default, + comparisons : !false_by_default, + computed_props: !false_by_default, + conditionals : !false_by_default, + dead_code : !false_by_default, + defaults : true, + directives : !false_by_default, + drop_console : false, + drop_debugger : !false_by_default, + ecma : 5, + evaluate : !false_by_default, + expression : false, + global_defs : false, + hoist_funs : false, + hoist_props : !false_by_default, + hoist_vars : false, + ie8 : false, + if_return : !false_by_default, + inline : !false_by_default, + join_vars : !false_by_default, + keep_classnames: false, + keep_fargs : true, + keep_fnames : false, + keep_infinity : false, + lhs_constants : !false_by_default, + loops : !false_by_default, + module : false, + negate_iife : !false_by_default, + passes : 1, + properties : !false_by_default, + pure_getters : !false_by_default && "strict", + pure_funcs : null, + pure_new : false, + reduce_funcs : !false_by_default, + reduce_vars : !false_by_default, + sequences : !false_by_default, + side_effects : !false_by_default, + switches : !false_by_default, + top_retain : null, + toplevel : !!(options && options["top_retain"]), + typeofs : !false_by_default, + unsafe : false, + unsafe_arrows : false, + unsafe_comps : false, + unsafe_Function: false, + unsafe_math : false, + unsafe_symbols: false, + unsafe_methods: false, + unsafe_proto : false, + unsafe_regexp : false, + unsafe_undefined: false, + unused : !false_by_default, + warnings : false // legacy + }, true); + var global_defs = this.options["global_defs"]; + if (typeof global_defs == "object") for (var key in global_defs) { + if (key[0] === "@" && HOP(global_defs, key)) { + global_defs[key.slice(1)] = parse(global_defs[key], { + expression: true + }); + } + } + if (this.options["inline"] === true) this.options["inline"] = 3; + var pure_funcs = this.options["pure_funcs"]; + if (typeof pure_funcs == "function") { + this.pure_funcs = pure_funcs; + } else { + this.pure_funcs = pure_funcs ? function(node) { + return !pure_funcs.includes(node.expression.print_to_string()); + } : return_true; + } + var top_retain = this.options["top_retain"]; + if (top_retain instanceof RegExp) { + this.top_retain = function(def) { + return top_retain.test(def.name); + }; + } else if (typeof top_retain == "function") { + this.top_retain = top_retain; + } else if (top_retain) { + if (typeof top_retain == "string") { + top_retain = top_retain.split(/,/); + } + this.top_retain = function(def) { + return top_retain.includes(def.name); + }; + } + if (this.options["module"]) { + this.directives["use strict"] = true; + this.options["toplevel"] = true; + } + var toplevel = this.options["toplevel"]; + this.toplevel = typeof toplevel == "string" ? { + funcs: /funcs/.test(toplevel), + vars: /vars/.test(toplevel) + } : { + funcs: toplevel, + vars: toplevel + }; + var sequences = this.options["sequences"]; + this.sequences_limit = sequences == 1 ? 800 : sequences | 0; + this.evaluated_regexps = new Map(); + this._toplevel = undefined; + this._mangle_options = mangle_options + ? format_mangler_options(mangle_options) + : mangle_options; + } + + mangle_options() { + var nth_identifier = this._mangle_options && this._mangle_options.nth_identifier || base54; + var module = this._mangle_options && this._mangle_options.module || this.option("module"); + return { ie8: this.option("ie8"), nth_identifier, module }; + } + + option(key) { + return this.options[key]; + } + + exposed(def) { + if (def.export) return true; + if (def.global) for (var i = 0, len = def.orig.length; i < len; i++) + if (!this.toplevel[def.orig[i] instanceof AST_SymbolDefun ? "funcs" : "vars"]) + return true; + return false; + } + + in_boolean_context() { + if (!this.option("booleans")) return false; + var self = this.self(); + for (var i = 0, p; p = this.parent(i); i++) { + if (p instanceof AST_SimpleStatement + || p instanceof AST_Conditional && p.condition === self + || p instanceof AST_DWLoop && p.condition === self + || p instanceof AST_For && p.condition === self + || p instanceof AST_If && p.condition === self + || p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self) { + return true; + } + if ( + p instanceof AST_Binary + && ( + p.operator == "&&" + || p.operator == "||" + || p.operator == "??" + ) + || p instanceof AST_Conditional + || p.tail_node() === self + ) { + self = p; + } else { + return false; + } + } + } + + in_32_bit_context(other_operand_must_be_number) { + if (!this.option("evaluate")) return false; + var self = this.self(); + for (var i = 0, p; p = this.parent(i); i++) { + if (p instanceof AST_Binary && bitwise_binop.has(p.operator)) { + if (other_operand_must_be_number) { + return (self === p.left ? p.right : p.left).is_number(this); + } else { + return true; + } + } + if (p instanceof AST_UnaryPrefix) { + return p.operator === "~"; + } + if ( + p instanceof AST_Binary + && ( + p.operator == "&&" + || p.operator == "||" + || p.operator == "??" + ) + || p instanceof AST_Conditional && p.condition !== self + || p.tail_node() === self + ) { + self = p; + } else { + return false; + } + } + } + + in_computed_key() { + if (!this.option("evaluate")) return false; + var self = this.self(); + for (var i = 0, p; p = this.parent(i); i++) { + if (p instanceof AST_ObjectProperty && p.key === self) { + return true; + } + } + return false; + } + + get_toplevel() { + return this._toplevel; + } + + compress(toplevel) { + toplevel = toplevel.resolve_defines(this); + this._toplevel = toplevel; + if (this.option("expression")) { + this._toplevel.process_expression(true); + } + var passes = +this.options.passes || 1; + var min_count = 1 / 0; + var stopping = false; + var mangle = this.mangle_options(); + for (var pass = 0; pass < passes; pass++) { + this._toplevel.figure_out_scope(mangle); + if (pass === 0 && this.option("drop_console")) { + // must be run before reduce_vars and compress pass + this._toplevel = this._toplevel.drop_console(this.option("drop_console")); + } + if (pass > 0 || this.option("reduce_vars")) { + this._toplevel.reset_opt_flags(this); + } + this._toplevel = this._toplevel.transform(this); + if (passes > 1) { + let count = 0; + walk(this._toplevel, () => { count++; }); + if (count < min_count) { + min_count = count; + stopping = false; + } else if (stopping) { + break; + } else { + stopping = true; + } + } + } + if (this.option("expression")) { + this._toplevel.process_expression(false); + } + toplevel = this._toplevel; + this._toplevel = undefined; + return toplevel; + } + + before(node, descend) { + if (has_flag(node, SQUEEZED)) return node; + var was_scope = false; + if (node instanceof AST_Scope) { + node = node.hoist_properties(this); + node = node.hoist_declarations(this); + was_scope = true; + } + // Before https://github.com/mishoo/UglifyJS2/pull/1602 AST_Node.optimize() + // would call AST_Node.transform() if a different instance of AST_Node is + // produced after def_optimize(). + // This corrupts TreeWalker.stack, which cause AST look-ups to malfunction. + // Migrate and defer all children's AST_Node.transform() to below, which + // will now happen after this parent AST_Node has been properly substituted + // thus gives a consistent AST snapshot. + descend(node, this); + // Existing code relies on how AST_Node.optimize() worked, and omitting the + // following replacement call would result in degraded efficiency of both + // output and performance. + descend(node, this); + var opt = node.optimize(this); + if (was_scope && opt instanceof AST_Scope) { + opt.drop_unused(this); + descend(opt, this); + } + if (opt === node) set_flag(opt, SQUEEZED); + return opt; + } + + /** Alternative to plain is_lhs() which doesn't work within .optimize() */ + is_lhs() { + const self = this.stack[this.stack.length - 1]; + const parent = this.stack[this.stack.length - 2]; + return is_lhs(self, parent); + } +} + + +function def_optimize(node, optimizer) { + node.DEFMETHOD("optimize", function(compressor) { + var self = this; + if (has_flag(self, OPTIMIZED)) return self; + if (compressor.has_directive("use asm")) return self; + var opt = optimizer(self, compressor); + set_flag(opt, OPTIMIZED); + return opt; + }); +} + +def_optimize(AST_Node, function(self) { + return self; +}); + +AST_Toplevel.DEFMETHOD("drop_console", function(options) { + const isArray = Array.isArray(options); + const tt = new TreeTransformer(function(self) { + if (self.TYPE !== "Call") { + return; + } + + var exp = self.expression; + + if (!(exp instanceof AST_PropAccess)) { + return; + } + + var name = exp.expression; + var property = exp.property; + var depth = 2; + while (name.expression) { + property = name.property; + name = name.expression; + depth++; + } + + if (isArray && !options.includes(property)) { + return; + } + + if (is_undeclared_ref(name) && name.name == "console") { + if ( + depth === 3 + && !["call", "apply"].includes(exp.property) + && is_used_in_expression(tt) + ) { + // a (used) call to Function.prototype methods (eg: console.log.bind(console)) + // but not .call and .apply which would also return undefined. + exp.expression = make_empty_function(self); + set_flag(exp.expression, SQUEEZED); + self.args = []; + } else { + return make_node(AST_Undefined, self); + } + } + }); + + return this.transform(tt); +}); + +AST_Node.DEFMETHOD("equivalent_to", function(node) { + return equivalent_to(this, node); +}); + +AST_Scope.DEFMETHOD("process_expression", function(insert, compressor) { + var self = this; + var tt = new TreeTransformer(function(node) { + if (insert && node instanceof AST_SimpleStatement) { + return make_node(AST_Return, node, { + value: node.body + }); + } + if (!insert && node instanceof AST_Return) { + if (compressor) { + var value = node.value && node.value.drop_side_effect_free(compressor, true); + return value + ? make_node(AST_SimpleStatement, node, { body: value }) + : make_node(AST_EmptyStatement, node); + } + return make_node(AST_SimpleStatement, node, { + body: node.value || make_node(AST_UnaryPrefix, node, { + operator: "void", + expression: make_node(AST_Number, node, { + value: 0 + }) + }) + }); + } + if (node instanceof AST_Class || node instanceof AST_Lambda && node !== self) { + return node; + } + if (node instanceof AST_Block) { + var index = node.body.length - 1; + if (index >= 0) { + node.body[index] = node.body[index].transform(tt); + } + } else if (node instanceof AST_If) { + node.body = node.body.transform(tt); + if (node.alternative) { + node.alternative = node.alternative.transform(tt); + } + } else if (node instanceof AST_With) { + node.body = node.body.transform(tt); + } + return node; + }); + self.transform(tt); +}); + +AST_Toplevel.DEFMETHOD("reset_opt_flags", function(compressor) { + const self = this; + const reduce_vars = compressor.option("reduce_vars"); + + const preparation = new TreeWalker(function(node, descend) { + clear_flag(node, CLEAR_BETWEEN_PASSES); + if (reduce_vars) { + if (compressor.top_retain + && node instanceof AST_Defun // Only functions are retained + && preparation.parent() === self + ) { + set_flag(node, TOP); + } + return node.reduce_vars(preparation, descend, compressor); + } + }); + // Stack of look-up tables to keep track of whether a `SymbolDef` has been + // properly assigned before use: + // - `push()` & `pop()` when visiting conditional branches + preparation.safe_ids = Object.create(null); + preparation.in_loop = null; + preparation.loop_ids = new Map(); + preparation.defs_to_safe_ids = new Map(); + self.walk(preparation); +}); + +AST_Symbol.DEFMETHOD("fixed_value", function() { + var fixed = this.thedef.fixed; + if (!fixed || fixed instanceof AST_Node) return fixed; + return fixed(); +}); + +AST_SymbolRef.DEFMETHOD("is_immutable", function() { + var orig = this.definition().orig; + return orig.length == 1 && orig[0] instanceof AST_SymbolLambda; +}); + +function find_variable(compressor, name) { + var scope, i = 0; + while (scope = compressor.parent(i++)) { + if (scope instanceof AST_Scope) break; + if (scope instanceof AST_Catch && scope.argname) { + scope = scope.argname.definition().scope; + break; + } + } + return scope.find_variable(name); +} + +var global_names = makePredicate("Array Boolean clearInterval clearTimeout console Date decodeURI decodeURIComponent encodeURI encodeURIComponent Error escape eval EvalError Function isFinite isNaN JSON Math Number parseFloat parseInt RangeError ReferenceError RegExp Object setInterval setTimeout String SyntaxError TypeError unescape URIError"); +AST_SymbolRef.DEFMETHOD("is_declared", function(compressor) { + return !this.definition().undeclared + || compressor.option("unsafe") && global_names.has(this.name); +}); + +/* -----[ optimizers ]----- */ + +var directives = new Set(["use asm", "use strict"]); +def_optimize(AST_Directive, function(self, compressor) { + if (compressor.option("directives") + && (!directives.has(self.value) || compressor.has_directive(self.value) !== self)) { + return make_node(AST_EmptyStatement, self); + } + return self; +}); + +def_optimize(AST_Debugger, function(self, compressor) { + if (compressor.option("drop_debugger")) + return make_node(AST_EmptyStatement, self); + return self; +}); + +def_optimize(AST_LabeledStatement, function(self, compressor) { + if (self.body instanceof AST_Break + && compressor.loopcontrol_target(self.body) === self.body) { + return make_node(AST_EmptyStatement, self); + } + return self.label.references.length == 0 ? self.body : self; +}); + +def_optimize(AST_Block, function(self, compressor) { + tighten_body(self.body, compressor); + return self; +}); + +function can_be_extracted_from_if_block(node) { + return !( + node instanceof AST_Const + || node instanceof AST_Let + || node instanceof AST_Using + || node instanceof AST_Class + ); +} + +def_optimize(AST_BlockStatement, function(self, compressor) { + tighten_body(self.body, compressor); + switch (self.body.length) { + case 1: + if (!compressor.has_directive("use strict") + && compressor.parent() instanceof AST_If + && can_be_extracted_from_if_block(self.body[0]) + || can_be_evicted_from_block(self.body[0])) { + return self.body[0]; + } + break; + case 0: return make_node(AST_EmptyStatement, self); + } + return self; +}); + +function opt_AST_Lambda(self, compressor) { + tighten_body(self.body, compressor); + if (compressor.option("side_effects") + && self.body.length == 1 + && self.body[0] === compressor.has_directive("use strict")) { + self.body.length = 0; + } + return self; +} +def_optimize(AST_Lambda, opt_AST_Lambda); + +AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) { + var self = this; + if (compressor.has_directive("use asm")) return self; + + var hoist_funs = compressor.option("hoist_funs"); + var hoist_vars = compressor.option("hoist_vars"); + + if (hoist_funs || hoist_vars) { + var dirs = []; + var hoisted = []; + var vars = new Map(), vars_found = 0, var_decl = 0; + // let's count var_decl first, we seem to waste a lot of + // space if we hoist `var` when there's only one. + walk(self, node => { + if (node instanceof AST_Scope && node !== self) + return true; + if (node instanceof AST_Var) { + ++var_decl; + return true; + } + }); + hoist_vars = hoist_vars && var_decl > 1; + var tt = new TreeTransformer( + function before(node) { + if (node !== self) { + if (node instanceof AST_Directive) { + dirs.push(node); + return make_node(AST_EmptyStatement, node); + } + if (hoist_funs && node instanceof AST_Defun + && !(tt.parent() instanceof AST_Export) + && tt.parent() === self) { + hoisted.push(node); + return make_node(AST_EmptyStatement, node); + } + if ( + hoist_vars + && node instanceof AST_Var + && !node.definitions.some(def => def.name instanceof AST_Destructuring) + ) { + node.definitions.forEach(function(def) { + vars.set(def.name.name, def); + ++vars_found; + }); + var seq = node.to_assignments(compressor); + var p = tt.parent(); + if (p instanceof AST_ForIn && p.init === node) { + if (seq == null) { + var def = node.definitions[0].name; + return make_node(AST_SymbolRef, def, def); + } + return seq; + } + if (p instanceof AST_For && p.init === node) { + return seq; + } + if (!seq) return make_node(AST_EmptyStatement, node); + return make_node(AST_SimpleStatement, node, { + body: seq + }); + } + if (node instanceof AST_Scope) + return node; // to avoid descending in nested scopes + } + } + ); + self = self.transform(tt); + if (vars_found > 0) { + // collect only vars which don't show up in self's arguments list + var defs = []; + const is_lambda = self instanceof AST_Lambda; + const args_as_names = is_lambda ? self.args_as_names() : null; + vars.forEach((def, name) => { + if (is_lambda && args_as_names.some((x) => x.name === def.name.name)) { + vars.delete(name); + } else { + def = def.clone(); + def.value = null; + defs.push(def); + vars.set(name, def); + } + }); + if (defs.length > 0) { + // try to merge in assignments + for (var i = 0; i < self.body.length;) { + if (self.body[i] instanceof AST_SimpleStatement) { + var expr = self.body[i].body, sym, assign; + if (expr instanceof AST_Assign + && expr.operator == "=" + && (sym = expr.left) instanceof AST_Symbol + && vars.has(sym.name) + ) { + var def = vars.get(sym.name); + if (def.value) break; + def.value = expr.right; + remove(defs, def); + defs.push(def); + self.body.splice(i, 1); + continue; + } + if (expr instanceof AST_Sequence + && (assign = expr.expressions[0]) instanceof AST_Assign + && assign.operator == "=" + && (sym = assign.left) instanceof AST_Symbol + && vars.has(sym.name) + ) { + var def = vars.get(sym.name); + if (def.value) break; + def.value = assign.right; + remove(defs, def); + defs.push(def); + self.body[i].body = make_sequence(expr, expr.expressions.slice(1)); + continue; + } + } + if (self.body[i] instanceof AST_EmptyStatement) { + self.body.splice(i, 1); + continue; + } + if (self.body[i] instanceof AST_BlockStatement) { + self.body.splice(i, 1, ...self.body[i].body); + continue; + } + break; + } + defs = make_node(AST_Var, self, { + definitions: defs + }); + hoisted.push(defs); + } + } + self.body = dirs.concat(hoisted, self.body); + } + return self; +}); + +AST_Scope.DEFMETHOD("hoist_properties", function(compressor) { + var self = this; + if (!compressor.option("hoist_props") || compressor.has_directive("use asm")) return self; + var top_retain = self instanceof AST_Toplevel && compressor.top_retain || return_false; + var defs_by_id = new Map(); + var hoister = new TreeTransformer(function(node, descend) { + if (node instanceof AST_VarDef) { + const sym = node.name; + let def; + let value; + if (sym.scope === self + && !(sym instanceof AST_SymbolUsing) + && (def = sym.definition()).escaped != 1 + && !def.assignments + && !def.direct_access + && !def.single_use + && !compressor.exposed(def) + && !top_retain(def) + && (value = sym.fixed_value()) === node.value + && value instanceof AST_Object + && !value.properties.some(prop => + prop instanceof AST_Expansion || prop.computed_key() + ) + ) { + descend(node, this); + const defs = new Map(); + const assignments = []; + value.properties.forEach(({ key, value }) => { + const scope = hoister.find_scope(); + const symbol = self.create_symbol(sym.CTOR, { + source: sym, + scope, + conflict_scopes: new Set([ + scope, + ...sym.definition().references.map(ref => ref.scope) + ]), + tentative_name: sym.name + "_" + key + }); + + defs.set(String(key), symbol.definition()); + + assignments.push(make_node(AST_VarDef, node, { + name: symbol, + value + })); + }); + defs_by_id.set(def.id, defs); + return MAP.splice(assignments); + } + } else if (node instanceof AST_PropAccess + && node.expression instanceof AST_SymbolRef + ) { + const defs = defs_by_id.get(node.expression.definition().id); + if (defs) { + const def = defs.get(String(get_simple_key(node.property))); + const sym = make_node(AST_SymbolRef, node, { + name: def.name, + scope: node.expression.scope, + thedef: def + }); + sym.reference({}); + return sym; + } + } + }); + return self.transform(hoister); +}); + +def_optimize(AST_SimpleStatement, function(self, compressor) { + if (compressor.option("side_effects")) { + var body = self.body; + var node = body.drop_side_effect_free(compressor, true); + if (!node) { + return make_node(AST_EmptyStatement, self); + } + if (node !== body) { + return make_node(AST_SimpleStatement, self, { body: node }); + } + } + return self; +}); + +def_optimize(AST_While, function(self, compressor) { + return compressor.option("loops") ? make_node(AST_For, self, self).optimize(compressor) : self; +}); + +def_optimize(AST_Do, function(self, compressor) { + if (!compressor.option("loops")) return self; + var cond = self.condition.tail_node().evaluate(compressor); + if (!(cond instanceof AST_Node)) { + if (cond) return make_node(AST_For, self, { + body: make_node(AST_BlockStatement, self.body, { + body: [ + self.body, + make_node(AST_SimpleStatement, self.condition, { + body: self.condition + }) + ] + }) + }).optimize(compressor); + if (!has_break_or_continue(self, compressor.parent())) { + return make_node(AST_BlockStatement, self.body, { + body: [ + self.body, + make_node(AST_SimpleStatement, self.condition, { + body: self.condition + }) + ] + }).optimize(compressor); + } + } + return self; +}); + +function if_break_in_loop(self, compressor) { + var first = self.body instanceof AST_BlockStatement ? self.body.body[0] : self.body; + if (compressor.option("dead_code") && is_break(first)) { + var body = []; + if (self.init instanceof AST_Statement) { + body.push(self.init); + } else if (self.init) { + body.push(make_node(AST_SimpleStatement, self.init, { + body: self.init + })); + } + if (self.condition) { + body.push(make_node(AST_SimpleStatement, self.condition, { + body: self.condition + })); + } + trim_unreachable_code(compressor, self.body, body); + return make_node(AST_BlockStatement, self, { + body: body + }); + } + if (first instanceof AST_If) { + if (is_break(first.body)) { + if (self.condition) { + self.condition = make_node(AST_Binary, self.condition, { + left: self.condition, + operator: "&&", + right: first.condition.negate(compressor), + }); + } else { + self.condition = first.condition.negate(compressor); + } + drop_it(first.alternative); + } else if (is_break(first.alternative)) { + if (self.condition) { + self.condition = make_node(AST_Binary, self.condition, { + left: self.condition, + operator: "&&", + right: first.condition, + }); + } else { + self.condition = first.condition; + } + drop_it(first.body); + } + } + return self; + + function is_break(node) { + return node instanceof AST_Break + && compressor.loopcontrol_target(node) === compressor.self(); + } + + function drop_it(rest) { + rest = as_statement_array(rest); + if (self.body instanceof AST_BlockStatement) { + self.body = self.body.clone(); + self.body.body = rest.concat(self.body.body.slice(1)); + self.body = self.body.transform(compressor); + } else { + self.body = make_node(AST_BlockStatement, self.body, { + body: rest + }).transform(compressor); + } + self = if_break_in_loop(self, compressor); + } +} + +def_optimize(AST_For, function(self, compressor) { + if (!compressor.option("loops")) return self; + if (compressor.option("side_effects") && self.init) { + self.init = self.init.drop_side_effect_free(compressor); + } + if (self.condition) { + var cond = self.condition.evaluate(compressor); + if (!(cond instanceof AST_Node)) { + if (cond) self.condition = null; + else if (!compressor.option("dead_code")) { + var orig = self.condition; + self.condition = make_node_from_constant(cond, self.condition); + self.condition = best_of_expression(self.condition.transform(compressor), orig); + } + } + if (compressor.option("dead_code")) { + if (cond instanceof AST_Node) cond = self.condition.tail_node().evaluate(compressor); + if (!cond) { + var body = []; + trim_unreachable_code(compressor, self.body, body); + if (self.init instanceof AST_Statement) { + body.push(self.init); + } else if (self.init) { + body.push(make_node(AST_SimpleStatement, self.init, { + body: self.init + })); + } + body.push(make_node(AST_SimpleStatement, self.condition, { + body: self.condition + })); + return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); + } + } + } + return if_break_in_loop(self, compressor); +}); + +def_optimize(AST_If, function(self, compressor) { + if (is_empty(self.alternative)) self.alternative = null; + + if (!compressor.option("conditionals")) return self; + // if condition can be statically determined, drop + // one of the blocks. note, statically determined implies + // “has no side effects”; also it doesn't work for cases like + // `x && true`, though it probably should. + var cond = self.condition.evaluate(compressor); + if (!compressor.option("dead_code") && !(cond instanceof AST_Node)) { + var orig = self.condition; + self.condition = make_node_from_constant(cond, orig); + self.condition = best_of_expression(self.condition.transform(compressor), orig); + } + if (compressor.option("dead_code")) { + if (cond instanceof AST_Node) cond = self.condition.tail_node().evaluate(compressor); + if (!cond) { + var body = []; + trim_unreachable_code(compressor, self.body, body); + body.push(make_node(AST_SimpleStatement, self.condition, { + body: self.condition + })); + if (self.alternative) body.push(self.alternative); + return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); + } else if (!(cond instanceof AST_Node)) { + var body = []; + body.push(make_node(AST_SimpleStatement, self.condition, { + body: self.condition + })); + body.push(self.body); + if (self.alternative) { + trim_unreachable_code(compressor, self.alternative, body); + } + return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); + } + } + var negated = self.condition.negate(compressor); + var self_condition_length = self.condition.size(); + var negated_length = negated.size(); + var negated_is_best = negated_length < self_condition_length; + if (self.alternative && negated_is_best) { + negated_is_best = false; // because we already do the switch here. + // no need to swap values of self_condition_length and negated_length + // here because they are only used in an equality comparison later on. + self.condition = negated; + var tmp = self.body; + self.body = self.alternative || make_node(AST_EmptyStatement, self); + self.alternative = tmp; + } + if (is_empty(self.body) && is_empty(self.alternative)) { + return make_node(AST_SimpleStatement, self.condition, { + body: self.condition.clone() + }).optimize(compressor); + } + if (self.body instanceof AST_SimpleStatement + && self.alternative instanceof AST_SimpleStatement) { + return make_node(AST_SimpleStatement, self, { + body: make_node(AST_Conditional, self, { + condition : self.condition, + consequent : self.body.body, + alternative : self.alternative.body + }) + }).optimize(compressor); + } + if (is_empty(self.alternative) && self.body instanceof AST_SimpleStatement) { + if (self_condition_length === negated_length && !negated_is_best + && self.condition instanceof AST_Binary && self.condition.operator == "||") { + // although the code length of self.condition and negated are the same, + // negated does not require additional surrounding parentheses. + // see https://github.com/mishoo/UglifyJS2/issues/979 + negated_is_best = true; + } + if (negated_is_best) return make_node(AST_SimpleStatement, self, { + body: make_node(AST_Binary, self, { + operator : "||", + left : negated, + right : self.body.body + }) + }).optimize(compressor); + return make_node(AST_SimpleStatement, self, { + body: make_node(AST_Binary, self, { + operator : "&&", + left : self.condition, + right : self.body.body + }) + }).optimize(compressor); + } + if (self.body instanceof AST_EmptyStatement + && self.alternative instanceof AST_SimpleStatement) { + return make_node(AST_SimpleStatement, self, { + body: make_node(AST_Binary, self, { + operator : "||", + left : self.condition, + right : self.alternative.body + }) + }).optimize(compressor); + } + if (self.body instanceof AST_Exit + && self.alternative instanceof AST_Exit + && self.body.TYPE == self.alternative.TYPE) { + return make_node(self.body.CTOR, self, { + value: make_node(AST_Conditional, self, { + condition : self.condition, + consequent : self.body.value || make_node(AST_Undefined, self.body), + alternative : self.alternative.value || make_node(AST_Undefined, self.alternative) + }).transform(compressor) + }).optimize(compressor); + } + if (self.body instanceof AST_If + && !self.body.alternative + && !self.alternative) { + self = make_node(AST_If, self, { + condition: make_node(AST_Binary, self.condition, { + operator: "&&", + left: self.condition, + right: self.body.condition + }), + body: self.body.body, + alternative: null + }); + } + if (aborts(self.body)) { + if (self.alternative) { + var alt = self.alternative; + self.alternative = null; + return make_node(AST_BlockStatement, self, { + body: [ self, alt ] + }).optimize(compressor); + } + } + if (aborts(self.alternative)) { + var body = self.body; + self.body = self.alternative; + self.condition = negated_is_best ? negated : self.condition.negate(compressor); + self.alternative = null; + return make_node(AST_BlockStatement, self, { + body: [ self, body ] + }).optimize(compressor); + } + return self; +}); + +def_optimize(AST_Switch, function(self, compressor) { + if (!compressor.option("switches")) return self; + var branch; + var value = self.expression.evaluate(compressor); + if (!(value instanceof AST_Node)) { + var orig = self.expression; + self.expression = make_node_from_constant(value, orig); + self.expression = best_of_expression(self.expression.transform(compressor), orig); + } + if (!compressor.option("dead_code")) return self; + if (value instanceof AST_Node) { + value = self.expression.tail_node().evaluate(compressor); + } + var decl = []; + var body = []; + var default_branch; + var exact_match; + for (var i = 0, len = self.body.length; i < len && !exact_match; i++) { + branch = self.body[i]; + if (branch instanceof AST_Default) { + if (!default_branch) { + default_branch = branch; + } else { + eliminate_branch(branch, body[body.length - 1]); + } + } else if (!(value instanceof AST_Node)) { + var exp = branch.expression.evaluate(compressor); + if (!(exp instanceof AST_Node) && exp !== value) { + eliminate_branch(branch, body[body.length - 1]); + continue; + } + if (exp instanceof AST_Node && !exp.has_side_effects(compressor)) { + exp = branch.expression.tail_node().evaluate(compressor); + } + if (exp === value) { + exact_match = branch; + if (default_branch) { + var default_index = body.indexOf(default_branch); + body.splice(default_index, 1); + eliminate_branch(default_branch, body[default_index - 1]); + default_branch = null; + } + } + } + body.push(branch); + } + while (i < len) eliminate_branch(self.body[i++], body[body.length - 1]); + self.body = body; + + let default_or_exact = default_branch || exact_match; + default_branch = null; + exact_match = null; + + // group equivalent branches so they will be located next to each other, + // that way the next micro-optimization will merge them. + // ** bail micro-optimization if not a simple switch case with breaks + if (body.every((branch, i) => + (branch === default_or_exact || branch.expression instanceof AST_Constant) + && (branch.body.length === 0 || aborts(branch) || body.length - 1 === i)) + ) { + for (let i = 0; i < body.length; i++) { + const branch = body[i]; + for (let j = i + 1; j < body.length; j++) { + const next = body[j]; + if (next.body.length === 0) continue; + const last_branch = j === (body.length - 1); + const equivalentBranch = branches_equivalent(next, branch, false); + if (equivalentBranch || (last_branch && branches_equivalent(next, branch, true))) { + if (!equivalentBranch && last_branch) { + next.body.push(make_node(AST_Break)); + } + + // let's find previous siblings with inert fallthrough... + let x = j - 1; + let fallthroughDepth = 0; + while (x > i) { + if (is_inert_body(body[x--])) { + fallthroughDepth++; + } else { + break; + } + } + + const plucked = body.splice(j - fallthroughDepth, 1 + fallthroughDepth); + body.splice(i + 1, 0, ...plucked); + i += plucked.length; + } + } + } + } + + // merge equivalent branches in a row + for (let i = 0; i < body.length; i++) { + let branch = body[i]; + if (branch.body.length === 0) continue; + if (!aborts(branch)) continue; + + for (let j = i + 1; j < body.length; i++, j++) { + let next = body[j]; + if (next.body.length === 0) continue; + if ( + branches_equivalent(next, branch, false) + || (j === body.length - 1 && branches_equivalent(next, branch, true)) + ) { + branch.body = []; + branch = next; + continue; + } + break; + } + } + + // Prune any empty branches at the end of the switch statement. + { + let i = body.length - 1; + for (; i >= 0; i--) { + let bbody = body[i].body; + if (is_break(bbody[bbody.length - 1], compressor)) bbody.pop(); + if (!is_inert_body(body[i])) break; + } + // i now points to the index of a branch that contains a body. By incrementing, it's + // pointing to the first branch that's empty. + i++; + if (!default_or_exact || body.indexOf(default_or_exact) >= i) { + // The default behavior is to do nothing. We can take advantage of that to + // remove all case expressions that are side-effect free that also do + // nothing, since they'll default to doing nothing. But we can't remove any + // case expressions before one that would side-effect, since they may cause + // the side-effect to be skipped. + for (let j = body.length - 1; j >= i; j--) { + let branch = body[j]; + if (branch === default_or_exact) { + default_or_exact = null; + body.pop(); + } else if (!branch.expression.has_side_effects(compressor)) { + body.pop(); + } else { + break; + } + } + } + } + + + // Prune side-effect free branches that fall into default. + DEFAULT: if (default_or_exact) { + let default_index = body.indexOf(default_or_exact); + let default_body_index = default_index; + for (; default_body_index < body.length - 1; default_body_index++) { + if (!is_inert_body(body[default_body_index])) break; + } + if (default_body_index < body.length - 1) { + break DEFAULT; + } + + let side_effect_index = body.length - 1; + for (; side_effect_index >= 0; side_effect_index--) { + let branch = body[side_effect_index]; + if (branch === default_or_exact) continue; + if (branch.expression.has_side_effects(compressor)) break; + } + // If the default behavior comes after any side-effect case expressions, + // then we can fold all side-effect free cases into the default branch. + // If the side-effect case is after the default, then any side-effect + // free cases could prevent the side-effect from occurring. + if (default_body_index > side_effect_index) { + let prev_body_index = default_index - 1; + for (; prev_body_index >= 0; prev_body_index--) { + if (!is_inert_body(body[prev_body_index])) break; + } + let before = Math.max(side_effect_index, prev_body_index) + 1; + let after = default_index; + if (side_effect_index > default_index) { + // If the default falls into the same body as a side-effect + // case, then we need preserve that case and only prune the + // cases after it. + after = side_effect_index; + body[side_effect_index].body = body[default_body_index].body; + } else { + // The default will be the last branch. + default_or_exact.body = body[default_body_index].body; + } + + // Prune everything after the default (or last side-effect case) + // until the next case with a body. + body.splice(after + 1, default_body_index - after); + // Prune everything before the default that falls into it. + body.splice(before, default_index - before); + } + } + + // See if we can remove the switch entirely if all cases (the default) fall into the same case body. + DEFAULT: if (default_or_exact) { + let i = body.findIndex(branch => !is_inert_body(branch)); + let caseBody; + // `i` is equal to one of the following: + // - `-1`, there is no body in the switch statement. + // - `body.length - 1`, all cases fall into the same body. + // - anything else, there are multiple bodies in the switch. + if (i === body.length - 1) { + // All cases fall into the case body. + let branch = body[i]; + if (has_nested_break(self)) break DEFAULT; + + // This is the last case body, and we've already pruned any breaks, so it's + // safe to hoist. + caseBody = make_node(AST_BlockStatement, branch, { + body: branch.body + }); + branch.body = []; + } else if (i !== -1) { + // If there are multiple bodies, then we cannot optimize anything. + break DEFAULT; + } + + let sideEffect = body.find( + branch => branch !== default_or_exact && branch.expression.has_side_effects(compressor) + ); + // If no cases cause a side-effect, we can eliminate the switch entirely. + if (!sideEffect) { + return make_node(AST_BlockStatement, self, { + body: decl.concat( + statement(self.expression), + default_or_exact.expression ? statement(default_or_exact.expression) : [], + caseBody || [] + ) + }).optimize(compressor); + } + + // If we're this far, either there was no body or all cases fell into the same body. + // If there was no body, then we don't need a default branch (because the default is + // do nothing). If there was a body, we'll extract it to after the switch, so the + // switch's new default is to do nothing and we can still prune it. + const default_index = body.indexOf(default_or_exact); + body.splice(default_index, 1); + default_or_exact = null; + + if (caseBody) { + // Recurse into switch statement one more time so that we can append the case body + // outside of the switch. This recursion will only happen once since we've pruned + // the default case. + return make_node(AST_BlockStatement, self, { + body: decl.concat(self, caseBody) + }).optimize(compressor); + } + // If we fall here, there is a default branch somewhere, there are no case bodies, + // and there's a side-effect somewhere. Just let the below paths take care of it. + } + + if (body.length > 0) { + body[0].body = decl.concat(body[0].body); + } + + if (body.length == 0) { + return make_node(AST_BlockStatement, self, { + body: decl.concat(statement(self.expression)) + }).optimize(compressor); + } + if (body.length == 1 && !has_nested_break(self)) { + // This is the last case body, and we've already pruned any breaks, so it's + // safe to hoist. + let branch = body[0]; + return make_node(AST_If, self, { + condition: make_node(AST_Binary, self, { + operator: "===", + left: self.expression, + right: branch.expression, + }), + body: make_node(AST_BlockStatement, branch, { + body: branch.body + }), + alternative: null + }).optimize(compressor); + } + if (body.length === 2 && default_or_exact && !has_nested_break(self)) { + let branch = body[0] === default_or_exact ? body[1] : body[0]; + let exact_exp = default_or_exact.expression && statement(default_or_exact.expression); + if (aborts(body[0])) { + // Only the first branch body could have a break (at the last statement) + let first = body[0]; + if (is_break(first.body[first.body.length - 1], compressor)) { + first.body.pop(); + } + return make_node(AST_If, self, { + condition: make_node(AST_Binary, self, { + operator: "===", + left: self.expression, + right: branch.expression, + }), + body: make_node(AST_BlockStatement, branch, { + body: branch.body + }), + alternative: make_node(AST_BlockStatement, default_or_exact, { + body: [].concat( + exact_exp || [], + default_or_exact.body + ) + }) + }).optimize(compressor); + } + let operator = "==="; + let consequent = make_node(AST_BlockStatement, branch, { + body: branch.body, + }); + let always = make_node(AST_BlockStatement, default_or_exact, { + body: [].concat( + exact_exp || [], + default_or_exact.body + ) + }); + if (body[0] === default_or_exact) { + operator = "!=="; + let tmp = always; + always = consequent; + consequent = tmp; + } + return make_node(AST_BlockStatement, self, { + body: [ + make_node(AST_If, self, { + condition: make_node(AST_Binary, self, { + operator: operator, + left: self.expression, + right: branch.expression, + }), + body: consequent, + alternative: null, + }), + always, + ], + }).optimize(compressor); + } + return self; + + function eliminate_branch(branch, prev) { + if (prev && !aborts(prev)) { + prev.body = prev.body.concat(branch.body); + } else { + trim_unreachable_code(compressor, branch, decl); + } + } + function branches_equivalent(branch, prev, insertBreak) { + let bbody = branch.body; + let pbody = prev.body; + if (insertBreak) { + bbody = bbody.concat(make_node(AST_Break)); + } + if (bbody.length !== pbody.length) return false; + let bblock = make_node(AST_BlockStatement, branch, { body: bbody }); + let pblock = make_node(AST_BlockStatement, prev, { body: pbody }); + return bblock.equivalent_to(pblock); + } + function statement(body) { + return make_node(AST_SimpleStatement, body, { body }); + } + function has_nested_break(root) { + let has_break = false; + + let tw = new TreeWalker(node => { + if (has_break) return true; + if (node instanceof AST_Lambda) return true; + if (node instanceof AST_SimpleStatement) return true; + if (!is_break(node, tw)) return; + let parent = tw.parent(); + if ( + parent instanceof AST_SwitchBranch + && parent.body[parent.body.length - 1] === node + ) { + return; + } + has_break = true; + }); + root.walk(tw); + return has_break; + } + function is_break(node, stack) { + return node instanceof AST_Break + && stack.loopcontrol_target(node) === self; + } + function is_inert_body(branch) { + return !aborts(branch) && !make_node(AST_BlockStatement, branch, { + body: branch.body + }).has_side_effects(compressor); + } +}); + +def_optimize(AST_Try, function(self, compressor) { + if (self.bcatch && self.bfinally && self.bfinally.body.every(is_empty)) self.bfinally = null; + + if (compressor.option("dead_code") && self.body.body.every(is_empty)) { + var body = []; + if (self.bcatch) { + trim_unreachable_code(compressor, self.bcatch, body); + } + if (self.bfinally) body.push(...self.bfinally.body); + return make_node(AST_BlockStatement, self, { + body: body + }).optimize(compressor); + } + return self; +}); + +AST_Definitions.DEFMETHOD("to_assignments", function(compressor) { + var reduce_vars = compressor.option("reduce_vars"); + var assignments = []; + + for (const def of this.definitions) { + if (def.value) { + var name = make_node(AST_SymbolRef, def.name, def.name); + assignments.push(make_node(AST_Assign, def, { + operator : "=", + logical: false, + left : name, + right : def.value + })); + if (reduce_vars) name.definition().fixed = false; + } + const thedef = def.name.definition(); + thedef.eliminated++; + thedef.replaced--; + } + + if (assignments.length == 0) return null; + return make_sequence(this, assignments); +}); + +def_optimize(AST_Definitions, function(self) { + if (self.definitions.length == 0) { + return make_node(AST_EmptyStatement, self); + } + return self; +}); + +def_optimize(AST_VarDef, function(self, compressor) { + if ( + self.name instanceof AST_SymbolLet + && self.value != null + && is_undefined(self.value, compressor) + ) { + self.value = null; + } + return self; +}); + +def_optimize(AST_Import, function(self) { + return self; +}); + +def_optimize(AST_Call, function(self, compressor) { + var exp = self.expression; + var fn = exp; + inline_array_like_spread(self.args); + var simple_args = self.args.every((arg) => !(arg instanceof AST_Expansion)); + + if (compressor.option("reduce_vars") && fn instanceof AST_SymbolRef) { + fn = fn.fixed_value(); + } + + var is_func = fn instanceof AST_Lambda; + + if (is_func && fn.pinned()) return self; + + if (compressor.option("unused") + && simple_args + && is_func + && !fn.uses_arguments) { + var pos = 0, last = 0; + for (var i = 0, len = self.args.length; i < len; i++) { + if (fn.argnames[i] instanceof AST_Expansion) { + if (has_flag(fn.argnames[i].expression, UNUSED)) while (i < len) { + var node = self.args[i++].drop_side_effect_free(compressor); + if (node) { + self.args[pos++] = node; + } + } else while (i < len) { + self.args[pos++] = self.args[i++]; + } + last = pos; + break; + } + var trim = i >= fn.argnames.length; + if (trim || has_flag(fn.argnames[i], UNUSED)) { + var node = self.args[i].drop_side_effect_free(compressor); + if (node) { + self.args[pos++] = node; + } else if (!trim) { + self.args[pos++] = make_node(AST_Number, self.args[i], { + value: 0 + }); + continue; + } + } else { + self.args[pos++] = self.args[i]; + } + last = pos; + } + self.args.length = last; + } + + if ( + exp instanceof AST_Dot + && exp.expression instanceof AST_SymbolRef + && exp.expression.name === "console" + && exp.expression.definition().undeclared + && exp.property === "assert" + ) { + const condition = self.args[0]; + if (condition) { + const value = condition.evaluate(compressor); + + if (value === 1 || value === true) { + return make_node(AST_Undefined, self); + } + } + } + + if (compressor.option("unsafe") && !exp.contains_optional()) { + if (exp instanceof AST_Dot && exp.start.value === "Array" && exp.property === "from" && self.args.length === 1) { + const [argument] = self.args; + if (argument instanceof AST_Array) { + return make_node(AST_Array, argument, { + elements: argument.elements + }).optimize(compressor); + } + } + if (is_undeclared_ref(exp)) switch (exp.name) { + case "Array": + if (self.args.length != 1) { + return make_node(AST_Array, self, { + elements: self.args + }).optimize(compressor); + } else if (self.args[0] instanceof AST_Number && self.args[0].value <= 11) { + const elements = []; + for (let i = 0; i < self.args[0].value; i++) elements.push(new AST_Hole); + return new AST_Array({ elements }); + } + break; + case "Object": + if (self.args.length == 0) { + return make_node(AST_Object, self, { + properties: [] + }); + } + break; + case "String": + if (self.args.length == 0) return make_node(AST_String, self, { + value: "" + }); + if (self.args.length <= 1) return make_node(AST_Binary, self, { + left: self.args[0], + operator: "+", + right: make_node(AST_String, self, { value: "" }) + }).optimize(compressor); + break; + case "Number": + if (self.args.length == 0) return make_node(AST_Number, self, { + value: 0 + }); + if (self.args.length == 1 && compressor.option("unsafe_math")) { + return make_node(AST_UnaryPrefix, self, { + expression: self.args[0], + operator: "+" + }).optimize(compressor); + } + break; + case "Symbol": + if (self.args.length == 1 && self.args[0] instanceof AST_String && compressor.option("unsafe_symbols")) + self.args.length = 0; + break; + case "Boolean": + if (self.args.length == 0) return make_node(AST_False, self); + if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, { + expression: make_node(AST_UnaryPrefix, self, { + expression: self.args[0], + operator: "!" + }), + operator: "!" + }).optimize(compressor); + break; + case "RegExp": + var params = []; + if (self.args.length >= 1 + && self.args.length <= 2 + && self.args.every((arg) => { + var value = arg.evaluate(compressor); + params.push(value); + return arg !== value; + }) + && regexp_is_safe(params[0]) + ) { + let [ source, flags ] = params; + source = regexp_source_fix(new RegExp(source).source); + const rx = make_node(AST_RegExp, self, { + value: { source, flags } + }); + if (rx._eval(compressor) !== rx) { + return rx; + } + } + break; + } else if (exp instanceof AST_Dot) switch(exp.property) { + case "toString": + if (self.args.length == 0 && !exp.expression.may_throw_on_access(compressor)) { + return make_node(AST_Binary, self, { + left: make_node(AST_String, self, { value: "" }), + operator: "+", + right: exp.expression + }).optimize(compressor); + } + break; + case "join": + if (exp.expression instanceof AST_Array) EXIT: { + var separator; + if (self.args.length > 0) { + separator = self.args[0].evaluate(compressor); + if (separator === self.args[0]) break EXIT; // not a constant + } + var elements = []; + var consts = []; + for (var i = 0, len = exp.expression.elements.length; i < len; i++) { + var el = exp.expression.elements[i]; + if (el instanceof AST_Expansion) break EXIT; + var value = el.evaluate(compressor); + if (value !== el) { + consts.push(value); + } else { + if (consts.length > 0) { + elements.push(make_node(AST_String, self, { + value: consts.join(separator) + })); + consts.length = 0; + } + elements.push(el); + } + } + if (consts.length > 0) { + elements.push(make_node(AST_String, self, { + value: consts.join(separator) + })); + } + if (elements.length == 0) return make_node(AST_String, self, { value: "" }); + if (elements.length == 1) { + if (elements[0].is_string(compressor)) { + return elements[0]; + } + return make_node(AST_Binary, elements[0], { + operator : "+", + left : make_node(AST_String, self, { value: "" }), + right : elements[0] + }); + } + if (separator == "") { + var first; + if (elements[0].is_string(compressor) + || elements[1].is_string(compressor)) { + first = elements.shift(); + } else { + first = make_node(AST_String, self, { value: "" }); + } + return elements.reduce(function(prev, el) { + return make_node(AST_Binary, el, { + operator : "+", + left : prev, + right : el + }); + }, first).optimize(compressor); + } + // need this awkward cloning to not affect original element + // best_of will decide which one to get through. + var node = self.clone(); + node.expression = node.expression.clone(); + node.expression.expression = node.expression.expression.clone(); + node.expression.expression.elements = elements; + return best_of(compressor, self, node); + } + break; + case "charAt": + if (exp.expression.is_string(compressor)) { + var arg = self.args[0]; + var index = arg ? arg.evaluate(compressor) : 0; + if (index !== arg) { + return make_node(AST_Sub, exp, { + expression: exp.expression, + property: make_node_from_constant(index | 0, arg || exp) + }).optimize(compressor); + } + } + break; + case "apply": + if (self.args.length == 2 && self.args[1] instanceof AST_Array) { + var args = self.args[1].elements.slice(); + args.unshift(self.args[0]); + return make_node(AST_Call, self, { + expression: make_node(AST_Dot, exp, { + expression: exp.expression, + optional: false, + property: "call" + }), + args: args + }).optimize(compressor); + } + break; + case "call": + var func = exp.expression; + if (func instanceof AST_SymbolRef) { + func = func.fixed_value(); + } + if (func instanceof AST_Lambda && !func.contains_this()) { + return (self.args.length ? make_sequence(this, [ + self.args[0], + make_node(AST_Call, self, { + expression: exp.expression, + args: self.args.slice(1) + }) + ]) : make_node(AST_Call, self, { + expression: exp.expression, + args: [] + })).optimize(compressor); + } + break; + } + } + + if (compressor.option("unsafe_Function") + && is_undeclared_ref(exp) + && exp.name == "Function") { + // new Function() => function(){} + if (self.args.length == 0) return make_empty_function(self).optimize(compressor); + if (self.args.every((x) => x instanceof AST_String)) { + // quite a corner-case, but we can handle it: + // https://github.com/mishoo/UglifyJS2/issues/203 + // if the code argument is a constant, then we can minify it. + try { + var code = "n(function(" + self.args.slice(0, -1).map(function(arg) { + return arg.value; + }).join(",") + "){" + self.args[self.args.length - 1].value + "})"; + var ast = parse(code); + var mangle = compressor.mangle_options(); + ast.figure_out_scope(mangle); + var comp = new Compressor(compressor.options, { + mangle_options: compressor._mangle_options + }); + ast = ast.transform(comp); + ast.figure_out_scope(mangle); + ast.compute_char_frequency(mangle); + ast.mangle_names(mangle); + var fun; + walk(ast, node => { + if (is_func_expr(node)) { + fun = node; + return walk_abort; + } + }); + var code = OutputStream(); + AST_BlockStatement.prototype._codegen.call(fun, fun, code); + self.args = [ + make_node(AST_String, self, { + value: fun.argnames.map(function(arg) { + return arg.print_to_string(); + }).join(",") + }), + make_node(AST_String, self.args[self.args.length - 1], { + value: code.get().replace(/^{|}$/g, "") + }) + ]; + return self; + } catch (ex) { + if (!(ex instanceof JS_Parse_Error)) { + throw ex; + } + + // Otherwise, it crashes at runtime. Or maybe it's nonstandard syntax. + } + } + } + + return inline_into_call(self, compressor); +}); + +/** Does this node contain optional property access or optional call? */ +AST_Node.DEFMETHOD("contains_optional", function() { + if ( + this instanceof AST_PropAccess + || this instanceof AST_Call + || this instanceof AST_Chain + ) { + if (this.optional) { + return true; + } else { + return this.expression.contains_optional(); + } + } else { + return false; + } +}); + +def_optimize(AST_New, function(self, compressor) { + if ( + compressor.option("unsafe") && + is_undeclared_ref(self.expression) && + ["Object", "RegExp", "Function", "Error", "Array"].includes(self.expression.name) + ) return make_node(AST_Call, self, self).transform(compressor); + return self; +}); + +def_optimize(AST_Sequence, function(self, compressor) { + if (!compressor.option("side_effects")) return self; + var expressions = []; + filter_for_side_effects(); + var end = expressions.length - 1; + trim_right_for_undefined(); + if (end == 0) { + self = maintain_this_binding(compressor.parent(), compressor.self(), expressions[0]); + if (!(self instanceof AST_Sequence)) self = self.optimize(compressor); + return self; + } + self.expressions = expressions; + return self; + + function filter_for_side_effects() { + var first = first_in_statement(compressor); + var last = self.expressions.length - 1; + self.expressions.forEach(function(expr, index) { + if (index < last) expr = expr.drop_side_effect_free(compressor, first); + if (expr) { + merge_sequence(expressions, expr); + first = false; + } + }); + } + + function trim_right_for_undefined() { + while (end > 0 && is_undefined(expressions[end], compressor)) end--; + if (end < expressions.length - 1) { + expressions[end] = make_node(AST_UnaryPrefix, self, { + operator : "void", + expression : expressions[end] + }); + expressions.length = end + 1; + } + } +}); + +AST_Unary.DEFMETHOD("lift_sequences", function(compressor) { + if (compressor.option("sequences")) { + if (this.expression instanceof AST_Sequence) { + var x = this.expression.expressions.slice(); + var e = this.clone(); + e.expression = x.pop(); + x.push(e); + return make_sequence(this, x).optimize(compressor); + } + } + return this; +}); + +def_optimize(AST_UnaryPostfix, function(self, compressor) { + return self.lift_sequences(compressor); +}); + +def_optimize(AST_UnaryPrefix, function(self, compressor) { + var e = self.expression; + if ( + self.operator == "delete" && + !( + e instanceof AST_SymbolRef || + e instanceof AST_PropAccess || + e instanceof AST_Chain || + is_identifier_atom(e) + ) + ) { + return make_sequence(self, [e, make_node(AST_True, self)]).optimize(compressor); + } + var seq = self.lift_sequences(compressor); + if (seq !== self) { + return seq; + } + if (compressor.option("side_effects") && self.operator == "void") { + e = e.drop_side_effect_free(compressor); + if (e) { + self.expression = e; + return self; + } else { + return make_node(AST_Undefined, self).optimize(compressor); + } + } + if (compressor.in_boolean_context()) { + switch (self.operator) { + case "!": + if (e instanceof AST_UnaryPrefix && e.operator == "!") { + // !!foo ==> foo, if we're in boolean context + return e.expression; + } + if (e instanceof AST_Binary) { + self = best_of(compressor, self, e.negate(compressor, first_in_statement(compressor))); + } + break; + case "typeof": + // typeof always returns a non-empty string, thus it's + // always true in booleans + // And we don't need to check if it's undeclared, because in typeof, that's OK + return (e instanceof AST_SymbolRef ? make_node(AST_True, self) : make_sequence(self, [ + e, + make_node(AST_True, self) + ])).optimize(compressor); + } + } + if (self.operator == "-" && e instanceof AST_Infinity) { + e = e.transform(compressor); + } + if (e instanceof AST_Binary + && (self.operator == "+" || self.operator == "-") + && (e.operator == "*" || e.operator == "/" || e.operator == "%")) { + return make_node(AST_Binary, self, { + operator: e.operator, + left: make_node(AST_UnaryPrefix, e.left, { + operator: self.operator, + expression: e.left + }), + right: e.right + }); + } + + if (compressor.option("evaluate")) { + // ~~x => x (in 32-bit context) + // ~~{32 bit integer} => {32 bit integer} + if ( + self.operator === "~" + && self.expression instanceof AST_UnaryPrefix + && self.expression.operator === "~" + && (compressor.in_32_bit_context(false) || self.expression.expression.is_32_bit_integer(compressor)) + ) { + return self.expression.expression; + } + + // ~(x ^ y) => x ^ ~y + if ( + self.operator === "~" + && e instanceof AST_Binary + && e.operator === "^" + ) { + if (e.left instanceof AST_UnaryPrefix && e.left.operator === "~") { + // ~(~x ^ y) => x ^ y + e.left = e.left.bitwise_negate(compressor, true); + } else { + e.right = e.right.bitwise_negate(compressor, true); + } + return e; + } + } + + if ( + self.operator != "-" + // avoid infinite recursion of numerals + || !(e instanceof AST_Number || e instanceof AST_Infinity || e instanceof AST_BigInt) + ) { + var ev = self.evaluate(compressor); + if (ev !== self) { + ev = make_node_from_constant(ev, self).optimize(compressor); + return best_of(compressor, ev, self); + } + } + return self; +}); + +AST_Binary.DEFMETHOD("lift_sequences", function(compressor) { + if (compressor.option("sequences")) { + if (this.left instanceof AST_Sequence) { + var x = this.left.expressions.slice(); + var e = this.clone(); + e.left = x.pop(); + x.push(e); + return make_sequence(this, x).optimize(compressor); + } + if (this.right instanceof AST_Sequence && !this.left.has_side_effects(compressor)) { + var assign = this.operator == "=" && this.left instanceof AST_SymbolRef; + var x = this.right.expressions; + var last = x.length - 1; + for (var i = 0; i < last; i++) { + if (!assign && x[i].has_side_effects(compressor)) break; + } + if (i == last) { + x = x.slice(); + var e = this.clone(); + e.right = x.pop(); + x.push(e); + return make_sequence(this, x).optimize(compressor); + } else if (i > 0) { + var e = this.clone(); + e.right = make_sequence(this.right, x.slice(i)); + x = x.slice(0, i); + x.push(e); + return make_sequence(this, x).optimize(compressor); + } + } + } + return this; +}); + +var commutativeOperators = makePredicate("== === != !== * & | ^"); +function is_object(node) { + return node instanceof AST_Array + || node instanceof AST_Lambda + || node instanceof AST_Object + || node instanceof AST_Class; +} + +def_optimize(AST_Binary, function(self, compressor) { + function reversible() { + return self.left.is_constant() + || self.right.is_constant() + || !self.left.has_side_effects(compressor) + && !self.right.has_side_effects(compressor); + } + function reverse(op) { + if (reversible()) { + if (op) self.operator = op; + var tmp = self.left; + self.left = self.right; + self.right = tmp; + } + } + if (compressor.option("lhs_constants") && commutativeOperators.has(self.operator)) { + if (self.right.is_constant() + && !self.left.is_constant()) { + // if right is a constant, whatever side effects the + // left side might have could not influence the + // result. hence, force switch. + + if (!(self.left instanceof AST_Binary + && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) { + reverse(); + } + } + } + self = self.lift_sequences(compressor); + if (compressor.option("comparisons")) switch (self.operator) { + case "===": + case "!==": + var is_strict_comparison = true; + if ( + (self.left.is_string(compressor) && self.right.is_string(compressor)) || + (self.left.is_number(compressor) && self.right.is_number(compressor)) || + (self.left.is_bigint(compressor) && self.right.is_bigint(compressor)) || + (self.left.is_boolean() && self.right.is_boolean()) || + self.left.equivalent_to(self.right) + ) { + self.operator = self.operator.substr(0, 2); + } + + // XXX: intentionally falling down to the next case + case "==": + case "!=": + // void 0 == x => null == x + if (!is_strict_comparison && is_undefined(self.left, compressor)) { + self.left = make_node(AST_Null, self.left); + // x == void 0 => x == null + } else if (!is_strict_comparison && is_undefined(self.right, compressor)) { + self.right = make_node(AST_Null, self.right); + } else if (compressor.option("typeofs") + // "undefined" == typeof x => undefined === x + && self.left instanceof AST_String + && self.left.value == "undefined" + && self.right instanceof AST_UnaryPrefix + && self.right.operator == "typeof") { + var expr = self.right.expression; + if (expr instanceof AST_SymbolRef ? expr.is_declared(compressor) + : !(expr instanceof AST_PropAccess && compressor.option("ie8"))) { + self.right = expr; + self.left = make_node(AST_Undefined, self.left).optimize(compressor); + if (self.operator.length == 2) self.operator += "="; + } + } else if (compressor.option("typeofs") + // typeof x === "undefined" => x === undefined + && self.left instanceof AST_UnaryPrefix + && self.left.operator == "typeof" + && self.right instanceof AST_String + && self.right.value == "undefined") { + var expr = self.left.expression; + if (expr instanceof AST_SymbolRef ? expr.is_declared(compressor) + : !(expr instanceof AST_PropAccess && compressor.option("ie8"))) { + self.left = expr; + self.right = make_node(AST_Undefined, self.right).optimize(compressor); + if (self.operator.length == 2) self.operator += "="; + } + } else if (self.left instanceof AST_SymbolRef + // obj !== obj => false + && self.right instanceof AST_SymbolRef + && self.left.definition() === self.right.definition() + && is_object(self.left.fixed_value())) { + return make_node(self.operator[0] == "=" ? AST_True : AST_False, self); + } else if (self.left.is_32_bit_integer(compressor) && self.right.is_32_bit_integer(compressor)) { + const not = node => make_node(AST_UnaryPrefix, node, { + operator: "!", + expression: node + }); + const booleanify = (node, truthy) => { + if (truthy) { + return compressor.in_boolean_context() + ? node + : not(not(node)); + } else { + return not(node); + } + }; + + // The only falsy 32-bit integer is 0 + if (self.left instanceof AST_Number && self.left.value === 0) { + return booleanify(self.right, self.operator[0] === "!"); + } + if (self.right instanceof AST_Number && self.right.value === 0) { + return booleanify(self.left, self.operator[0] === "!"); + } + + // Mask all-bits check + // (x & 0xFF) != 0xFF => !(~x & 0xFF) + let and_op, x, mask; + if ( + (and_op = + self.left instanceof AST_Binary ? self.left + : self.right instanceof AST_Binary ? self.right : null) + && (mask = and_op === self.left ? self.right : self.left) + && and_op.operator === "&" + && mask instanceof AST_Number + && mask.is_32_bit_integer(compressor) + && (x = + and_op.left.equivalent_to(mask) ? and_op.right + : and_op.right.equivalent_to(mask) ? and_op.left : null) + ) { + let optimized = booleanify(make_node(AST_Binary, self, { + operator: "&", + left: mask, + right: make_node(AST_UnaryPrefix, self, { + operator: "~", + expression: x + }) + }), self.operator[0] === "!"); + + return best_of(compressor, optimized, self); + } + } + break; + case "&&": + case "||": + var lhs = self.left; + if (lhs.operator == self.operator) { + lhs = lhs.right; + } + if (lhs instanceof AST_Binary + && lhs.operator == (self.operator == "&&" ? "!==" : "===") + && self.right instanceof AST_Binary + && lhs.operator == self.right.operator + && (is_undefined(lhs.left, compressor) && self.right.left instanceof AST_Null + || lhs.left instanceof AST_Null && is_undefined(self.right.left, compressor)) + && !lhs.right.has_side_effects(compressor) + && lhs.right.equivalent_to(self.right.right)) { + var combined = make_node(AST_Binary, self, { + operator: lhs.operator.slice(0, -1), + left: make_node(AST_Null, self), + right: lhs.right + }); + if (lhs !== self.left) { + combined = make_node(AST_Binary, self, { + operator: self.operator, + left: self.left.left, + right: combined + }); + } + return combined; + } + break; + } + if (self.operator == "+" && compressor.in_boolean_context()) { + var ll = self.left.evaluate(compressor); + var rr = self.right.evaluate(compressor); + if (ll && typeof ll == "string") { + return make_sequence(self, [ + self.right, + make_node(AST_True, self) + ]).optimize(compressor); + } + if (rr && typeof rr == "string") { + return make_sequence(self, [ + self.left, + make_node(AST_True, self) + ]).optimize(compressor); + } + } + if (compressor.option("comparisons") && self.is_boolean()) { + if (!(compressor.parent() instanceof AST_Binary) + || compressor.parent() instanceof AST_Assign) { + var negated = make_node(AST_UnaryPrefix, self, { + operator: "!", + expression: self.negate(compressor, first_in_statement(compressor)) + }); + self = best_of(compressor, self, negated); + } + if (compressor.option("unsafe_comps")) { + switch (self.operator) { + case "<": reverse(">"); break; + case "<=": reverse(">="); break; + } + } + } + if (self.operator == "+") { + if (self.right instanceof AST_String + && self.right.getValue() == "" + && self.left.is_string(compressor)) { + return self.left; + } + if (self.left instanceof AST_String + && self.left.getValue() == "" + && self.right.is_string(compressor)) { + return self.right; + } + if (self.left instanceof AST_Binary + && self.left.operator == "+" + && self.left.left instanceof AST_String + && self.left.left.getValue() == "" + && self.right.is_string(compressor)) { + self.left = self.left.right; + return self; + } + } + if (compressor.option("evaluate")) { + switch (self.operator) { + case "&&": + var ll = has_flag(self.left, TRUTHY) + ? true + : has_flag(self.left, FALSY) + ? false + : self.left.evaluate(compressor); + if (!ll) { + return maintain_this_binding(compressor.parent(), compressor.self(), self.left).optimize(compressor); + } else if (!(ll instanceof AST_Node)) { + return make_sequence(self, [ self.left, self.right ]).optimize(compressor); + } + var rr = self.right.evaluate(compressor); + if (!rr) { + if (compressor.in_boolean_context()) { + return make_sequence(self, [ + self.left, + make_node(AST_False, self) + ]).optimize(compressor); + } else { + set_flag(self, FALSY); + } + } else if (!(rr instanceof AST_Node)) { + var parent = compressor.parent(); + if (parent.operator == "&&" && parent.left === compressor.self() || compressor.in_boolean_context()) { + return self.left.optimize(compressor); + } + } + // x || false && y ---> x ? y : false + if (self.left.operator == "||") { + var lr = self.left.right.evaluate(compressor); + if (!lr) return make_node(AST_Conditional, self, { + condition: self.left.left, + consequent: self.right, + alternative: self.left.right + }).optimize(compressor); + } + break; + case "||": + var ll = has_flag(self.left, TRUTHY) + ? true + : has_flag(self.left, FALSY) + ? false + : self.left.evaluate(compressor); + if (!ll) { + return make_sequence(self, [ self.left, self.right ]).optimize(compressor); + } else if (!(ll instanceof AST_Node)) { + return maintain_this_binding(compressor.parent(), compressor.self(), self.left).optimize(compressor); + } + var rr = self.right.evaluate(compressor); + if (!rr) { + var parent = compressor.parent(); + if (parent.operator == "||" && parent.left === compressor.self() || compressor.in_boolean_context()) { + return self.left.optimize(compressor); + } + } else if (!(rr instanceof AST_Node)) { + if (compressor.in_boolean_context()) { + return make_sequence(self, [ + self.left, + make_node(AST_True, self) + ]).optimize(compressor); + } else { + set_flag(self, TRUTHY); + } + } + if (self.left.operator == "&&") { + var lr = self.left.right.evaluate(compressor); + if (lr && !(lr instanceof AST_Node)) return make_node(AST_Conditional, self, { + condition: self.left.left, + consequent: self.left.right, + alternative: self.right + }).optimize(compressor); + } + break; + case "??": + if (is_nullish(self.left, compressor)) { + return self.right; + } + + var ll = self.left.evaluate(compressor); + if (!(ll instanceof AST_Node)) { + // if we know the value for sure we can simply compute right away. + return ll == null ? self.right : self.left; + } + + if (compressor.in_boolean_context()) { + const rr = self.right.evaluate(compressor); + if (!(rr instanceof AST_Node) && !rr) { + return self.left; + } + } + } + var associative = true; + switch (self.operator) { + case "+": + // (x + "foo") + "bar" => x + "foobar" + if (self.right instanceof AST_Constant + && self.left instanceof AST_Binary + && self.left.operator == "+" + && self.left.is_string(compressor)) { + var binary = make_node(AST_Binary, self, { + operator: "+", + left: self.left.right, + right: self.right, + }); + var r = binary.optimize(compressor); + if (binary !== r) { + self = make_node(AST_Binary, self, { + operator: "+", + left: self.left.left, + right: r + }); + } + } + // (x + "foo") + ("bar" + y) => (x + "foobar") + y + if (self.left instanceof AST_Binary + && self.left.operator == "+" + && self.left.is_string(compressor) + && self.right instanceof AST_Binary + && self.right.operator == "+" + && self.right.is_string(compressor)) { + var binary = make_node(AST_Binary, self, { + operator: "+", + left: self.left.right, + right: self.right.left, + }); + var m = binary.optimize(compressor); + if (binary !== m) { + self = make_node(AST_Binary, self, { + operator: "+", + left: make_node(AST_Binary, self.left, { + operator: "+", + left: self.left.left, + right: m + }), + right: self.right.right + }); + } + } + // a + -b => a - b + if (self.right instanceof AST_UnaryPrefix + && self.right.operator == "-" + && self.left.is_number_or_bigint(compressor)) { + self = make_node(AST_Binary, self, { + operator: "-", + left: self.left, + right: self.right.expression + }); + break; + } + // -a + b => b - a + if (self.left instanceof AST_UnaryPrefix + && self.left.operator == "-" + && reversible() + && self.right.is_number_or_bigint(compressor)) { + self = make_node(AST_Binary, self, { + operator: "-", + left: self.right, + right: self.left.expression + }); + break; + } + // `foo${bar}baz` + 1 => `foo${bar}baz1` + if (self.left instanceof AST_TemplateString) { + var l = self.left; + var r = self.right.evaluate(compressor); + if (r != self.right) { + l.segments[l.segments.length - 1].value += String(r); + return l; + } + } + // 1 + `foo${bar}baz` => `1foo${bar}baz` + if (self.right instanceof AST_TemplateString) { + var r = self.right; + var l = self.left.evaluate(compressor); + if (l != self.left) { + r.segments[0].value = String(l) + r.segments[0].value; + return r; + } + } + // `1${bar}2` + `foo${bar}baz` => `1${bar}2foo${bar}baz` + if (self.left instanceof AST_TemplateString + && self.right instanceof AST_TemplateString) { + var l = self.left; + var segments = l.segments; + var r = self.right; + segments[segments.length - 1].value += r.segments[0].value; + for (var i = 1; i < r.segments.length; i++) { + segments.push(r.segments[i]); + } + return l; + } + case "*": + associative = compressor.option("unsafe_math"); + case "&": + case "|": + case "^": + // a + +b => +b + a + if ( + self.left.is_number_or_bigint(compressor) + && self.right.is_number_or_bigint(compressor) + && reversible() + && !(self.left instanceof AST_Binary + && self.left.operator != self.operator + && PRECEDENCE[self.left.operator] >= PRECEDENCE[self.operator])) { + var reversed = make_node(AST_Binary, self, { + operator: self.operator, + left: self.right, + right: self.left + }); + if (self.right instanceof AST_Constant + && !(self.left instanceof AST_Constant)) { + self = best_of(compressor, reversed, self); + } else { + self = best_of(compressor, self, reversed); + } + } + if (associative && self.is_number_or_bigint(compressor)) { + // a + (b + c) => (a + b) + c + if (self.right instanceof AST_Binary + && self.right.operator == self.operator) { + self = make_node(AST_Binary, self, { + operator: self.operator, + left: make_node(AST_Binary, self.left, { + operator: self.operator, + left: self.left, + right: self.right.left, + start: self.left.start, + end: self.right.left.end + }), + right: self.right.right + }); + } + // (n + 2) + 3 => 5 + n + // (2 * n) * 3 => 6 + n + if (self.right instanceof AST_Constant + && self.left instanceof AST_Binary + && self.left.operator == self.operator) { + if (self.left.left instanceof AST_Constant) { + self = make_node(AST_Binary, self, { + operator: self.operator, + left: make_node(AST_Binary, self.left, { + operator: self.operator, + left: self.left.left, + right: self.right, + start: self.left.left.start, + end: self.right.end + }), + right: self.left.right + }); + } else if (self.left.right instanceof AST_Constant) { + self = make_node(AST_Binary, self, { + operator: self.operator, + left: make_node(AST_Binary, self.left, { + operator: self.operator, + left: self.left.right, + right: self.right, + start: self.left.right.start, + end: self.right.end + }), + right: self.left.left + }); + } + } + // (a | 1) | (2 | d) => (3 | a) | b + if (self.left instanceof AST_Binary + && self.left.operator == self.operator + && self.left.right instanceof AST_Constant + && self.right instanceof AST_Binary + && self.right.operator == self.operator + && self.right.left instanceof AST_Constant) { + self = make_node(AST_Binary, self, { + operator: self.operator, + left: make_node(AST_Binary, self.left, { + operator: self.operator, + left: make_node(AST_Binary, self.left.left, { + operator: self.operator, + left: self.left.right, + right: self.right.left, + start: self.left.right.start, + end: self.right.left.end + }), + right: self.left.left + }), + right: self.right.right + }); + } + } + } + + // bitwise ops + if (bitwise_binop.has(self.operator)) { + // Use De Morgan's laws + // z & (X | y) + // => z & X (given y & z === 0) + // => z & X | {y & z} (given y & z !== 0) + let y, z, x_node, y_node, z_node = self.left; + if ( + self.operator === "&" + && self.right instanceof AST_Binary + && self.right.operator === "|" + && typeof (z = self.left.evaluate(compressor)) === "number" + ) { + if (typeof (y = self.right.right.evaluate(compressor)) === "number") { + // z & (X | y) + x_node = self.right.left; + y_node = self.right.right; + } else if (typeof (y = self.right.left.evaluate(compressor)) === "number") { + // z & (y | X) + x_node = self.right.right; + y_node = self.right.left; + } + + if (x_node && y_node) { + if ((y & z) === 0) { + self = make_node(AST_Binary, self, { + operator: self.operator, + left: z_node, + right: x_node + }); + } else { + const reordered_ops = make_node(AST_Binary, self, { + operator: "|", + left: make_node(AST_Binary, self, { + operator: "&", + left: x_node, + right: z_node + }), + right: make_node_from_constant(y & z, y_node), + }); + + self = best_of(compressor, self, reordered_ops); + } + } + } + + // x | x => 0 | x + // x & x => 0 | x + if ( + (self.operator === "|" || self.operator === "&") + && self.left.equivalent_to(self.right) + && !self.left.has_side_effects(compressor) + && compressor.in_32_bit_context(true) + ) { + self.left = make_node(AST_Number, self, { value: 0 }); + self.operator = "|"; + } + + // ~x ^ ~y => x ^ y + if ( + self.operator === "^" + && self.left instanceof AST_UnaryPrefix + && self.left.operator === "~" + && self.right instanceof AST_UnaryPrefix + && self.right.operator === "~" + ) { + self = make_node(AST_Binary, self, { + operator: "^", + left: self.left.expression, + right: self.right.expression + }); + } + + + // Shifts that do nothing + // {anything} >> 0 => {anything} | 0 + // {anything} << 0 => {anything} | 0 + if ( + (self.operator === "<<" || self.operator === ">>") + && self.right instanceof AST_Number && self.right.value === 0 + ) { + self.operator = "|"; + } + + // Find useless to-bitwise conversions + // {32 bit integer} | 0 => {32 bit integer} + // {32 bit integer} ^ 0 => {32 bit integer} + const zero_side = self.right instanceof AST_Number && self.right.value === 0 ? self.right + : self.left instanceof AST_Number && self.left.value === 0 ? self.left + : null; + const non_zero_side = zero_side && (zero_side === self.right ? self.left : self.right); + if ( + zero_side + && (self.operator === "|" || self.operator === "^") + && (non_zero_side.is_32_bit_integer(compressor) || compressor.in_32_bit_context(true)) + ) { + return non_zero_side; + } + + // {anything} & 0 => 0 + if ( + zero_side + && self.operator === "&" + && !non_zero_side.has_side_effects(compressor) + && non_zero_side.is_32_bit_integer(compressor) + ) { + return zero_side; + } + + // ~0 is all ones, as well as -1. + // We can ellide some operations with it. + const is_full_mask = (node) => + node instanceof AST_Number && node.value === -1 + || + node instanceof AST_UnaryPrefix + && node.operator === "-" + && node.expression instanceof AST_Number + && node.expression.value === 1; + + const full_mask = is_full_mask(self.right) ? self.right + : is_full_mask(self.left) ? self.left + : null; + const other_side = (full_mask === self.right ? self.left : self.right); + + // {32 bit integer} & -1 => {32 bit integer} + if ( + full_mask + && self.operator === "&" + && ( + other_side.is_32_bit_integer(compressor) + || compressor.in_32_bit_context(true) + ) + ) { + return other_side; + } + + // {anything} ^ -1 => ~{anything} + if ( + full_mask + && self.operator === "^" + && ( + other_side.is_32_bit_integer(compressor) + || compressor.in_32_bit_context(true) + ) + ) { + return other_side.bitwise_negate(compressor); + } + } + } + // x && (y && z) ==> x && y && z + // x || (y || z) ==> x || y || z + // x + ("y" + z) ==> x + "y" + z + // "x" + (y + "z")==> "x" + y + "z" + if (self.right instanceof AST_Binary + && self.right.operator == self.operator + && (lazy_op.has(self.operator) + || (self.operator == "+" + && (self.right.left.is_string(compressor) + || (self.left.is_string(compressor) + && self.right.right.is_string(compressor))))) + ) { + self.left = make_node(AST_Binary, self.left, { + operator : self.operator, + left : self.left.transform(compressor), + right : self.right.left.transform(compressor) + }); + self.right = self.right.right.transform(compressor); + return self.transform(compressor); + } + var ev = self.evaluate(compressor); + if (ev !== self) { + ev = make_node_from_constant(ev, self).optimize(compressor); + return best_of(compressor, ev, self); + } + return self; +}); + +def_optimize(AST_SymbolExport, function(self) { + return self; +}); + +def_optimize(AST_SymbolRef, function(self, compressor) { + if ( + !compressor.option("ie8") + && is_undeclared_ref(self) + && !compressor.find_parent(AST_With) + ) { + switch (self.name) { + case "undefined": + return make_node(AST_Undefined, self).optimize(compressor); + case "NaN": + return make_node(AST_NaN, self).optimize(compressor); + case "Infinity": + return make_node(AST_Infinity, self).optimize(compressor); + } + } + + if (compressor.option("reduce_vars") && !compressor.is_lhs()) { + return inline_into_symbolref(self, compressor); + } else { + return self; + } +}); + +function is_atomic(lhs, self) { + return lhs instanceof AST_SymbolRef || lhs.TYPE === self.TYPE; +} + +def_optimize(AST_Undefined, function(self, compressor) { + if (compressor.option("unsafe_undefined")) { + var undef = find_variable(compressor, "undefined"); + if (undef) { + var ref = make_node(AST_SymbolRef, self, { + name : "undefined", + scope : undef.scope, + thedef : undef + }); + set_flag(ref, UNDEFINED); + return ref; + } + } + var lhs = compressor.is_lhs(); + if (lhs && is_atomic(lhs, self)) return self; + return make_node(AST_UnaryPrefix, self, { + operator: "void", + expression: make_node(AST_Number, self, { + value: 0 + }) + }); +}); + +def_optimize(AST_Infinity, function(self, compressor) { + var lhs = compressor.is_lhs(); + if (lhs && is_atomic(lhs, self)) return self; + if ( + compressor.option("keep_infinity") + && !(lhs && !is_atomic(lhs, self)) + && !find_variable(compressor, "Infinity") + ) { + return self; + } + return make_node(AST_Binary, self, { + operator: "/", + left: make_node(AST_Number, self, { + value: 1 + }), + right: make_node(AST_Number, self, { + value: 0 + }) + }); +}); + +def_optimize(AST_NaN, function(self, compressor) { + var lhs = compressor.is_lhs(); + if (lhs && !is_atomic(lhs, self) + || find_variable(compressor, "NaN")) { + return make_node(AST_Binary, self, { + operator: "/", + left: make_node(AST_Number, self, { + value: 0 + }), + right: make_node(AST_Number, self, { + value: 0 + }) + }); + } + return self; +}); + +const ASSIGN_OPS = makePredicate("+ - / * % >> << >>> | ^ &"); +const ASSIGN_OPS_COMMUTATIVE = makePredicate("* | ^ &"); +def_optimize(AST_Assign, function(self, compressor) { + if (self.logical) { + return self.lift_sequences(compressor); + } + + var def; + // x = x ---> x + if ( + self.operator === "=" + && self.left instanceof AST_SymbolRef + && self.left.name !== "arguments" + && !(def = self.left.definition()).undeclared + && self.right.equivalent_to(self.left) + ) { + return self.right; + } + + if (compressor.option("dead_code") + && self.left instanceof AST_SymbolRef + && (def = self.left.definition()).scope === compressor.find_parent(AST_Lambda)) { + var level = 0, node, parent = self; + do { + node = parent; + parent = compressor.parent(level++); + if (parent instanceof AST_Exit) { + if (in_try(level, parent)) break; + if (is_reachable(def.scope, [ def ])) break; + if (self.operator == "=") return self.right; + def.fixed = false; + return make_node(AST_Binary, self, { + operator: self.operator.slice(0, -1), + left: self.left, + right: self.right + }).optimize(compressor); + } + } while (parent instanceof AST_Binary && parent.right === node + || parent instanceof AST_Sequence && parent.tail_node() === node); + } + self = self.lift_sequences(compressor); + + if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary) { + // x = expr1 OP expr2 + if (self.right.left instanceof AST_SymbolRef + && self.right.left.name == self.left.name + && ASSIGN_OPS.has(self.right.operator)) { + // x = x - 2 ---> x -= 2 + self.operator = self.right.operator + "="; + self.right = self.right.right; + } else if (self.right.right instanceof AST_SymbolRef + && self.right.right.name == self.left.name + && ASSIGN_OPS_COMMUTATIVE.has(self.right.operator) + && !self.right.left.has_side_effects(compressor)) { + // x = 2 & x ---> x &= 2 + self.operator = self.right.operator + "="; + self.right = self.right.left; + } + } + return self; + + function in_try(level, node) { + function may_assignment_throw() { + const right = self.right; + self.right = make_node(AST_Null, right); + const may_throw = node.may_throw(compressor); + self.right = right; + + return may_throw; + } + + var stop_at = self.left.definition().scope.get_defun_scope(); + var parent; + while ((parent = compressor.parent(level++)) !== stop_at) { + if (parent instanceof AST_Try) { + if (parent.bfinally) return true; + if (parent.bcatch && may_assignment_throw()) return true; + } + } + } +}); + +def_optimize(AST_DefaultAssign, function(self, compressor) { + if (!compressor.option("evaluate")) { + return self; + } + var evaluateRight = self.right.evaluate(compressor); + + // `[x = undefined] = foo` ---> `[x] = foo` + // `(arg = undefined) => ...` ---> `(arg) => ...` (unless `keep_fargs`) + // `((arg = undefined) => ...)()` ---> `((arg) => ...)()` + let lambda, iife; + if (evaluateRight === undefined) { + if ( + (lambda = compressor.parent()) instanceof AST_Lambda + ? ( + compressor.option("keep_fargs") === false + || (iife = compressor.parent(1)).TYPE === "Call" + && iife.expression === lambda + ) + : true + ) { + self = self.left; + } + } else if (evaluateRight !== self.right) { + evaluateRight = make_node_from_constant(evaluateRight, self.right); + self.right = best_of_expression(evaluateRight, self.right); + } + + return self; +}); + +function is_nullish_check(check, check_subject, compressor) { + if (check_subject.may_throw(compressor)) return false; + + let nullish_side; + + // foo == null + if ( + check instanceof AST_Binary + && check.operator === "==" + // which side is nullish? + && ( + (nullish_side = is_nullish(check.left, compressor) && check.left) + || (nullish_side = is_nullish(check.right, compressor) && check.right) + ) + // is the other side the same as the check_subject + && ( + nullish_side === check.left + ? check.right + : check.left + ).equivalent_to(check_subject) + ) { + return true; + } + + // foo === null || foo === undefined + if (check instanceof AST_Binary && check.operator === "||") { + let null_cmp; + let undefined_cmp; + + const find_comparison = cmp => { + if (!( + cmp instanceof AST_Binary + && (cmp.operator === "===" || cmp.operator === "==") + )) { + return false; + } + + let found = 0; + let defined_side; + + if (cmp.left instanceof AST_Null) { + found++; + null_cmp = cmp; + defined_side = cmp.right; + } + if (cmp.right instanceof AST_Null) { + found++; + null_cmp = cmp; + defined_side = cmp.left; + } + if (is_undefined(cmp.left, compressor)) { + found++; + undefined_cmp = cmp; + defined_side = cmp.right; + } + if (is_undefined(cmp.right, compressor)) { + found++; + undefined_cmp = cmp; + defined_side = cmp.left; + } + + if (found !== 1) { + return false; + } + + if (!defined_side.equivalent_to(check_subject)) { + return false; + } + + return true; + }; + + if (!find_comparison(check.left)) return false; + if (!find_comparison(check.right)) return false; + + if (null_cmp && undefined_cmp && null_cmp !== undefined_cmp) { + return true; + } + } + + return false; +} + +def_optimize(AST_Conditional, function(self, compressor) { + if (!compressor.option("conditionals")) return self; + // This looks like lift_sequences(), should probably be under "sequences" + if (self.condition instanceof AST_Sequence) { + var expressions = self.condition.expressions.slice(); + self.condition = expressions.pop(); + expressions.push(self); + return make_sequence(self, expressions); + } + var cond = self.condition.evaluate(compressor); + if (cond !== self.condition) { + if (cond) { + return maintain_this_binding(compressor.parent(), compressor.self(), self.consequent); + } else { + return maintain_this_binding(compressor.parent(), compressor.self(), self.alternative); + } + } + var negated = cond.negate(compressor, first_in_statement(compressor)); + if (best_of(compressor, cond, negated) === negated) { + self = make_node(AST_Conditional, self, { + condition: negated, + consequent: self.alternative, + alternative: self.consequent + }); + } + var condition = self.condition; + var consequent = self.consequent; + var alternative = self.alternative; + // x?x:y --> x||y + if (condition instanceof AST_SymbolRef + && consequent instanceof AST_SymbolRef + && condition.definition() === consequent.definition()) { + return make_node(AST_Binary, self, { + operator: "||", + left: condition, + right: alternative + }); + } + // if (foo) exp = something; else exp = something_else; + // | + // v + // exp = foo ? something : something_else; + if ( + consequent instanceof AST_Assign + && alternative instanceof AST_Assign + && consequent.operator === alternative.operator + && consequent.logical === alternative.logical + && consequent.left.equivalent_to(alternative.left) + && (!self.condition.has_side_effects(compressor) + || consequent.operator == "=" + && !consequent.left.has_side_effects(compressor)) + ) { + return make_node(AST_Assign, self, { + operator: consequent.operator, + left: consequent.left, + logical: consequent.logical, + right: make_node(AST_Conditional, self, { + condition: self.condition, + consequent: consequent.right, + alternative: alternative.right + }) + }); + } + // x ? y(a) : y(b) --> y(x ? a : b) + var arg_index; + if (consequent instanceof AST_Call + && alternative.TYPE === consequent.TYPE + && consequent.args.length > 0 + && consequent.args.length == alternative.args.length + && consequent.expression.equivalent_to(alternative.expression) + && !self.condition.has_side_effects(compressor) + && !consequent.expression.has_side_effects(compressor) + && typeof (arg_index = single_arg_diff()) == "number") { + var node = consequent.clone(); + node.args[arg_index] = make_node(AST_Conditional, self, { + condition: self.condition, + consequent: consequent.args[arg_index], + alternative: alternative.args[arg_index] + }); + return node; + } + // a ? b : c ? b : d --> (a || c) ? b : d + if (alternative instanceof AST_Conditional + && consequent.equivalent_to(alternative.consequent)) { + return make_node(AST_Conditional, self, { + condition: make_node(AST_Binary, self, { + operator: "||", + left: condition, + right: alternative.condition + }), + consequent: consequent, + alternative: alternative.alternative + }).optimize(compressor); + } + + // a == null ? b : a -> a ?? b + if ( + compressor.option("ecma") >= 2020 && + is_nullish_check(condition, alternative, compressor) + ) { + return make_node(AST_Binary, self, { + operator: "??", + left: alternative, + right: consequent + }).optimize(compressor); + } + + // a ? b : (c, b) --> (a || c), b + if (alternative instanceof AST_Sequence + && consequent.equivalent_to(alternative.expressions[alternative.expressions.length - 1])) { + return make_sequence(self, [ + make_node(AST_Binary, self, { + operator: "||", + left: condition, + right: make_sequence(self, alternative.expressions.slice(0, -1)) + }), + consequent + ]).optimize(compressor); + } + // a ? b : (c && b) --> (a || c) && b + if (alternative instanceof AST_Binary + && alternative.operator == "&&" + && consequent.equivalent_to(alternative.right)) { + return make_node(AST_Binary, self, { + operator: "&&", + left: make_node(AST_Binary, self, { + operator: "||", + left: condition, + right: alternative.left + }), + right: consequent + }).optimize(compressor); + } + // x?y?z:a:a --> x&&y?z:a + if (consequent instanceof AST_Conditional + && consequent.alternative.equivalent_to(alternative)) { + return make_node(AST_Conditional, self, { + condition: make_node(AST_Binary, self, { + left: self.condition, + operator: "&&", + right: consequent.condition + }), + consequent: consequent.consequent, + alternative: alternative + }); + } + // x ? y : y --> x, y + if (consequent.equivalent_to(alternative)) { + return make_sequence(self, [ + self.condition, + consequent + ]).optimize(compressor); + } + // x ? y || z : z --> x && y || z + if (consequent instanceof AST_Binary + && consequent.operator == "||" + && consequent.right.equivalent_to(alternative)) { + return make_node(AST_Binary, self, { + operator: "||", + left: make_node(AST_Binary, self, { + operator: "&&", + left: self.condition, + right: consequent.left + }), + right: alternative + }).optimize(compressor); + } + + const in_bool = compressor.in_boolean_context(); + if (is_true(self.consequent)) { + if (is_false(self.alternative)) { + // c ? true : false ---> !!c + return booleanize(self.condition); + } + // c ? true : x ---> !!c || x + return make_node(AST_Binary, self, { + operator: "||", + left: booleanize(self.condition), + right: self.alternative + }); + } + if (is_false(self.consequent)) { + if (is_true(self.alternative)) { + // c ? false : true ---> !c + return booleanize(self.condition.negate(compressor)); + } + // c ? false : x ---> !c && x + return make_node(AST_Binary, self, { + operator: "&&", + left: booleanize(self.condition.negate(compressor)), + right: self.alternative + }); + } + if (is_true(self.alternative)) { + // c ? x : true ---> !c || x + return make_node(AST_Binary, self, { + operator: "||", + left: booleanize(self.condition.negate(compressor)), + right: self.consequent + }); + } + if (is_false(self.alternative)) { + // c ? x : false ---> !!c && x + return make_node(AST_Binary, self, { + operator: "&&", + left: booleanize(self.condition), + right: self.consequent + }); + } + + return self; + + function booleanize(node) { + if (node.is_boolean()) return node; + // !!expression + return make_node(AST_UnaryPrefix, node, { + operator: "!", + expression: node.negate(compressor) + }); + } + + // AST_True or !0 + function is_true(node) { + return node instanceof AST_True + || in_bool + && node instanceof AST_Constant + && node.getValue() + || (node instanceof AST_UnaryPrefix + && node.operator == "!" + && node.expression instanceof AST_Constant + && !node.expression.getValue()); + } + // AST_False or !1 + function is_false(node) { + return node instanceof AST_False + || in_bool + && node instanceof AST_Constant + && !node.getValue() + || (node instanceof AST_UnaryPrefix + && node.operator == "!" + && node.expression instanceof AST_Constant + && node.expression.getValue()); + } + + function single_arg_diff() { + var a = consequent.args; + var b = alternative.args; + for (var i = 0, len = a.length; i < len; i++) { + if (a[i] instanceof AST_Expansion) return; + if (!a[i].equivalent_to(b[i])) { + if (b[i] instanceof AST_Expansion) return; + for (var j = i + 1; j < len; j++) { + if (a[j] instanceof AST_Expansion) return; + if (!a[j].equivalent_to(b[j])) return; + } + return i; + } + } + } +}); + +def_optimize(AST_Boolean, function(self, compressor) { + if (compressor.in_boolean_context()) return make_node(AST_Number, self, { + value: +self.value + }); + var p = compressor.parent(); + if (compressor.option("booleans_as_integers")) { + if (p instanceof AST_Binary && (p.operator == "===" || p.operator == "!==")) { + p.operator = p.operator.replace(/=$/, ""); + } + return make_node(AST_Number, self, { + value: +self.value + }); + } + if (compressor.option("booleans")) { + if (p instanceof AST_Binary && (p.operator == "==" + || p.operator == "!=")) { + return make_node(AST_Number, self, { + value: +self.value + }); + } + return make_node(AST_UnaryPrefix, self, { + operator: "!", + expression: make_node(AST_Number, self, { + value: 1 - self.value + }) + }); + } + return self; +}); + +function safe_to_flatten(value, compressor) { + if (value instanceof AST_SymbolRef) { + value = value.fixed_value(); + } + if (!value) return false; + if (!(value instanceof AST_Lambda || value instanceof AST_Class)) return true; + if (!(value instanceof AST_Lambda && value.contains_this())) return true; + return compressor.parent() instanceof AST_New; +} + +AST_PropAccess.DEFMETHOD("flatten_object", function(key, compressor) { + if (!compressor.option("properties")) return; + if (key === "__proto__") return; + if (this instanceof AST_DotHash) return; + + var arrows = compressor.option("unsafe_arrows") && compressor.option("ecma") >= 2015; + var expr = this.expression; + if (expr instanceof AST_Object) { + var props = expr.properties; + + for (var i = props.length; --i >= 0;) { + var prop = props[i]; + + if ("" + (prop instanceof AST_ConciseMethod ? prop.key.name : prop.key) == key) { + const all_props_flattenable = props.every((p) => + (p instanceof AST_ObjectKeyVal + || arrows && p instanceof AST_ConciseMethod && !p.value.is_generator + ) + && !p.computed_key() + ); + + if (!all_props_flattenable) return; + if (!safe_to_flatten(prop.value, compressor)) return; + + return make_node(AST_Sub, this, { + expression: make_node(AST_Array, expr, { + elements: props.map(function(prop) { + var v = prop.value; + if (v instanceof AST_Accessor) { + v = make_node(AST_Function, v, v); + } + + var k = prop.key; + if (k instanceof AST_Node && !(k instanceof AST_SymbolMethod)) { + return make_sequence(prop, [ k, v ]); + } + + return v; + }) + }), + property: make_node(AST_Number, this, { + value: i + }) + }); + } + } + } +}); + +def_optimize(AST_Sub, function(self, compressor) { + var expr = self.expression; + var prop = self.property; + if (compressor.option("properties")) { + var key = prop.evaluate(compressor); + if (key !== prop) { + if (typeof key == "string") { + if (key == "undefined") { + key = undefined; + } else { + var value = parseFloat(key); + if (value.toString() == key) { + key = value; + } + } + } + prop = self.property = best_of_expression( + prop, + make_node_from_constant(key, prop).transform(compressor) + ); + var property = "" + key; + if (is_basic_identifier_string(property) + && property.length <= prop.size() + 1) { + return make_node(AST_Dot, self, { + expression: expr, + optional: self.optional, + property: property, + quote: prop.quote, + }).optimize(compressor); + } + } + } + var fn; + OPT_ARGUMENTS: if (compressor.option("arguments") + && expr instanceof AST_SymbolRef + && expr.name == "arguments" + && expr.definition().orig.length == 1 + && (fn = expr.scope) instanceof AST_Lambda + && fn.uses_arguments + && !(fn instanceof AST_Arrow) + && prop instanceof AST_Number) { + var index = prop.getValue(); + var params = new Set(); + var argnames = fn.argnames; + for (var n = 0; n < argnames.length; n++) { + if (!(argnames[n] instanceof AST_SymbolFunarg)) { + break OPT_ARGUMENTS; // destructuring parameter - bail + } + var param = argnames[n].name; + if (params.has(param)) { + break OPT_ARGUMENTS; // duplicate parameter - bail + } + params.add(param); + } + var argname = fn.argnames[index]; + if (argname && compressor.has_directive("use strict")) { + var def = argname.definition(); + if (!compressor.option("reduce_vars") || def.assignments || def.orig.length > 1) { + argname = null; + } + } else if (!argname && !compressor.option("keep_fargs") && index < fn.argnames.length + 5) { + while (index >= fn.argnames.length) { + argname = fn.create_symbol(AST_SymbolFunarg, { + source: fn, + scope: fn, + tentative_name: "argument_" + fn.argnames.length, + }); + fn.argnames.push(argname); + } + } + if (argname) { + var sym = make_node(AST_SymbolRef, self, argname); + sym.reference({}); + clear_flag(argname, UNUSED); + return sym; + } + } + if (compressor.is_lhs()) return self; + if (key !== prop) { + var sub = self.flatten_object(property, compressor); + if (sub) { + expr = self.expression = sub.expression; + prop = self.property = sub.property; + } + } + if (compressor.option("properties") && compressor.option("side_effects") + && prop instanceof AST_Number && expr instanceof AST_Array) { + var index = prop.getValue(); + var elements = expr.elements; + var retValue = elements[index]; + FLATTEN: if (safe_to_flatten(retValue, compressor)) { + var flatten = true; + var values = []; + for (var i = elements.length; --i > index;) { + var value = elements[i].drop_side_effect_free(compressor); + if (value) { + values.unshift(value); + if (flatten && value.has_side_effects(compressor)) flatten = false; + } + } + if (retValue instanceof AST_Expansion) break FLATTEN; + retValue = retValue instanceof AST_Hole ? make_node(AST_Undefined, retValue) : retValue; + if (!flatten) values.unshift(retValue); + while (--i >= 0) { + var value = elements[i]; + if (value instanceof AST_Expansion) break FLATTEN; + value = value.drop_side_effect_free(compressor); + if (value) values.unshift(value); + else index--; + } + if (flatten) { + values.push(retValue); + return make_sequence(self, values).optimize(compressor); + } else return make_node(AST_Sub, self, { + expression: make_node(AST_Array, expr, { + elements: values + }), + property: make_node(AST_Number, prop, { + value: index + }) + }); + } + } + var ev = self.evaluate(compressor); + if (ev !== self) { + ev = make_node_from_constant(ev, self).optimize(compressor); + return best_of(compressor, ev, self); + } + return self; +}); + +def_optimize(AST_Chain, function (self, compressor) { + if (is_nullish(self.expression, compressor)) { + let parent = compressor.parent(); + // It's valid to delete a nullish optional chain, but if we optimized + // this to `delete undefined` then it would appear to be a syntax error + // when we try to optimize the delete. Thankfully, `delete 0` is fine. + if (parent instanceof AST_UnaryPrefix && parent.operator === "delete") { + return make_node_from_constant(0, self); + } + return make_node(AST_Undefined, self); + } + if ( + self.expression instanceof AST_PropAccess + || self.expression instanceof AST_Call + ) { + return self; + } else { + // Keep the AST valid, in case the child swapped itself + return self.expression; + } +}); + +def_optimize(AST_Dot, function(self, compressor) { + const parent = compressor.parent(); + if (compressor.is_lhs()) return self; + if (compressor.option("unsafe_proto") + && self.expression instanceof AST_Dot + && self.expression.property == "prototype") { + var exp = self.expression.expression; + if (is_undeclared_ref(exp)) switch (exp.name) { + case "Array": + self.expression = make_node(AST_Array, self.expression, { + elements: [] + }); + break; + case "Function": + self.expression = make_empty_function(self.expression); + break; + case "Number": + self.expression = make_node(AST_Number, self.expression, { + value: 0 + }); + break; + case "Object": + self.expression = make_node(AST_Object, self.expression, { + properties: [] + }); + break; + case "RegExp": + self.expression = make_node(AST_RegExp, self.expression, { + value: { source: "t", flags: "" } + }); + break; + case "String": + self.expression = make_node(AST_String, self.expression, { + value: "" + }); + break; + } + } + if (!(parent instanceof AST_Call) || !has_annotation(parent, _NOINLINE)) { + const sub = self.flatten_object(self.property, compressor); + if (sub) return sub.optimize(compressor); + } + + if (self.expression instanceof AST_PropAccess + && parent instanceof AST_PropAccess) { + return self; + } + + let ev = self.evaluate(compressor); + if (ev !== self) { + ev = make_node_from_constant(ev, self).optimize(compressor); + return best_of(compressor, ev, self); + } + return self; +}); + +function literals_in_boolean_context(self, compressor) { + if (compressor.in_boolean_context()) { + return best_of(compressor, self, make_sequence(self, [ + self, + make_node(AST_True, self) + ]).optimize(compressor)); + } + return self; +} + +function inline_array_like_spread(elements) { + for (var i = 0; i < elements.length; i++) { + var el = elements[i]; + if (el instanceof AST_Expansion) { + var expr = el.expression; + if ( + expr instanceof AST_Array + && !expr.elements.some(elm => elm instanceof AST_Hole) + ) { + elements.splice(i, 1, ...expr.elements); + // Step back one, as the element at i is now new. + i--; + } + // In array-like spread, spreading a non-iterable value is TypeError. + // We therefore can’t optimize anything else, unlike with object spread. + } + } +} + +def_optimize(AST_Array, function(self, compressor) { + var optimized = literals_in_boolean_context(self, compressor); + if (optimized !== self) { + return optimized; + } + inline_array_like_spread(self.elements); + return self; +}); + +function inline_object_prop_spread(props) { + for (var i = 0; i < props.length; i++) { + var prop = props[i]; + if (prop instanceof AST_Expansion) { + const expr = prop.expression; + if ( + expr instanceof AST_Object + && expr.properties.every(prop => prop instanceof AST_ObjectKeyVal) + ) { + props.splice(i, 1, ...expr.properties); + // Step back one, as the property at i is now new. + i--; + } else if (( + // `expr.is_constant()` returns `false` for `AST_RegExp`, so need both. + expr instanceof AST_Constant + || expr.is_constant() + ) && !(expr instanceof AST_String)) { + // Unlike array-like spread, in object spread, spreading a + // non-iterable value silently does nothing; it is thus safe + // to remove. AST_String is the only iterable constant. + props.splice(i, 1); + i--; + } + } + } +} + +def_optimize(AST_Object, function(self, compressor) { + var optimized = literals_in_boolean_context(self, compressor); + if (optimized !== self) { + return optimized; + } + inline_object_prop_spread(self.properties); + return self; +}); + +def_optimize(AST_RegExp, literals_in_boolean_context); + +def_optimize(AST_Return, function(self, compressor) { + if (self.value && is_undefined(self.value, compressor)) { + self.value = null; + } + return self; +}); + +def_optimize(AST_Arrow, opt_AST_Lambda); + +def_optimize(AST_Function, function(self, compressor) { + self = opt_AST_Lambda(self, compressor); + if (compressor.option("unsafe_arrows") + && compressor.option("ecma") >= 2015 + && !self.name + && !self.is_generator + && !self.uses_arguments + && !self.pinned()) { + const uses_this = walk(self, node => { + if (node instanceof AST_This) return walk_abort; + }); + if (!uses_this) return make_node(AST_Arrow, self, self).optimize(compressor); + } + return self; +}); + +def_optimize(AST_Class, function(self) { + for (let i = 0; i < self.properties.length; i++) { + const prop = self.properties[i]; + if (prop instanceof AST_ClassStaticBlock && prop.body.length == 0) { + self.properties.splice(i, 1); + i--; + } + } + + return self; +}); + +def_optimize(AST_ClassStaticBlock, function(self, compressor) { + tighten_body(self.body, compressor); + return self; +}); + +def_optimize(AST_Yield, function(self, compressor) { + if (self.expression && !self.is_star && is_undefined(self.expression, compressor)) { + self.expression = null; + } + return self; +}); + +def_optimize(AST_TemplateString, function(self, compressor) { + if ( + !compressor.option("evaluate") + || compressor.parent() instanceof AST_PrefixedTemplateString + ) { + return self; + } + + var segments = []; + for (var i = 0; i < self.segments.length; i++) { + var segment = self.segments[i]; + if (segment instanceof AST_Node) { + var result = segment.evaluate(compressor); + // Evaluate to constant value + // Constant value shorter than ${segment} + if (result !== segment && (result + "").length <= segment.size() + "${}".length) { + // There should always be a previous and next segment if segment is a node + segments[segments.length - 1].value = segments[segments.length - 1].value + result + self.segments[++i].value; + continue; + } + // `before ${`innerBefore ${any} innerAfter`} after` => `before innerBefore ${any} innerAfter after` + // TODO: + // `before ${'test' + foo} after` => `before innerBefore ${any} innerAfter after` + // `before ${foo + 'test} after` => `before innerBefore ${any} innerAfter after` + if (segment instanceof AST_TemplateString) { + var inners = segment.segments; + segments[segments.length - 1].value += inners[0].value; + for (var j = 1; j < inners.length; j++) { + segment = inners[j]; + segments.push(segment); + } + continue; + } + } + segments.push(segment); + } + self.segments = segments; + + // `foo` => "foo" + if (segments.length == 1) { + return make_node(AST_String, self, segments[0]); + } + + if ( + segments.length === 3 + && segments[1] instanceof AST_Node + && ( + segments[1].is_string(compressor) + || segments[1].is_number_or_bigint(compressor) + || is_nullish(segments[1], compressor) + || compressor.option("unsafe") + ) + ) { + // `foo${bar}` => "foo" + bar + if (segments[2].value === "") { + return make_node(AST_Binary, self, { + operator: "+", + left: make_node(AST_String, self, { + value: segments[0].value, + }), + right: segments[1], + }); + } + // `${bar}baz` => bar + "baz" + if (segments[0].value === "") { + return make_node(AST_Binary, self, { + operator: "+", + left: segments[1], + right: make_node(AST_String, self, { + value: segments[2].value, + }), + }); + } + } + return self; +}); + +def_optimize(AST_PrefixedTemplateString, function(self) { + return self; +}); + +// ["p"]:1 ---> p:1 +// [42]:1 ---> 42:1 +function lift_key(self, compressor) { + if (!compressor.option("computed_props")) return self; + // save a comparison in the typical case + if (!(self.key instanceof AST_Constant)) return self; + // allow certain acceptable props as not all AST_Constants are true constants + if (self.key instanceof AST_String || self.key instanceof AST_Number) { + const key = self.key.value.toString(); + + if (key === "__proto__") return self; + if (key == "constructor" + && compressor.parent() instanceof AST_Class) return self; + if (self instanceof AST_ObjectKeyVal) { + self.quote = self.key.quote; + self.key = key; + } else if (self instanceof AST_ClassProperty) { + self.quote = self.key.quote; + self.key = make_node(AST_SymbolClassProperty, self.key, { + name: key, + }); + } else { + self.quote = self.key.quote; + self.key = make_node(AST_SymbolMethod, self.key, { + name: key, + }); + } + } + return self; +} + +def_optimize(AST_ObjectProperty, lift_key); + +def_optimize(AST_ConciseMethod, function(self, compressor) { + lift_key(self, compressor); + // p(){return x;} ---> p:()=>x + if (compressor.option("arrows") + && compressor.parent() instanceof AST_Object + && !self.value.is_generator + && !self.value.uses_arguments + && !self.value.pinned() + && self.value.body.length == 1 + && self.value.body[0] instanceof AST_Return + && self.value.body[0].value + && !self.value.contains_this()) { + var arrow = make_node(AST_Arrow, self.value, self.value); + arrow.async = self.value.async; + arrow.is_generator = self.value.is_generator; + return make_node(AST_ObjectKeyVal, self, { + key: self.key instanceof AST_SymbolMethod ? self.key.name : self.key, + value: arrow, + quote: self.quote, + }); + } + return self; +}); + +def_optimize(AST_ObjectKeyVal, function(self, compressor) { + lift_key(self, compressor); + // p:function(){} ---> p(){} + // p:function*(){} ---> *p(){} + // p:async function(){} ---> async p(){} + // p:()=>{} ---> p(){} + // p:async()=>{} ---> async p(){} + var unsafe_methods = compressor.option("unsafe_methods"); + if (unsafe_methods + && compressor.option("ecma") >= 2015 + && (!(unsafe_methods instanceof RegExp) || unsafe_methods.test(self.key + ""))) { + var key = self.key; + var value = self.value; + var is_arrow_with_block = value instanceof AST_Arrow + && Array.isArray(value.body) + && !value.contains_this(); + if ((is_arrow_with_block || value instanceof AST_Function) && !value.name) { + return make_node(AST_ConciseMethod, self, { + key: key instanceof AST_Node ? key : make_node(AST_SymbolMethod, self, { + name: key, + }), + value: make_node(AST_Accessor, value, value), + quote: self.quote, + }); + } + } + return self; +}); + +def_optimize(AST_Destructuring, function(self, compressor) { + if (compressor.option("pure_getters") == true + && compressor.option("unused") + && !self.is_array + && Array.isArray(self.names) + && !is_destructuring_export_decl(compressor) + && !(self.names[self.names.length - 1] instanceof AST_Expansion)) { + var keep = []; + for (var i = 0; i < self.names.length; i++) { + var elem = self.names[i]; + if (!(elem instanceof AST_ObjectKeyVal + && typeof elem.key == "string" + && elem.value instanceof AST_SymbolDeclaration + && !should_retain(compressor, elem.value.definition()))) { + keep.push(elem); + } + } + if (keep.length != self.names.length) { + self.names = keep; + } + } + return self; + + function is_destructuring_export_decl(compressor) { + var ancestors = [/^VarDef$/, /^(Const|Let|Var)$/, /^Export$/]; + for (var a = 0, p = 0, len = ancestors.length; a < len; p++) { + var parent = compressor.parent(p); + if (!parent) return false; + if (a === 0 && parent.TYPE == "Destructuring") continue; + if (!ancestors[a].test(parent.TYPE)) { + return false; + } + a++; + } + return true; + } + + function should_retain(compressor, def) { + if (def.references.length) return true; + if (!def.global) return false; + if (compressor.toplevel.vars) { + if (compressor.top_retain) { + return compressor.top_retain(def); + } + return false; + } + return true; + } +}); + +export { + Compressor, +}; diff --git a/node_modules/terser/lib/compress/inference.js b/node_modules/terser/lib/compress/inference.js new file mode 100644 index 0000000..0a3da37 --- /dev/null +++ b/node_modules/terser/lib/compress/inference.js @@ -0,0 +1,1128 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +import { + AST_Array, + AST_Arrow, + AST_Assign, + AST_BigInt, + AST_Binary, + AST_Block, + AST_BlockStatement, + AST_Call, + AST_Case, + AST_Chain, + AST_Class, + AST_DefClass, + AST_ClassStaticBlock, + AST_ClassPrivateProperty, + AST_ClassProperty, + AST_ConciseMethod, + AST_Conditional, + AST_Constant, + AST_Definitions, + AST_Dot, + AST_EmptyStatement, + AST_Expansion, + AST_False, + AST_ForIn, + AST_Function, + AST_If, + AST_Import, + AST_ImportMeta, + AST_Jump, + AST_LabeledStatement, + AST_Lambda, + AST_New, + AST_Node, + AST_Null, + AST_Number, + AST_Object, + AST_ObjectGetter, + AST_ObjectKeyVal, + AST_ObjectProperty, + AST_ObjectSetter, + AST_PrivateGetter, + AST_PrivateMethod, + AST_PrivateSetter, + AST_PropAccess, + AST_RegExp, + AST_Return, + AST_Scope, + AST_Sequence, + AST_SimpleStatement, + AST_Statement, + AST_String, + AST_Sub, + AST_Switch, + AST_SwitchBranch, + AST_SymbolClassProperty, + AST_SymbolDeclaration, + AST_SymbolRef, + AST_TemplateSegment, + AST_TemplateString, + AST_This, + AST_True, + AST_Try, + AST_Unary, + AST_UnaryPostfix, + AST_UnaryPrefix, + AST_Undefined, + AST_VarDef, + + walk, + walk_abort, + + _PURE +} from "../ast.js"; +import { + makePredicate, + return_true, + return_false, + return_null, + return_this, + make_node, + member, + has_annotation, +} from "../utils/index.js"; +import { make_sequence, best_of_expression, read_property, requires_sequence_to_maintain_binding } from "./common.js"; + +import { INLINED, UNDEFINED, has_flag } from "./compressor-flags.js"; +import { pure_prop_access_globals, is_pure_native_fn, is_pure_native_method } from "./native-objects.js"; + +// Functions and methods to infer certain facts about expressions +// It's not always possible to be 100% sure about something just by static analysis, +// so `true` means yes, and `false` means maybe + +export const is_undeclared_ref = (node) => + node instanceof AST_SymbolRef && node.definition().undeclared; + +export const bitwise_binop = makePredicate("<<< >> << & | ^ ~"); +export const lazy_op = makePredicate("&& || ??"); +export const unary_side_effects = makePredicate("delete ++ --"); + +// methods to determine whether an expression has a boolean result type +(function(def_is_boolean) { + const unary_bool = makePredicate("! delete"); + const binary_bool = makePredicate("in instanceof == != === !== < <= >= >"); + def_is_boolean(AST_Node, return_false); + def_is_boolean(AST_UnaryPrefix, function() { + return unary_bool.has(this.operator); + }); + def_is_boolean(AST_Binary, function() { + return binary_bool.has(this.operator) + || lazy_op.has(this.operator) + && this.left.is_boolean() + && this.right.is_boolean(); + }); + def_is_boolean(AST_Conditional, function() { + return this.consequent.is_boolean() && this.alternative.is_boolean(); + }); + def_is_boolean(AST_Assign, function() { + return this.operator == "=" && this.right.is_boolean(); + }); + def_is_boolean(AST_Sequence, function() { + return this.tail_node().is_boolean(); + }); + def_is_boolean(AST_True, return_true); + def_is_boolean(AST_False, return_true); +})(function(node, func) { + node.DEFMETHOD("is_boolean", func); +}); + +// methods to determine if an expression has a numeric result type +(function(def_is_number) { + def_is_number(AST_Node, return_false); + def_is_number(AST_Number, return_true); + const unary = makePredicate("+ - ~ ++ --"); + def_is_number(AST_Unary, function(compressor) { + return unary.has(this.operator) && this.expression.is_number(compressor); + }); + const numeric_ops = makePredicate("- * / % & | ^ << >> >>>"); + def_is_number(AST_Binary, function(compressor) { + if (this.operator === "+") { + // Both sides need to be `number`. Or one is a `number` and the other is number-ish. + return this.left.is_number(compressor) && this.right.is_number_or_bigint(compressor) + || this.right.is_number(compressor) && this.left.is_number_or_bigint(compressor); + } else if (numeric_ops.has(this.operator)) { + return this.left.is_number(compressor) || this.right.is_number(compressor); + } else { + return false; + } + }); + def_is_number(AST_Assign, function(compressor) { + return (this.operator === "=" || numeric_ops.has(this.operator.slice(0, -1))) + && this.right.is_number(compressor); + }); + def_is_number(AST_Sequence, function(compressor) { + return this.tail_node().is_number(compressor); + }); + def_is_number(AST_Conditional, function(compressor) { + return this.consequent.is_number(compressor) && this.alternative.is_number(compressor); + }); +})(function(node, func) { + node.DEFMETHOD("is_number", func); +}); + +// methods to determine if an expression returns a BigInt +(function(def_is_bigint) { + def_is_bigint(AST_Node, return_false); + def_is_bigint(AST_BigInt, return_true); + const unary = makePredicate("+ - ~ ++ --"); + def_is_bigint(AST_Unary, function(compressor) { + return unary.has(this.operator) && this.expression.is_bigint(compressor); + }); + const numeric_ops = makePredicate("- * / % & | ^ << >>"); + def_is_bigint(AST_Binary, function(compressor) { + if (this.operator === "+") { + return this.left.is_bigint(compressor) && this.right.is_number_or_bigint(compressor) + || this.right.is_bigint(compressor) && this.left.is_number_or_bigint(compressor); + } else if (numeric_ops.has(this.operator)) { + return this.left.is_bigint(compressor) || this.right.is_bigint(compressor); + } else { + return false; + } + }); + def_is_bigint(AST_Assign, function(compressor) { + return (numeric_ops.has(this.operator.slice(0, -1)) || this.operator == "=") + && this.right.is_bigint(compressor); + }); + def_is_bigint(AST_Sequence, function(compressor) { + return this.tail_node().is_bigint(compressor); + }); + def_is_bigint(AST_Conditional, function(compressor) { + return this.consequent.is_bigint(compressor) && this.alternative.is_bigint(compressor); + }); +})(function(node, func) { + node.DEFMETHOD("is_bigint", func); +}); + +// methods to determine if an expression is a number or a bigint +(function(def_is_number_or_bigint) { + def_is_number_or_bigint(AST_Node, return_false); + def_is_number_or_bigint(AST_Number, return_true); + def_is_number_or_bigint(AST_BigInt, return_true); + const numeric_unary_ops = makePredicate("+ - ~ ++ --"); + def_is_number_or_bigint(AST_Unary, function(_compressor) { + return numeric_unary_ops.has(this.operator); + }); + const numeric_ops = makePredicate("- * / % & | ^ << >>"); + def_is_number_or_bigint(AST_Binary, function(compressor) { + return this.operator === "+" + ? this.left.is_number_or_bigint(compressor) && this.right.is_number_or_bigint(compressor) + : numeric_ops.has(this.operator); + }); + def_is_number_or_bigint(AST_Assign, function(compressor) { + return numeric_ops.has(this.operator.slice(0, -1)) + || this.operator == "=" && this.right.is_number_or_bigint(compressor); + }); + def_is_number_or_bigint(AST_Sequence, function(compressor) { + return this.tail_node().is_number_or_bigint(compressor); + }); + def_is_number_or_bigint(AST_Conditional, function(compressor) { + return this.consequent.is_number_or_bigint(compressor) && this.alternative.is_number_or_bigint(compressor); + }); +}(function (node, func) { + node.DEFMETHOD("is_number_or_bigint", func); +})); + + +// methods to determine if an expression is a 32 bit integer (IE results from bitwise ops, or is an integer constant fitting in that size +(function(def_is_32_bit_integer) { + def_is_32_bit_integer(AST_Node, return_false); + def_is_32_bit_integer(AST_Number, function(_compressor) { + return this.value === (this.value | 0); + }); + def_is_32_bit_integer(AST_UnaryPrefix, function(compressor) { + return this.operator == "~" ? this.expression.is_number(compressor) + : this.operator === "+" ? this.expression.is_32_bit_integer(compressor) + : false; + }); + def_is_32_bit_integer(AST_Binary, function(compressor) { + return bitwise_binop.has(this.operator) + && (this.left.is_number(compressor) || this.right.is_number(compressor)); + }); +}(function (node, func) { + node.DEFMETHOD("is_32_bit_integer", func); +})); + +// methods to determine if an expression has a string result type +(function(def_is_string) { + def_is_string(AST_Node, return_false); + def_is_string(AST_String, return_true); + def_is_string(AST_TemplateString, return_true); + def_is_string(AST_UnaryPrefix, function() { + return this.operator == "typeof"; + }); + def_is_string(AST_Binary, function(compressor) { + return this.operator == "+" && + (this.left.is_string(compressor) || this.right.is_string(compressor)); + }); + def_is_string(AST_Assign, function(compressor) { + return (this.operator == "=" || this.operator == "+=") && this.right.is_string(compressor); + }); + def_is_string(AST_Sequence, function(compressor) { + return this.tail_node().is_string(compressor); + }); + def_is_string(AST_Conditional, function(compressor) { + return this.consequent.is_string(compressor) && this.alternative.is_string(compressor); + }); +})(function(node, func) { + node.DEFMETHOD("is_string", func); +}); + +export function is_undefined(node, compressor) { + return ( + has_flag(node, UNDEFINED) + || node instanceof AST_Undefined + || node instanceof AST_UnaryPrefix + && node.operator == "void" + && !node.expression.has_side_effects(compressor) + ); +} + +// Is the node explicitly null or undefined. +function is_null_or_undefined(node, compressor) { + let fixed; + return ( + node instanceof AST_Null + || is_undefined(node, compressor) + || ( + node instanceof AST_SymbolRef + && (fixed = node.definition().fixed) instanceof AST_Node + && is_nullish(fixed, compressor) + ) + ); +} + +// Find out if this expression is optionally chained from a base-point that we +// can statically analyze as null or undefined. +export function is_nullish_shortcircuited(node, compressor) { + if (node instanceof AST_PropAccess || node instanceof AST_Call) { + return ( + (node.optional && is_null_or_undefined(node.expression, compressor)) + || is_nullish_shortcircuited(node.expression, compressor) + ); + } + if (node instanceof AST_Chain) return is_nullish_shortcircuited(node.expression, compressor); + return false; +} + +// Find out if something is == null, or can short circuit into nullish. +// Used to optimize ?. and ?? +export function is_nullish(node, compressor) { + if (is_null_or_undefined(node, compressor)) return true; + return is_nullish_shortcircuited(node, compressor); +} + +// Determine if expression might cause side effects +// If there's a possibility that a node may change something when it's executed, this returns true +(function(def_has_side_effects) { + def_has_side_effects(AST_Node, return_true); + + def_has_side_effects(AST_EmptyStatement, return_false); + def_has_side_effects(AST_Constant, return_false); + def_has_side_effects(AST_This, return_false); + + function any(list, compressor) { + for (var i = list.length; --i >= 0;) + if (list[i].has_side_effects(compressor)) + return true; + return false; + } + + def_has_side_effects(AST_Block, function(compressor) { + return any(this.body, compressor); + }); + def_has_side_effects(AST_Call, function(compressor) { + if ( + !this.is_callee_pure(compressor) + && (!this.expression.is_call_pure(compressor) + || this.expression.has_side_effects(compressor)) + ) { + return true; + } + return any(this.args, compressor); + }); + def_has_side_effects(AST_Switch, function(compressor) { + return this.expression.has_side_effects(compressor) + || any(this.body, compressor); + }); + def_has_side_effects(AST_Case, function(compressor) { + return this.expression.has_side_effects(compressor) + || any(this.body, compressor); + }); + def_has_side_effects(AST_Try, function(compressor) { + return this.body.has_side_effects(compressor) + || this.bcatch && this.bcatch.has_side_effects(compressor) + || this.bfinally && this.bfinally.has_side_effects(compressor); + }); + def_has_side_effects(AST_If, function(compressor) { + return this.condition.has_side_effects(compressor) + || this.body && this.body.has_side_effects(compressor) + || this.alternative && this.alternative.has_side_effects(compressor); + }); + def_has_side_effects(AST_ImportMeta, return_false); + def_has_side_effects(AST_LabeledStatement, function(compressor) { + return this.body.has_side_effects(compressor); + }); + def_has_side_effects(AST_SimpleStatement, function(compressor) { + return this.body.has_side_effects(compressor); + }); + def_has_side_effects(AST_Lambda, return_false); + def_has_side_effects(AST_Class, function (compressor) { + if (this.extends && this.extends.has_side_effects(compressor)) { + return true; + } + return any(this.properties, compressor); + }); + def_has_side_effects(AST_ClassStaticBlock, function(compressor) { + return any(this.body, compressor); + }); + def_has_side_effects(AST_Binary, function(compressor) { + return this.left.has_side_effects(compressor) + || this.right.has_side_effects(compressor); + }); + def_has_side_effects(AST_Assign, return_true); + def_has_side_effects(AST_Conditional, function(compressor) { + return this.condition.has_side_effects(compressor) + || this.consequent.has_side_effects(compressor) + || this.alternative.has_side_effects(compressor); + }); + def_has_side_effects(AST_Unary, function(compressor) { + return unary_side_effects.has(this.operator) + || this.expression.has_side_effects(compressor); + }); + def_has_side_effects(AST_SymbolRef, function(compressor) { + return !this.is_declared(compressor) && !pure_prop_access_globals.has(this.name); + }); + def_has_side_effects(AST_SymbolClassProperty, return_false); + def_has_side_effects(AST_SymbolDeclaration, return_false); + def_has_side_effects(AST_Object, function(compressor) { + return any(this.properties, compressor); + }); + def_has_side_effects(AST_ObjectKeyVal, function(compressor) { + return ( + this.computed_key() && this.key.has_side_effects(compressor) + || this.value && this.value.has_side_effects(compressor) + ); + }); + def_has_side_effects([ + AST_ClassProperty, + AST_ClassPrivateProperty, + ], function(compressor) { + return ( + this.computed_key() && this.key.has_side_effects(compressor) + || this.static && this.value && this.value.has_side_effects(compressor) + ); + }); + def_has_side_effects([ + AST_PrivateMethod, + AST_PrivateGetter, + AST_PrivateSetter, + AST_ConciseMethod, + AST_ObjectGetter, + AST_ObjectSetter, + ], function(compressor) { + return this.computed_key() && this.key.has_side_effects(compressor); + }); + def_has_side_effects(AST_Array, function(compressor) { + return any(this.elements, compressor); + }); + def_has_side_effects(AST_Dot, function(compressor) { + if (is_nullish(this, compressor)) { + return this.expression.has_side_effects(compressor); + } + if (!this.optional && this.expression.may_throw_on_access(compressor)) { + return true; + } + + return this.expression.has_side_effects(compressor); + }); + def_has_side_effects(AST_Sub, function(compressor) { + if (is_nullish(this, compressor)) { + return this.expression.has_side_effects(compressor); + } + if (!this.optional && this.expression.may_throw_on_access(compressor)) { + return true; + } + + var property = this.property.has_side_effects(compressor); + if (property && this.optional) return true; // "?." is a condition + + return property || this.expression.has_side_effects(compressor); + }); + def_has_side_effects(AST_Chain, function (compressor) { + return this.expression.has_side_effects(compressor); + }); + def_has_side_effects(AST_Sequence, function(compressor) { + return any(this.expressions, compressor); + }); + def_has_side_effects(AST_Definitions, function(compressor) { + return any(this.definitions, compressor); + }); + def_has_side_effects(AST_VarDef, function() { + return this.value != null; + }); + def_has_side_effects(AST_TemplateSegment, return_false); + def_has_side_effects(AST_TemplateString, function(compressor) { + return any(this.segments, compressor); + }); +})(function(node_or_nodes, func) { + for (const node of [].concat(node_or_nodes)) { + node.DEFMETHOD("has_side_effects", func); + } +}); + +// determine if expression may throw +(function(def_may_throw) { + def_may_throw(AST_Node, return_true); + + def_may_throw(AST_Constant, return_false); + def_may_throw(AST_EmptyStatement, return_false); + def_may_throw(AST_Lambda, return_false); + def_may_throw(AST_SymbolDeclaration, return_false); + def_may_throw(AST_This, return_false); + def_may_throw(AST_ImportMeta, return_false); + + function any(list, compressor) { + for (var i = list.length; --i >= 0;) + if (list[i].may_throw(compressor)) + return true; + return false; + } + + def_may_throw(AST_Class, function(compressor) { + if (this.extends && this.extends.may_throw(compressor)) return true; + return any(this.properties, compressor); + }); + def_may_throw(AST_ClassStaticBlock, function (compressor) { + return any(this.body, compressor); + }); + + def_may_throw(AST_Array, function(compressor) { + return any(this.elements, compressor); + }); + def_may_throw(AST_Assign, function(compressor) { + if (this.right.may_throw(compressor)) return true; + if (!compressor.has_directive("use strict") + && this.operator == "=" + && this.left instanceof AST_SymbolRef) { + return false; + } + return this.left.may_throw(compressor); + }); + def_may_throw(AST_Binary, function(compressor) { + return this.left.may_throw(compressor) + || this.right.may_throw(compressor); + }); + def_may_throw(AST_Block, function(compressor) { + return any(this.body, compressor); + }); + def_may_throw(AST_Call, function(compressor) { + if (is_nullish(this, compressor)) return false; + if (any(this.args, compressor)) return true; + if (this.is_callee_pure(compressor)) return false; + if (this.expression.may_throw(compressor)) return true; + return !(this.expression instanceof AST_Lambda) + || any(this.expression.body, compressor); + }); + def_may_throw(AST_Case, function(compressor) { + return this.expression.may_throw(compressor) + || any(this.body, compressor); + }); + def_may_throw(AST_Conditional, function(compressor) { + return this.condition.may_throw(compressor) + || this.consequent.may_throw(compressor) + || this.alternative.may_throw(compressor); + }); + def_may_throw(AST_Definitions, function(compressor) { + return any(this.definitions, compressor); + }); + def_may_throw(AST_If, function(compressor) { + return this.condition.may_throw(compressor) + || this.body && this.body.may_throw(compressor) + || this.alternative && this.alternative.may_throw(compressor); + }); + def_may_throw(AST_LabeledStatement, function(compressor) { + return this.body.may_throw(compressor); + }); + def_may_throw(AST_Object, function(compressor) { + return any(this.properties, compressor); + }); + def_may_throw(AST_ObjectKeyVal, function(compressor) { + return ( + this.computed_key() && this.key.may_throw(compressor) + || this.value ? this.value.may_throw(compressor) : false + ); + }); + def_may_throw([ + AST_ClassProperty, + AST_ClassPrivateProperty, + ], function(compressor) { + return ( + this.computed_key() && this.key.may_throw(compressor) + || this.static && this.value && this.value.may_throw(compressor) + ); + }); + def_may_throw([ + AST_ConciseMethod, + AST_ObjectGetter, + AST_ObjectSetter, + ], function(compressor) { + return this.computed_key() && this.key.may_throw(compressor); + }); + def_may_throw([ + AST_PrivateMethod, + AST_PrivateGetter, + AST_PrivateSetter, + ], return_false); + def_may_throw(AST_Return, function(compressor) { + return this.value && this.value.may_throw(compressor); + }); + def_may_throw(AST_Sequence, function(compressor) { + return any(this.expressions, compressor); + }); + def_may_throw(AST_SimpleStatement, function(compressor) { + return this.body.may_throw(compressor); + }); + def_may_throw(AST_Dot, function(compressor) { + if (is_nullish(this, compressor)) return false; + return !this.optional && this.expression.may_throw_on_access(compressor) + || this.expression.may_throw(compressor); + }); + def_may_throw(AST_Sub, function(compressor) { + if (is_nullish(this, compressor)) return false; + return !this.optional && this.expression.may_throw_on_access(compressor) + || this.expression.may_throw(compressor) + || this.property.may_throw(compressor); + }); + def_may_throw(AST_Chain, function(compressor) { + return this.expression.may_throw(compressor); + }); + def_may_throw(AST_Switch, function(compressor) { + return this.expression.may_throw(compressor) + || any(this.body, compressor); + }); + def_may_throw(AST_SymbolRef, function(compressor) { + return !this.is_declared(compressor) && !pure_prop_access_globals.has(this.name); + }); + def_may_throw(AST_SymbolClassProperty, return_false); + def_may_throw(AST_Try, function(compressor) { + return this.bcatch ? this.bcatch.may_throw(compressor) : this.body.may_throw(compressor) + || this.bfinally && this.bfinally.may_throw(compressor); + }); + def_may_throw(AST_Unary, function(compressor) { + if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef) + return false; + return this.expression.may_throw(compressor); + }); + def_may_throw(AST_VarDef, function(compressor) { + if (!this.value) return false; + return this.value.may_throw(compressor); + }); +})(function(node_or_nodes, func) { + for (const node of [].concat(node_or_nodes)) { + node.DEFMETHOD("may_throw", func); + } +}); + +// determine if expression is constant +(function(def_is_constant_expression) { + function all_refs_local(scope) { + let result = true; + walk(this, node => { + if (node instanceof AST_SymbolRef) { + if (has_flag(this, INLINED)) { + result = false; + return walk_abort; + } + var def = node.definition(); + if ( + member(def, this.enclosed) + && !this.variables.has(def.name) + ) { + if (scope) { + var scope_def = scope.find_variable(node); + if (def.undeclared ? !scope_def : scope_def === def) { + result = "f"; + return true; + } + } + result = false; + return walk_abort; + } + return true; + } + if (node instanceof AST_This && this instanceof AST_Arrow) { + result = false; + return walk_abort; + } + }); + return result; + } + + def_is_constant_expression(AST_Node, return_false); + def_is_constant_expression(AST_Constant, return_true); + def_is_constant_expression(AST_Class, function(scope) { + if (this.extends && !this.extends.is_constant_expression(scope)) { + return false; + } + + for (const prop of this.properties) { + if (prop.computed_key() && !prop.key.is_constant_expression(scope)) { + return false; + } + if (prop.static && prop.value && !prop.value.is_constant_expression(scope)) { + return false; + } + if (prop instanceof AST_ClassStaticBlock) { + return false; + } + } + + return all_refs_local.call(this, scope); + }); + def_is_constant_expression(AST_Lambda, all_refs_local); + def_is_constant_expression(AST_Unary, function() { + return this.expression.is_constant_expression(); + }); + def_is_constant_expression(AST_Binary, function() { + return this.left.is_constant_expression() + && this.right.is_constant_expression(); + }); + def_is_constant_expression(AST_Array, function() { + return this.elements.every((l) => l.is_constant_expression()); + }); + def_is_constant_expression(AST_Object, function() { + return this.properties.every((l) => l.is_constant_expression()); + }); + def_is_constant_expression(AST_ObjectProperty, function() { + return !!(!(this.key instanceof AST_Node) && this.value && this.value.is_constant_expression()); + }); +})(function(node, func) { + node.DEFMETHOD("is_constant_expression", func); +}); + + +// may_throw_on_access() +// returns true if this node may be null, undefined or contain `AST_Accessor` +(function(def_may_throw_on_access) { + AST_Node.DEFMETHOD("may_throw_on_access", function(compressor) { + return !compressor.option("pure_getters") + || this._dot_throw(compressor); + }); + + function is_strict(compressor) { + return /strict/.test(compressor.option("pure_getters")); + } + + def_may_throw_on_access(AST_Node, is_strict); + def_may_throw_on_access(AST_Null, return_true); + def_may_throw_on_access(AST_Undefined, return_true); + def_may_throw_on_access(AST_Constant, return_false); + def_may_throw_on_access(AST_Array, return_false); + def_may_throw_on_access(AST_Object, function(compressor) { + if (!is_strict(compressor)) return false; + for (var i = this.properties.length; --i >=0;) + if (this.properties[i]._dot_throw(compressor)) return true; + return false; + }); + // Do not be as strict with classes as we are with objects. + // Hopefully the community is not going to abuse static getters and setters. + // https://github.com/terser/terser/issues/724#issuecomment-643655656 + def_may_throw_on_access(AST_Class, return_false); + def_may_throw_on_access(AST_ObjectProperty, return_false); + def_may_throw_on_access(AST_ObjectGetter, return_true); + def_may_throw_on_access(AST_Expansion, function(compressor) { + return this.expression._dot_throw(compressor); + }); + def_may_throw_on_access(AST_Function, return_false); + def_may_throw_on_access(AST_Arrow, return_false); + def_may_throw_on_access(AST_UnaryPostfix, return_false); + def_may_throw_on_access(AST_UnaryPrefix, function() { + return this.operator == "void"; + }); + def_may_throw_on_access(AST_Binary, function(compressor) { + return (this.operator == "&&" || this.operator == "||" || this.operator == "??") + && (this.left._dot_throw(compressor) || this.right._dot_throw(compressor)); + }); + def_may_throw_on_access(AST_Assign, function(compressor) { + if (this.logical) return true; + + return this.operator == "=" + && this.right._dot_throw(compressor); + }); + def_may_throw_on_access(AST_Conditional, function(compressor) { + return this.consequent._dot_throw(compressor) + || this.alternative._dot_throw(compressor); + }); + def_may_throw_on_access(AST_Dot, function(compressor) { + if (!is_strict(compressor)) return false; + + if (this.property == "prototype") { + return !( + this.expression instanceof AST_Function + || this.expression instanceof AST_Class + ); + } + return true; + }); + def_may_throw_on_access(AST_Chain, function(compressor) { + return this.expression._dot_throw(compressor); + }); + def_may_throw_on_access(AST_Sequence, function(compressor) { + return this.tail_node()._dot_throw(compressor); + }); + def_may_throw_on_access(AST_SymbolRef, function(compressor) { + if (this.name === "arguments" && this.scope instanceof AST_Lambda) return false; + if (has_flag(this, UNDEFINED)) return true; + if (!is_strict(compressor)) return false; + if (is_undeclared_ref(this) && this.is_declared(compressor)) return false; + if (this.is_immutable()) return false; + var fixed = this.fixed_value(); + return !fixed || fixed._dot_throw(compressor); + }); +})(function(node, func) { + node.DEFMETHOD("_dot_throw", func); +}); + +export function is_lhs(node, parent) { + if (parent instanceof AST_Unary && unary_side_effects.has(parent.operator)) return parent.expression; + if (parent instanceof AST_Assign && parent.left === node) return node; + if (parent instanceof AST_ForIn && parent.init === node) return node; +} + +// method to negate an expression +(function(def_negate) { + function basic_negation(exp) { + return make_node(AST_UnaryPrefix, exp, { + operator: "!", + expression: exp + }); + } + function best(orig, alt, first_in_statement) { + var negated = basic_negation(orig); + if (first_in_statement) { + var stat = make_node(AST_SimpleStatement, alt, { + body: alt + }); + return best_of_expression(negated, stat) === stat ? alt : negated; + } + return best_of_expression(negated, alt); + } + def_negate(AST_Node, function() { + return basic_negation(this); + }); + def_negate(AST_Statement, function() { + throw new Error("Cannot negate a statement"); + }); + def_negate(AST_Function, function() { + return basic_negation(this); + }); + def_negate(AST_Class, function() { + return basic_negation(this); + }); + def_negate(AST_Arrow, function() { + return basic_negation(this); + }); + def_negate(AST_UnaryPrefix, function() { + if (this.operator == "!") + return this.expression; + return basic_negation(this); + }); + def_negate(AST_Sequence, function(compressor) { + var expressions = this.expressions.slice(); + expressions.push(expressions.pop().negate(compressor)); + return make_sequence(this, expressions); + }); + def_negate(AST_Conditional, function(compressor, first_in_statement) { + var self = this.clone(); + self.consequent = self.consequent.negate(compressor); + self.alternative = self.alternative.negate(compressor); + return best(this, self, first_in_statement); + }); + def_negate(AST_Binary, function(compressor, first_in_statement) { + var self = this.clone(), op = this.operator; + if (compressor.option("unsafe_comps")) { + switch (op) { + case "<=" : self.operator = ">" ; return self; + case "<" : self.operator = ">=" ; return self; + case ">=" : self.operator = "<" ; return self; + case ">" : self.operator = "<=" ; return self; + } + } + switch (op) { + case "==" : self.operator = "!="; return self; + case "!=" : self.operator = "=="; return self; + case "===": self.operator = "!=="; return self; + case "!==": self.operator = "==="; return self; + case "&&": + self.operator = "||"; + self.left = self.left.negate(compressor, first_in_statement); + self.right = self.right.negate(compressor); + return best(this, self, first_in_statement); + case "||": + self.operator = "&&"; + self.left = self.left.negate(compressor, first_in_statement); + self.right = self.right.negate(compressor); + return best(this, self, first_in_statement); + } + return basic_negation(this); + }); +})(function(node, func) { + node.DEFMETHOD("negate", function(compressor, first_in_statement) { + return func.call(this, compressor, first_in_statement); + }); +}); + +(function (def_bitwise_negate) { + function basic_bitwise_negation(exp) { + return make_node(AST_UnaryPrefix, exp, { + operator: "~", + expression: exp + }); + } + + def_bitwise_negate(AST_Node, function(_compressor) { + return basic_bitwise_negation(this); + }); + + def_bitwise_negate(AST_Number, function(_compressor) { + const neg = ~this.value; + if (neg.toString().length > this.value.toString().length) { + return basic_bitwise_negation(this); + } + return make_node(AST_Number, this, { value: neg }); + }); + + def_bitwise_negate(AST_UnaryPrefix, function(compressor, in_32_bit_context) { + if ( + this.operator == "~" + && ( + this.expression.is_32_bit_integer(compressor) || + (in_32_bit_context != null ? in_32_bit_context : compressor.in_32_bit_context()) + ) + ) { + return this.expression; + } else { + return basic_bitwise_negation(this); + } + }); +})(function (node, func) { + node.DEFMETHOD("bitwise_negate", func); +}); + +// Is the callee of this function pure? +var global_pure_fns = makePredicate("Boolean decodeURI decodeURIComponent Date encodeURI encodeURIComponent Error escape EvalError isFinite isNaN Number Object parseFloat parseInt RangeError ReferenceError String SyntaxError TypeError unescape URIError"); +AST_Call.DEFMETHOD("is_callee_pure", function(compressor) { + if (compressor.option("unsafe")) { + var expr = this.expression; + var first_arg = (this.args && this.args[0] && this.args[0].evaluate(compressor)); + if ( + expr.expression && expr.expression.name === "hasOwnProperty" && + (first_arg == null || first_arg.thedef && first_arg.thedef.undeclared) + ) { + return false; + } + if (is_undeclared_ref(expr) && global_pure_fns.has(expr.name)) return true; + if ( + expr instanceof AST_Dot + && is_undeclared_ref(expr.expression) + && is_pure_native_fn(expr.expression.name, expr.property) + ) { + return true; + } + } + if ((this instanceof AST_New) && compressor.option("pure_new")) { + return true; + } + if (compressor.option("side_effects") && has_annotation(this, _PURE)) { + return true; + } + return !compressor.pure_funcs(this); +}); + +// If I call this, is it a pure function? +AST_Node.DEFMETHOD("is_call_pure", return_false); +AST_Dot.DEFMETHOD("is_call_pure", function(compressor) { + if (!compressor.option("unsafe")) return; + const expr = this.expression; + + let native_obj; + if (expr instanceof AST_Array) { + native_obj = "Array"; + } else if (expr.is_boolean()) { + native_obj = "Boolean"; + } else if (expr.is_number(compressor)) { + native_obj = "Number"; + } else if (expr instanceof AST_RegExp) { + native_obj = "RegExp"; + } else if (expr.is_string(compressor)) { + native_obj = "String"; + } else if (!this.may_throw_on_access(compressor)) { + native_obj = "Object"; + } + return native_obj != null && is_pure_native_method(native_obj, this.property); +}); + +// tell me if a statement aborts +export const aborts = (thing) => thing && thing.aborts(); + +(function(def_aborts) { + def_aborts(AST_Statement, return_null); + def_aborts(AST_Jump, return_this); + function block_aborts() { + for (var i = 0; i < this.body.length; i++) { + if (aborts(this.body[i])) { + return this.body[i]; + } + } + return null; + } + def_aborts(AST_Import, return_null); + def_aborts(AST_BlockStatement, block_aborts); + def_aborts(AST_SwitchBranch, block_aborts); + def_aborts(AST_DefClass, function () { + for (const prop of this.properties) { + if (prop instanceof AST_ClassStaticBlock) { + if (prop.aborts()) return prop; + } + } + return null; + }); + def_aborts(AST_ClassStaticBlock, block_aborts); + def_aborts(AST_If, function() { + return this.alternative && aborts(this.body) && aborts(this.alternative) && this; + }); +})(function(node, func) { + node.DEFMETHOD("aborts", func); +}); + +AST_Node.DEFMETHOD("contains_this", function() { + return walk(this, node => { + if (node instanceof AST_This) return walk_abort; + if ( + node !== this + && node instanceof AST_Scope + && !(node instanceof AST_Arrow) + ) { + return true; + } + }); +}); + +export function is_modified(compressor, tw, node, value, level, immutable) { + var parent = tw.parent(level); + var lhs = is_lhs(node, parent); + if (lhs) return lhs; + if (!immutable + && parent instanceof AST_Call + && parent.expression === node + && !(value instanceof AST_Arrow) + && !(value instanceof AST_Class) + && !parent.is_callee_pure(compressor) + && (!(value instanceof AST_Function) + || !(parent instanceof AST_New) && value.contains_this())) { + return true; + } + if (parent instanceof AST_Array) { + return is_modified(compressor, tw, parent, parent, level + 1); + } + if (parent instanceof AST_ObjectKeyVal && node === parent.value) { + var obj = tw.parent(level + 1); + return is_modified(compressor, tw, obj, obj, level + 2); + } + if (parent instanceof AST_PropAccess && parent.expression === node) { + var prop = read_property(value, parent.property); + return !immutable && is_modified(compressor, tw, parent, prop, level + 1); + } +} + +/** + * Check if a node may be used by the expression it's in + * void (0, 1, {node}, 2) -> false + * console.log(0, {node}) -> true + */ +export function is_used_in_expression(tw) { + for (let p = -1, node, parent; node = tw.parent(p), parent = tw.parent(p + 1); p++) { + if (parent instanceof AST_Sequence) { + const nth_expression = parent.expressions.indexOf(node); + if (nth_expression !== parent.expressions.length - 1) { + // Detect (0, x.noThis)() constructs + const grandparent = tw.parent(p + 2); + if ( + parent.expressions.length > 2 + || parent.expressions.length === 1 + || !requires_sequence_to_maintain_binding(grandparent, parent, parent.expressions[1]) + ) { + return false; + } + return true; + } else { + continue; + } + } + if (parent instanceof AST_Unary) { + const op = parent.operator; + if (op === "void") { + return false; + } + if (op === "typeof" || op === "+" || op === "-" || op === "!" || op === "~") { + continue; + } + } + if ( + parent instanceof AST_SimpleStatement + || parent instanceof AST_LabeledStatement + ) { + return false; + } + if (parent instanceof AST_Scope) { + return false; + } + return true; + } + + return true; +} diff --git a/node_modules/terser/lib/compress/inline.js b/node_modules/terser/lib/compress/inline.js new file mode 100644 index 0000000..5d39009 --- /dev/null +++ b/node_modules/terser/lib/compress/inline.js @@ -0,0 +1,684 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +import { + AST_Array, + AST_Assign, + AST_Block, + AST_Call, + AST_Catch, + AST_Class, + AST_ClassExpression, + AST_DefaultAssign, + AST_DefClass, + AST_Defun, + AST_Destructuring, + AST_EmptyStatement, + AST_Expansion, + AST_Export, + AST_Function, + AST_IterationStatement, + AST_Lambda, + AST_Node, + AST_Number, + AST_Object, + AST_ObjectKeyVal, + AST_PropAccess, + AST_Return, + AST_Scope, + AST_SimpleStatement, + AST_Statement, + AST_SymbolDefun, + AST_SymbolFunarg, + AST_SymbolLambda, + AST_SymbolRef, + AST_SymbolVar, + AST_This, + AST_Toplevel, + AST_UnaryPrefix, + AST_Undefined, + AST_Var, + AST_VarDef, + + walk, + + _INLINE, + _NOINLINE, + _PURE, +} from "../ast.js"; +import { make_node, has_annotation } from "../utils/index.js"; +import "../size.js"; + +import "./evaluate.js"; +import "./drop-side-effect-free.js"; +import "./reduce-vars.js"; +import { + SQUEEZED, + INLINED, + UNUSED, + + has_flag, + set_flag, +} from "./compressor-flags.js"; +import { + make_sequence, + best_of, + make_node_from_constant, + identifier_atom, + is_empty, + is_func_expr, + is_iife_call, + is_reachable, + is_recursive_ref, + retain_top_func, +} from "./common.js"; + +/** + * Module that contains the inlining logic. + * + * @module + * + * The stars of the show are `inline_into_symbolref` and `inline_into_call`. + */ + +function within_array_or_object_literal(compressor) { + var node, level = 0; + while (node = compressor.parent(level++)) { + if (node instanceof AST_Statement) return false; + if (node instanceof AST_Array + || node instanceof AST_ObjectKeyVal + || node instanceof AST_Object) { + return true; + } + } + return false; +} + +function scope_encloses_variables_in_this_scope(scope, pulled_scope) { + for (const enclosed of pulled_scope.enclosed) { + if (pulled_scope.variables.has(enclosed.name)) { + continue; + } + const looked_up = scope.find_variable(enclosed.name); + if (looked_up) { + if (looked_up === enclosed) continue; + return true; + } + } + return false; +} + +/** + * An extra check function for `top_retain` option, compare the length of const identifier + * and init value length and return true if init value is longer than identifier. for example: + * ``` + * // top_retain: ["example"] + * const example = 100 + * ``` + * it will return false because length of "100" is short than identifier "example". + */ +function is_const_symbol_short_than_init_value(def, fixed_value) { + if (def.orig.length === 1 && fixed_value) { + const init_value_length = fixed_value.size(); + const identifer_length = def.name.length; + return init_value_length > identifer_length; + } + return true; +} + +export function inline_into_symbolref(self, compressor) { + if (compressor.in_computed_key()) return self; + + const parent = compressor.parent(); + const def = self.definition(); + const nearest_scope = compressor.find_scope(); + let fixed = self.fixed_value(); + if ( + compressor.top_retain && + def.global && + compressor.top_retain(def) && + // when identifier is in top_retain option dose not mean we can always inline it. + // if identifier name is longer then init value, we can replace it. + is_const_symbol_short_than_init_value(def, fixed) + ) { + // keep it + def.fixed = false; + def.single_use = false; + return self; + } + + if (dont_inline_lambda_in_loop(compressor, fixed)) return self; + + let single_use = def.single_use + && !(parent instanceof AST_Call + && (parent.is_callee_pure(compressor)) + || has_annotation(parent, _NOINLINE)) + && !(parent instanceof AST_Export + && fixed instanceof AST_Lambda + && fixed.name); + + if (single_use && fixed instanceof AST_Node) { + single_use = + !fixed.has_side_effects(compressor) + && !fixed.may_throw(compressor); + } + + if (fixed instanceof AST_Class && def.scope !== self.scope) { + return self; + } + + if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) { + if (retain_top_func(fixed, compressor)) { + single_use = false; + } else if (def.scope !== self.scope + && (def.escaped == 1 + || has_flag(fixed, INLINED) + || within_array_or_object_literal(compressor) + || !compressor.option("reduce_funcs"))) { + single_use = false; + } else if (is_recursive_ref(compressor, def)) { + single_use = false; + } else if (def.scope !== self.scope || def.orig[0] instanceof AST_SymbolFunarg) { + single_use = fixed.is_constant_expression(self.scope); + if (single_use == "f") { + var scope = self.scope; + do { + if (scope instanceof AST_Defun || is_func_expr(scope)) { + set_flag(scope, INLINED); + } + } while (scope = scope.parent_scope); + } + } + } + + if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) { + single_use = + def.scope === self.scope + && !scope_encloses_variables_in_this_scope(nearest_scope, fixed) + || parent instanceof AST_Call + && parent.expression === self + && !scope_encloses_variables_in_this_scope(nearest_scope, fixed) + && !(fixed.name && fixed.name.definition().recursive_refs > 0); + } + + if (single_use && fixed) { + if (fixed instanceof AST_DefClass) { + set_flag(fixed, SQUEEZED); + fixed = make_node(AST_ClassExpression, fixed, fixed); + } + if (fixed instanceof AST_Defun) { + set_flag(fixed, SQUEEZED); + fixed = make_node(AST_Function, fixed, fixed); + } + if (def.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) { + const defun_def = fixed.name.definition(); + let lambda_def = fixed.variables.get(fixed.name.name); + let name = lambda_def && lambda_def.orig[0]; + if (!(name instanceof AST_SymbolLambda)) { + name = make_node(AST_SymbolLambda, fixed.name, fixed.name); + name.scope = fixed; + fixed.name = name; + lambda_def = fixed.def_function(name); + } + walk(fixed, node => { + if (node instanceof AST_SymbolRef && node.definition() === defun_def) { + node.thedef = lambda_def; + lambda_def.references.push(node); + } + }); + } + if ( + (fixed instanceof AST_Lambda || fixed instanceof AST_Class) + && fixed.parent_scope !== nearest_scope + ) { + fixed = fixed.clone(true, compressor.get_toplevel()); + + nearest_scope.add_child_scope(fixed); + } + return fixed.optimize(compressor); + } + + // multiple uses + if (fixed) { + let replace; + + if (fixed instanceof AST_This) { + if (!(def.orig[0] instanceof AST_SymbolFunarg) + && def.references.every((ref) => + def.scope === ref.scope + )) { + replace = fixed; + } + } else { + var ev = fixed.evaluate(compressor); + if ( + ev !== fixed + && (compressor.option("unsafe_regexp") || !(ev instanceof RegExp)) + ) { + replace = make_node_from_constant(ev, fixed); + } + } + + if (replace) { + const name_length = self.size(compressor); + const replace_size = replace.size(compressor); + + let overhead = 0; + if (compressor.option("unused") && !compressor.exposed(def)) { + overhead = + (name_length + 2 + fixed.size(compressor)) / + (def.references.length - def.assignments); + } + + if (replace_size <= name_length + overhead) { + return replace; + } + } + } + + return self; +} + +export function inline_into_call(self, compressor) { + if (compressor.in_computed_key()) return self; + + var exp = self.expression; + var fn = exp; + var simple_args = self.args.every((arg) => !(arg instanceof AST_Expansion)); + + if (compressor.option("reduce_vars") + && fn instanceof AST_SymbolRef + && !has_annotation(self, _NOINLINE) + ) { + const fixed = fn.fixed_value(); + + if ( + retain_top_func(fixed, compressor) + || !compressor.toplevel.funcs && exp.definition().global + ) { + return self; + } + + fn = fixed; + } + + if ( + dont_inline_lambda_in_loop(compressor, fn) + && !has_annotation(self, _INLINE) + ) return self; + + var is_func = fn instanceof AST_Lambda; + + var stat = is_func && fn.body[0]; + var is_regular_func = is_func && !fn.is_generator && !fn.async; + var can_inline = is_regular_func && compressor.option("inline") && !self.is_callee_pure(compressor); + if (can_inline && stat instanceof AST_Return) { + let returned = stat.value; + if (!returned || returned.is_constant_expression()) { + if (returned) { + returned = returned.clone(true); + } else { + returned = make_node(AST_Undefined, self); + } + const args = self.args.concat(returned); + return make_sequence(self, args).optimize(compressor); + } + + // optimize identity function + if ( + fn.argnames.length === 1 + && (fn.argnames[0] instanceof AST_SymbolFunarg) + && self.args.length < 2 + && !(self.args[0] instanceof AST_Expansion) + && returned instanceof AST_SymbolRef + && returned.name === fn.argnames[0].name + ) { + const replacement = + (self.args[0] || make_node(AST_Undefined)).optimize(compressor); + + let parent; + if ( + replacement instanceof AST_PropAccess + && (parent = compressor.parent()) instanceof AST_Call + && parent.expression === self + ) { + // identity function was being used to remove `this`, like in + // + // id(bag.no_this)(...) + // + // Replace with a larger but more effish (0, bag.no_this) wrapper. + + return make_sequence(self, [ + make_node(AST_Number, self, { value: 0 }), + replacement + ]); + } + // replace call with first argument or undefined if none passed + return replacement; + } + } + + if (can_inline) { + var scope, in_loop, level = -1; + let def; + let returned_value; + let nearest_scope; + if (simple_args + && !fn.uses_arguments + && !(compressor.parent() instanceof AST_Class) + && !(fn.name && fn instanceof AST_Function) + && (returned_value = can_flatten_body(stat)) + && (exp === fn + || has_annotation(self, _INLINE) + || compressor.option("unused") + && (def = exp.definition()).references.length == 1 + && !is_recursive_ref(compressor, def) + && fn.is_constant_expression(exp.scope)) + && !has_annotation(self, _PURE | _NOINLINE) + && !fn.contains_this() + && can_inject_symbols() + && (nearest_scope = compressor.find_scope()) + && !scope_encloses_variables_in_this_scope(nearest_scope, fn) + && !(function in_default_assign() { + // Due to the fact function parameters have their own scope + // which can't use `var something` in the function body within, + // we simply don't inline into DefaultAssign. + let i = 0; + let p; + while ((p = compressor.parent(i++))) { + if (p instanceof AST_DefaultAssign) return true; + if (p instanceof AST_Block) break; + } + return false; + })() + && !(scope instanceof AST_Class) + ) { + set_flag(fn, SQUEEZED); + nearest_scope.add_child_scope(fn); + return make_sequence(self, flatten_fn(returned_value)).optimize(compressor); + } + } + + if (can_inline && has_annotation(self, _INLINE)) { + set_flag(fn, SQUEEZED); + fn = make_node(fn.CTOR === AST_Defun ? AST_Function : fn.CTOR, fn, fn); + fn = fn.clone(true); + fn.figure_out_scope({}, { + parent_scope: compressor.find_scope(), + toplevel: compressor.get_toplevel() + }); + + return make_node(AST_Call, self, { + expression: fn, + args: self.args, + }).optimize(compressor); + } + + const can_drop_this_call = is_regular_func && compressor.option("side_effects") && fn.body.every(is_empty); + if (can_drop_this_call) { + var args = self.args.concat(make_node(AST_Undefined, self)); + return make_sequence(self, args).optimize(compressor); + } + + if (compressor.option("negate_iife") + && compressor.parent() instanceof AST_SimpleStatement + && is_iife_call(self)) { + return self.negate(compressor, true); + } + + var ev = self.evaluate(compressor); + if (ev !== self) { + ev = make_node_from_constant(ev, self).optimize(compressor); + return best_of(compressor, ev, self); + } + + return self; + + function return_value(stat) { + if (!stat) return make_node(AST_Undefined, self); + if (stat instanceof AST_Return) { + if (!stat.value) return make_node(AST_Undefined, self); + return stat.value.clone(true); + } + if (stat instanceof AST_SimpleStatement) { + return make_node(AST_UnaryPrefix, stat, { + operator: "void", + expression: stat.body.clone(true) + }); + } + } + + function can_flatten_body(stat) { + var body = fn.body; + var len = body.length; + if (compressor.option("inline") < 3) { + return len == 1 && return_value(stat); + } + stat = null; + for (var i = 0; i < len; i++) { + var line = body[i]; + if (line instanceof AST_Var) { + if (stat && !line.definitions.every((var_def) => + !var_def.value + )) { + return false; + } + } else if (stat) { + return false; + } else if (!(line instanceof AST_EmptyStatement)) { + stat = line; + } + } + return return_value(stat); + } + + function can_inject_args(block_scoped, safe_to_inject) { + for (var i = 0, len = fn.argnames.length; i < len; i++) { + var arg = fn.argnames[i]; + if (arg instanceof AST_DefaultAssign) { + if (has_flag(arg.left, UNUSED)) continue; + return false; + } + if (arg instanceof AST_Destructuring) return false; + if (arg instanceof AST_Expansion) { + if (has_flag(arg.expression, UNUSED)) continue; + return false; + } + if (has_flag(arg, UNUSED)) continue; + if (!safe_to_inject + || block_scoped.has(arg.name) + || identifier_atom.has(arg.name) + || scope.conflicting_def(arg.name)) { + return false; + } + if (in_loop) in_loop.push(arg.definition()); + } + return true; + } + + function can_inject_vars(block_scoped, safe_to_inject) { + var len = fn.body.length; + for (var i = 0; i < len; i++) { + var stat = fn.body[i]; + if (!(stat instanceof AST_Var)) continue; + if (!safe_to_inject) return false; + for (var j = stat.definitions.length; --j >= 0;) { + var name = stat.definitions[j].name; + if (name instanceof AST_Destructuring + || block_scoped.has(name.name) + || identifier_atom.has(name.name) + || scope.conflicting_def(name.name)) { + return false; + } + if (in_loop) in_loop.push(name.definition()); + } + } + return true; + } + + function can_inject_symbols() { + var block_scoped = new Set(); + do { + scope = compressor.parent(++level); + if (scope.is_block_scope() && scope.block_scope) { + // TODO this is sometimes undefined during compression. + // But it should always have a value! + scope.block_scope.variables.forEach(function (variable) { + block_scoped.add(variable.name); + }); + } + if (scope instanceof AST_Catch) { + // TODO can we delete? AST_Catch is a block scope. + if (scope.argname) { + block_scoped.add(scope.argname.name); + } + } else if (scope instanceof AST_IterationStatement) { + in_loop = []; + } else if (scope instanceof AST_SymbolRef) { + if (scope.fixed_value() instanceof AST_Scope) return false; + } + } while (!(scope instanceof AST_Scope)); + + var safe_to_inject = !(scope instanceof AST_Toplevel) || compressor.toplevel.vars; + var inline = compressor.option("inline"); + if (!can_inject_vars(block_scoped, inline >= 3 && safe_to_inject)) return false; + if (!can_inject_args(block_scoped, inline >= 2 && safe_to_inject)) return false; + return !in_loop || in_loop.length == 0 || !is_reachable(fn, in_loop); + } + + function append_var(decls, expressions, name, value) { + var def = name.definition(); + + // Name already exists, only when a function argument had the same name + const already_appended = scope.variables.has(name.name); + if (!already_appended) { + scope.variables.set(name.name, def); + scope.enclosed.push(def); + decls.push(make_node(AST_VarDef, name, { + name: name, + value: null + })); + } + + var sym = make_node(AST_SymbolRef, name, name); + def.references.push(sym); + if (value) expressions.push(make_node(AST_Assign, self, { + operator: "=", + logical: false, + left: sym, + right: value.clone() + })); + } + + function flatten_args(decls, expressions) { + var len = fn.argnames.length; + for (var i = self.args.length; --i >= len;) { + expressions.push(self.args[i]); + } + for (i = len; --i >= 0;) { + var name = fn.argnames[i]; + var value = self.args[i]; + if (has_flag(name, UNUSED) || !name.name || scope.conflicting_def(name.name)) { + if (value) expressions.push(value); + } else { + var symbol = make_node(AST_SymbolVar, name, name); + name.definition().orig.push(symbol); + if (!value && in_loop) value = make_node(AST_Undefined, self); + append_var(decls, expressions, symbol, value); + } + } + decls.reverse(); + expressions.reverse(); + } + + function flatten_vars(decls, expressions) { + var pos = expressions.length; + for (var i = 0, lines = fn.body.length; i < lines; i++) { + var stat = fn.body[i]; + if (!(stat instanceof AST_Var)) continue; + for (var j = 0, defs = stat.definitions.length; j < defs; j++) { + var var_def = stat.definitions[j]; + var name = var_def.name; + append_var(decls, expressions, name, var_def.value); + if (in_loop && fn.argnames.every((argname) => + argname.name != name.name + )) { + var def = fn.variables.get(name.name); + var sym = make_node(AST_SymbolRef, name, name); + def.references.push(sym); + expressions.splice(pos++, 0, make_node(AST_Assign, var_def, { + operator: "=", + logical: false, + left: sym, + right: make_node(AST_Undefined, name) + })); + } + } + } + } + + function flatten_fn(returned_value) { + var decls = []; + var expressions = []; + flatten_args(decls, expressions); + flatten_vars(decls, expressions); + expressions.push(returned_value); + + if (decls.length) { + const i = scope.body.indexOf(compressor.parent(level - 1)) + 1; + scope.body.splice(i, 0, make_node(AST_Var, fn, { + definitions: decls + })); + } + + return expressions.map(exp => exp.clone(true)); + } +} + +/** prevent inlining functions into loops, for performance reasons */ +function dont_inline_lambda_in_loop(compressor, maybe_lambda) { + return ( + (maybe_lambda instanceof AST_Lambda || maybe_lambda instanceof AST_Class) + && !!compressor.is_within_loop() + ); +} diff --git a/node_modules/terser/lib/compress/native-objects.js b/node_modules/terser/lib/compress/native-objects.js new file mode 100644 index 0000000..d7cb704 --- /dev/null +++ b/node_modules/terser/lib/compress/native-objects.js @@ -0,0 +1,206 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +import { makePredicate } from "../utils/index.js"; + +// Lists of native methods, useful for `unsafe` option which assumes they exist. +// Note: Lots of methods and functions are missing here, in case they aren't pure +// or not available in all JS environments. + +function make_nested_lookup(obj) { + const out = new Map(); + for (var key of Object.keys(obj)) { + out.set(key, makePredicate(obj[key])); + } + + const does_have = (global_name, fname) => { + const inner_map = out.get(global_name); + return inner_map != null && inner_map.has(fname); + }; + return does_have; +} + +// Objects which are safe to access without throwing or causing a side effect. +// Usually we'd check the `unsafe` option first but these are way too common for that +export const pure_prop_access_globals = new Set([ + "Number", + "String", + "Array", + "Object", + "Function", + "Promise", +]); + +const object_methods = [ + "constructor", + "toString", + "valueOf", +]; + +export const is_pure_native_method = make_nested_lookup({ + Array: [ + "at", + "flat", + "includes", + "indexOf", + "join", + "lastIndexOf", + "slice", + ...object_methods, + ], + Boolean: object_methods, + Function: object_methods, + Number: [ + "toExponential", + "toFixed", + "toPrecision", + ...object_methods, + ], + Object: object_methods, + RegExp: [ + "test", + ...object_methods, + ], + String: [ + "at", + "charAt", + "charCodeAt", + "charPointAt", + "concat", + "endsWith", + "fromCharCode", + "fromCodePoint", + "includes", + "indexOf", + "italics", + "lastIndexOf", + "localeCompare", + "match", + "matchAll", + "normalize", + "padStart", + "padEnd", + "repeat", + "replace", + "replaceAll", + "search", + "slice", + "split", + "startsWith", + "substr", + "substring", + "repeat", + "toLocaleLowerCase", + "toLocaleUpperCase", + "toLowerCase", + "toUpperCase", + "trim", + "trimEnd", + "trimStart", + ...object_methods, + ], +}); + +export const is_pure_native_fn = make_nested_lookup({ + Array: [ + "isArray", + ], + Math: [ + "abs", + "acos", + "asin", + "atan", + "ceil", + "cos", + "exp", + "floor", + "log", + "round", + "sin", + "sqrt", + "tan", + "atan2", + "pow", + "max", + "min", + ], + Number: [ + "isFinite", + "isNaN", + ], + Object: [ + "create", + "getOwnPropertyDescriptor", + "getOwnPropertyNames", + "getPrototypeOf", + "isExtensible", + "isFrozen", + "isSealed", + "hasOwn", + "keys", + ], + String: [ + "fromCharCode", + ], +}); + +// Known numeric values which come with JS environments +export const is_pure_native_value = make_nested_lookup({ + Math: [ + "E", + "LN10", + "LN2", + "LOG2E", + "LOG10E", + "PI", + "SQRT1_2", + "SQRT2", + ], + Number: [ + "MAX_VALUE", + "MIN_VALUE", + "NaN", + "NEGATIVE_INFINITY", + "POSITIVE_INFINITY", + ], +}); diff --git a/node_modules/terser/lib/compress/reduce-vars.js b/node_modules/terser/lib/compress/reduce-vars.js new file mode 100644 index 0000000..fb7a54f --- /dev/null +++ b/node_modules/terser/lib/compress/reduce-vars.js @@ -0,0 +1,865 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +import { + AST_Accessor, + AST_Array, + AST_Assign, + AST_Await, + AST_Binary, + AST_Block, + AST_Call, + AST_Case, + AST_Chain, + AST_Class, + AST_ClassStaticBlock, + AST_ClassExpression, + AST_Conditional, + AST_Default, + AST_Defun, + AST_Destructuring, + AST_Do, + AST_Exit, + AST_Expansion, + AST_For, + AST_ForIn, + AST_If, + AST_LabeledStatement, + AST_Lambda, + AST_New, + AST_Node, + AST_Number, + AST_ObjectKeyVal, + AST_PropAccess, + AST_Scope, + AST_Sequence, + AST_SimpleStatement, + AST_Symbol, + AST_SymbolCatch, + AST_SymbolConst, + AST_SymbolDeclaration, + AST_SymbolDefun, + AST_SymbolFunarg, + AST_SymbolLambda, + AST_SymbolRef, + AST_This, + AST_Toplevel, + AST_Try, + AST_Unary, + AST_UnaryPrefix, + AST_Undefined, + AST_UsingDef, + AST_VarDef, + AST_VarDefLike, + AST_While, + AST_Yield, + + walk, + walk_body, + walk_parent, +} from "../ast.js"; +import { HOP, make_node, noop } from "../utils/index.js"; + +import { lazy_op, is_modified, is_lhs } from "./inference.js"; +import { INLINED, clear_flag } from "./compressor-flags.js"; +import { read_property, has_break_or_continue, is_recursive_ref } from "./common.js"; + +/** + * Define the method AST_Node#reduce_vars, which goes through the AST in + * execution order to perform basic flow analysis + */ +function def_reduce_vars(node, func) { + node.DEFMETHOD("reduce_vars", func); +} + +def_reduce_vars(AST_Node, noop); + +/** Clear definition properties */ +function reset_def(compressor, def) { + def.assignments = 0; + def.chained = false; + def.direct_access = false; + def.escaped = 0; + def.recursive_refs = 0; + def.references = []; + def.single_use = undefined; + if ( + def.scope.pinned() + || (def.orig[0] instanceof AST_SymbolFunarg && def.scope.uses_arguments) + ) { + def.fixed = false; + } else if (def.orig[0] instanceof AST_SymbolConst || !compressor.exposed(def)) { + def.fixed = def.init; + } else { + def.fixed = false; + } +} + +function reset_variables(tw, compressor, node) { + node.variables.forEach(function(def) { + reset_def(compressor, def); + if (def.fixed === null) { + tw.defs_to_safe_ids.set(def.id, tw.safe_ids); + mark(tw, def, true); + } else if (def.fixed) { + tw.loop_ids.set(def.id, tw.in_loop); + mark(tw, def, true); + } + }); +} + +function reset_block_variables(compressor, node) { + if (node.block_scope) node.block_scope.variables.forEach((def) => { + reset_def(compressor, def); + }); +} + +function push(tw) { + tw.safe_ids = Object.create(tw.safe_ids); +} + +function pop(tw) { + tw.safe_ids = Object.getPrototypeOf(tw.safe_ids); +} + +function mark(tw, def, safe) { + tw.safe_ids[def.id] = safe; +} + +function safe_to_read(tw, def) { + if (def.single_use == "m") return false; + if (tw.safe_ids[def.id]) { + if (def.fixed == null) { + var orig = def.orig[0]; + if (orig instanceof AST_SymbolFunarg || orig.name == "arguments") return false; + def.fixed = make_node(AST_Undefined, orig); + } + return true; + } + return def.fixed instanceof AST_Defun; +} + +function safe_to_assign(tw, def, scope, value) { + if (def.fixed === undefined) return true; + let def_safe_ids; + if (def.fixed === null + && (def_safe_ids = tw.defs_to_safe_ids.get(def.id)) + ) { + def_safe_ids[def.id] = false; + tw.defs_to_safe_ids.delete(def.id); + return true; + } + if (!HOP(tw.safe_ids, def.id)) return false; + if (!safe_to_read(tw, def)) return false; + if (def.fixed === false) return false; + if (def.fixed != null && (!value || def.references.length > def.assignments)) return false; + if (def.fixed instanceof AST_Defun) { + return value instanceof AST_Node && def.fixed.parent_scope === scope; + } + return def.orig.every((sym) => { + return !(sym instanceof AST_SymbolConst + || sym instanceof AST_SymbolDefun + || sym instanceof AST_SymbolLambda); + }); +} + +function ref_once(tw, compressor, def) { + return compressor.option("unused") + && !def.scope.pinned() + && def.references.length - def.recursive_refs == 1 + && tw.loop_ids.get(def.id) === tw.in_loop; +} + +function is_immutable(value) { + if (!value) return false; + return value.is_constant() + || value instanceof AST_Lambda + || value instanceof AST_This; +} + +// A definition "escapes" when its value can leave the point of use. +// Example: `a = b || c` +// In this example, "b" and "c" are escaping, because they're going into "a" +// +// def.escaped is != 0 when it escapes. +// +// When greater than 1, it means that N chained properties will be read off +// of that def before an escape occurs. This is useful for evaluating +// property accesses, where you need to know when to stop. +function mark_escaped(tw, d, scope, node, value, level = 0, depth = 1) { + var parent = tw.parent(level); + if (value) { + if (value.is_constant()) return; + if (value instanceof AST_ClassExpression) return; + } + + if ( + parent instanceof AST_Assign && (parent.operator === "=" || parent.logical) && node === parent.right + || parent instanceof AST_Call && (node !== parent.expression || parent instanceof AST_New) + || parent instanceof AST_Exit && node === parent.value && node.scope !== d.scope + || parent instanceof AST_VarDefLike && node === parent.value + || parent instanceof AST_Yield && node === parent.value && node.scope !== d.scope + ) { + if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1; + if (!d.escaped || d.escaped > depth) d.escaped = depth; + return; + } else if ( + parent instanceof AST_Array + || parent instanceof AST_Await + || parent instanceof AST_Binary && lazy_op.has(parent.operator) + || parent instanceof AST_Conditional && node !== parent.condition + || parent instanceof AST_Expansion + || parent instanceof AST_Sequence && node === parent.tail_node() + ) { + mark_escaped(tw, d, scope, parent, parent, level + 1, depth); + } else if (parent instanceof AST_ObjectKeyVal && node === parent.value) { + var obj = tw.parent(level + 1); + + mark_escaped(tw, d, scope, obj, obj, level + 2, depth); + } else if (parent instanceof AST_PropAccess && node === parent.expression) { + value = read_property(value, parent.property); + + mark_escaped(tw, d, scope, parent, value, level + 1, depth + 1); + if (value) return; + } + + if (level > 0) return; + if (parent instanceof AST_Sequence && node !== parent.tail_node()) return; + if (parent instanceof AST_SimpleStatement) return; + + d.direct_access = true; +} + +const suppress = node => walk(node, node => { + if (!(node instanceof AST_Symbol)) return; + var d = node.definition(); + if (!d) return; + if (node instanceof AST_SymbolRef) d.references.push(node); + d.fixed = false; +}); + +def_reduce_vars(AST_Accessor, function(tw, descend, compressor) { + push(tw); + reset_variables(tw, compressor, this); + descend(); + pop(tw); + return true; +}); + +def_reduce_vars(AST_Assign, function(tw, descend, compressor) { + var node = this; + if (node.left instanceof AST_Destructuring) { + suppress(node.left); + return; + } + + const finish_walk = () => { + if (node.logical) { + node.left.walk(tw); + + push(tw); + node.right.walk(tw); + pop(tw); + + return true; + } + }; + + var sym = node.left; + if (!(sym instanceof AST_SymbolRef)) return finish_walk(); + + var def = sym.definition(); + var safe = safe_to_assign(tw, def, sym.scope, node.right); + def.assignments++; + if (!safe) return finish_walk(); + + var fixed = def.fixed; + if (!fixed && node.operator != "=" && !node.logical) return finish_walk(); + + var eq = node.operator == "="; + var value = eq ? node.right : node; + if (is_modified(compressor, tw, node, value, 0)) return finish_walk(); + + def.references.push(sym); + + if (!node.logical) { + if (!eq) def.chained = true; + + def.fixed = eq ? function() { + return node.right; + } : function() { + return make_node(AST_Binary, node, { + operator: node.operator.slice(0, -1), + left: fixed instanceof AST_Node ? fixed : fixed(), + right: node.right + }); + }; + } + + if (node.logical) { + mark(tw, def, false); + push(tw); + node.right.walk(tw); + pop(tw); + return true; + } + + mark(tw, def, false); + node.right.walk(tw); + mark(tw, def, true); + + mark_escaped(tw, def, sym.scope, node, value, 0, 1); + + return true; +}); + +def_reduce_vars(AST_Binary, function(tw) { + if (!lazy_op.has(this.operator)) return; + this.left.walk(tw); + push(tw); + this.right.walk(tw); + pop(tw); + return true; +}); + +def_reduce_vars(AST_Block, function(tw, descend, compressor) { + reset_block_variables(compressor, this); +}); + +def_reduce_vars(AST_Case, function(tw) { + push(tw); + this.expression.walk(tw); + pop(tw); + push(tw); + walk_body(this, tw); + pop(tw); + return true; +}); + +def_reduce_vars(AST_Class, function(tw, descend) { + clear_flag(this, INLINED); + push(tw); + descend(); + pop(tw); + return true; +}); + +def_reduce_vars(AST_ClassStaticBlock, function(tw, descend, compressor) { + reset_block_variables(compressor, this); +}); + +def_reduce_vars(AST_Conditional, function(tw) { + this.condition.walk(tw); + push(tw); + this.consequent.walk(tw); + pop(tw); + push(tw); + this.alternative.walk(tw); + pop(tw); + return true; +}); + +def_reduce_vars(AST_Chain, function(tw, descend) { + // Chains' conditions apply left-to-right, cumulatively. + // If we walk normally we don't go in that order because we would pop before pushing again + // Solution: AST_PropAccess and AST_Call push when they are optional, and never pop. + // Then we pop everything when they are done being walked. + const safe_ids = tw.safe_ids; + + descend(); + + // Unroll back to start + tw.safe_ids = safe_ids; + return true; +}); + +def_reduce_vars(AST_Call, function (tw) { + this.expression.walk(tw); + + if (this.optional) { + // Never pop -- it's popped at AST_Chain above + push(tw); + } + + for (const arg of this.args) arg.walk(tw); + + return true; +}); + +def_reduce_vars(AST_PropAccess, function (tw) { + if (!this.optional) return; + + this.expression.walk(tw); + + // Never pop -- it's popped at AST_Chain above + push(tw); + + if (this.property instanceof AST_Node) this.property.walk(tw); + + return true; +}); + +def_reduce_vars(AST_Default, function(tw, descend) { + push(tw); + descend(); + pop(tw); + return true; +}); + +function mark_lambda(tw, descend, compressor) { + clear_flag(this, INLINED); + push(tw); + reset_variables(tw, compressor, this); + + var iife; + if (!this.name + && !this.uses_arguments + && !this.pinned() + && (iife = tw.parent()) instanceof AST_Call + && iife.expression === this + && !iife.args.some(arg => arg instanceof AST_Expansion) + && this.argnames.every(arg_name => arg_name instanceof AST_Symbol) + ) { + // Virtually turn IIFE parameters into variable definitions: + // (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})() + // So existing transformation rules can work on them. + this.argnames.forEach((arg, i) => { + if (!arg.definition) return; + var d = arg.definition(); + // Avoid setting fixed when there's more than one origin for a variable value + if (d.orig.length > 1) return; + if (d.fixed === undefined && (!this.uses_arguments || tw.has_directive("use strict"))) { + d.fixed = function() { + return iife.args[i] || make_node(AST_Undefined, iife); + }; + tw.loop_ids.set(d.id, tw.in_loop); + mark(tw, d, true); + } else { + d.fixed = false; + } + }); + } + + descend(); + pop(tw); + + handle_defined_after_hoist(this); + + return true; +} + +/** + * It's possible for a hoisted function to use something that's not defined yet. Example: + * + * hoisted(); + * var defined_after = true; + * function hoisted() { + * // use defined_after + * } + * + * Or even indirectly: + * + * B(); + * var defined_after = true; + * function A() { + * // use defined_after + * } + * function B() { + * A(); + * } + * + * Access a variable before declaration will either throw a ReferenceError + * (if the variable is declared with `let` or `const`), + * or get an `undefined` (if the variable is declared with `var`). + * + * If the variable is inlined into the function, the behavior will change. + * + * This function is called on the parent to disallow inlining of such variables, + */ +function handle_defined_after_hoist(parent) { + const defuns = []; + walk(parent, node => { + if (node === parent) return; + if (node instanceof AST_Defun) { + defuns.push(node); + return true; + } + if ( + node instanceof AST_Scope + || node instanceof AST_SimpleStatement + ) return true; + }); + + // `defun` id to array of `defun` it uses + const defun_dependencies_map = new Map(); + // `defun` id to array of enclosing `def` that are used by the function + const dependencies_map = new Map(); + // all symbol ids that will be tracked for read/write + const symbols_of_interest = new Set(); + const defuns_of_interest = new Set(); + + for (const defun of defuns) { + const fname_def = defun.name.definition(); + const enclosing_defs = []; + + for (const def of defun.enclosed) { + if ( + def.fixed === false + || def === fname_def + || def.scope.get_defun_scope() !== parent + ) { + continue; + } + + symbols_of_interest.add(def.id); + + // found a reference to another function + if ( + def.assignments === 0 + && def.orig.length === 1 + && def.orig[0] instanceof AST_SymbolDefun + ) { + defuns_of_interest.add(def.id); + symbols_of_interest.add(def.id); + + defuns_of_interest.add(fname_def.id); + symbols_of_interest.add(fname_def.id); + + if (!defun_dependencies_map.has(fname_def.id)) { + defun_dependencies_map.set(fname_def.id, []); + } + defun_dependencies_map.get(fname_def.id).push(def.id); + + continue; + } + + enclosing_defs.push(def); + } + + if (enclosing_defs.length) { + dependencies_map.set(fname_def.id, enclosing_defs); + defuns_of_interest.add(fname_def.id); + symbols_of_interest.add(fname_def.id); + } + } + + // No defuns use outside constants + if (!dependencies_map.size) { + return; + } + + // Increment to count "symbols of interest" (defuns or defs) that we found. + // These are tracked in AST order so we can check which is after which. + let symbol_index = 1; + // Map a defun ID to its first read (a `symbol_index`) + const defun_first_read_map = new Map(); + // Map a symbol ID to its last write (a `symbol_index`) + const symbol_last_write_map = new Map(); + + walk_parent(parent, (node, walk_info) => { + if (node instanceof AST_Symbol && node.thedef) { + const id = node.definition().id; + + symbol_index++; + + // Track last-writes to symbols + if (symbols_of_interest.has(id)) { + if (node instanceof AST_SymbolDeclaration || is_lhs(node, walk_info.parent())) { + symbol_last_write_map.set(id, symbol_index); + } + } + + // Track first-reads of defuns (refined later) + if (defuns_of_interest.has(id)) { + if (!defun_first_read_map.has(id) && !is_recursive_ref(walk_info, id)) { + defun_first_read_map.set(id, symbol_index); + } + } + } + }); + + // Refine `defun_first_read_map` to be as high as possible + for (const [defun, defun_first_read] of defun_first_read_map) { + // Update all dependencies of `defun` + const queue = new Set(defun_dependencies_map.get(defun)); + for (const enclosed_defun of queue) { + let enclosed_defun_first_read = defun_first_read_map.get(enclosed_defun); + if (enclosed_defun_first_read != null && enclosed_defun_first_read < defun_first_read) { + continue; + } + + defun_first_read_map.set(enclosed_defun, defun_first_read); + + for (const enclosed_enclosed_defun of defun_dependencies_map.get(enclosed_defun) || []) { + queue.add(enclosed_enclosed_defun); + } + } + } + + // ensure write-then-read order, otherwise clear `fixed` + // This is safe because last-writes (found_symbol_writes) are assumed to be as late as possible, and first-reads (defun_first_read_map) are assumed to be as early as possible. + for (const [defun, defs] of dependencies_map) { + const defun_first_read = defun_first_read_map.get(defun); + if (defun_first_read === undefined) { + continue; + } + + for (const def of defs) { + if (def.fixed === false) { + continue; + } + + let def_last_write = symbol_last_write_map.get(def.id) || 0; + + if (defun_first_read < def_last_write) { + def.fixed = false; + } + } + } +} + +def_reduce_vars(AST_Lambda, mark_lambda); + +def_reduce_vars(AST_Do, function(tw, descend, compressor) { + reset_block_variables(compressor, this); + const saved_loop = tw.in_loop; + tw.in_loop = this; + push(tw); + this.body.walk(tw); + if (has_break_or_continue(this)) { + pop(tw); + push(tw); + } + this.condition.walk(tw); + pop(tw); + tw.in_loop = saved_loop; + return true; +}); + +def_reduce_vars(AST_For, function(tw, descend, compressor) { + reset_block_variables(compressor, this); + if (this.init) this.init.walk(tw); + const saved_loop = tw.in_loop; + tw.in_loop = this; + push(tw); + if (this.condition) this.condition.walk(tw); + this.body.walk(tw); + if (this.step) { + if (has_break_or_continue(this)) { + pop(tw); + push(tw); + } + this.step.walk(tw); + } + pop(tw); + tw.in_loop = saved_loop; + return true; +}); + +def_reduce_vars(AST_ForIn, function(tw, descend, compressor) { + reset_block_variables(compressor, this); + suppress(this.init); + this.object.walk(tw); + const saved_loop = tw.in_loop; + tw.in_loop = this; + push(tw); + this.body.walk(tw); + pop(tw); + tw.in_loop = saved_loop; + return true; +}); + +def_reduce_vars(AST_If, function(tw) { + this.condition.walk(tw); + push(tw); + this.body.walk(tw); + pop(tw); + if (this.alternative) { + push(tw); + this.alternative.walk(tw); + pop(tw); + } + return true; +}); + +def_reduce_vars(AST_LabeledStatement, function(tw) { + push(tw); + this.body.walk(tw); + pop(tw); + return true; +}); + +def_reduce_vars(AST_SymbolCatch, function() { + this.definition().fixed = false; +}); + +def_reduce_vars(AST_SymbolRef, function(tw, descend, compressor) { + var d = this.definition(); + d.references.push(this); + if (d.references.length == 1 + && !d.fixed + && d.orig[0] instanceof AST_SymbolDefun) { + tw.loop_ids.set(d.id, tw.in_loop); + } + var fixed_value; + if (d.fixed === undefined || !safe_to_read(tw, d)) { + d.fixed = false; + } else if (d.fixed) { + fixed_value = this.fixed_value(); + if ( + fixed_value instanceof AST_Lambda + && is_recursive_ref(tw, d) + ) { + d.recursive_refs++; + } else if (fixed_value + && !compressor.exposed(d) + && ref_once(tw, compressor, d) + ) { + d.single_use = + fixed_value instanceof AST_Lambda && !fixed_value.pinned() + || fixed_value instanceof AST_Class + || d.scope === this.scope && fixed_value.is_constant_expression(); + } else { + d.single_use = false; + } + if (is_modified(compressor, tw, this, fixed_value, 0, is_immutable(fixed_value))) { + if (d.single_use) { + d.single_use = "m"; + } else { + d.fixed = false; + } + } + } + mark_escaped(tw, d, this.scope, this, fixed_value, 0, 1); +}); + +def_reduce_vars(AST_Toplevel, function(tw, descend, compressor) { + this.globals.forEach(function(def) { + reset_def(compressor, def); + }); + reset_variables(tw, compressor, this); + descend(); + handle_defined_after_hoist(this); + return true; +}); + +def_reduce_vars(AST_Try, function(tw, descend, compressor) { + reset_block_variables(compressor, this); + push(tw); + this.body.walk(tw); + pop(tw); + if (this.bcatch) { + push(tw); + this.bcatch.walk(tw); + pop(tw); + } + if (this.bfinally) this.bfinally.walk(tw); + return true; +}); + +def_reduce_vars(AST_Unary, function(tw) { + var node = this; + if (node.operator !== "++" && node.operator !== "--") return; + var exp = node.expression; + if (!(exp instanceof AST_SymbolRef)) return; + var def = exp.definition(); + var safe = safe_to_assign(tw, def, exp.scope, true); + def.assignments++; + if (!safe) return; + var fixed = def.fixed; + if (!fixed) return; + def.references.push(exp); + def.chained = true; + def.fixed = function() { + return make_node(AST_Binary, node, { + operator: node.operator.slice(0, -1), + left: make_node(AST_UnaryPrefix, node, { + operator: "+", + expression: fixed instanceof AST_Node ? fixed : fixed() + }), + right: make_node(AST_Number, node, { + value: 1 + }) + }); + }; + mark(tw, def, true); + return true; +}); + +def_reduce_vars(AST_VarDef, function(tw, descend) { + var node = this; + if (node.name instanceof AST_Destructuring) { + suppress(node.name); + return; + } + var d = node.name.definition(); + if (node.value) { + if (safe_to_assign(tw, d, node.name.scope, node.value)) { + d.fixed = function() { + return node.value; + }; + tw.loop_ids.set(d.id, tw.in_loop); + mark(tw, d, false); + descend(); + mark(tw, d, true); + return true; + } else { + d.fixed = false; + } + } +}); + +def_reduce_vars(AST_UsingDef, function() { + suppress(this.name); +}); + +def_reduce_vars(AST_While, function(tw, descend, compressor) { + reset_block_variables(compressor, this); + const saved_loop = tw.in_loop; + tw.in_loop = this; + push(tw); + descend(); + pop(tw); + tw.in_loop = saved_loop; + return true; +}); diff --git a/node_modules/terser/lib/compress/tighten-body.js b/node_modules/terser/lib/compress/tighten-body.js new file mode 100644 index 0000000..9bf80dc --- /dev/null +++ b/node_modules/terser/lib/compress/tighten-body.js @@ -0,0 +1,1530 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +import { + AST_Array, + AST_Arrow, + AST_Assign, + AST_Await, + AST_Binary, + AST_Block, + AST_BlockStatement, + AST_Break, + AST_Call, + AST_Case, + AST_Chain, + AST_Class, + AST_Conditional, + AST_Constant, + AST_Continue, + AST_Debugger, + AST_Default, + AST_Definitions, + AST_DefinitionsLike, + AST_Defun, + AST_Destructuring, + AST_Directive, + AST_Dot, + AST_DWLoop, + AST_EmptyStatement, + AST_Exit, + AST_Expansion, + AST_Export, + AST_For, + AST_ForIn, + AST_If, + AST_Import, + AST_IterationStatement, + AST_Lambda, + AST_LoopControl, + AST_Node, + AST_Number, + AST_Object, + AST_ObjectKeyVal, + AST_ObjectProperty, + AST_PropAccess, + AST_RegExp, + AST_Return, + AST_Scope, + AST_Sequence, + AST_SimpleStatement, + AST_Sub, + AST_Switch, + AST_Symbol, + AST_SymbolConst, + AST_SymbolDeclaration, + AST_SymbolDefun, + AST_SymbolFunarg, + AST_SymbolLambda, + AST_SymbolLet, + AST_SymbolRef, + AST_SymbolUsing, + AST_SymbolVar, + AST_This, + AST_Try, + AST_TryBlock, + AST_Unary, + AST_UnaryPostfix, + AST_UnaryPrefix, + AST_Undefined, + AST_Using, + AST_Var, + AST_VarDef, + AST_With, + AST_Yield, + + TreeTransformer, + TreeWalker, + walk, + walk_abort, + + _NOINLINE, +} from "../ast.js"; +import { + make_node, + MAP, + member, + remove, + has_annotation +} from "../utils/index.js"; + +import { pure_prop_access_globals } from "./native-objects.js"; +import { + lazy_op, + unary_side_effects, + is_modified, + is_lhs, + aborts +} from "./inference.js"; +import { WRITE_ONLY, clear_flag } from "./compressor-flags.js"; +import { + make_sequence, + merge_sequence, + maintain_this_binding, + is_func_expr, + is_identifier_atom, + is_ref_of, + can_be_evicted_from_block, + as_statement_array, +} from "./common.js"; + +function loop_body(x) { + if (x instanceof AST_IterationStatement) { + return x.body instanceof AST_BlockStatement ? x.body : x; + } + return x; +} + +function is_lhs_read_only(lhs) { + if (lhs instanceof AST_This) return true; + if (lhs instanceof AST_SymbolRef) return lhs.definition().orig[0] instanceof AST_SymbolLambda; + if (lhs instanceof AST_PropAccess) { + lhs = lhs.expression; + if (lhs instanceof AST_SymbolRef) { + if (lhs.is_immutable()) return false; + lhs = lhs.fixed_value(); + } + if (!lhs) return true; + if (lhs instanceof AST_RegExp) return false; + if (lhs instanceof AST_Constant) return true; + return is_lhs_read_only(lhs); + } + return false; +} + +/** var a = 1 --> var a*/ +function remove_initializers(var_statement) { + var decls = []; + var_statement.definitions.forEach(function(def) { + if (def.name instanceof AST_SymbolDeclaration) { + def.value = null; + decls.push(def); + } else { + def.declarations_as_names().forEach(name => { + decls.push(make_node(AST_VarDef, def, { + name, + value: null + })); + }); + } + }); + return decls.length ? make_node(AST_Var, var_statement, { definitions: decls }) : null; +} + +/** Called on code which we know is unreachable, to keep elements that affect outside of it. */ +export function trim_unreachable_code(compressor, stat, target) { + walk(stat, node => { + if (node instanceof AST_Var) { + const no_initializers = remove_initializers(node); + if (no_initializers) target.push(no_initializers); + return true; + } + if ( + node instanceof AST_Defun + && (node === stat || !compressor.has_directive("use strict")) + ) { + target.push(node === stat ? node : make_node(AST_Var, node, { + definitions: [ + make_node(AST_VarDef, node, { + name: make_node(AST_SymbolVar, node.name, node.name), + value: null + }) + ] + })); + return true; + } + if (node instanceof AST_Export || node instanceof AST_Import) { + target.push(node); + return true; + } + if (node instanceof AST_Scope) { + return true; + } + }); +} + +/** Tighten a bunch of statements together, and perform statement-level optimization. */ +export function tighten_body(statements, compressor) { + const nearest_scope = compressor.find_scope(); + const defun_scope = nearest_scope.get_defun_scope(); + const { in_loop, in_try } = find_loop_scope_try(); + + var CHANGED, max_iter = 10; + do { + CHANGED = false; + eliminate_spurious_blocks(statements); + if (compressor.option("dead_code")) { + eliminate_dead_code(statements, compressor); + } + if (compressor.option("if_return")) { + handle_if_return(statements, compressor); + } + if (compressor.sequences_limit > 0) { + sequencesize(statements, compressor); + sequencesize_2(statements, compressor); + } + if (compressor.option("join_vars")) { + join_consecutive_vars(statements); + } + if (compressor.option("collapse_vars")) { + collapse(statements, compressor); + } + } while (CHANGED && max_iter-- > 0); + + function find_loop_scope_try() { + var node = compressor.self(), level = 0, in_loop = false, in_try = false; + do { + if (node instanceof AST_IterationStatement) { + in_loop = true; + } else if (node instanceof AST_Scope) { + break; + } else if (node instanceof AST_TryBlock) { + in_try = true; + } + } while (node = compressor.parent(level++)); + + return { in_loop, in_try }; + } + + // Search from right to left for assignment-like expressions: + // - `var a = x;` + // - `a = x;` + // - `++a` + // For each candidate, scan from left to right for first usage, then try + // to fold assignment into the site for compression. + // Will not attempt to collapse assignments into or past code blocks + // which are not sequentially executed, e.g. loops and conditionals. + function collapse(statements, compressor) { + if (nearest_scope.pinned() || defun_scope.pinned()) + return statements; + var args; + var candidates = []; + var stat_index = statements.length; + var scanner = new TreeTransformer(function (node) { + if (abort) + return node; + // Skip nodes before `candidate` as quickly as possible + if (!hit) { + if (node !== hit_stack[hit_index]) + return node; + hit_index++; + if (hit_index < hit_stack.length) + return handle_custom_scan_order(node); + hit = true; + stop_after = find_stop(node, 0); + if (stop_after === node) + abort = true; + return node; + } + // Stop immediately if these node types are encountered + var parent = scanner.parent(); + if (node instanceof AST_Assign + && (node.logical || node.operator != "=" && lhs.equivalent_to(node.left)) + || node instanceof AST_Await + || node instanceof AST_Using + || node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression) + || + (node instanceof AST_Call || node instanceof AST_PropAccess) + && node.optional + || node instanceof AST_Debugger + || node instanceof AST_Destructuring + || node instanceof AST_Expansion + && node.expression instanceof AST_Symbol + && ( + node.expression instanceof AST_This + || node.expression.definition().references.length > 1 + ) + || node instanceof AST_IterationStatement && !(node instanceof AST_For) + || node instanceof AST_LoopControl + || node instanceof AST_Try + || node instanceof AST_With + || node instanceof AST_Yield + || node instanceof AST_Export + || node instanceof AST_Class + || parent instanceof AST_For && node !== parent.init + || !replace_all + && ( + node instanceof AST_SymbolRef + && !node.is_declared(compressor) + && !pure_prop_access_globals.has(node) + ) + || node instanceof AST_SymbolRef + && parent instanceof AST_Call + && has_annotation(parent, _NOINLINE) + || node instanceof AST_ObjectProperty && node.key instanceof AST_Node + ) { + abort = true; + return node; + } + // Stop only if candidate is found within conditional branches + if (!stop_if_hit && (!lhs_local || !replace_all) + && (parent instanceof AST_Binary && lazy_op.has(parent.operator) && parent.left !== node + || parent instanceof AST_Conditional && parent.condition !== node + || parent instanceof AST_If && parent.condition !== node)) { + stop_if_hit = parent; + } + // Replace variable with assignment when found + if ( + can_replace + && !(node instanceof AST_SymbolDeclaration) + && lhs.equivalent_to(node) + && !shadows(scanner.find_scope() || nearest_scope, lvalues) + ) { + if (stop_if_hit) { + abort = true; + return node; + } + if (is_lhs(node, parent)) { + if (value_def) + replaced++; + return node; + } else { + replaced++; + if (value_def && candidate instanceof AST_VarDef) + return node; + } + CHANGED = abort = true; + if (candidate instanceof AST_UnaryPostfix) { + return make_node(AST_UnaryPrefix, candidate, candidate); + } + if (candidate instanceof AST_VarDef) { + var def = candidate.name.definition(); + var value = candidate.value; + if (def.references.length - def.replaced == 1 && !compressor.exposed(def)) { + def.replaced++; + if (funarg && is_identifier_atom(value)) { + return value.transform(compressor); + } else { + return maintain_this_binding(parent, node, value); + } + } + return make_node(AST_Assign, candidate, { + operator: "=", + logical: false, + left: make_node(AST_SymbolRef, candidate.name, candidate.name), + right: value + }); + } + clear_flag(candidate, WRITE_ONLY); + return candidate; + } + // These node types have child nodes that execute sequentially, + // but are otherwise not safe to scan into or beyond them. + var sym; + if (node instanceof AST_Call + || node instanceof AST_Exit + && (side_effects || lhs instanceof AST_PropAccess || may_modify(lhs)) + || node instanceof AST_PropAccess + && (side_effects || node.expression.may_throw_on_access(compressor)) + || node instanceof AST_SymbolRef + && ((lvalues.has(node.name) && lvalues.get(node.name).modified) || side_effects && may_modify(node)) + || node instanceof AST_VarDef && node.value + && (lvalues.has(node.name.name) || side_effects && may_modify(node.name)) + || node instanceof AST_Using + || (sym = is_lhs(node.left, node)) + && (sym instanceof AST_PropAccess || lvalues.has(sym.name)) + || may_throw + && (in_try ? node.has_side_effects(compressor) : side_effects_external(node))) { + stop_after = node; + if (node instanceof AST_Scope) + abort = true; + } + return handle_custom_scan_order(node); + }, function (node) { + if (abort) + return; + if (stop_after === node) + abort = true; + if (stop_if_hit === node) + stop_if_hit = null; + }); + + var multi_replacer = new TreeTransformer(function (node) { + if (abort) + return node; + // Skip nodes before `candidate` as quickly as possible + if (!hit) { + if (node !== hit_stack[hit_index]) + return node; + hit_index++; + if (hit_index < hit_stack.length) + return; + hit = true; + return node; + } + // Replace variable when found + if (node instanceof AST_SymbolRef + && node.name == def.name) { + if (!--replaced) + abort = true; + if (is_lhs(node, multi_replacer.parent())) + return node; + def.replaced++; + value_def.replaced--; + return candidate.value; + } + // Skip (non-executed) functions and (leading) default case in switch statements + if (node instanceof AST_Default || node instanceof AST_Scope) + return node; + }); + + while (--stat_index >= 0) { + // Treat parameters as collapsible in IIFE, i.e. + // function(a, b){ ... }(x()); + // would be translated into equivalent assignments: + // var a = x(), b = undefined; + if (stat_index == 0 && compressor.option("unused")) + extract_args(); + // Find collapsible assignments + var hit_stack = []; + extract_candidates(statements[stat_index]); + while (candidates.length > 0) { + hit_stack = candidates.pop(); + var hit_index = 0; + var candidate = hit_stack[hit_stack.length - 1]; + var value_def = null; + var stop_after = null; + var stop_if_hit = null; + var lhs = get_lhs(candidate); + if (!lhs || is_lhs_read_only(lhs) || lhs.has_side_effects(compressor)) + continue; + // Locate symbols which may execute code outside of scanning range + var lvalues = get_lvalues(candidate); + var lhs_local = is_lhs_local(lhs); + if (lhs instanceof AST_SymbolRef) { + lvalues.set(lhs.name, { def: lhs.definition(), modified: false }); + } + var side_effects = value_has_side_effects(candidate); + var replace_all = replace_all_symbols(); + var may_throw = candidate.may_throw(compressor); + var funarg = candidate.name instanceof AST_SymbolFunarg; + var hit = funarg; + var abort = false, replaced = 0, can_replace = !args || !hit; + if (!can_replace) { + for ( + let j = compressor.self().argnames.lastIndexOf(candidate.name) + 1; + !abort && j < args.length; + j++ + ) { + args[j].transform(scanner); + } + can_replace = true; + } + for (var i = stat_index; !abort && i < statements.length; i++) { + statements[i].transform(scanner); + } + if (value_def) { + var def = candidate.name.definition(); + if (abort && def.references.length - def.replaced > replaced) + replaced = false; + else { + abort = false; + hit_index = 0; + hit = funarg; + for (var i = stat_index; !abort && i < statements.length; i++) { + statements[i].transform(multi_replacer); + } + value_def.single_use = false; + } + } + if (replaced && !remove_candidate(candidate)) + statements.splice(stat_index, 1); + } + } + + function handle_custom_scan_order(node) { + // Skip (non-executed) functions + if (node instanceof AST_Scope) + return node; + + // Scan case expressions first in a switch statement + if (node instanceof AST_Switch) { + node.expression = node.expression.transform(scanner); + for (var i = 0, len = node.body.length; !abort && i < len; i++) { + var branch = node.body[i]; + if (branch instanceof AST_Case) { + if (!hit) { + if (branch !== hit_stack[hit_index]) + continue; + hit_index++; + } + branch.expression = branch.expression.transform(scanner); + if (!replace_all) + break; + } + } + abort = true; + return node; + } + } + + function redefined_within_scope(def, scope) { + if (def.global) + return false; + let cur_scope = def.scope; + while (cur_scope && cur_scope !== scope) { + if (cur_scope.variables.has(def.name)) { + return true; + } + cur_scope = cur_scope.parent_scope; + } + return false; + } + + function has_overlapping_symbol(fn, arg, fn_strict) { + var found = false, scan_this = !(fn instanceof AST_Arrow); + arg.walk(new TreeWalker(function (node, descend) { + if (found) + return true; + if (node instanceof AST_SymbolRef && (fn.variables.has(node.name) || redefined_within_scope(node.definition(), fn))) { + var s = node.definition().scope; + if (s !== defun_scope) + while (s = s.parent_scope) { + if (s === defun_scope) + return true; + } + return found = true; + } + if ((fn_strict || scan_this) && node instanceof AST_This) { + return found = true; + } + if (node instanceof AST_Scope && !(node instanceof AST_Arrow)) { + var prev = scan_this; + scan_this = false; + descend(); + scan_this = prev; + return true; + } + })); + return found; + } + + function arg_is_injectable(arg) { + if (arg instanceof AST_Expansion) return false; + const contains_await = walk(arg, (node) => { + if (node instanceof AST_Await) return walk_abort; + }); + if (contains_await) return false; + return true; + } + function extract_args() { + var iife, fn = compressor.self(); + if (is_func_expr(fn) + && !fn.name + && !fn.uses_arguments + && !fn.pinned() + && (iife = compressor.parent()) instanceof AST_Call + && iife.expression === fn + && iife.args.every(arg_is_injectable) + ) { + var fn_strict = compressor.has_directive("use strict"); + if (fn_strict && !member(fn_strict, fn.body)) + fn_strict = false; + var len = fn.argnames.length; + args = iife.args.slice(len); + var names = new Set(); + for (var i = len; --i >= 0;) { + var sym = fn.argnames[i]; + var arg = iife.args[i]; + // The following two line fix is a duplicate of the fix at + // https://github.com/terser/terser/commit/011d3eb08cefe6922c7d1bdfa113fc4aeaca1b75 + // This might mean that these two pieces of code (one here in collapse_vars and another in reduce_vars + // Might be doing the exact same thing. + const def = sym.definition && sym.definition(); + const is_reassigned = def && def.orig.length > 1; + if (is_reassigned) + continue; + args.unshift(make_node(AST_VarDef, sym, { + name: sym, + value: arg + })); + if (names.has(sym.name)) + continue; + names.add(sym.name); + if (sym instanceof AST_Expansion) { + var elements = iife.args.slice(i); + if (elements.every((arg) => !has_overlapping_symbol(fn, arg, fn_strict) + )) { + candidates.unshift([make_node(AST_VarDef, sym, { + name: sym.expression, + value: make_node(AST_Array, iife, { + elements: elements + }) + })]); + } + } else { + if (!arg) { + arg = make_node(AST_Undefined, sym).transform(compressor); + } else if (arg instanceof AST_Lambda && arg.pinned() + || has_overlapping_symbol(fn, arg, fn_strict)) { + arg = null; + } + if (arg) + candidates.unshift([make_node(AST_VarDef, sym, { + name: sym, + value: arg + })]); + } + } + } + } + + function extract_candidates(expr) { + hit_stack.push(expr); + if (expr instanceof AST_Assign) { + if (!expr.left.has_side_effects(compressor) + && !(expr.right instanceof AST_Chain)) { + candidates.push(hit_stack.slice()); + } + extract_candidates(expr.right); + } else if (expr instanceof AST_Binary) { + extract_candidates(expr.left); + extract_candidates(expr.right); + } else if (expr instanceof AST_Call && !has_annotation(expr, _NOINLINE)) { + extract_candidates(expr.expression); + expr.args.forEach(extract_candidates); + } else if (expr instanceof AST_Case) { + extract_candidates(expr.expression); + } else if (expr instanceof AST_Conditional) { + extract_candidates(expr.condition); + extract_candidates(expr.consequent); + extract_candidates(expr.alternative); + } else if (expr instanceof AST_Definitions) { + var len = expr.definitions.length; + // limit number of trailing variable definitions for consideration + var i = len - 200; + if (i < 0) + i = 0; + for (; i < len; i++) { + extract_candidates(expr.definitions[i]); + } + } else if (expr instanceof AST_DWLoop) { + extract_candidates(expr.condition); + if (!(expr.body instanceof AST_Block)) { + extract_candidates(expr.body); + } + } else if (expr instanceof AST_Exit) { + if (expr.value) + extract_candidates(expr.value); + } else if (expr instanceof AST_For) { + if (expr.init) + extract_candidates(expr.init); + if (expr.condition) + extract_candidates(expr.condition); + if (expr.step) + extract_candidates(expr.step); + if (!(expr.body instanceof AST_Block)) { + extract_candidates(expr.body); + } + } else if (expr instanceof AST_ForIn) { + extract_candidates(expr.object); + if (!(expr.body instanceof AST_Block)) { + extract_candidates(expr.body); + } + } else if (expr instanceof AST_If) { + extract_candidates(expr.condition); + if (!(expr.body instanceof AST_Block)) { + extract_candidates(expr.body); + } + if (expr.alternative && !(expr.alternative instanceof AST_Block)) { + extract_candidates(expr.alternative); + } + } else if (expr instanceof AST_Sequence) { + expr.expressions.forEach(extract_candidates); + } else if (expr instanceof AST_SimpleStatement) { + extract_candidates(expr.body); + } else if (expr instanceof AST_Switch) { + extract_candidates(expr.expression); + expr.body.forEach(extract_candidates); + } else if (expr instanceof AST_Unary) { + if (expr.operator == "++" || expr.operator == "--") { + candidates.push(hit_stack.slice()); + } + } else if (expr instanceof AST_VarDef) { + if (expr.value && !(expr.value instanceof AST_Chain)) { + candidates.push(hit_stack.slice()); + extract_candidates(expr.value); + } + } + hit_stack.pop(); + } + + function find_stop(node, level, write_only) { + var parent = scanner.parent(level); + if (parent instanceof AST_Assign) { + if (write_only + && !parent.logical + && !(parent.left instanceof AST_PropAccess + || lvalues.has(parent.left.name))) { + return find_stop(parent, level + 1, write_only); + } + return node; + } + if (parent instanceof AST_Binary) { + if (write_only && (!lazy_op.has(parent.operator) || parent.left === node)) { + return find_stop(parent, level + 1, write_only); + } + return node; + } + if (parent instanceof AST_Call) + return node; + if (parent instanceof AST_Case) + return node; + if (parent instanceof AST_Conditional) { + if (write_only && parent.condition === node) { + return find_stop(parent, level + 1, write_only); + } + return node; + } + if (parent instanceof AST_Definitions) { + return find_stop(parent, level + 1, true); + } + if (parent instanceof AST_Exit) { + return write_only ? find_stop(parent, level + 1, write_only) : node; + } + if (parent instanceof AST_If) { + if (write_only && parent.condition === node) { + return find_stop(parent, level + 1, write_only); + } + return node; + } + if (parent instanceof AST_IterationStatement) + return node; + if (parent instanceof AST_Sequence) { + return find_stop(parent, level + 1, parent.tail_node() !== node); + } + if (parent instanceof AST_SimpleStatement) { + return find_stop(parent, level + 1, true); + } + if (parent instanceof AST_Switch) + return node; + if (parent instanceof AST_VarDef) + return node; + return null; + } + + function mangleable_var(var_def) { + var value = var_def.value; + if (!(value instanceof AST_SymbolRef)) + return; + if (value.name == "arguments") + return; + var def = value.definition(); + if (def.undeclared) + return; + return value_def = def; + } + + function get_lhs(expr) { + if (expr instanceof AST_Assign && expr.logical) { + return false; + } else if (expr instanceof AST_VarDef && expr.name instanceof AST_SymbolDeclaration) { + var def = expr.name.definition(); + if (!member(expr.name, def.orig)) + return; + var referenced = def.references.length - def.replaced; + if (!referenced) + return; + var declared = def.orig.length - def.eliminated; + if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg) + || (referenced > 1 ? mangleable_var(expr) : !compressor.exposed(def))) { + return make_node(AST_SymbolRef, expr.name, expr.name); + } + } else { + const lhs = expr instanceof AST_Assign + ? expr.left + : expr.expression; + return !is_ref_of(lhs, AST_SymbolConst) + && !is_ref_of(lhs, AST_SymbolLet) + && !is_ref_of(lhs, AST_SymbolUsing) + && lhs; + } + } + + function get_rvalue(expr) { + if (expr instanceof AST_Assign) { + return expr.right; + } else { + return expr.value; + } + } + + function get_lvalues(expr) { + var lvalues = new Map(); + if (expr instanceof AST_Unary) + return lvalues; + var tw = new TreeWalker(function (node) { + var sym = node; + while (sym instanceof AST_PropAccess) + sym = sym.expression; + if (sym instanceof AST_SymbolRef) { + const prev = lvalues.get(sym.name); + if (!prev || !prev.modified) { + lvalues.set(sym.name, { + def: sym.definition(), + modified: is_modified(compressor, tw, node, node, 0) + }); + } + } + }); + get_rvalue(expr).walk(tw); + return lvalues; + } + + function remove_candidate(expr) { + if (expr.name instanceof AST_SymbolFunarg) { + var iife = compressor.parent(), argnames = compressor.self().argnames; + var index = argnames.indexOf(expr.name); + if (index < 0) { + iife.args.length = Math.min(iife.args.length, argnames.length - 1); + } else { + var args = iife.args; + if (args[index]) + args[index] = make_node(AST_Number, args[index], { + value: 0 + }); + } + return true; + } + var found = false; + return statements[stat_index].transform(new TreeTransformer(function (node, descend, in_list) { + if (found) + return node; + if (node === expr || node.body === expr) { + found = true; + if (node instanceof AST_VarDef) { + node.value = node.name instanceof AST_SymbolConst + ? make_node(AST_Undefined, node.value) // `const` always needs value. + : null; + return node; + } + return in_list ? MAP.skip : null; + } + }, function (node) { + if (node instanceof AST_Sequence) + switch (node.expressions.length) { + case 0: return null; + case 1: return node.expressions[0]; + } + })); + } + + function is_lhs_local(lhs) { + while (lhs instanceof AST_PropAccess) + lhs = lhs.expression; + return lhs instanceof AST_SymbolRef + && lhs.definition().scope.get_defun_scope() === defun_scope + && !(in_loop + && (lvalues.has(lhs.name) + || candidate instanceof AST_Unary + || (candidate instanceof AST_Assign + && !candidate.logical + && candidate.operator != "="))); + } + + function value_has_side_effects(expr) { + if (expr instanceof AST_Unary) + return unary_side_effects.has(expr.operator); + return get_rvalue(expr).has_side_effects(compressor); + } + + function replace_all_symbols() { + if (side_effects) + return false; + if (value_def) + return true; + if (lhs instanceof AST_SymbolRef) { + var def = lhs.definition(); + if (def.references.length - def.replaced == (candidate instanceof AST_VarDef ? 1 : 2)) { + return true; + } + } + return false; + } + + function may_modify(sym) { + if (!sym.definition) + return true; // AST_Destructuring + var def = sym.definition(); + if (def.orig.length == 1 && def.orig[0] instanceof AST_SymbolDefun) + return false; + if (def.scope.get_defun_scope() !== defun_scope) + return true; + return def.references.some((ref) => + ref.scope.get_defun_scope() !== defun_scope + ); + } + + function side_effects_external(node, lhs) { + if (node instanceof AST_Assign) + return side_effects_external(node.left, true); + if (node instanceof AST_Unary) + return side_effects_external(node.expression, true); + if (node instanceof AST_VarDef) + return node.value && side_effects_external(node.value); + if (lhs) { + if (node instanceof AST_Dot) + return side_effects_external(node.expression, true); + if (node instanceof AST_Sub) + return side_effects_external(node.expression, true); + if (node instanceof AST_SymbolRef) + return node.definition().scope.get_defun_scope() !== defun_scope; + } + return false; + } + + /** + * Will any of the pulled-in lvalues shadow a variable in newScope or parents? + * similar to scope_encloses_variables_in_this_scope */ + function shadows(my_scope, lvalues) { + for (const { def } of lvalues.values()) { + const looked_up = my_scope.find_variable(def.name); + if (looked_up) { + if (looked_up === def) continue; + return true; + } + } + return false; + } + } + + function eliminate_spurious_blocks(statements) { + var seen_dirs = []; + for (var i = 0; i < statements.length;) { + var stat = statements[i]; + if (stat instanceof AST_BlockStatement && stat.body.every(can_be_evicted_from_block)) { + CHANGED = true; + eliminate_spurious_blocks(stat.body); + statements.splice(i, 1, ...stat.body); + i += stat.body.length; + } else if (stat instanceof AST_EmptyStatement) { + CHANGED = true; + statements.splice(i, 1); + } else if (stat instanceof AST_Directive) { + if (seen_dirs.indexOf(stat.value) < 0) { + i++; + seen_dirs.push(stat.value); + } else { + CHANGED = true; + statements.splice(i, 1); + } + } else + i++; + } + } + + function handle_if_return(statements, compressor) { + var self = compressor.self(); + var multiple_if_returns = has_multiple_if_returns(statements); + var in_lambda = self instanceof AST_Lambda; + // Prevent extremely deep nesting + // https://github.com/terser/terser/issues/1432 + // https://github.com/webpack/webpack/issues/17548 + const iteration_start = Math.min(statements.length, 500); + for (var i = iteration_start; --i >= 0;) { + var stat = statements[i]; + var j = next_index(i); + var next = statements[j]; + + if (in_lambda && !next && stat instanceof AST_Return) { + if (!stat.value) { + CHANGED = true; + statements.splice(i, 1); + continue; + } + if (stat.value instanceof AST_UnaryPrefix && stat.value.operator == "void") { + CHANGED = true; + statements[i] = make_node(AST_SimpleStatement, stat, { + body: stat.value.expression + }); + continue; + } + } + + if (stat instanceof AST_If) { + let ab, new_else; + + ab = aborts(stat.body); + if ( + can_merge_flow(ab) + && (new_else = as_statement_array_with_return(stat.body, ab)) + ) { + if (ab.label) { + remove(ab.label.thedef.references, ab); + } + CHANGED = true; + stat = stat.clone(); + stat.condition = stat.condition.negate(compressor); + stat.body = make_node(AST_BlockStatement, stat, { + body: as_statement_array(stat.alternative).concat(extract_defuns()) + }); + stat.alternative = make_node(AST_BlockStatement, stat, { + body: new_else + }); + statements[i] = stat.transform(compressor); + continue; + } + + ab = aborts(stat.alternative); + if ( + can_merge_flow(ab) + && (new_else = as_statement_array_with_return(stat.alternative, ab)) + ) { + if (ab.label) { + remove(ab.label.thedef.references, ab); + } + CHANGED = true; + stat = stat.clone(); + stat.body = make_node(AST_BlockStatement, stat.body, { + body: as_statement_array(stat.body).concat(extract_defuns()) + }); + stat.alternative = make_node(AST_BlockStatement, stat.alternative, { + body: new_else + }); + statements[i] = stat.transform(compressor); + continue; + } + } + + if (stat instanceof AST_If && stat.body instanceof AST_Return) { + var value = stat.body.value; + //--- + // pretty silly case, but: + // if (foo()) return; return; ==> foo(); return; + if (!value && !stat.alternative + && (in_lambda && !next || next instanceof AST_Return && !next.value)) { + CHANGED = true; + statements[i] = make_node(AST_SimpleStatement, stat.condition, { + body: stat.condition + }); + continue; + } + //--- + // if (foo()) return x; return y; ==> return foo() ? x : y; + if (value && !stat.alternative && next instanceof AST_Return && next.value) { + CHANGED = true; + stat = stat.clone(); + stat.alternative = next; + statements[i] = stat.transform(compressor); + statements.splice(j, 1); + continue; + } + //--- + // if (foo()) return x; [ return ; ] ==> return foo() ? x : undefined; + if (value && !stat.alternative + && (!next && in_lambda && multiple_if_returns + || next instanceof AST_Return)) { + CHANGED = true; + stat = stat.clone(); + stat.alternative = next || make_node(AST_Return, stat, { + value: null + }); + statements[i] = stat.transform(compressor); + if (next) + statements.splice(j, 1); + continue; + } + //--- + // if (a) return b; if (c) return d; e; ==> return a ? b : c ? d : void e; + // + // if sequences is not enabled, this can lead to an endless loop (issue #866). + // however, with sequences on this helps producing slightly better output for + // the example code. + var prev = statements[prev_index(i)]; + if (compressor.option("sequences") && in_lambda && !stat.alternative + && prev instanceof AST_If && prev.body instanceof AST_Return + && next_index(j) == statements.length && next instanceof AST_SimpleStatement) { + CHANGED = true; + stat = stat.clone(); + stat.alternative = make_node(AST_BlockStatement, next, { + body: [ + next, + make_node(AST_Return, next, { + value: null + }) + ] + }); + statements[i] = stat.transform(compressor); + statements.splice(j, 1); + continue; + } + } + } + + function has_multiple_if_returns(statements) { + var n = 0; + for (var i = statements.length; --i >= 0;) { + var stat = statements[i]; + if (stat instanceof AST_If && stat.body instanceof AST_Return) { + if (++n > 1) + return true; + } + } + return false; + } + + function is_return_void(value) { + return !value || value instanceof AST_UnaryPrefix && value.operator == "void"; + } + + function can_merge_flow(ab) { + if (!ab) + return false; + for (var j = i + 1, len = statements.length; j < len; j++) { + var stat = statements[j]; + if (stat instanceof AST_DefinitionsLike && !(stat instanceof AST_Var)) + return false; + } + var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab) : null; + return ab instanceof AST_Return && in_lambda && is_return_void(ab.value) + || ab instanceof AST_Continue && self === loop_body(lct) + || ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct; + } + + function extract_defuns() { + var tail = statements.slice(i + 1); + statements.length = i + 1; + return tail.filter(function (stat) { + if (stat instanceof AST_Defun) { + statements.push(stat); + return false; + } + return true; + }); + } + + function as_statement_array_with_return(node, ab) { + var body = as_statement_array(node); + if (ab !== body[body.length - 1]) { + return undefined; + } + body = body.slice(0, -1); + if (!body.every(stat => can_be_evicted_from_block(stat))) { + return undefined; + } + if (ab.value) { + body.push(make_node(AST_SimpleStatement, ab.value, { + body: ab.value.expression + })); + } + return body; + } + + function next_index(i) { + for (var j = i + 1, len = statements.length; j < len; j++) { + var stat = statements[j]; + if (!(stat instanceof AST_Var && declarations_only(stat))) { + break; + } + } + return j; + } + + function prev_index(i) { + for (var j = i; --j >= 0;) { + var stat = statements[j]; + if (!(stat instanceof AST_Var && declarations_only(stat))) { + break; + } + } + return j; + } + } + + function eliminate_dead_code(statements, compressor) { + var has_quit; + var self = compressor.self(); + for (var i = 0, n = 0, len = statements.length; i < len; i++) { + var stat = statements[i]; + if (stat instanceof AST_LoopControl) { + var lct = compressor.loopcontrol_target(stat); + if (stat instanceof AST_Break + && !(lct instanceof AST_IterationStatement) + && loop_body(lct) === self + || stat instanceof AST_Continue + && loop_body(lct) === self) { + if (stat.label) { + remove(stat.label.thedef.references, stat); + } + } else { + statements[n++] = stat; + } + } else { + statements[n++] = stat; + } + if (aborts(stat)) { + has_quit = statements.slice(i + 1); + break; + } + } + statements.length = n; + CHANGED = n != len; + if (has_quit) + has_quit.forEach(function (stat) { + trim_unreachable_code(compressor, stat, statements); + }); + } + + function declarations_only(node) { + return node.definitions.every((var_def) => !var_def.value); + } + + function sequencesize(statements, compressor) { + if (statements.length < 2) + return; + var seq = [], n = 0; + function push_seq() { + if (!seq.length) + return; + var body = make_sequence(seq[0], seq); + statements[n++] = make_node(AST_SimpleStatement, body, { body: body }); + seq = []; + } + for (var i = 0, len = statements.length; i < len; i++) { + var stat = statements[i]; + if (stat instanceof AST_SimpleStatement) { + if (seq.length >= compressor.sequences_limit) + push_seq(); + var body = stat.body; + if (seq.length > 0) + body = body.drop_side_effect_free(compressor); + if (body) + merge_sequence(seq, body); + } else if (stat instanceof AST_Definitions && declarations_only(stat) + || stat instanceof AST_Defun) { + statements[n++] = stat; + } else { + push_seq(); + statements[n++] = stat; + } + } + push_seq(); + statements.length = n; + if (n != len) + CHANGED = true; + } + + function to_simple_statement(block, decls) { + if (!(block instanceof AST_BlockStatement)) + return block; + var stat = null; + for (var i = 0, len = block.body.length; i < len; i++) { + var line = block.body[i]; + if (line instanceof AST_Var && declarations_only(line)) { + decls.push(line); + } else if (stat || line instanceof AST_DefinitionsLike && !(line instanceof AST_Var)) { + return false; + } else { + stat = line; + } + } + return stat; + } + + function sequencesize_2(statements, compressor) { + function cons_seq(right) { + n--; + CHANGED = true; + var left = prev.body; + return make_sequence(left, [left, right]).transform(compressor); + } + var n = 0, prev; + for (var i = 0; i < statements.length; i++) { + var stat = statements[i]; + if (prev) { + if (stat instanceof AST_Exit) { + stat.value = cons_seq(stat.value || make_node(AST_Undefined, stat).transform(compressor)); + } else if (stat instanceof AST_For) { + if (!(stat.init instanceof AST_DefinitionsLike)) { + const abort = walk(prev.body, node => { + if (node instanceof AST_Scope) + return true; + if (node instanceof AST_Binary + && node.operator === "in") { + return walk_abort; + } + }); + if (!abort) { + if (stat.init) + stat.init = cons_seq(stat.init); + else { + stat.init = prev.body; + n--; + CHANGED = true; + } + } + } + } else if (stat instanceof AST_ForIn) { + if (!(stat.init instanceof AST_DefinitionsLike) || stat.init instanceof AST_Var) { + stat.object = cons_seq(stat.object); + } + } else if (stat instanceof AST_If) { + stat.condition = cons_seq(stat.condition); + } else if (stat instanceof AST_Switch) { + stat.expression = cons_seq(stat.expression); + } else if (stat instanceof AST_With) { + stat.expression = cons_seq(stat.expression); + } + } + if (compressor.option("conditionals") && stat instanceof AST_If) { + var decls = []; + var body = to_simple_statement(stat.body, decls); + var alt = to_simple_statement(stat.alternative, decls); + if (body !== false && alt !== false && decls.length > 0) { + var len = decls.length; + decls.push(make_node(AST_If, stat, { + condition: stat.condition, + body: body || make_node(AST_EmptyStatement, stat.body), + alternative: alt + })); + decls.unshift(n, 1); + [].splice.apply(statements, decls); + i += len; + n += len + 1; + prev = null; + CHANGED = true; + continue; + } + } + statements[n++] = stat; + prev = stat instanceof AST_SimpleStatement ? stat : null; + } + statements.length = n; + } + + function join_object_assignments(defn, body) { + if (!(defn instanceof AST_Definitions)) + return; + var def = defn.definitions[defn.definitions.length - 1]; + if (!(def.value instanceof AST_Object)) + return; + var exprs; + if (body instanceof AST_Assign && !body.logical) { + exprs = [body]; + } else if (body instanceof AST_Sequence) { + exprs = body.expressions.slice(); + } + if (!exprs) + return; + var trimmed = false; + do { + var node = exprs[0]; + if (!(node instanceof AST_Assign)) + break; + if (node.operator != "=") + break; + if (!(node.left instanceof AST_PropAccess)) + break; + var sym = node.left.expression; + if (!(sym instanceof AST_SymbolRef)) + break; + if (def.name.name != sym.name) + break; + if (!node.right.is_constant_expression(nearest_scope)) + break; + var prop = node.left.property; + if (prop instanceof AST_Node) { + prop = prop.evaluate(compressor); + } + if (prop instanceof AST_Node) + break; + prop = "" + prop; + var diff = compressor.option("ecma") < 2015 + && compressor.has_directive("use strict") ? function (node) { + return node.key != prop && (node.key && node.key.name != prop); + } : function (node) { + return node.key && node.key.name != prop; + }; + if (!def.value.properties.every(diff)) + break; + var p = def.value.properties.filter(function (p) { return p.key === prop; })[0]; + if (!p) { + def.value.properties.push(make_node(AST_ObjectKeyVal, node, { + key: prop, + value: node.right + })); + } else { + p.value = new AST_Sequence({ + start: p.start, + expressions: [p.value.clone(), node.right.clone()], + end: p.end + }); + } + exprs.shift(); + trimmed = true; + } while (exprs.length); + return trimmed && exprs; + } + + function join_consecutive_vars(statements) { + var defs; + for (var i = 0, j = -1, len = statements.length; i < len; i++) { + var stat = statements[i]; + var prev = statements[j]; + if (stat instanceof AST_Definitions) { + if (prev && prev.TYPE == stat.TYPE) { + prev.definitions = prev.definitions.concat(stat.definitions); + CHANGED = true; + } else if (defs && defs.TYPE == stat.TYPE && declarations_only(stat)) { + defs.definitions = defs.definitions.concat(stat.definitions); + CHANGED = true; + } else { + statements[++j] = stat; + defs = stat; + } + } else if ( + stat instanceof AST_Using + && prev instanceof AST_Using + && prev.await === stat.await + ) { + prev.definitions = prev.definitions.concat(stat.definitions); + } else if (stat instanceof AST_Exit) { + stat.value = extract_object_assignments(stat.value); + } else if (stat instanceof AST_For) { + var exprs = join_object_assignments(prev, stat.init); + if (exprs) { + CHANGED = true; + stat.init = exprs.length ? make_sequence(stat.init, exprs) : null; + statements[++j] = stat; + } else if ( + prev instanceof AST_Var + && (!stat.init || stat.init.TYPE == prev.TYPE) + ) { + if (stat.init) { + prev.definitions = prev.definitions.concat(stat.init.definitions); + } + stat.init = prev; + statements[j] = stat; + CHANGED = true; + } else if ( + defs instanceof AST_Var + && stat.init instanceof AST_Var + && declarations_only(stat.init) + ) { + defs.definitions = defs.definitions.concat(stat.init.definitions); + stat.init = null; + statements[++j] = stat; + CHANGED = true; + } else { + statements[++j] = stat; + } + } else if (stat instanceof AST_ForIn) { + stat.object = extract_object_assignments(stat.object); + } else if (stat instanceof AST_If) { + stat.condition = extract_object_assignments(stat.condition); + } else if (stat instanceof AST_SimpleStatement) { + var exprs = join_object_assignments(prev, stat.body); + if (exprs) { + CHANGED = true; + if (!exprs.length) + continue; + stat.body = make_sequence(stat.body, exprs); + } + statements[++j] = stat; + } else if (stat instanceof AST_Switch) { + stat.expression = extract_object_assignments(stat.expression); + } else if (stat instanceof AST_With) { + stat.expression = extract_object_assignments(stat.expression); + } else { + statements[++j] = stat; + } + } + statements.length = j + 1; + + function extract_object_assignments(value) { + statements[++j] = stat; + var exprs = join_object_assignments(prev, value); + if (exprs) { + CHANGED = true; + if (exprs.length) { + return make_sequence(value, exprs); + } else if (value instanceof AST_Sequence) { + return value.tail_node().left; + } else { + return value.left; + } + } + return value; + } + } +} diff --git a/node_modules/terser/lib/equivalent-to.js b/node_modules/terser/lib/equivalent-to.js new file mode 100644 index 0000000..1a858c4 --- /dev/null +++ b/node_modules/terser/lib/equivalent-to.js @@ -0,0 +1,303 @@ +import { + AST_Array, + AST_Atom, + AST_Await, + AST_BigInt, + AST_Binary, + AST_Block, + AST_Call, + AST_Catch, + AST_Chain, + AST_Class, + AST_ClassProperty, + AST_ClassPrivateProperty, + AST_ConciseMethod, + AST_Conditional, + AST_Debugger, + AST_DefinitionsLike, + AST_Destructuring, + AST_Directive, + AST_Do, + AST_Dot, + AST_DotHash, + AST_EmptyStatement, + AST_Expansion, + AST_Export, + AST_Finally, + AST_For, + AST_ForIn, + AST_ForOf, + AST_If, + AST_Import, + AST_ImportMeta, + AST_Jump, + AST_LabeledStatement, + AST_Lambda, + AST_LoopControl, + AST_NameMapping, + AST_NewTarget, + AST_Node, + AST_Number, + AST_Object, + AST_ObjectGetter, + AST_ObjectKeyVal, + AST_ObjectProperty, + AST_ObjectSetter, + AST_PrefixedTemplateString, + AST_PrivateIn, + AST_PrivateMethod, + AST_PropAccess, + AST_RegExp, + AST_Sequence, + AST_SimpleStatement, + AST_String, + AST_Super, + AST_Switch, + AST_SwitchBranch, + AST_Symbol, + AST_TemplateSegment, + AST_TemplateString, + AST_This, + AST_Toplevel, + AST_Try, + AST_Unary, + AST_VarDefLike, + AST_While, + AST_With, + AST_Yield +} from "./ast.js"; + +const shallow_cmp = (node1, node2) => { + return ( + node1 === null && node2 === null + || node1.TYPE === node2.TYPE && node1.shallow_cmp(node2) + ); +}; + +export const equivalent_to = (tree1, tree2) => { + if (!shallow_cmp(tree1, tree2)) return false; + const walk_1_state = [tree1]; + const walk_2_state = [tree2]; + + const walk_1_push = walk_1_state.push.bind(walk_1_state); + const walk_2_push = walk_2_state.push.bind(walk_2_state); + + while (walk_1_state.length && walk_2_state.length) { + const node_1 = walk_1_state.pop(); + const node_2 = walk_2_state.pop(); + + if (!shallow_cmp(node_1, node_2)) return false; + + node_1._children_backwards(walk_1_push); + node_2._children_backwards(walk_2_push); + + if (walk_1_state.length !== walk_2_state.length) { + // Different number of children + return false; + } + } + + return walk_1_state.length == 0 && walk_2_state.length == 0; +}; + +const pass_through = () => true; + +AST_Node.prototype.shallow_cmp = function () { + throw new Error("did not find a shallow_cmp function for " + this.constructor.name); +}; + +AST_Debugger.prototype.shallow_cmp = pass_through; + +AST_Directive.prototype.shallow_cmp = function(other) { + return this.value === other.value; +}; + +AST_SimpleStatement.prototype.shallow_cmp = pass_through; + +AST_Block.prototype.shallow_cmp = pass_through; + +AST_EmptyStatement.prototype.shallow_cmp = pass_through; + +AST_LabeledStatement.prototype.shallow_cmp = function(other) { + return this.label.name === other.label.name; +}; + +AST_Do.prototype.shallow_cmp = pass_through; + +AST_While.prototype.shallow_cmp = pass_through; + +AST_For.prototype.shallow_cmp = function(other) { + return (this.init == null ? other.init == null : this.init === other.init) && (this.condition == null ? other.condition == null : this.condition === other.condition) && (this.step == null ? other.step == null : this.step === other.step); +}; + +AST_ForIn.prototype.shallow_cmp = pass_through; + +AST_ForOf.prototype.shallow_cmp = pass_through; + +AST_With.prototype.shallow_cmp = pass_through; + +AST_Toplevel.prototype.shallow_cmp = pass_through; + +AST_Expansion.prototype.shallow_cmp = pass_through; + +AST_Lambda.prototype.shallow_cmp = function(other) { + return this.is_generator === other.is_generator && this.async === other.async; +}; + +AST_Destructuring.prototype.shallow_cmp = function(other) { + return this.is_array === other.is_array; +}; + +AST_PrefixedTemplateString.prototype.shallow_cmp = pass_through; + +AST_TemplateString.prototype.shallow_cmp = pass_through; + +AST_TemplateSegment.prototype.shallow_cmp = function(other) { + return this.value === other.value; +}; + +AST_Jump.prototype.shallow_cmp = pass_through; + +AST_LoopControl.prototype.shallow_cmp = pass_through; + +AST_Await.prototype.shallow_cmp = pass_through; + +AST_Yield.prototype.shallow_cmp = function(other) { + return this.is_star === other.is_star; +}; + +AST_If.prototype.shallow_cmp = function(other) { + return this.alternative == null ? other.alternative == null : this.alternative === other.alternative; +}; + +AST_Switch.prototype.shallow_cmp = pass_through; + +AST_SwitchBranch.prototype.shallow_cmp = pass_through; + +AST_Try.prototype.shallow_cmp = function(other) { + return (this.body === other.body) && (this.bcatch == null ? other.bcatch == null : this.bcatch === other.bcatch) && (this.bfinally == null ? other.bfinally == null : this.bfinally === other.bfinally); +}; + +AST_Catch.prototype.shallow_cmp = function(other) { + return this.argname == null ? other.argname == null : this.argname === other.argname; +}; + +AST_Finally.prototype.shallow_cmp = pass_through; + +AST_DefinitionsLike.prototype.shallow_cmp = pass_through; + +AST_VarDefLike.prototype.shallow_cmp = function(other) { + return this.value == null ? other.value == null : this.value === other.value; +}; + +AST_NameMapping.prototype.shallow_cmp = pass_through; + +AST_Import.prototype.shallow_cmp = function(other) { + return (this.imported_name == null ? other.imported_name == null : this.imported_name === other.imported_name) && (this.imported_names == null ? other.imported_names == null : this.imported_names === other.imported_names) && (this.attributes == null ? other.attributes == null : this.attributes === other.attributes); +}; + +AST_ImportMeta.prototype.shallow_cmp = pass_through; + +AST_Export.prototype.shallow_cmp = function(other) { + return (this.exported_definition == null ? other.exported_definition == null : this.exported_definition === other.exported_definition) && (this.exported_value == null ? other.exported_value == null : this.exported_value === other.exported_value) && (this.exported_names == null ? other.exported_names == null : this.exported_names === other.exported_names) && (this.attributes == null ? other.attributes == null : this.attributes === other.attributes) && this.module_name === other.module_name && this.is_default === other.is_default; +}; + +AST_Call.prototype.shallow_cmp = pass_through; + +AST_Sequence.prototype.shallow_cmp = pass_through; + +AST_PropAccess.prototype.shallow_cmp = pass_through; + +AST_Chain.prototype.shallow_cmp = pass_through; + +AST_Dot.prototype.shallow_cmp = function(other) { + return this.property === other.property; +}; + +AST_DotHash.prototype.shallow_cmp = function(other) { + return this.property === other.property; +}; + +AST_Unary.prototype.shallow_cmp = function(other) { + return this.operator === other.operator; +}; + +AST_Binary.prototype.shallow_cmp = function(other) { + return this.operator === other.operator; +}; + +AST_PrivateIn.prototype.shallow_cmp = pass_through; + +AST_Conditional.prototype.shallow_cmp = pass_through; + +AST_Array.prototype.shallow_cmp = pass_through; + +AST_Object.prototype.shallow_cmp = pass_through; + +AST_ObjectProperty.prototype.shallow_cmp = pass_through; + +AST_ObjectKeyVal.prototype.shallow_cmp = function(other) { + return this.key === other.key && this.quote === other.quote; +}; + +AST_ObjectSetter.prototype.shallow_cmp = function(other) { + return this.static === other.static; +}; + +AST_ObjectGetter.prototype.shallow_cmp = function(other) { + return this.static === other.static; +}; + +AST_ConciseMethod.prototype.shallow_cmp = function(other) { + return this.static === other.static; +}; + +AST_PrivateMethod.prototype.shallow_cmp = function(other) { + return this.static === other.static; +}; + +AST_Class.prototype.shallow_cmp = function(other) { + return (this.name == null ? other.name == null : this.name === other.name) && (this.extends == null ? other.extends == null : this.extends === other.extends); +}; + +AST_ClassProperty.prototype.shallow_cmp = function(other) { + return this.static === other.static + && (typeof this.key === "string" + ? this.key === other.key + : true /* AST_Node handled elsewhere */); +}; + +AST_ClassPrivateProperty.prototype.shallow_cmp = function(other) { + return this.static === other.static; +}; + +AST_Symbol.prototype.shallow_cmp = function(other) { + return this.name === other.name; +}; + +AST_NewTarget.prototype.shallow_cmp = pass_through; + +AST_This.prototype.shallow_cmp = pass_through; + +AST_Super.prototype.shallow_cmp = pass_through; + +AST_String.prototype.shallow_cmp = function(other) { + return this.value === other.value; +}; + +AST_Number.prototype.shallow_cmp = function(other) { + return this.value === other.value; +}; + +AST_BigInt.prototype.shallow_cmp = function(other) { + return this.value === other.value; +}; + +AST_RegExp.prototype.shallow_cmp = function (other) { + return ( + this.value.flags === other.value.flags + && this.value.source === other.value.source + ); +}; + +AST_Atom.prototype.shallow_cmp = pass_through; diff --git a/node_modules/terser/lib/minify.js b/node_modules/terser/lib/minify.js new file mode 100644 index 0000000..80f65a7 --- /dev/null +++ b/node_modules/terser/lib/minify.js @@ -0,0 +1,412 @@ +"use strict"; +/* eslint-env browser, es6, node */ + +import { + defaults, + map_from_object, + map_to_object, + HOP, +} from "./utils/index.js"; +import { AST_Toplevel, AST_Node, walk, AST_Scope } from "./ast.js"; +import { parse } from "./parse.js"; +import { OutputStream } from "./output.js"; +import { Compressor } from "./compress/index.js"; +import { base54 } from "./scope.js"; +import { SourceMap } from "./sourcemap.js"; +import { + mangle_properties, + mangle_private_properties, + reserve_quoted_keys, + find_annotated_props, +} from "./propmangle.js"; + +// to/from base64 functions +// Prefer built-in Buffer, if available, then use hack +// https://developer.mozilla.org/en-US/docs/Glossary/Base64#The_Unicode_Problem +var to_ascii = typeof Buffer !== "undefined" + ? (b64) => Buffer.from(b64, "base64").toString() + : (b64) => decodeURIComponent(escape(atob(b64))); +var to_base64 = typeof Buffer !== "undefined" + ? (str) => Buffer.from(str).toString("base64") + : (str) => btoa(unescape(encodeURIComponent(str))); + +function read_source_map(code) { + var match = /(?:^|[^.])\/\/# sourceMappingURL=data:application\/json(;[\w=-]*)?;base64,([+/0-9A-Za-z]*=*)\s*$/.exec(code); + if (!match) { + console.warn("inline source map not found"); + return null; + } + return to_ascii(match[2]); +} + +function set_shorthand(name, options, keys) { + if (options[name]) { + keys.forEach(function(key) { + if (options[key]) { + if (typeof options[key] != "object") options[key] = {}; + if (!(name in options[key])) options[key][name] = options[name]; + } + }); + } +} + +function init_cache(cache) { + if (!cache) return; + if (!("props" in cache)) { + cache.props = new Map(); + } else if (!(cache.props instanceof Map)) { + cache.props = map_from_object(cache.props); + } +} + +function cache_to_json(cache) { + return { + props: map_to_object(cache.props) + }; +} + +function log_input(files, options, fs, debug_folder) { + if (!(fs && fs.writeFileSync && fs.mkdirSync)) { + return; + } + + try { + fs.mkdirSync(debug_folder); + } catch (e) { + if (e.code !== "EEXIST") throw e; + } + + const log_path = `${debug_folder}/terser-debug-${(Math.random() * 9999999) | 0}.log`; + + options = options || {}; + + const options_str = JSON.stringify(options, (_key, thing) => { + if (typeof thing === "function") return "[Function " + thing.toString() + "]"; + if (thing instanceof RegExp) return "[RegExp " + thing.toString() + "]"; + return thing; + }, 4); + + const files_str = (file) => { + if (typeof file === "object" && options.parse && options.parse.spidermonkey) { + return JSON.stringify(file, null, 2); + } else if (typeof file === "object") { + return Object.keys(file) + .map((key) => key + ": " + files_str(file[key])) + .join("\n\n"); + } else if (typeof file === "string") { + return "```\n" + file + "\n```"; + } else { + return file; // What do? + } + }; + + fs.writeFileSync(log_path, "Options: \n" + options_str + "\n\nInput files:\n\n" + files_str(files) + "\n"); +} + +function* minify_sync_or_async(files, options, _fs_module) { + if ( + _fs_module + && typeof process === "object" + && process.env + && typeof process.env.TERSER_DEBUG_DIR === "string" + ) { + log_input(files, options, _fs_module, process.env.TERSER_DEBUG_DIR); + } + + options = defaults(options, { + compress: {}, + ecma: undefined, + enclose: false, + ie8: false, + keep_classnames: undefined, + keep_fnames: false, + mangle: {}, + module: false, + nameCache: null, + output: null, + format: null, + parse: {}, + rename: undefined, + safari10: false, + sourceMap: false, + spidermonkey: false, + timings: false, + toplevel: false, + warnings: false, + wrap: false, + }, true); + + var timings = options.timings && { + start: Date.now() + }; + if (options.keep_classnames === undefined) { + options.keep_classnames = options.keep_fnames; + } + if (options.rename === undefined) { + options.rename = options.compress && options.mangle; + } + if (options.output && options.format) { + throw new Error("Please only specify either output or format option, preferrably format."); + } + options.format = options.format || options.output || {}; + set_shorthand("ecma", options, [ "parse", "compress", "format" ]); + set_shorthand("ie8", options, [ "compress", "mangle", "format" ]); + set_shorthand("keep_classnames", options, [ "compress", "mangle" ]); + set_shorthand("keep_fnames", options, [ "compress", "mangle" ]); + set_shorthand("module", options, [ "parse", "compress", "mangle" ]); + set_shorthand("safari10", options, [ "mangle", "format" ]); + set_shorthand("toplevel", options, [ "compress", "mangle" ]); + set_shorthand("warnings", options, [ "compress" ]); // legacy + var quoted_props; + if (options.mangle) { + options.mangle = defaults(options.mangle, { + cache: options.nameCache && (options.nameCache.vars || {}), + eval: false, + ie8: false, + keep_classnames: false, + keep_fnames: false, + module: false, + nth_identifier: base54, + properties: false, + reserved: [], + safari10: false, + toplevel: false, + }, true); + if (options.mangle.properties) { + if (typeof options.mangle.properties != "object") { + options.mangle.properties = {}; + } + if (options.mangle.properties.keep_quoted) { + quoted_props = options.mangle.properties.reserved; + if (!Array.isArray(quoted_props)) quoted_props = []; + options.mangle.properties.reserved = quoted_props; + } + if (options.nameCache && !("cache" in options.mangle.properties)) { + options.mangle.properties.cache = options.nameCache.props || {}; + } + } + init_cache(options.mangle.cache); + init_cache(options.mangle.properties.cache); + } + if (options.sourceMap) { + options.sourceMap = defaults(options.sourceMap, { + asObject: false, + content: null, + filename: null, + includeSources: false, + root: null, + url: null, + }, true); + } + + // -- Parse phase -- + if (timings) timings.parse = Date.now(); + var toplevel; + if (files instanceof AST_Toplevel) { + toplevel = files; + } else { + if (typeof files == "string" || (options.parse.spidermonkey && !Array.isArray(files))) { + files = [ files ]; + } + options.parse = options.parse || {}; + options.parse.toplevel = null; + + if (options.parse.spidermonkey) { + options.parse.toplevel = AST_Node.from_mozilla_ast(Object.keys(files).reduce(function(toplevel, name) { + if (!toplevel) return files[name]; + toplevel.body = toplevel.body.concat(files[name].body); + return toplevel; + }, null)); + } else { + delete options.parse.spidermonkey; + + for (var name in files) if (HOP(files, name)) { + options.parse.filename = name; + options.parse.toplevel = parse(files[name], options.parse); + if (options.sourceMap && options.sourceMap.content == "inline") { + if (Object.keys(files).length > 1) + throw new Error("inline source map only works with singular input"); + options.sourceMap.content = read_source_map(files[name]); + } + } + } + if (options.parse.toplevel === null) { + throw new Error("no source file given"); + } + + toplevel = options.parse.toplevel; + } + if (quoted_props && options.mangle.properties.keep_quoted !== "strict") { + reserve_quoted_keys(toplevel, quoted_props); + } + var annotated_props; + if (options.mangle && options.mangle.properties) { + annotated_props = find_annotated_props(toplevel); + } + if (options.wrap) { + toplevel = toplevel.wrap_commonjs(options.wrap); + } + if (options.enclose) { + toplevel = toplevel.wrap_enclose(options.enclose); + } + if (timings) timings.rename = Date.now(); + // disable rename on harmony due to expand_names bug in for-of loops + // https://github.com/mishoo/UglifyJS2/issues/2794 + if (0 && options.rename) { + toplevel.figure_out_scope(options.mangle); + toplevel.expand_names(options.mangle); + } + + // -- Compress phase -- + if (timings) timings.compress = Date.now(); + if (options.compress) { + toplevel = new Compressor(options.compress, { + mangle_options: options.mangle + }).compress(toplevel); + } + + // -- Mangle phase -- + if (timings) timings.scope = Date.now(); + if (options.mangle) toplevel.figure_out_scope(options.mangle); + if (timings) timings.mangle = Date.now(); + if (options.mangle) { + toplevel.compute_char_frequency(options.mangle); + toplevel.mangle_names(options.mangle); + toplevel = mangle_private_properties(toplevel, options.mangle); + } + if (timings) timings.properties = Date.now(); + if (options.mangle && options.mangle.properties) { + toplevel = mangle_properties(toplevel, options.mangle.properties, annotated_props); + } + + // Format phase + if (timings) timings.format = Date.now(); + var result = {}; + if (options.format.ast) { + result.ast = toplevel; + } + if (options.format.spidermonkey) { + result.ast = toplevel.to_mozilla_ast(); + } + let format_options; + if (!HOP(options.format, "code") || options.format.code) { + // Make a shallow copy so that we can modify without mutating the user's input. + format_options = {...options.format}; + if (!format_options.ast) { + // Destroy stuff to save RAM. (unless the deprecated `ast` option is on) + format_options._destroy_ast = true; + + walk(toplevel, node => { + if (node instanceof AST_Scope) { + node.variables = undefined; + node.enclosed = undefined; + node.parent_scope = undefined; + } + if (node.block_scope) { + node.block_scope.variables = undefined; + node.block_scope.enclosed = undefined; + node.block_scope.parent_scope = undefined; + } + }); + } + + if (options.sourceMap) { + if (options.sourceMap.includeSources && files instanceof AST_Toplevel) { + throw new Error("original source content unavailable"); + } + format_options.source_map = yield* SourceMap({ + file: options.sourceMap.filename, + orig: options.sourceMap.content, + root: options.sourceMap.root, + files: options.sourceMap.includeSources ? files : null, + }); + } + delete format_options.ast; + delete format_options.code; + delete format_options.spidermonkey; + var stream = OutputStream(format_options); + toplevel.print(stream); + result.code = stream.get(); + if (options.sourceMap) { + Object.defineProperty(result, "map", { + configurable: true, + enumerable: true, + get() { + const map = format_options.source_map.getEncoded(); + return (result.map = options.sourceMap.asObject ? map : JSON.stringify(map)); + }, + set(value) { + Object.defineProperty(result, "map", { + value, + writable: true, + }); + } + }); + result.decoded_map = format_options.source_map.getDecoded(); + if (options.sourceMap.url == "inline") { + var sourceMap = typeof result.map === "object" ? JSON.stringify(result.map) : result.map; + result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(sourceMap); + } else if (options.sourceMap.url) { + result.code += "\n//# sourceMappingURL=" + options.sourceMap.url; + } + } + } + if (options.nameCache && options.mangle) { + if (options.mangle.cache) options.nameCache.vars = cache_to_json(options.mangle.cache); + if (options.mangle.properties && options.mangle.properties.cache) { + options.nameCache.props = cache_to_json(options.mangle.properties.cache); + } + } + if (format_options && format_options.source_map) { + format_options.source_map.destroy(); + } + if (timings) { + timings.end = Date.now(); + result.timings = { + parse: 1e-3 * (timings.rename - timings.parse), + rename: 1e-3 * (timings.compress - timings.rename), + compress: 1e-3 * (timings.scope - timings.compress), + scope: 1e-3 * (timings.mangle - timings.scope), + mangle: 1e-3 * (timings.properties - timings.mangle), + properties: 1e-3 * (timings.format - timings.properties), + format: 1e-3 * (timings.end - timings.format), + total: 1e-3 * (timings.end - timings.start) + }; + } + return result; +} + +async function minify(files, options, _fs_module) { + const gen = minify_sync_or_async(files, options, _fs_module); + + let yielded; + let val; + do { + val = gen.next(await yielded); + yielded = val.value; + } while (!val.done); + + return val.value; +} + +function minify_sync(files, options, _fs_module) { + const gen = minify_sync_or_async(files, options, _fs_module); + + let yielded; + let val; + do { + if (yielded && typeof yielded.then === "function") { + throw new Error("minify_sync cannot be used with the legacy source-map module"); + } + val = gen.next(yielded); + yielded = val.value; + } while (!val.done); + + return val.value; +} + +export { + minify, + minify_sync, + to_ascii, +}; diff --git a/node_modules/terser/lib/mozilla-ast.js b/node_modules/terser/lib/mozilla-ast.js new file mode 100644 index 0000000..d55c911 --- /dev/null +++ b/node_modules/terser/lib/mozilla-ast.js @@ -0,0 +1,2098 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +import { make_node } from "./utils/index.js"; +import { + AST_Accessor, + AST_Array, + AST_Arrow, + AST_Assign, + AST_Atom, + AST_Await, + AST_BigInt, + AST_Binary, + AST_Block, + AST_BlockStatement, + AST_Boolean, + AST_Break, + AST_Call, + AST_Case, + AST_Catch, + AST_Chain, + AST_Class, + AST_ClassStaticBlock, + AST_ClassExpression, + AST_ClassProperty, + AST_ClassPrivateProperty, + AST_ConciseMethod, + AST_Conditional, + AST_Const, + AST_Constant, + AST_Continue, + AST_Debugger, + AST_Default, + AST_DefaultAssign, + AST_DefClass, + AST_DefinitionsLike, + AST_Defun, + AST_Destructuring, + AST_Directive, + AST_Do, + AST_Dot, + AST_DotHash, + AST_EmptyStatement, + AST_Expansion, + AST_Export, + AST_False, + AST_Finally, + AST_For, + AST_ForIn, + AST_ForOf, + AST_Function, + AST_Hole, + AST_If, + AST_Import, + AST_ImportMeta, + AST_Label, + AST_LabeledStatement, + AST_LabelRef, + AST_Lambda, + AST_Let, + AST_NameMapping, + AST_New, + AST_NewTarget, + AST_Node, + AST_Null, + AST_Number, + AST_Object, + AST_ObjectGetter, + AST_ObjectKeyVal, + AST_ObjectProperty, + AST_ObjectSetter, + AST_PrefixedTemplateString, + AST_PrivateGetter, + AST_PrivateMethod, + AST_PrivateSetter, + AST_PrivateIn, + AST_PropAccess, + AST_RegExp, + AST_Return, + AST_Sequence, + AST_SimpleStatement, + AST_Statement, + AST_String, + AST_Sub, + AST_Super, + AST_Switch, + AST_SwitchBranch, + AST_Symbol, + AST_SymbolCatch, + AST_SymbolClass, + AST_SymbolClassProperty, + AST_SymbolPrivateProperty, + AST_SymbolConst, + AST_SymbolDefClass, + AST_SymbolDefun, + AST_SymbolExport, + AST_SymbolExportForeign, + AST_SymbolFunarg, + AST_SymbolImport, + AST_SymbolImportForeign, + AST_SymbolLambda, + AST_SymbolLet, + AST_SymbolMethod, + AST_SymbolRef, + AST_SymbolVar, + AST_SymbolUsing, + AST_TemplateSegment, + AST_TemplateString, + AST_This, + AST_Throw, + AST_Token, + AST_Toplevel, + AST_True, + AST_Try, + AST_TryBlock, + AST_Unary, + AST_UnaryPostfix, + AST_UnaryPrefix, + AST_Using, + AST_UsingDef, + AST_Var, + AST_VarDef, + AST_VarDefLike, + AST_While, + AST_With, + AST_Yield, +} from "./ast.js"; +import { is_basic_identifier_string } from "./parse.js"; + +(function() { + + var normalize_directives = function(body) { + for (var i = 0; i < body.length; i++) { + if (body[i] instanceof AST_Statement && body[i].body instanceof AST_String) { + body[i] = new AST_Directive({ + start: body[i].start, + end: body[i].end, + quote: '"', + value: body[i].body.value + }); + } else { + return body; + } + } + + return body; + }; + + function import_attributes_from_moz(attributes) { + if (attributes && attributes.length > 0) { + return new AST_Object({ + start: my_start_token(attributes), + end: my_end_token(attributes), + properties: attributes.map((attr) => + new AST_ObjectKeyVal({ + start: my_start_token(attr), + end: my_end_token(attr), + key: attr.key.name || attr.key.value, + value: from_moz(attr.value) + }) + ) + }); + } + return null; + } + + var MOZ_TO_ME = { + Program: function(M) { + return new AST_Toplevel({ + start: my_start_token(M), + end: my_end_token(M), + body: normalize_directives(M.body.map(from_moz)) + }); + }, + + ArrayPattern: function(M) { + return new AST_Destructuring({ + start: my_start_token(M), + end: my_end_token(M), + names: M.elements.map(function(elm) { + if (elm === null) { + return new AST_Hole(); + } + return from_moz(elm); + }), + is_array: true + }); + }, + + ObjectPattern: function(M) { + return new AST_Destructuring({ + start: my_start_token(M), + end: my_end_token(M), + names: M.properties.map(from_moz), + is_array: false + }); + }, + + AssignmentPattern: function(M) { + return new AST_DefaultAssign({ + start: my_start_token(M), + end: my_end_token(M), + left: from_moz(M.left), + operator: "=", + right: from_moz(M.right) + }); + }, + + SpreadElement: function(M) { + return new AST_Expansion({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz(M.argument) + }); + }, + + RestElement: function(M) { + return new AST_Expansion({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz(M.argument) + }); + }, + + TemplateElement: function(M) { + return new AST_TemplateSegment({ + start: my_start_token(M), + end: my_end_token(M), + value: M.value.cooked, + raw: M.value.raw + }); + }, + + TemplateLiteral: function(M) { + var segments = []; + for (var i = 0; i < M.quasis.length; i++) { + segments.push(from_moz(M.quasis[i])); + if (M.expressions[i]) { + segments.push(from_moz(M.expressions[i])); + } + } + return new AST_TemplateString({ + start: my_start_token(M), + end: my_end_token(M), + segments: segments + }); + }, + + TaggedTemplateExpression: function(M) { + return new AST_PrefixedTemplateString({ + start: my_start_token(M), + end: my_end_token(M), + template_string: from_moz(M.quasi), + prefix: from_moz(M.tag) + }); + }, + + FunctionDeclaration: function(M) { + return new AST_Defun({ + start: my_start_token(M), + end: my_end_token(M), + name: M.id && from_moz_symbol(AST_SymbolDefun, M.id), + argnames: M.params.map(M => from_moz_pattern(M, AST_SymbolFunarg)), + is_generator: M.generator, + async: M.async, + body: normalize_directives(from_moz(M.body).body) + }); + }, + + FunctionExpression: function(M) { + return from_moz_lambda(M, /*is_method=*/false); + }, + + ArrowFunctionExpression: function(M) { + const body = M.body.type === "BlockStatement" + ? from_moz(M.body).body + : [make_node(AST_Return, {}, { value: from_moz(M.body) })]; + return new AST_Arrow({ + start: my_start_token(M), + end: my_end_token(M), + argnames: M.params.map(p => from_moz_pattern(p, AST_SymbolFunarg)), + body, + async: M.async, + }); + }, + + ExpressionStatement: function(M) { + return new AST_SimpleStatement({ + start: my_start_token(M), + end: my_end_token(M), + body: from_moz(M.expression) + }); + }, + + TryStatement: function(M) { + var handlers = M.handlers || [M.handler]; + if (handlers.length > 1 || M.guardedHandlers && M.guardedHandlers.length) { + throw new Error("Multiple catch clauses are not supported."); + } + return new AST_Try({ + start : my_start_token(M), + end : my_end_token(M), + body : new AST_TryBlock(from_moz(M.block)), + bcatch : from_moz(handlers[0]), + bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null + }); + }, + + Property: function(M) { + if (M.kind == "init" && !M.method) { + var args = { + start : my_start_token(M.key || M.value), + end : my_end_token(M.value), + key : M.computed + ? from_moz(M.key) + : M.key.name || String(M.key.value), + quote : from_moz_quote(M.key, M.computed), + static : false, // always an object + value : from_moz(M.value) + }; + + return new AST_ObjectKeyVal(args); + } else { + var value = from_moz_lambda(M.value, /*is_method=*/true); + var args = { + start : my_start_token(M.key || M.value), + end : my_end_token(M.value), + key : M.computed + ? from_moz(M.key) + : from_moz_symbol(AST_SymbolMethod, M.key), + quote : from_moz_quote(M.key, M.computed), + static : false, // always an object + value, + }; + + if (M.kind == "get") return new AST_ObjectGetter(args); + if (M.kind == "set") return new AST_ObjectSetter(args); + if (M.method) return new AST_ConciseMethod(args); + } + }, + + MethodDefinition: function(M) { + const is_private = M.key.type === "PrivateIdentifier"; + const key = M.computed ? from_moz(M.key) : new AST_SymbolMethod({ name: M.key.name || String(M.key.value) }); + + var args = { + start : my_start_token(M), + end : my_end_token(M), + key, + quote : from_moz_quote(M.key, M.computed), + value : from_moz_lambda(M.value, /*is_method=*/true), + static : M.static, + }; + if (M.kind == "get") { + return new (is_private ? AST_PrivateGetter : AST_ObjectGetter)(args); + } + if (M.kind == "set") { + return new (is_private ? AST_PrivateSetter : AST_ObjectSetter)(args); + } + return new (is_private ? AST_PrivateMethod : AST_ConciseMethod)(args); + }, + + FieldDefinition: function(M) { + let key; + if (M.computed) { + key = from_moz(M.key); + } else { + if (M.key.type !== "Identifier") throw new Error("Non-Identifier key in FieldDefinition"); + key = from_moz(M.key); + } + return new AST_ClassProperty({ + start : my_start_token(M), + end : my_end_token(M), + quote : from_moz_quote(M.key, M.computed), + key, + value : from_moz(M.value), + static : M.static, + }); + }, + + PropertyDefinition: function(M) { + let key; + if (M.computed) { + key = from_moz(M.key); + } else if (M.key.type === "PrivateIdentifier") { + return new AST_ClassPrivateProperty({ + start : my_start_token(M), + end : my_end_token(M), + key : from_moz(M.key), + value : from_moz(M.value), + static : M.static, + }); + } else { + key = from_moz_symbol(AST_SymbolClassProperty, M.key); + } + + return new AST_ClassProperty({ + start : my_start_token(M), + end : my_end_token(M), + quote : from_moz_quote(M.key, M.computed), + key, + value : from_moz(M.value), + static : M.static, + }); + }, + + PrivateIdentifier: function (M) { + return new AST_SymbolPrivateProperty({ + start: my_start_token(M), + end: my_end_token(M), + name: M.name + }); + }, + + StaticBlock: function(M) { + return new AST_ClassStaticBlock({ + start : my_start_token(M), + end : my_end_token(M), + body : M.body.map(from_moz), + }); + }, + + ArrayExpression: function(M) { + return new AST_Array({ + start : my_start_token(M), + end : my_end_token(M), + elements : M.elements.map(function(elem) { + return elem === null ? new AST_Hole() : from_moz(elem); + }) + }); + }, + + ObjectExpression: function(M) { + return new AST_Object({ + start : my_start_token(M), + end : my_end_token(M), + properties : M.properties.map(function(prop) { + if (prop.type === "SpreadElement") { + return from_moz(prop); + } + prop.type = "Property"; + return from_moz(prop); + }) + }); + }, + + SequenceExpression: function(M) { + return new AST_Sequence({ + start : my_start_token(M), + end : my_end_token(M), + expressions: M.expressions.map(from_moz) + }); + }, + + MemberExpression: function(M) { + if (M.property.type === "PrivateIdentifier") { + return new AST_DotHash({ + start : my_start_token(M), + end : my_end_token(M), + property : M.property.name, + expression : from_moz(M.object), + optional : M.optional || false + }); + } + return new (M.computed ? AST_Sub : AST_Dot)({ + start : my_start_token(M), + end : my_end_token(M), + property : M.computed ? from_moz(M.property) : M.property.name, + expression : from_moz(M.object), + optional : M.optional || false + }); + }, + + ChainExpression: function(M) { + return new AST_Chain({ + start : my_start_token(M), + end : my_end_token(M), + expression : from_moz(M.expression) + }); + }, + + SwitchCase: function(M) { + return new (M.test ? AST_Case : AST_Default)({ + start : my_start_token(M), + end : my_end_token(M), + expression : from_moz(M.test), + body : M.consequent.map(from_moz) + }); + }, + + VariableDeclaration: function(M) { + let decl_type; + let defs_type = AST_VarDef; + let sym_type; + let await_using = false; + if (M.kind === "const") { + decl_type = AST_Const; + sym_type = AST_SymbolConst; + } else if (M.kind === "let") { + decl_type = AST_Let; + sym_type = AST_SymbolLet; + } else if (M.kind === "using") { + decl_type = AST_Using; + defs_type = AST_UsingDef; + sym_type = AST_SymbolUsing; + } else if (M.kind === "await using") { + decl_type = AST_Using; + defs_type = AST_UsingDef; + sym_type = AST_SymbolUsing; + await_using = true; + } else { + decl_type = AST_Var; + sym_type = AST_SymbolVar; + } + const definitions = M.declarations.map(M => { + return new defs_type({ + start: my_start_token(M), + end: my_end_token(M), + name: from_moz_pattern(M.id, sym_type), + value: from_moz(M.init), + }); + }); + return new decl_type({ + start : my_start_token(M), + end : my_end_token(M), + definitions : definitions, + await : await_using, + }); + }, + + ImportDeclaration: function(M) { + var imported_name = null; + var imported_names = null; + M.specifiers.forEach(function (specifier) { + if (specifier.type === "ImportSpecifier" || specifier.type === "ImportNamespaceSpecifier") { + if (!imported_names) { imported_names = []; } + imported_names.push(from_moz(specifier)); + } else if (specifier.type === "ImportDefaultSpecifier") { + imported_name = from_moz(specifier); + } + }); + return new AST_Import({ + start : my_start_token(M), + end : my_end_token(M), + imported_name: imported_name, + imported_names : imported_names, + module_name : from_moz(M.source), + attributes: import_attributes_from_moz(M.attributes || M.assertions) + }); + }, + + ImportSpecifier: function(M) { + return new AST_NameMapping({ + start: my_start_token(M), + end: my_end_token(M), + foreign_name: from_moz_symbol(AST_SymbolImportForeign, M.imported, M.imported.type === "Literal"), + name: from_moz_symbol(AST_SymbolImport, M.local) + }); + }, + + ImportDefaultSpecifier: function(M) { + return from_moz_symbol(AST_SymbolImport, M.local); + }, + + ImportNamespaceSpecifier: function(M) { + return new AST_NameMapping({ + start: my_start_token(M), + end: my_end_token(M), + foreign_name: new AST_SymbolImportForeign({ name: "*" }), + name: from_moz_symbol(AST_SymbolImport, M.local) + }); + }, + + ImportExpression: function(M) { + const args = [from_moz(M.source)]; + if (M.options) { + args.push(from_moz(M.options)); + } + return new AST_Call({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz({ + type: "Identifier", + name: "import" + }), + optional: false, + args + }); + }, + + ExportAllDeclaration: function(M) { + var foreign_name = M.exported == null ? + new AST_SymbolExportForeign({ name: "*" }) : + from_moz_symbol(AST_SymbolExportForeign, M.exported, M.exported.type === "Literal"); + return new AST_Export({ + start: my_start_token(M), + end: my_end_token(M), + exported_names: [ + new AST_NameMapping({ + start: my_start_token(M), + end: my_end_token(M), + name: new AST_SymbolExport({ name: "*" }), + foreign_name: foreign_name + }) + ], + module_name: from_moz(M.source), + attributes: import_attributes_from_moz(M.attributes || M.assertions) + }); + }, + + ExportNamedDeclaration: function(M) { + if (M.declaration) { + // export const, export function, ... + return new AST_Export({ + start: my_start_token(M), + end: my_end_token(M), + exported_definition: from_moz(M.declaration), + exported_names: null, + module_name: null, + attributes: null, + }); + } else { + return new AST_Export({ + start: my_start_token(M), + end: my_end_token(M), + exported_definition: null, + exported_names: M.specifiers && M.specifiers.length ? M.specifiers.map(from_moz) : [], + module_name: from_moz(M.source), + attributes: import_attributes_from_moz(M.attributes || M.assertions), + }); + } + }, + + ExportDefaultDeclaration: function(M) { + return new AST_Export({ + start: my_start_token(M), + end: my_end_token(M), + exported_value: from_moz(M.declaration), + is_default: true + }); + }, + + ExportSpecifier: function(M) { + return new AST_NameMapping({ + start: my_start_token(M), + end: my_end_token(M), + foreign_name: from_moz_symbol(AST_SymbolExportForeign, M.exported, M.exported.type === "Literal"), + name: from_moz_symbol(AST_SymbolExport, M.local, M.local.type === "Literal"), + }); + }, + + Literal: function(M) { + var val = M.value, args = { + start : my_start_token(M), + end : my_end_token(M) + }; + var rx = M.regex; + if (rx && rx.pattern) { + // RegExpLiteral as per ESTree AST spec + args.value = { + source: rx.pattern, + flags: rx.flags + }; + return new AST_RegExp(args); + } else if (rx) { + // support legacy RegExp + const rx_source = M.raw || val; + const match = rx_source.match(/^\/(.*)\/(\w*)$/); + if (!match) throw new Error("Invalid regex source " + rx_source); + const [_, source, flags] = match; + args.value = { source, flags }; + return new AST_RegExp(args); + } + const bi = typeof M.value === "bigint" ? M.value.toString() : M.bigint; + if (typeof bi === "string") { + args.value = bi; + args.raw = M.raw; + return new AST_BigInt(args); + } + if (val === null) return new AST_Null(args); + switch (typeof val) { + case "string": + args.quote = "\""; + args.value = val; + return new AST_String(args); + case "number": + args.value = val; + args.raw = M.raw || val.toString(); + return new AST_Number(args); + case "boolean": + return new (val ? AST_True : AST_False)(args); + } + }, + + MetaProperty: function(M) { + if (M.meta.name === "new" && M.property.name === "target") { + return new AST_NewTarget({ + start: my_start_token(M), + end: my_end_token(M) + }); + } else if (M.meta.name === "import" && M.property.name === "meta") { + return new AST_ImportMeta({ + start: my_start_token(M), + end: my_end_token(M) + }); + } + }, + + Identifier: function(M) { + return new AST_SymbolRef({ + start : my_start_token(M), + end : my_end_token(M), + name : M.name + }); + }, + + EmptyStatement: function(M) { + return new AST_EmptyStatement({ + start: my_start_token(M), + end: my_end_token(M) + }); + }, + + BlockStatement: function(M) { + return new AST_BlockStatement({ + start: my_start_token(M), + end: my_end_token(M), + body: M.body.map(from_moz) + }); + }, + + IfStatement: function(M) { + return new AST_If({ + start: my_start_token(M), + end: my_end_token(M), + condition: from_moz(M.test), + body: from_moz(M.consequent), + alternative: from_moz(M.alternate) + }); + }, + + LabeledStatement: function(M) { + try { + const label = from_moz_symbol(AST_Label, M.label); + FROM_MOZ_LABELS.push(label); + + const stat = new AST_LabeledStatement({ + start: my_start_token(M), + end: my_end_token(M), + label, + body: from_moz(M.body) + }); + + return stat; + } finally { + FROM_MOZ_LABELS.pop(); + } + }, + + BreakStatement: function(M) { + return new AST_Break({ + start: my_start_token(M), + end: my_end_token(M), + label: from_moz_label_ref(M.label), + }); + }, + + ContinueStatement: function(M) { + return new AST_Continue({ + start: my_start_token(M), + end: my_end_token(M), + label: from_moz_label_ref(M.label), + }); + }, + + WithStatement: function(M) { + return new AST_With({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz(M.object), + body: from_moz(M.body) + }); + }, + + SwitchStatement: function(M) { + return new AST_Switch({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz(M.discriminant), + body: M.cases.map(from_moz) + }); + }, + + ReturnStatement: function(M) { + return new AST_Return({ + start: my_start_token(M), + end: my_end_token(M), + value: from_moz(M.argument) + }); + }, + + ThrowStatement: function(M) { + return new AST_Throw({ + start: my_start_token(M), + end: my_end_token(M), + value: from_moz(M.argument) + }); + }, + + WhileStatement: function(M) { + return new AST_While({ + start: my_start_token(M), + end: my_end_token(M), + condition: from_moz(M.test), + body: from_moz(M.body) + }); + }, + + DoWhileStatement: function(M) { + return new AST_Do({ + start: my_start_token(M), + end: my_end_token(M), + condition: from_moz(M.test), + body: from_moz(M.body) + }); + }, + + ForStatement: function(M) { + return new AST_For({ + start: my_start_token(M), + end: my_end_token(M), + init: from_moz(M.init), + condition: from_moz(M.test), + step: from_moz(M.update), + body: from_moz(M.body) + }); + }, + + ForInStatement: function(M) { + return new AST_ForIn({ + start: my_start_token(M), + end: my_end_token(M), + init: from_moz(M.left), + object: from_moz(M.right), + body: from_moz(M.body) + }); + }, + + ForOfStatement: function(M) { + return new AST_ForOf({ + start: my_start_token(M), + end: my_end_token(M), + init: from_moz(M.left), + object: from_moz(M.right), + body: from_moz(M.body), + await: M.await + }); + }, + + AwaitExpression: function(M) { + return new AST_Await({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz(M.argument) + }); + }, + + YieldExpression: function(M) { + return new AST_Yield({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz(M.argument), + is_star: M.delegate + }); + }, + + DebuggerStatement: function(M) { + return new AST_Debugger({ + start: my_start_token(M), + end: my_end_token(M) + }); + }, + + CatchClause: function(M) { + return new AST_Catch({ + start: my_start_token(M), + end: my_end_token(M), + argname: M.param ? from_moz_pattern(M.param, AST_SymbolCatch) : null, + body: from_moz(M.body).body + }); + }, + + ThisExpression: function(M) { + return new AST_This({ + start: my_start_token(M), + name: "this", + end: my_end_token(M) + }); + }, + + Super: function(M) { + return new AST_Super({ + start: my_start_token(M), + end: my_end_token(M), + name: "super", + }); + }, + + BinaryExpression: function(M) { + if (M.left.type === "PrivateIdentifier") { + return new AST_PrivateIn({ + start: my_start_token(M), + end: my_end_token(M), + key: new AST_SymbolPrivateProperty({ + start: my_start_token(M.left), + end: my_end_token(M.left), + name: M.left.name + }), + value: from_moz(M.right), + }); + } + return new AST_Binary({ + start: my_start_token(M), + end: my_end_token(M), + operator: M.operator, + left: from_moz(M.left), + right: from_moz(M.right) + }); + }, + + LogicalExpression: function(M) { + return new AST_Binary({ + start: my_start_token(M), + end: my_end_token(M), + operator: M.operator, + left: from_moz(M.left), + right: from_moz(M.right) + }); + }, + + AssignmentExpression: function(M) { + return new AST_Assign({ + start: my_start_token(M), + end: my_end_token(M), + operator: M.operator, + logical: M.operator === "??=" || M.operator === "&&=" || M.operator === "||=", + left: from_moz(M.left), + right: from_moz(M.right) + }); + }, + + ConditionalExpression: function(M) { + return new AST_Conditional({ + start: my_start_token(M), + end: my_end_token(M), + condition: from_moz(M.test), + consequent: from_moz(M.consequent), + alternative: from_moz(M.alternate) + }); + }, + + NewExpression: function(M) { + return new AST_New({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz(M.callee), + args: M.arguments.map(from_moz) + }); + }, + + CallExpression: function(M) { + return new AST_Call({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz(M.callee), + optional: M.optional, + args: M.arguments.map(from_moz) + }); + } + }; + + MOZ_TO_ME.UpdateExpression = + MOZ_TO_ME.UnaryExpression = function To_Moz_Unary(M) { + var prefix = "prefix" in M ? M.prefix + : M.type == "UnaryExpression" ? true : false; + return new (prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({ + start : my_start_token(M), + end : my_end_token(M), + operator : M.operator, + expression : from_moz(M.argument) + }); + }; + + MOZ_TO_ME.ClassDeclaration = + MOZ_TO_ME.ClassExpression = function From_Moz_Class(M) { + return new (M.type === "ClassDeclaration" ? AST_DefClass : AST_ClassExpression)({ + start : my_start_token(M), + end : my_end_token(M), + name : M.id && from_moz_symbol(M.type === "ClassDeclaration" ? AST_SymbolDefClass : AST_SymbolClass, M.id), + extends : from_moz(M.superClass), + properties: M.body.body.map(from_moz) + }); + }; + + def_to_moz(AST_EmptyStatement, function To_Moz_EmptyStatement() { + return { + type: "EmptyStatement" + }; + }); + def_to_moz(AST_BlockStatement, function To_Moz_BlockStatement(M) { + return { + type: "BlockStatement", + body: M.body.map(to_moz) + }; + }); + def_to_moz(AST_If, function To_Moz_IfStatement(M) { + return { + type: "IfStatement", + test: to_moz(M.condition), + consequent: to_moz(M.body), + alternate: to_moz(M.alternative) + }; + }); + def_to_moz(AST_LabeledStatement, function To_Moz_LabeledStatement(M) { + return { + type: "LabeledStatement", + label: to_moz(M.label), + body: to_moz(M.body) + }; + }); + def_to_moz(AST_Break, function To_Moz_BreakStatement(M) { + return { + type: "BreakStatement", + label: to_moz(M.label) + }; + }); + def_to_moz(AST_Continue, function To_Moz_ContinueStatement(M) { + return { + type: "ContinueStatement", + label: to_moz(M.label) + }; + }); + def_to_moz(AST_With, function To_Moz_WithStatement(M) { + return { + type: "WithStatement", + object: to_moz(M.expression), + body: to_moz(M.body) + }; + }); + def_to_moz(AST_Switch, function To_Moz_SwitchStatement(M) { + return { + type: "SwitchStatement", + discriminant: to_moz(M.expression), + cases: M.body.map(to_moz) + }; + }); + def_to_moz(AST_Return, function To_Moz_ReturnStatement(M) { + return { + type: "ReturnStatement", + argument: to_moz(M.value) + }; + }); + def_to_moz(AST_Throw, function To_Moz_ThrowStatement(M) { + return { + type: "ThrowStatement", + argument: to_moz(M.value) + }; + }); + def_to_moz(AST_While, function To_Moz_WhileStatement(M) { + return { + type: "WhileStatement", + test: to_moz(M.condition), + body: to_moz(M.body) + }; + }); + def_to_moz(AST_Do, function To_Moz_DoWhileStatement(M) { + return { + type: "DoWhileStatement", + test: to_moz(M.condition), + body: to_moz(M.body) + }; + }); + def_to_moz(AST_For, function To_Moz_ForStatement(M) { + return { + type: "ForStatement", + init: to_moz(M.init), + test: to_moz(M.condition), + update: to_moz(M.step), + body: to_moz(M.body) + }; + }); + def_to_moz(AST_ForIn, function To_Moz_ForInStatement(M) { + return { + type: "ForInStatement", + left: to_moz(M.init), + right: to_moz(M.object), + body: to_moz(M.body) + }; + }); + def_to_moz(AST_ForOf, function To_Moz_ForOfStatement(M) { + return { + type: "ForOfStatement", + left: to_moz(M.init), + right: to_moz(M.object), + body: to_moz(M.body), + await: M.await + }; + }); + def_to_moz(AST_Await, function To_Moz_AwaitExpression(M) { + return { + type: "AwaitExpression", + argument: to_moz(M.expression) + }; + }); + def_to_moz(AST_Yield, function To_Moz_YieldExpression(M) { + return { + type: "YieldExpression", + argument: to_moz(M.expression), + delegate: M.is_star + }; + }); + def_to_moz(AST_Debugger, function To_Moz_DebuggerStatement() { + return { + type: "DebuggerStatement" + }; + }); + def_to_moz(AST_VarDefLike, function To_Moz_VariableDeclarator(M) { + return { + type: "VariableDeclarator", + id: to_moz(M.name), + init: to_moz(M.value) + }; + }); + + def_to_moz(AST_This, function To_Moz_ThisExpression() { + return { + type: "ThisExpression" + }; + }); + def_to_moz(AST_Super, function To_Moz_Super() { + return { + type: "Super" + }; + }); + def_to_moz(AST_Conditional, function To_Moz_ConditionalExpression(M) { + return { + type: "ConditionalExpression", + test: to_moz(M.condition), + consequent: to_moz(M.consequent), + alternate: to_moz(M.alternative) + }; + }); + def_to_moz(AST_New, function To_Moz_NewExpression(M) { + return { + type: "NewExpression", + callee: to_moz(M.expression), + arguments: M.args.map(to_moz) + }; + }); + def_to_moz(AST_Call, function To_Moz_CallExpression(M) { + if (M.expression instanceof AST_SymbolRef && M.expression.name === "import") { + const [source, options] = M.args.map(to_moz); + return { + type: "ImportExpression", + source, + options: options || null + }; + } + + return { + type: "CallExpression", + callee: to_moz(M.expression), + optional: M.optional, + arguments: M.args.map(to_moz) + }; + }); + + def_to_moz(AST_Toplevel, function To_Moz_Program(M) { + return to_moz_scope("Program", M); + }); + + def_to_moz(AST_Expansion, function To_Moz_Spread(M) { + return { + type: to_moz_in_destructuring() ? "RestElement" : "SpreadElement", + argument: to_moz(M.expression) + }; + }); + + def_to_moz(AST_PrefixedTemplateString, function To_Moz_TaggedTemplateExpression(M) { + return { + type: "TaggedTemplateExpression", + tag: to_moz(M.prefix), + quasi: to_moz(M.template_string) + }; + }); + + def_to_moz(AST_TemplateString, function To_Moz_TemplateLiteral(M) { + var quasis = []; + var expressions = []; + for (var i = 0; i < M.segments.length; i++) { + if (i % 2 !== 0) { + expressions.push(to_moz(M.segments[i])); + } else { + quasis.push({ + type: "TemplateElement", + value: { + raw: M.segments[i].raw, + cooked: M.segments[i].value + }, + tail: i === M.segments.length - 1 + }); + } + } + return { + type: "TemplateLiteral", + quasis: quasis, + expressions: expressions + }; + }); + + def_to_moz(AST_Defun, function To_Moz_FunctionDeclaration(M) { + return { + type: "FunctionDeclaration", + id: to_moz(M.name), + params: M.argnames.map(to_moz_pattern), + generator: M.is_generator, + async: M.async, + body: to_moz_scope("BlockStatement", M) + }; + }); + + def_to_moz(AST_Function, function To_Moz_FunctionExpression(M) { + return { + type: "FunctionExpression", + id: to_moz(M.name), + params: M.argnames.map(to_moz_pattern), + generator: M.is_generator || false, + async: M.async || false, + body: to_moz_scope("BlockStatement", M) + }; + }); + + def_to_moz(AST_Arrow, function To_Moz_ArrowFunctionExpression(M) { + var body = M.body.length === 1 && M.body[0] instanceof AST_Return && M.body[0].value + ? to_moz(M.body[0].value) + : { + type: "BlockStatement", + body: M.body.map(to_moz) + }; + return { + type: "ArrowFunctionExpression", + params: M.argnames.map(to_moz_pattern), + async: M.async, + body: body, + }; + }); + + def_to_moz(AST_Destructuring, function To_Moz_ObjectPattern(M) { + if (M.is_array) { + return { + type: "ArrayPattern", + elements: M.names.map( + M => M instanceof AST_Hole ? null : to_moz_pattern(M) + ), + }; + } + return { + type: "ObjectPattern", + properties: M.names.map(M => { + if (M instanceof AST_ObjectKeyVal) { + var computed = M.computed_key(); + const [shorthand, key] = to_moz_property_key(M.key, computed, M.quote, M.value); + + return { + type: "Property", + computed, + kind: "init", + key: key, + method: false, + shorthand, + value: to_moz_pattern(M.value) + }; + } else { + return to_moz_pattern(M); + } + }), + }; + }); + + def_to_moz(AST_DefaultAssign, function To_Moz_AssignmentExpression(M) { + return { + type: "AssignmentPattern", + left: to_moz_pattern(M.left), + right: to_moz(M.right), + }; + }); + + def_to_moz(AST_Directive, function To_Moz_Directive(M) { + return { + type: "ExpressionStatement", + expression: { + type: "Literal", + value: M.value, + raw: M.print_to_string() + }, + directive: M.value + }; + }); + + def_to_moz(AST_SimpleStatement, function To_Moz_ExpressionStatement(M) { + return { + type: "ExpressionStatement", + expression: to_moz(M.body) + }; + }); + + def_to_moz(AST_SwitchBranch, function To_Moz_SwitchCase(M) { + return { + type: "SwitchCase", + test: to_moz(M.expression), + consequent: M.body.map(to_moz) + }; + }); + + def_to_moz(AST_Try, function To_Moz_TryStatement(M) { + return { + type: "TryStatement", + block: to_moz_block(M.body), + handler: to_moz(M.bcatch), + guardedHandlers: [], + finalizer: to_moz(M.bfinally) + }; + }); + + def_to_moz(AST_Catch, function To_Moz_CatchClause(M) { + return { + type: "CatchClause", + param: M.argname != null ? to_moz_pattern(M.argname) : null, + body: to_moz_block(M) + }; + }); + + def_to_moz(AST_DefinitionsLike, function To_Moz_VariableDeclaration(M) { + return { + type: "VariableDeclaration", + kind: + M instanceof AST_Const ? "const" : + M instanceof AST_Let ? "let" : + M instanceof AST_Using ? (M.await ? "await using" : "using") : + "var", + declarations: M.definitions.map(to_moz) + }; + }); + + function import_attributes_to_moz(attribute) { + const import_attributes = []; + if (attribute) { + for (const { key, value } of attribute.properties) { + const key_moz = is_basic_identifier_string(key) + ? { type: "Identifier", name: key } + : { type: "Literal", value: key, raw: JSON.stringify(key) }; + import_attributes.push({ + type: "ImportAttribute", + key: key_moz, + value: to_moz(value) + }); + } + } + return import_attributes; + } + + def_to_moz(AST_Export, function To_Moz_ExportDeclaration(M) { + if (M.exported_names) { + var first_exported = M.exported_names[0]; + if (first_exported && first_exported.name.name === "*" && !first_exported.name.quote) { + var foreign_name = first_exported.foreign_name; + var exported = foreign_name.name === "*" && !foreign_name.quote + ? null + : to_moz(foreign_name); + return { + type: "ExportAllDeclaration", + source: to_moz(M.module_name), + exported: exported, + attributes: import_attributes_to_moz(M.attributes) + }; + } + return { + type: "ExportNamedDeclaration", + specifiers: M.exported_names.map(function (name_mapping) { + return { + type: "ExportSpecifier", + exported: to_moz(name_mapping.foreign_name), + local: to_moz(name_mapping.name) + }; + }), + declaration: to_moz(M.exported_definition), + source: to_moz(M.module_name), + attributes: import_attributes_to_moz(M.attributes) + }; + } + + if (M.is_default) { + return { + type: "ExportDefaultDeclaration", + declaration: to_moz(M.exported_value || M.exported_definition), + }; + } else { + return { + type: "ExportNamedDeclaration", + declaration: to_moz(M.exported_value || M.exported_definition), + specifiers: [], + source: null, + }; + } + }); + + def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) { + var specifiers = []; + if (M.imported_name) { + specifiers.push({ + type: "ImportDefaultSpecifier", + local: to_moz(M.imported_name) + }); + } + if (M.imported_names) { + var first_imported_foreign_name = M.imported_names[0].foreign_name; + if (first_imported_foreign_name.name === "*" && !first_imported_foreign_name.quote) { + specifiers.push({ + type: "ImportNamespaceSpecifier", + local: to_moz(M.imported_names[0].name) + }); + } else { + M.imported_names.forEach(function(name_mapping) { + specifiers.push({ + type: "ImportSpecifier", + local: to_moz(name_mapping.name), + imported: to_moz(name_mapping.foreign_name) + }); + }); + } + } + return { + type: "ImportDeclaration", + specifiers: specifiers, + source: to_moz(M.module_name), + attributes: import_attributes_to_moz(M.attributes) + }; + }); + + def_to_moz(AST_ImportMeta, function To_Moz_MetaProperty() { + return { + type: "MetaProperty", + meta: { + type: "Identifier", + name: "import" + }, + property: { + type: "Identifier", + name: "meta" + } + }; + }); + + def_to_moz(AST_Sequence, function To_Moz_SequenceExpression(M) { + return { + type: "SequenceExpression", + expressions: M.expressions.map(to_moz) + }; + }); + + def_to_moz(AST_DotHash, function To_Moz_PrivateMemberExpression(M) { + return { + type: "MemberExpression", + object: to_moz(M.expression), + computed: false, + property: { + type: "PrivateIdentifier", + name: M.property + }, + optional: M.optional + }; + }); + + def_to_moz(AST_PropAccess, function To_Moz_MemberExpression(M) { + var isComputed = M instanceof AST_Sub; + return { + type: "MemberExpression", + object: to_moz(M.expression), + computed: isComputed, + property: isComputed ? to_moz(M.property) : {type: "Identifier", name: M.property}, + optional: M.optional + }; + }); + + def_to_moz(AST_Chain, function To_Moz_ChainExpression(M) { + return { + type: "ChainExpression", + expression: to_moz(M.expression) + }; + }); + + def_to_moz(AST_Unary, function To_Moz_Unary(M) { + return { + type: M.operator == "++" || M.operator == "--" ? "UpdateExpression" : "UnaryExpression", + operator: M.operator, + prefix: M instanceof AST_UnaryPrefix, + argument: to_moz(M.expression) + }; + }); + + def_to_moz(AST_Binary, function To_Moz_BinaryExpression(M) { + if (M.operator == "=" && to_moz_in_destructuring()) { + return { + type: "AssignmentPattern", + left: to_moz(M.left), + right: to_moz(M.right) + }; + } + + const type = M.operator == "&&" || M.operator == "||" || M.operator === "??" + ? "LogicalExpression" + : "BinaryExpression"; + + return { + type, + left: to_moz(M.left), + operator: M.operator, + right: to_moz(M.right) + }; + }); + + def_to_moz(AST_Assign, function To_Moz_AssignmentExpression(M) { + return { + type: "AssignmentExpression", + operator: M.operator, + left: to_moz(M.left), + right: to_moz(M.right) + }; + }); + + def_to_moz(AST_PrivateIn, function To_Moz_BinaryExpression_PrivateIn(M) { + return { + type: "BinaryExpression", + left: { type: "PrivateIdentifier", name: M.key.name }, + operator: "in", + right: to_moz(M.value), + }; + }); + + def_to_moz(AST_Array, function To_Moz_ArrayExpression(M) { + return { + type: "ArrayExpression", + elements: M.elements.map(to_moz) + }; + }); + + def_to_moz(AST_Object, function To_Moz_ObjectExpression(M) { + return { + type: "ObjectExpression", + properties: M.properties.map(to_moz) + }; + }); + + def_to_moz(AST_ObjectProperty, function To_Moz_Property(M, parent) { + var computed = M.computed_key(); + const [shorthand, key] = to_moz_property_key(M.key, computed, M.quote, M.value); + + var kind; + if (M instanceof AST_ObjectGetter) { + kind = "get"; + } else + if (M instanceof AST_ObjectSetter) { + kind = "set"; + } + if (M instanceof AST_PrivateGetter || M instanceof AST_PrivateSetter) { + const kind = M instanceof AST_PrivateGetter ? "get" : "set"; + return { + type: "MethodDefinition", + computed: false, + kind: kind, + static: M.static, + key: { + type: "PrivateIdentifier", + name: M.key.name + }, + value: to_moz(M.value) + }; + } + if (M instanceof AST_ClassPrivateProperty) { + return { + type: "PropertyDefinition", + key: { + type: "PrivateIdentifier", + name: M.key.name + }, + value: to_moz(M.value), + computed: false, + static: M.static + }; + } + if (M instanceof AST_ClassProperty) { + return { + type: "PropertyDefinition", + key, + value: to_moz(M.value), + computed, + static: M.static + }; + } + if (parent instanceof AST_Class) { + return { + type: "MethodDefinition", + computed: computed, + kind: kind, + static: M.static, + key: to_moz(M.key), + value: to_moz(M.value) + }; + } + return { + type: "Property", + computed: computed, + method: false, + shorthand, + kind: kind, + key: key, + value: to_moz(M.value) + }; + }); + + def_to_moz(AST_ObjectKeyVal, function To_Moz_Property(M) { + var computed = M.computed_key(); + const [shorthand, key] = to_moz_property_key(M.key, computed, M.quote, M.value); + + return { + type: "Property", + computed: computed, + shorthand: shorthand, + method: false, + kind: "init", + key: key, + value: to_moz(M.value) + }; + }); + + def_to_moz(AST_ConciseMethod, function To_Moz_MethodDefinition(M, parent) { + const computed = M.computed_key(); + const [_always_false, key] = to_moz_property_key(M.key, computed, M.quote, M.value); + + if (parent instanceof AST_Object) { + return { + type: "Property", + kind: "init", + computed, + method: true, + shorthand: false, + key, + value: to_moz(M.value), + }; + } + + return { + type: "MethodDefinition", + kind: !computed && M.key.name === "constructor" ? "constructor" : "method", + computed, + key, + value: to_moz(M.value), + static: M.static, + }; + }); + + def_to_moz(AST_PrivateMethod, function To_Moz_MethodDefinition(M) { + return { + type: "MethodDefinition", + kind: "method", + key: { type: "PrivateIdentifier", name: M.key.name }, + value: to_moz(M.value), + computed: false, + static: M.static, + }; + }); + + def_to_moz(AST_Class, function To_Moz_Class(M) { + var type = M instanceof AST_ClassExpression ? "ClassExpression" : "ClassDeclaration"; + return { + type: type, + superClass: to_moz(M.extends), + id: M.name ? to_moz(M.name) : null, + body: { + type: "ClassBody", + body: M.properties.map(to_moz) + } + }; + }); + + def_to_moz(AST_ClassStaticBlock, function To_Moz_StaticBlock(M) { + return { + type: "StaticBlock", + body: M.body.map(to_moz), + }; + }); + + def_to_moz(AST_NewTarget, function To_Moz_MetaProperty() { + return { + type: "MetaProperty", + meta: { + type: "Identifier", + name: "new" + }, + property: { + type: "Identifier", + name: "target" + } + }; + }); + + def_to_moz(AST_Symbol, function To_Moz_Identifier(M, parent) { + if ( + (M instanceof AST_SymbolMethod && parent.quote) || + (( + M instanceof AST_SymbolImportForeign || + M instanceof AST_SymbolExportForeign || + M instanceof AST_SymbolExport + ) && M.quote) + ) { + return { + type: "Literal", + value: M.name + }; + } + var def = M.definition(); + return { + type: "Identifier", + name: def ? def.mangled_name || def.name : M.name + }; + }); + + def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) { + const pattern = M.value.source; + const flags = M.value.flags; + return { + type: "Literal", + value: null, + raw: M.print_to_string(), + regex: { pattern, flags } + }; + }); + + def_to_moz(AST_Constant, function To_Moz_Literal(M) { + var value = M.value; + return { + type: "Literal", + value: value, + raw: M.raw || M.print_to_string() + }; + }); + + def_to_moz(AST_Atom, function To_Moz_Atom(M) { + return { + type: "Identifier", + name: String(M.value) + }; + }); + + def_to_moz(AST_BigInt, M => ({ + type: "Literal", + // value cannot be represented natively + // see: https://github.com/estree/estree/blob/master/es2020.md#bigintliteral + value: null, + // `M.value` is a string that may be a hex number representation. + // but "bigint" property should have only decimal digits + bigint: typeof BigInt === "function" ? BigInt(M.value).toString() : M.value, + raw: M.raw, + })); + + AST_Boolean.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast); + AST_Null.DEFMETHOD("to_mozilla_ast", AST_Constant.prototype.to_mozilla_ast); + AST_Hole.DEFMETHOD("to_mozilla_ast", function To_Moz_ArrayHole() { return null; }); + + AST_Block.DEFMETHOD("to_mozilla_ast", AST_BlockStatement.prototype.to_mozilla_ast); + AST_Lambda.DEFMETHOD("to_mozilla_ast", AST_Function.prototype.to_mozilla_ast); + + /* -----[ tools ]----- */ + + function my_start_token(moznode) { + var loc = moznode.loc, start = loc && loc.start; + var range = moznode.range; + return new AST_Token( + "", + "", + start && start.line || 0, + start && start.column || 0, + range ? range [0] : moznode.start, + false, + [], + [], + loc && loc.source, + ); + } + + function my_end_token(moznode) { + var loc = moznode.loc, end = loc && loc.end; + var range = moznode.range; + return new AST_Token( + "", + "", + end && end.line || 0, + end && end.column || 0, + range ? range [0] : moznode.end, + false, + [], + [], + loc && loc.source, + ); + } + + var FROM_MOZ_LABELS = null; + + function from_moz(node) { + if (node == null) return null; + return MOZ_TO_ME[node.type](node); + } + + function from_moz_quote(moz_key, computed) { + if (!computed && moz_key.type === "Literal" && typeof moz_key.value === "string") { + return '"'; + } else { + return ""; + } + } + + function from_moz_symbol(symbol_type, M, has_quote) { + return new symbol_type({ + start: my_start_token(M), + quote: has_quote ? '"' : undefined, + name: M.type === "Identifier" ? M.name : String(M.value), + end: my_end_token(M), + }); + } + + function from_moz_lambda(M, is_method) { + return new (is_method ? AST_Accessor : AST_Function)({ + start: my_start_token(M), + end: my_end_token(M), + name: M.id && from_moz_symbol(is_method ? AST_SymbolMethod : AST_SymbolLambda, M.id), + argnames: M.params.map(M => from_moz_pattern(M, AST_SymbolFunarg)), + is_generator: M.generator, + async: M.async, + body: normalize_directives(from_moz(M.body).body) + }); + } + + function from_moz_pattern(M, sym_type) { + switch (M.type) { + case "ObjectPattern": + return new AST_Destructuring({ + start: my_start_token(M), + end: my_end_token(M), + names: M.properties.map(p => from_moz_pattern(p, sym_type)), + is_array: false + }); + + case "Property": + var key = M.key; + var args = { + start : my_start_token(key || M.value), + end : my_end_token(M.value), + key : key.type == "Identifier" ? key.name : String(key.value), + quote : !M.computed && key.type === "Literal" && typeof key.value === "string" + ? '"' + : "", + value : from_moz_pattern(M.value, sym_type) + }; + if (M.computed) { + args.key = from_moz(M.key); + } + return new AST_ObjectKeyVal(args); + + case "ArrayPattern": + return new AST_Destructuring({ + start: my_start_token(M), + end: my_end_token(M), + names: M.elements.map(function(elm) { + if (elm === null) { + return new AST_Hole(); + } + return from_moz_pattern(elm, sym_type); + }), + is_array: true + }); + + case "SpreadElement": + case "RestElement": + return new AST_Expansion({ + start: my_start_token(M), + end: my_end_token(M), + expression: from_moz_pattern(M.argument, sym_type), + }); + + case "AssignmentPattern": + return new AST_DefaultAssign({ + start : my_start_token(M), + end : my_end_token(M), + left : from_moz_pattern(M.left, sym_type), + operator: "=", + right : from_moz(M.right), + }); + + case "Identifier": + return new sym_type({ + start : my_start_token(M), + end : my_end_token(M), + name : M.name, + }); + + default: + throw new Error("Invalid node type for destructuring: " + M.type); + } + } + + function from_moz_label_ref(m_label) { + if (!m_label) return null; + + const label = from_moz_symbol(AST_LabelRef, m_label); + + let i = FROM_MOZ_LABELS.length; + while (i--) { + const label_origin = FROM_MOZ_LABELS[i]; + + if (label.name === label_origin.name) { + label.thedef = label_origin; + break; + } + } + + return label; + } + + AST_Node.from_mozilla_ast = function(node) { + var save_labels = FROM_MOZ_LABELS; + FROM_MOZ_LABELS = []; + var ast = from_moz(node); + FROM_MOZ_LABELS = save_labels; + return ast; + }; + + function set_moz_loc(mynode, moznode) { + var start = mynode.start; + var end = mynode.end; + if (!(start && end)) { + return moznode; + } + if (start.pos != null && end.endpos != null) { + moznode.range = [start.pos, end.endpos]; + } + if (start.line) { + moznode.loc = { + start: {line: start.line, column: start.col}, + end: end.endline ? {line: end.endline, column: end.endcol} : null + }; + if (start.file) { + moznode.loc.source = start.file; + } + } + return moznode; + } + + function def_to_moz(mytype, handler) { + mytype.DEFMETHOD("to_mozilla_ast", function(parent) { + return set_moz_loc(this, handler(this, parent)); + }); + } + + var TO_MOZ_STACK = null; + + function to_moz(node) { + if (TO_MOZ_STACK === null) { TO_MOZ_STACK = []; } + TO_MOZ_STACK.push(node); + var ast = node != null ? node.to_mozilla_ast(TO_MOZ_STACK[TO_MOZ_STACK.length - 2]) : null; + TO_MOZ_STACK.pop(); + if (TO_MOZ_STACK.length === 0) { TO_MOZ_STACK = null; } + return ast; + } + + /** Object property keys can be number literals, string literals, or raw names. Additionally they can be shorthand. We decide that here. */ + function to_moz_property_key(key, computed = false, quote = false, value = null) { + if (computed) { + return [false, to_moz(key)]; + } + + const key_name = typeof key === "string" ? key : key.name; + let moz_key; + if (quote) { + moz_key = { type: "Literal", value: key_name, raw: JSON.stringify(key_name) }; + } else if ("" + +key_name === key_name && +key_name >= 0) { + // representable as a number + moz_key = { type: "Literal", value: +key_name, raw: JSON.stringify(+key_name) }; + } else { + moz_key = { type: "Identifier", name: key_name }; + } + + const shorthand = + moz_key.type === "Identifier" + && moz_key.name === key_name + && (value instanceof AST_Symbol && value.name === key_name + || value instanceof AST_DefaultAssign && value.left.name === key_name); + return [shorthand, moz_key]; + } + + function to_moz_pattern(node) { + if (node instanceof AST_Expansion) { + return { + type: "RestElement", + argument: to_moz_pattern(node.expression), + }; + } + + if (( + node instanceof AST_Symbol + || node instanceof AST_Destructuring + || node instanceof AST_DefaultAssign + || node instanceof AST_PropAccess + )) { + // Plain translation + return to_moz(node); + } + + throw new Error(node.TYPE); + } + + function to_moz_in_destructuring() { + var i = TO_MOZ_STACK.length; + while (i--) { + if (TO_MOZ_STACK[i] instanceof AST_Destructuring) { + return true; + } + } + return false; + } + + function to_moz_block(node) { + return { + type: "BlockStatement", + body: node.body.map(to_moz) + }; + } + + function to_moz_scope(type, node) { + var body = node.body.map(to_moz); + if (node.body[0] instanceof AST_SimpleStatement && node.body[0].body instanceof AST_String) { + body.unshift(to_moz(new AST_EmptyStatement(node.body[0]))); + } + return { + type: type, + body: body + }; + } +})(); diff --git a/node_modules/terser/lib/output.js b/node_modules/terser/lib/output.js new file mode 100644 index 0000000..ed19a24 --- /dev/null +++ b/node_modules/terser/lib/output.js @@ -0,0 +1,2537 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +"use strict"; + +import { + defaults, + makePredicate, + noop, + regexp_source_fix, + sort_regexp_flags, + return_false, + return_true, +} from "./utils/index.js"; +import { first_in_statement, left_is_object } from "./utils/first_in_statement.js"; +import { + AST_Array, + AST_Arrow, + AST_Assign, + AST_Await, + AST_BigInt, + AST_Binary, + AST_BlockStatement, + AST_Break, + AST_Call, + AST_Case, + AST_Catch, + AST_Chain, + AST_Class, + AST_ClassExpression, + AST_ClassPrivateProperty, + AST_ClassProperty, + AST_ClassStaticBlock, + AST_ConciseMethod, + AST_PrivateGetter, + AST_PrivateMethod, + AST_SymbolPrivateProperty, + AST_PrivateSetter, + AST_PrivateIn, + AST_Conditional, + AST_Const, + AST_Constant, + AST_Continue, + AST_Debugger, + AST_Default, + AST_DefaultAssign, + AST_Definitions, + AST_DefinitionsLike, + AST_Defun, + AST_Destructuring, + AST_Directive, + AST_Do, + AST_Dot, + AST_DotHash, + AST_EmptyStatement, + AST_Exit, + AST_Expansion, + AST_Export, + AST_Finally, + AST_For, + AST_ForIn, + AST_ForOf, + AST_Function, + AST_Hole, + AST_If, + AST_Import, + AST_ImportMeta, + AST_Jump, + AST_LabeledStatement, + AST_Lambda, + AST_Let, + AST_LoopControl, + AST_NameMapping, + AST_New, + AST_NewTarget, + AST_Node, + AST_Number, + AST_Object, + AST_ObjectGetter, + AST_ObjectKeyVal, + AST_ObjectProperty, + AST_ObjectSetter, + AST_PrefixedTemplateString, + AST_PropAccess, + AST_RegExp, + AST_Return, + AST_Scope, + AST_Sequence, + AST_SimpleStatement, + AST_Statement, + AST_StatementWithBody, + AST_String, + AST_Sub, + AST_Super, + AST_Switch, + AST_SwitchBranch, + AST_Symbol, + AST_SymbolClassProperty, + AST_SymbolMethod, + AST_SymbolRef, + AST_TemplateSegment, + AST_TemplateString, + AST_This, + AST_Throw, + AST_Toplevel, + AST_Try, + AST_TryBlock, + AST_Unary, + AST_UnaryPostfix, + AST_UnaryPrefix, + AST_Using, + AST_Var, + AST_VarDefLike, + AST_While, + AST_With, + AST_Yield, + TreeWalker, + walk, + walk_abort +} from "./ast.js"; +import { + get_full_char_code, + get_full_char, + is_identifier_char, + is_basic_identifier_string, + is_identifier_string, + PRECEDENCE, + ALL_RESERVED_WORDS, +} from "./parse.js"; + +const CODE_LINE_BREAK = 10; +const CODE_SPACE = 32; + +const r_annotation = /[@#]__(PURE|INLINE|NOINLINE)__/; + +function is_some_comments(comment) { + // multiline comment + return ( + (comment.type === "comment2" || comment.type === "comment1") + && /@preserve|@copyright|@lic|@cc_on|^\**!/i.test(comment.value) + ); +} + +const ROPE_COMMIT_WHEN = 8 * 1000; +class Rope { + constructor() { + this.committed = ""; + this.current = ""; + } + + append(str) { + /** When `this.current` is too long, commit it. */ + if (this.current.length > ROPE_COMMIT_WHEN) { + this.committed += this.current + str; + this.current = ""; + } else { + this.current += str; + } + } + + insertAt(char, index) { + const { committed, current } = this; + if (index < committed.length) { + this.committed = committed.slice(0, index) + char + committed.slice(index); + } else if (index === committed.length) { + this.committed += char; + } else { + index -= committed.length; + this.committed += current.slice(0, index) + char; + this.current = current.slice(index); + } + } + + charAt(index) { + const { committed } = this; + if (index < committed.length) return committed[index]; + return this.current[index - committed.length]; + } + + charCodeAt(index) { + const { committed } = this; + if (index < committed.length) return committed.charCodeAt(index); + return this.current.charCodeAt(index - committed.length); + } + + length() { + return this.committed.length + this.current.length; + } + + expectDirective() { + // /^$|[;{][\s\n]*$/ + + let ch, n = this.length(); + + if (n <= 0) return true; + + // Skip N whitespace from the end + while ( + (ch = this.charCodeAt(--n)) + && (ch == CODE_SPACE || ch == CODE_LINE_BREAK) + ); + + // either ";", or "{", or the string ended + return !ch || ch === 59 || ch === 123; + } + + hasNLB() { + let n = this.length() - 1; + while (n >= 0) { + const code = this.charCodeAt(n--); + + if (code === CODE_LINE_BREAK) return true; + if (code !== CODE_SPACE) return false; + } + return true; + } + + + toString() { + return this.committed + this.current; + } +} + +function OutputStream(options) { + + var readonly = !options; + options = defaults(options, { + ascii_only : false, + beautify : false, + braces : false, + comments : "some", + ecma : 5, + ie8 : false, + indent_level : 4, + indent_start : 0, + inline_script : true, + keep_numbers : false, + keep_quoted_props : false, + max_line_len : false, + preamble : null, + preserve_annotations : false, + quote_keys : false, + quote_style : 0, + safari10 : false, + semicolons : true, + shebang : true, + shorthand : undefined, + source_map : null, + webkit : false, + width : 80, + wrap_iife : false, + wrap_func_args : false, + + _destroy_ast : false + }, true); + + if (options.shorthand === undefined) + options.shorthand = options.ecma > 5; + + // Convert comment option to RegExp if necessary and set up comments filter + var comment_filter = return_false; // Default case, throw all comments away + if (options.comments) { + let comments = options.comments; + if (typeof options.comments === "string" && /^\/.*\/[a-zA-Z]*$/.test(options.comments)) { + var regex_pos = options.comments.lastIndexOf("/"); + comments = new RegExp( + options.comments.substr(1, regex_pos - 1), + options.comments.substr(regex_pos + 1) + ); + } + if (comments instanceof RegExp) { + comment_filter = function(comment) { + return comment.type != "comment5" && comments.test(comment.value); + }; + } else if (typeof comments === "function") { + comment_filter = function(comment) { + return comment.type != "comment5" && comments(this, comment); + }; + } else if (comments === "some") { + comment_filter = is_some_comments; + } else { // NOTE includes "all" option + comment_filter = return_true; + } + } + + if (options.preserve_annotations) { + let prev_comment_filter = comment_filter; + comment_filter = function (comment) { + return r_annotation.test(comment.value) || prev_comment_filter.apply(this, arguments); + }; + } + + var indentation = 0; + var current_col = 0; + var current_line = 1; + var current_pos = 0; + var OUTPUT = new Rope(); + let printed_comments = new Set(); + + var to_utf8 = options.ascii_only ? function(str, identifier = false, regexp = false) { + if (options.ecma >= 2015 && !options.safari10 && !regexp) { + str = str.replace(/[\ud800-\udbff][\udc00-\udfff]/g, function(ch) { + var code = get_full_char_code(ch, 0).toString(16); + return "\\u{" + code + "}"; + }); + } + return str.replace(/[\u0000-\u001f\u007f-\uffff]/g, function(ch) { + var code = ch.charCodeAt(0).toString(16); + if (code.length <= 2 && !identifier) { + while (code.length < 2) code = "0" + code; + return "\\x" + code; + } else { + while (code.length < 4) code = "0" + code; + return "\\u" + code; + } + }); + } : function(str) { + return str.replace(/[\ud800-\udbff][\udc00-\udfff]|([\ud800-\udbff]|[\udc00-\udfff])/g, function(match, lone) { + if (lone) { + return "\\u" + lone.charCodeAt(0).toString(16); + } + return match; + }); + }; + + function make_string(str, quote) { + var dq = 0, sq = 0; + str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g, + function(s, i) { + switch (s) { + case '"': ++dq; return '"'; + case "'": ++sq; return "'"; + case "\\": return "\\\\"; + case "\n": return "\\n"; + case "\r": return "\\r"; + case "\t": return "\\t"; + case "\b": return "\\b"; + case "\f": return "\\f"; + case "\x0B": return options.ie8 ? "\\x0B" : "\\v"; + case "\u2028": return "\\u2028"; + case "\u2029": return "\\u2029"; + case "\ufeff": return "\\ufeff"; + case "\0": + return /[0-9]/.test(get_full_char(str, i+1)) ? "\\x00" : "\\0"; + } + return s; + }); + function quote_single() { + return "'" + str.replace(/\x27/g, "\\'") + "'"; + } + function quote_double() { + return '"' + str.replace(/\x22/g, '\\"') + '"'; + } + function quote_template() { + return "`" + str.replace(/`/g, "\\`") + "`"; + } + str = to_utf8(str); + if (quote === "`") return quote_template(); + switch (options.quote_style) { + case 1: + return quote_single(); + case 2: + return quote_double(); + case 3: + return quote == "'" ? quote_single() : quote_double(); + default: + return dq > sq ? quote_single() : quote_double(); + } + } + + function encode_string(str, quote) { + var ret = make_string(str, quote); + if (options.inline_script) { + ret = ret.replace(/<\x2f(script)([>\/\t\n\f\r ])/gi, "<\\/$1$2"); + ret = ret.replace(/\x3c!--/g, "\\x3c!--"); + ret = ret.replace(/--\x3e/g, "--\\x3e"); + } + return ret; + } + + function make_name(name) { + name = name.toString(); + name = to_utf8(name, true); + return name; + } + + function make_indent(back) { + return " ".repeat(options.indent_start + indentation - back * options.indent_level); + } + + /* -----[ beautification/minification ]----- */ + + var has_parens = false; + var might_need_space = false; + var might_need_semicolon = false; + var might_add_newline = 0; + var need_newline_indented = false; + var need_space = false; + var newline_insert = -1; + var last = ""; + var mapping_token, mapping_name, mappings = options.source_map && []; + + var do_add_mapping = mappings ? function() { + mappings.forEach(function(mapping) { + try { + let { name, token } = mapping; + if (name !== false) { + if (token.type == "name" || token.type === "privatename") { + name = token.value; + } else if (name instanceof AST_Symbol) { + name = token.type === "string" ? token.value : name.name; + } + } + options.source_map.add( + mapping.token.file, + mapping.line, mapping.col, + mapping.token.line, mapping.token.col, + is_basic_identifier_string(name) ? name : undefined + ); + } catch(ex) { + // Ignore bad mapping + } + }); + mappings = []; + } : noop; + + var ensure_line_len = options.max_line_len ? function() { + if (current_col > options.max_line_len) { + if (might_add_newline) { + OUTPUT.insertAt("\n", might_add_newline); + const len_after_newline = OUTPUT.length() - might_add_newline - 1; + if (mappings) { + var delta = len_after_newline - current_col; + mappings.forEach(function(mapping) { + mapping.line++; + mapping.col += delta; + }); + } + current_line++; + current_pos++; + current_col = len_after_newline; + } + } + if (might_add_newline) { + might_add_newline = 0; + do_add_mapping(); + } + } : noop; + + var requireSemicolonChars = makePredicate("( [ + * / - , . `"); + + function print(str) { + str = String(str); + var ch = get_full_char(str, 0); + if (need_newline_indented && ch) { + need_newline_indented = false; + if (ch !== "\n") { + print("\n"); + indent(); + } + } + if (need_space && ch) { + need_space = false; + if (!/[\s;})]/.test(ch)) { + space(); + } + } + newline_insert = -1; + var prev = last.charAt(last.length - 1); + if (might_need_semicolon) { + might_need_semicolon = false; + + if (prev === ":" && ch === "}" || (!ch || !";}".includes(ch)) && prev !== ";") { + if (options.semicolons || requireSemicolonChars.has(ch)) { + OUTPUT.append(";"); + current_col++; + current_pos++; + } else { + ensure_line_len(); + if (current_col > 0) { + OUTPUT.append("\n"); + current_pos++; + current_line++; + current_col = 0; + } + + if (/^\s+$/.test(str)) { + // reset the semicolon flag, since we didn't print one + // now and might still have to later + might_need_semicolon = true; + } + } + + if (!options.beautify) + might_need_space = false; + } + } + + if (might_need_space) { + if ((is_identifier_char(prev) + && (is_identifier_char(ch) || ch == "\\")) + || (ch == "/" && ch == prev) + || ((ch == "+" || ch == "-") && ch == last) + ) { + OUTPUT.append(" "); + current_col++; + current_pos++; + } + might_need_space = false; + } + + if (mapping_token) { + mappings.push({ + token: mapping_token, + name: mapping_name, + line: current_line, + col: current_col + }); + mapping_token = false; + if (!might_add_newline) do_add_mapping(); + } + + OUTPUT.append(str); + has_parens = str[str.length - 1] == "("; + current_pos += str.length; + var a = str.split(/\r?\n/), n = a.length - 1; + current_line += n; + current_col += a[0].length; + if (n > 0) { + ensure_line_len(); + current_col = a[n].length; + } + last = str; + } + + var star = function() { + print("*"); + }; + + var space = options.beautify ? function() { + print(" "); + } : function() { + might_need_space = true; + }; + + var indent = options.beautify ? function(half) { + if (options.beautify) { + print(make_indent(half ? 0.5 : 0)); + } + } : noop; + + var with_indent = options.beautify ? function(col, cont) { + if (col === true) col = next_indent(); + var save_indentation = indentation; + indentation = col; + var ret = cont(); + indentation = save_indentation; + return ret; + } : function(col, cont) { return cont(); }; + + var newline = options.beautify ? function() { + if (newline_insert < 0) return print("\n"); + if (OUTPUT.charAt(newline_insert) != "\n") { + OUTPUT.insertAt("\n", newline_insert); + current_pos++; + current_line++; + } + newline_insert++; + } : options.max_line_len ? function() { + ensure_line_len(); + might_add_newline = OUTPUT.length(); + } : noop; + + var semicolon = options.beautify ? function() { + print(";"); + } : function() { + might_need_semicolon = true; + }; + + function force_semicolon() { + might_need_semicolon = false; + print(";"); + } + + function next_indent() { + return indentation + options.indent_level; + } + + function with_block(cont) { + var ret; + print("{"); + newline(); + with_indent(next_indent(), function() { + ret = cont(); + }); + indent(); + print("}"); + return ret; + } + + function with_parens(cont) { + print("("); + //XXX: still nice to have that for argument lists + //var ret = with_indent(current_col, cont); + var ret = cont(); + print(")"); + return ret; + } + + function with_square(cont) { + print("["); + //var ret = with_indent(current_col, cont); + var ret = cont(); + print("]"); + return ret; + } + + function comma() { + print(","); + space(); + } + + function colon() { + print(":"); + space(); + } + + var add_mapping = mappings ? function(token, name) { + mapping_token = token; + mapping_name = name; + } : noop; + + function get() { + if (might_add_newline) { + ensure_line_len(); + } + return OUTPUT.toString(); + } + + function filter_comment(comment) { + if (!options.preserve_annotations) { + comment = comment.replace(r_annotation, " "); + } + if (/^\s*$/.test(comment)) { + return ""; + } + return comment.replace(/(<\s*\/\s*)(script)/i, "<\\/$2"); + } + + function prepend_comments(node) { + var self = this; + var start = node.start; + if (!start) return; + var printed_comments = self.printed_comments; + + // There cannot be a newline between return/yield and its value. + const keyword_with_value = + node instanceof AST_Exit && node.value + || (node instanceof AST_Await || node instanceof AST_Yield) + && node.expression; + + if ( + start.comments_before + && printed_comments.has(start.comments_before) + ) { + if (keyword_with_value) { + start.comments_before = []; + } else { + return; + } + } + + var comments = start.comments_before; + if (!comments) { + comments = start.comments_before = []; + } + printed_comments.add(comments); + + if (keyword_with_value) { + var tw = new TreeWalker(function(node) { + var parent = tw.parent(); + if (parent instanceof AST_Exit + || parent instanceof AST_Await + || parent instanceof AST_Yield + || parent instanceof AST_Binary && parent.left === node + || parent.TYPE == "Call" && parent.expression === node + || parent instanceof AST_Conditional && parent.condition === node + || parent instanceof AST_Dot && parent.expression === node + || parent instanceof AST_Sequence && parent.expressions[0] === node + || parent instanceof AST_Sub && parent.expression === node + || parent instanceof AST_UnaryPostfix) { + if (!node.start) return; + var text = node.start.comments_before; + if (text && !printed_comments.has(text)) { + printed_comments.add(text); + comments = comments.concat(text); + } + } else { + return true; + } + }); + tw.push(node); + keyword_with_value.walk(tw); + } + + if (current_pos == 0) { + if (comments.length > 0 && options.shebang && comments[0].type === "comment5" + && !printed_comments.has(comments[0])) { + print("#!" + comments.shift().value + "\n"); + indent(); + } + var preamble = options.preamble; + if (preamble) { + print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n")); + } + } + + comments = comments.filter(comment_filter, node).filter(c => !printed_comments.has(c)); + if (comments.length == 0) return; + var last_nlb = OUTPUT.hasNLB(); + comments.forEach(function(c, i) { + printed_comments.add(c); + if (!last_nlb) { + if (c.nlb) { + print("\n"); + indent(); + last_nlb = true; + } else if (i > 0) { + space(); + } + } + + if (/comment[134]/.test(c.type)) { + var value = filter_comment(c.value); + if (value) { + print("//" + value + "\n"); + indent(); + } + last_nlb = true; + } else if (c.type == "comment2") { + var value = filter_comment(c.value); + if (value) { + print("/*" + value + "*/"); + } + last_nlb = false; + } + }); + if (!last_nlb) { + if (start.nlb) { + print("\n"); + indent(); + } else { + space(); + } + } + } + + function append_comments(node, tail) { + var self = this; + var token = node.end; + if (!token) return; + var printed_comments = self.printed_comments; + var comments = token[tail ? "comments_before" : "comments_after"]; + if (!comments || printed_comments.has(comments)) return; + if (!(node instanceof AST_Statement || comments.every((c) => + !/comment[134]/.test(c.type) + ))) return; + printed_comments.add(comments); + var insert = OUTPUT.length(); + comments.filter(comment_filter, node).forEach(function(c, i) { + if (printed_comments.has(c)) return; + printed_comments.add(c); + need_space = false; + if (need_newline_indented) { + print("\n"); + indent(); + need_newline_indented = false; + } else if (c.nlb && (i > 0 || !OUTPUT.hasNLB())) { + print("\n"); + indent(); + } else if (i > 0 || !tail) { + space(); + } + if (/comment[134]/.test(c.type)) { + const value = filter_comment(c.value); + if (value) { + print("//" + value); + } + need_newline_indented = true; + } else if (c.type == "comment2") { + const value = filter_comment(c.value); + if (value) { + print("/*" + value + "*/"); + } + need_space = true; + } + }); + if (OUTPUT.length() > insert) newline_insert = insert; + } + + /** + * When output.option("_destroy_ast") is enabled, destroy the function. + * Call this after printing it. + */ + const gc_scope = + options["_destroy_ast"] + ? function gc_scope(scope) { + scope.body.length = 0; + scope.argnames.length = 0; + } + : noop; + + var stack = []; + return { + get : get, + toString : get, + indent : indent, + in_directive : false, + use_asm : null, + active_scope : null, + indentation : function() { return indentation; }, + current_width : function() { return current_col - indentation; }, + should_break : function() { return options.width && this.current_width() >= options.width; }, + has_parens : function() { return has_parens; }, + newline : newline, + print : print, + star : star, + space : space, + comma : comma, + colon : colon, + last : function() { return last; }, + semicolon : semicolon, + force_semicolon : force_semicolon, + to_utf8 : to_utf8, + print_name : function(name) { print(make_name(name)); }, + print_string : function(str, quote, escape_directive) { + var encoded = encode_string(str, quote); + if (escape_directive === true && !encoded.includes("\\")) { + // Insert semicolons to break directive prologue + if (!OUTPUT.expectDirective()) { + force_semicolon(); + } + force_semicolon(); + } + print(encoded); + }, + print_template_string_chars: function(str) { + var encoded = encode_string(str, "`").replace(/\${/g, "\\${"); + return print(encoded.substr(1, encoded.length - 2)); + }, + encode_string : encode_string, + next_indent : next_indent, + with_indent : with_indent, + with_block : with_block, + with_parens : with_parens, + with_square : with_square, + add_mapping : add_mapping, + option : function(opt) { return options[opt]; }, + gc_scope, + printed_comments: printed_comments, + prepend_comments: readonly ? noop : prepend_comments, + append_comments : readonly || comment_filter === return_false ? noop : append_comments, + line : function() { return current_line; }, + col : function() { return current_col; }, + pos : function() { return current_pos; }, + push_node : function(node) { stack.push(node); }, + pop_node : function() { return stack.pop(); }, + parent : function(n) { + return stack[stack.length - 2 - (n || 0)]; + } + }; + +} + +/* -----[ code generators ]----- */ + +(function() { + + /* -----[ utils ]----- */ + + function DEFPRINT(nodetype, generator) { + nodetype.DEFMETHOD("_codegen", generator); + } + + AST_Node.DEFMETHOD("print", function(output, force_parens) { + var self = this, generator = self._codegen; + if (self instanceof AST_Scope) { + output.active_scope = self; + } else if (!output.use_asm && self instanceof AST_Directive && self.value == "use asm") { + output.use_asm = output.active_scope; + } + function doit() { + output.prepend_comments(self); + self.add_source_map(output); + generator(self, output); + output.append_comments(self); + } + output.push_node(self); + if (force_parens || self.needs_parens(output)) { + output.with_parens(doit); + } else { + doit(); + } + output.pop_node(); + if (self === output.use_asm) { + output.use_asm = null; + } + }); + AST_Node.DEFMETHOD("_print", AST_Node.prototype.print); + + AST_Node.DEFMETHOD("print_to_string", function(options) { + var output = OutputStream(options); + this.print(output); + return output.get(); + }); + + /* -----[ PARENTHESES ]----- */ + + function PARENS(nodetype, func) { + if (Array.isArray(nodetype)) { + nodetype.forEach(function(nodetype) { + PARENS(nodetype, func); + }); + } else { + nodetype.DEFMETHOD("needs_parens", func); + } + } + + PARENS(AST_Node, return_false); + + // a function expression needs parens around it when it's provably + // the first token to appear in a statement. + PARENS(AST_Function, function(output) { + if (!output.has_parens() && first_in_statement(output)) { + return true; + } + + if (output.option("webkit")) { + var p = output.parent(); + if (p instanceof AST_PropAccess && p.expression === this) { + return true; + } + } + + if (output.option("wrap_iife")) { + var p = output.parent(); + if (p instanceof AST_Call && p.expression === this) { + return true; + } + } + + if (output.option("wrap_func_args")) { + var p = output.parent(); + if (p instanceof AST_Call && p.args.includes(this)) { + return true; + } + } + + return false; + }); + + PARENS(AST_Arrow, function(output) { + var p = output.parent(); + + if ( + output.option("wrap_func_args") + && p instanceof AST_Call + && p.args.includes(this) + ) { + return true; + } + return p instanceof AST_PropAccess && p.expression === this + || p instanceof AST_Conditional && p.condition === this; + }); + + // same goes for an object literal (as in AST_Function), because + // otherwise {...} would be interpreted as a block of code. + PARENS(AST_Object, function(output) { + return !output.has_parens() && first_in_statement(output); + }); + + PARENS(AST_ClassExpression, first_in_statement); + + PARENS(AST_Unary, function(output) { + var p = output.parent(); + return p instanceof AST_PropAccess && p.expression === this + || p instanceof AST_Call && p.expression === this + || p instanceof AST_Binary + && p.operator === "**" + && this instanceof AST_UnaryPrefix + && p.left === this + && this.operator !== "++" + && this.operator !== "--"; + }); + + PARENS(AST_Await, function(output) { + var p = output.parent(); + return p instanceof AST_PropAccess && p.expression === this + || p instanceof AST_Call && p.expression === this + || p instanceof AST_Binary && p.operator === "**" && p.left === this + || output.option("safari10") && p instanceof AST_UnaryPrefix; + }); + + PARENS(AST_Sequence, function(output) { + var p = output.parent(); + return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4) + || p instanceof AST_Unary // !(foo, bar, baz) + || p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8 + || p instanceof AST_VarDefLike // var a = (1, 2), b = a + a; ==> b == 4 + || p instanceof AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2 + || p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ] + || p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2 + || p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30) + * ==> 20 (side effect, set a := 10 and b := 20) */ + || p instanceof AST_Arrow // x => (x, x) + || p instanceof AST_DefaultAssign // x => (x = (0, function(){})) + || p instanceof AST_Expansion // [...(a, b)] + || p instanceof AST_ForOf && this === p.object // for (e of (foo, bar)) {} + || p instanceof AST_Yield // yield (foo, bar) + || p instanceof AST_Export // export default (foo, bar) + ; + }); + + PARENS(AST_Binary, function(output) { + var p = output.parent(); + // (foo && bar)() + if (p instanceof AST_Call && p.expression === this) + return true; + // typeof (foo && bar) + if (p instanceof AST_Unary) + return true; + // (foo && bar)["prop"], (foo && bar).prop + if (p instanceof AST_PropAccess && p.expression === this) + return true; + // this deals with precedence: 3 * (2 + 1) + if (p instanceof AST_Binary) { + const parent_op = p.operator; + const op = this.operator; + + // It is forbidden for ?? to be used with || or && without parens. + if (op === "??" && (parent_op === "||" || parent_op === "&&")) { + return true; + } + if (parent_op === "??" && (op === "||" || op === "&&")) { + return true; + } + + const pp = PRECEDENCE[parent_op]; + const sp = PRECEDENCE[op]; + if (pp > sp + || (pp == sp + && (this === p.right || parent_op == "**"))) { + return true; + } + } + if (p instanceof AST_PrivateIn) { + const op = this.operator; + + const pp = PRECEDENCE["in"]; + const sp = PRECEDENCE[op]; + if (pp > sp || (pp == sp && this === p.value)) { + return true; + } + } + }); + + PARENS(AST_PrivateIn, function(output) { + var p = output.parent(); + // (#x in this)() + if (p instanceof AST_Call && p.expression === this) { + return true; + } + // typeof (#x in this) + if (p instanceof AST_Unary) { + return true; + } + // (#x in this)["prop"], (#x in this).prop + if (p instanceof AST_PropAccess && p.expression === this) { + return true; + } + // same precedence as regular in operator + if (p instanceof AST_Binary) { + const parent_op = p.operator; + + const pp = PRECEDENCE[parent_op]; + const sp = PRECEDENCE["in"]; + if (pp > sp + || (pp == sp + && (this === p.right || parent_op == "**"))) { + return true; + } + } + // rules are the same as binary in, but the class differs + if (p instanceof AST_PrivateIn && this === p.value) { + return true; + } + }); + + PARENS(AST_Yield, function(output) { + var p = output.parent(); + // (yield 1) + (yield 2) + // a = yield 3 + if (p instanceof AST_Binary && p.operator !== "=") + return true; + // (yield 1)() + // new (yield 1)() + if (p instanceof AST_Call && p.expression === this) + return true; + // (yield 1) ? yield 2 : yield 3 + if (p instanceof AST_Conditional && p.condition === this) + return true; + // -(yield 4) + if (p instanceof AST_Unary) + return true; + // (yield x).foo + // (yield x)['foo'] + if (p instanceof AST_PropAccess && p.expression === this) + return true; + }); + + PARENS(AST_Chain, function(output) { + var p = output.parent(); + if (!(p instanceof AST_Call || p instanceof AST_PropAccess)) return false; + return p.expression === this; + }); + + PARENS(AST_PropAccess, function(output) { + var p = output.parent(); + if (p instanceof AST_New && p.expression === this) { + // i.e. new (foo.bar().baz) + // + // if there's one call into this subtree, then we need + // parens around it too, otherwise the call will be + // interpreted as passing the arguments to the upper New + // expression. + return walk(this, node => { + if (node instanceof AST_Scope) return true; + if (node instanceof AST_Call) { + return walk_abort; // makes walk() return true. + } + }); + } + }); + + PARENS(AST_Call, function(output) { + var p = output.parent(), p1; + if (p instanceof AST_New && p.expression === this + || p instanceof AST_Export && p.is_default && this.expression instanceof AST_Function) + return true; + + // workaround for Safari bug. + // https://bugs.webkit.org/show_bug.cgi?id=123506 + return this.expression instanceof AST_Function + && p instanceof AST_PropAccess + && p.expression === this + && (p1 = output.parent(1)) instanceof AST_Assign + && p1.left === p; + }); + + PARENS(AST_New, function(output) { + var p = output.parent(); + if (this.args.length === 0 + && (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]() + || p instanceof AST_Call && p.expression === this + || p instanceof AST_PrefixedTemplateString && p.prefix === this)) // (new foo)(bar) + return true; + }); + + PARENS(AST_Number, function(output) { + var p = output.parent(); + if (p instanceof AST_PropAccess && p.expression === this) { + var value = this.getValue(); + if (value < 0 || /^0/.test(make_num(value))) { + return true; + } + } + }); + + PARENS(AST_BigInt, function(output) { + var p = output.parent(); + if (p instanceof AST_PropAccess && p.expression === this) { + var value = this.getValue(); + if (value.startsWith("-")) { + return true; + } + } + }); + + PARENS([ AST_Assign, AST_Conditional ], function(output) { + var p = output.parent(); + // !(a = false) → true + if (p instanceof AST_Unary) + return true; + // 1 + (a = 2) + 3 → 6, side effect setting a = 2 + if (p instanceof AST_Binary && !(p instanceof AST_Assign)) + return true; + // (a = func)() —or— new (a = Object)() + if (p instanceof AST_Call && p.expression === this) + return true; + // (a = foo) ? bar : baz + if (p instanceof AST_Conditional && p.condition === this) + return true; + // (a = foo)["prop"] —or— (a = foo).prop + if (p instanceof AST_PropAccess && p.expression === this) + return true; + // ({a, b} = {a: 1, b: 2}), a destructuring assignment + if (this instanceof AST_Assign && this.left instanceof AST_Destructuring && this.left.is_array === false) + return true; + }); + + /* -----[ PRINTERS ]----- */ + + DEFPRINT(AST_Directive, function(self, output) { + output.print_string(self.value, self.quote); + output.semicolon(); + }); + + DEFPRINT(AST_Expansion, function (self, output) { + output.print("..."); + self.expression.print(output); + }); + + DEFPRINT(AST_Destructuring, function (self, output) { + output.print(self.is_array ? "[" : "{"); + var len = self.names.length; + self.names.forEach(function (name, i) { + if (i > 0) output.comma(); + name.print(output); + // If the final element is a hole, we need to make sure it + // doesn't look like a trailing comma, by inserting an actual + // trailing comma. + if (i == len - 1 && name instanceof AST_Hole) output.comma(); + }); + output.print(self.is_array ? "]" : "}"); + }); + + DEFPRINT(AST_Debugger, function(self, output) { + output.print("debugger"); + output.semicolon(); + }); + + /* -----[ statements ]----- */ + + function display_body(body, is_toplevel, output, allow_directives) { + var last = body.length - 1; + output.in_directive = allow_directives; + body.forEach(function(stmt, i) { + if (output.in_directive === true && !(stmt instanceof AST_Directive || + stmt instanceof AST_EmptyStatement || + (stmt instanceof AST_SimpleStatement && stmt.body instanceof AST_String) + )) { + output.in_directive = false; + } + if (!(stmt instanceof AST_EmptyStatement)) { + output.indent(); + stmt.print(output); + if (!(i == last && is_toplevel)) { + output.newline(); + if (is_toplevel) output.newline(); + } + } + if (output.in_directive === true && + stmt instanceof AST_SimpleStatement && + stmt.body instanceof AST_String + ) { + output.in_directive = false; + } + }); + output.in_directive = false; + } + + AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output) { + print_maybe_braced_body(this.body, output); + }); + + DEFPRINT(AST_Statement, function(self, output) { + self.body.print(output); + output.semicolon(); + }); + DEFPRINT(AST_Toplevel, function(self, output) { + display_body(self.body, true, output, true); + output.print(""); + }); + DEFPRINT(AST_LabeledStatement, function(self, output) { + self.label.print(output); + output.colon(); + self.body.print(output); + }); + DEFPRINT(AST_SimpleStatement, function(self, output) { + self.body.print(output); + output.semicolon(); + }); + function print_braced_empty(self, output) { + output.print("{"); + output.with_indent(output.next_indent(), function() { + output.append_comments(self, true); + }); + output.add_mapping(self.end); + output.print("}"); + } + function print_braced(self, output, allow_directives) { + if (self.body.length > 0) { + output.with_block(function() { + display_body(self.body, false, output, allow_directives); + output.add_mapping(self.end); + }); + } else print_braced_empty(self, output); + } + DEFPRINT(AST_BlockStatement, function(self, output) { + print_braced(self, output); + }); + DEFPRINT(AST_EmptyStatement, function(self, output) { + output.semicolon(); + }); + DEFPRINT(AST_Do, function(self, output) { + output.print("do"); + output.space(); + make_block(self.body, output); + output.space(); + output.print("while"); + output.space(); + output.with_parens(function() { + self.condition.print(output); + }); + output.semicolon(); + }); + DEFPRINT(AST_While, function(self, output) { + output.print("while"); + output.space(); + output.with_parens(function() { + self.condition.print(output); + }); + output.space(); + self._do_print_body(output); + }); + DEFPRINT(AST_For, function(self, output) { + output.print("for"); + output.space(); + output.with_parens(function() { + if (self.init) { + if (self.init instanceof AST_DefinitionsLike) { + self.init.print(output); + } else { + parenthesize_for_noin(self.init, output, true); + } + output.print(";"); + output.space(); + } else { + output.print(";"); + } + if (self.condition) { + self.condition.print(output); + output.print(";"); + output.space(); + } else { + output.print(";"); + } + if (self.step) { + self.step.print(output); + } + }); + output.space(); + self._do_print_body(output); + }); + DEFPRINT(AST_ForIn, function(self, output) { + output.print("for"); + if (self.await) { + output.space(); + output.print("await"); + } + output.space(); + output.with_parens(function() { + self.init.print(output); + output.space(); + output.print(self instanceof AST_ForOf ? "of" : "in"); + output.space(); + self.object.print(output); + }); + output.space(); + self._do_print_body(output); + }); + DEFPRINT(AST_With, function(self, output) { + output.print("with"); + output.space(); + output.with_parens(function() { + self.expression.print(output); + }); + output.space(); + self._do_print_body(output); + }); + + /* -----[ functions ]----- */ + AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword) { + var self = this; + if (!nokeyword) { + if (self.async) { + output.print("async"); + output.space(); + } + output.print("function"); + if (self.is_generator) { + output.star(); + } + if (self.name) { + output.space(); + } + } + if (self.name instanceof AST_Symbol) { + self.name.print(output); + } else if (nokeyword && self.name instanceof AST_Node) { + output.with_square(function() { + self.name.print(output); // Computed method name + }); + } + output.with_parens(function() { + self.argnames.forEach(function(arg, i) { + if (i) output.comma(); + arg.print(output); + }); + }); + output.space(); + print_braced(self, output, true); + }); + DEFPRINT(AST_Lambda, function(self, output) { + self._do_print(output); + output.gc_scope(self); + }); + + DEFPRINT(AST_PrefixedTemplateString, function(self, output) { + var tag = self.prefix; + var parenthesize_tag = tag instanceof AST_Lambda + || tag instanceof AST_Binary + || tag instanceof AST_Conditional + || tag instanceof AST_Sequence + || tag instanceof AST_Unary + || tag instanceof AST_Dot && tag.expression instanceof AST_Object; + if (parenthesize_tag) output.print("("); + self.prefix.print(output); + if (parenthesize_tag) output.print(")"); + self.template_string.print(output); + }); + DEFPRINT(AST_TemplateString, function(self, output) { + var is_tagged = output.parent() instanceof AST_PrefixedTemplateString; + + output.print("`"); + for (var i = 0; i < self.segments.length; i++) { + if (!(self.segments[i] instanceof AST_TemplateSegment)) { + output.print("${"); + self.segments[i].print(output); + output.print("}"); + } else if (is_tagged) { + output.print(self.segments[i].raw); + } else { + output.print_template_string_chars(self.segments[i].value); + } + } + output.print("`"); + }); + DEFPRINT(AST_TemplateSegment, function(self, output) { + output.print_template_string_chars(self.value); + }); + + AST_Arrow.DEFMETHOD("_do_print", function(output) { + var self = this; + var parent = output.parent(); + var needs_parens = (parent instanceof AST_Binary && + !(parent instanceof AST_Assign) && + !(parent instanceof AST_DefaultAssign)) || + parent instanceof AST_Unary || + (parent instanceof AST_Call && self === parent.expression); + if (needs_parens) { output.print("("); } + if (self.async) { + output.print("async"); + output.space(); + } + if (self.argnames.length === 1 && self.argnames[0] instanceof AST_Symbol) { + self.argnames[0].print(output); + } else { + output.with_parens(function() { + self.argnames.forEach(function(arg, i) { + if (i) output.comma(); + arg.print(output); + }); + }); + } + output.space(); + output.print("=>"); + output.space(); + const first_statement = self.body[0]; + if ( + self.body.length === 1 + && first_statement instanceof AST_Return + ) { + const returned = first_statement.value; + if (!returned) { + output.print("{}"); + } else if (left_is_object(returned)) { + output.print("("); + returned.print(output); + output.print(")"); + } else { + returned.print(output); + } + } else { + print_braced(self, output); + } + if (needs_parens) { output.print(")"); } + output.gc_scope(self); + }); + + /* -----[ exits ]----- */ + AST_Exit.DEFMETHOD("_do_print", function(output, kind) { + output.print(kind); + if (this.value) { + output.space(); + const comments = this.value.start.comments_before; + if (comments && comments.length && !output.printed_comments.has(comments)) { + output.print("("); + this.value.print(output); + output.print(")"); + } else { + this.value.print(output); + } + } + output.semicolon(); + }); + DEFPRINT(AST_Return, function(self, output) { + self._do_print(output, "return"); + }); + DEFPRINT(AST_Throw, function(self, output) { + self._do_print(output, "throw"); + }); + + /* -----[ yield ]----- */ + + DEFPRINT(AST_Yield, function(self, output) { + var star = self.is_star ? "*" : ""; + output.print("yield" + star); + if (self.expression) { + output.space(); + self.expression.print(output); + } + }); + + DEFPRINT(AST_Await, function(self, output) { + output.print("await"); + output.space(); + var e = self.expression; + var parens = !( + e instanceof AST_Call + || e instanceof AST_SymbolRef + || e instanceof AST_PropAccess + || e instanceof AST_Unary + || e instanceof AST_Constant + || e instanceof AST_Await + || e instanceof AST_Object + ); + if (parens) output.print("("); + self.expression.print(output); + if (parens) output.print(")"); + }); + + /* -----[ loop control ]----- */ + AST_LoopControl.DEFMETHOD("_do_print", function(output, kind) { + output.print(kind); + if (this.label) { + output.space(); + this.label.print(output); + } + output.semicolon(); + }); + DEFPRINT(AST_Break, function(self, output) { + self._do_print(output, "break"); + }); + DEFPRINT(AST_Continue, function(self, output) { + self._do_print(output, "continue"); + }); + + /* -----[ if ]----- */ + function make_then(self, output) { + var b = self.body; + if (output.option("braces") + || output.option("ie8") && b instanceof AST_Do) + return make_block(b, output); + // The squeezer replaces "block"-s that contain only a single + // statement with the statement itself; technically, the AST + // is correct, but this can create problems when we output an + // IF having an ELSE clause where the THEN clause ends in an + // IF *without* an ELSE block (then the outer ELSE would refer + // to the inner IF). This function checks for this case and + // adds the block braces if needed. + if (!b) return output.force_semicolon(); + while (true) { + if (b instanceof AST_If) { + if (!b.alternative) { + make_block(self.body, output); + return; + } + b = b.alternative; + } else if (b instanceof AST_StatementWithBody) { + b = b.body; + } else break; + } + print_maybe_braced_body(self.body, output); + } + DEFPRINT(AST_If, function(self, output) { + output.print("if"); + output.space(); + output.with_parens(function() { + self.condition.print(output); + }); + output.space(); + if (self.alternative) { + make_then(self, output); + output.space(); + output.print("else"); + output.space(); + if (self.alternative instanceof AST_If) + self.alternative.print(output); + else + print_maybe_braced_body(self.alternative, output); + } else { + self._do_print_body(output); + } + }); + + /* -----[ switch ]----- */ + DEFPRINT(AST_Switch, function(self, output) { + output.print("switch"); + output.space(); + output.with_parens(function() { + self.expression.print(output); + }); + output.space(); + var last = self.body.length - 1; + if (last < 0) print_braced_empty(self, output); + else output.with_block(function() { + self.body.forEach(function(branch, i) { + output.indent(true); + branch.print(output); + if (i < last && branch.body.length > 0) + output.newline(); + }); + }); + }); + AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output) { + output.newline(); + this.body.forEach(function(stmt) { + output.indent(); + stmt.print(output); + output.newline(); + }); + }); + DEFPRINT(AST_Default, function(self, output) { + output.print("default:"); + self._do_print_body(output); + }); + DEFPRINT(AST_Case, function(self, output) { + output.print("case"); + output.space(); + self.expression.print(output); + output.print(":"); + self._do_print_body(output); + }); + + /* -----[ exceptions ]----- */ + DEFPRINT(AST_Try, function(self, output) { + output.print("try"); + output.space(); + self.body.print(output); + if (self.bcatch) { + output.space(); + self.bcatch.print(output); + } + if (self.bfinally) { + output.space(); + self.bfinally.print(output); + } + }); + DEFPRINT(AST_TryBlock, function(self, output) { + print_braced(self, output); + }); + DEFPRINT(AST_Catch, function(self, output) { + output.print("catch"); + if (self.argname) { + output.space(); + output.with_parens(function() { + self.argname.print(output); + }); + } + output.space(); + print_braced(self, output); + }); + DEFPRINT(AST_Finally, function(self, output) { + output.print("finally"); + output.space(); + print_braced(self, output); + }); + + /* -----[ var/const ]----- */ + AST_DefinitionsLike.DEFMETHOD("_do_print", function(output, kind) { + output.print(kind); + output.space(); + this.definitions.forEach(function(def, i) { + if (i) output.comma(); + def.print(output); + }); + var p = output.parent(); + var in_for = p instanceof AST_For || p instanceof AST_ForIn; + var output_semicolon = !in_for || p && p.init !== this; + if (output_semicolon) + output.semicolon(); + }); + DEFPRINT(AST_Let, function(self, output) { + self._do_print(output, "let"); + }); + DEFPRINT(AST_Var, function(self, output) { + self._do_print(output, "var"); + }); + DEFPRINT(AST_Const, function(self, output) { + self._do_print(output, "const"); + }); + DEFPRINT(AST_Using, function(self, output) { + self._do_print(output, self.await ? "await using" : "using"); + }); + DEFPRINT(AST_Import, function(self, output) { + output.print("import"); + output.space(); + if (self.imported_name) { + self.imported_name.print(output); + } + if (self.imported_name && self.imported_names) { + output.print(","); + output.space(); + } + if (self.imported_names) { + if (self.imported_names.length === 1 && + self.imported_names[0].foreign_name.name === "*" && + !self.imported_names[0].foreign_name.quote) { + self.imported_names[0].print(output); + } else { + output.print("{"); + self.imported_names.forEach(function (name_import, i) { + output.space(); + name_import.print(output); + if (i < self.imported_names.length - 1) { + output.print(","); + } + }); + output.space(); + output.print("}"); + } + } + if (self.imported_name || self.imported_names) { + output.space(); + output.print("from"); + output.space(); + } + self.module_name.print(output); + if (self.attributes) { + output.print("with"); + self.attributes.print(output); + } + output.semicolon(); + }); + DEFPRINT(AST_ImportMeta, function(self, output) { + output.print("import.meta"); + }); + + DEFPRINT(AST_NameMapping, function(self, output) { + var is_import = output.parent() instanceof AST_Import; + var definition = self.name.definition(); + var foreign_name = self.foreign_name; + var names_are_different = + (definition && definition.mangled_name || self.name.name) !== + foreign_name.name; + if (!names_are_different && + foreign_name.name === "*" && + !!foreign_name.quote != !!self.name.quote) { + // export * as "*" + names_are_different = true; + } + var foreign_name_is_name = !foreign_name.quote; + if (names_are_different) { + if (is_import) { + if (foreign_name_is_name) { + output.print(foreign_name.name); + } else { + output.print_string(foreign_name.name, foreign_name.quote); + } + } else { + if (!self.name.quote) { + self.name.print(output); + } else { + output.print_string(self.name.name, self.name.quote); + } + + } + output.space(); + output.print("as"); + output.space(); + if (is_import) { + self.name.print(output); + } else { + if (foreign_name_is_name) { + output.print(foreign_name.name); + } else { + output.print_string(foreign_name.name, foreign_name.quote); + } + } + } else { + if (!self.name.quote) { + self.name.print(output); + } else { + output.print_string(self.name.name, self.name.quote); + } + } + }); + + DEFPRINT(AST_Export, function(self, output) { + output.print("export"); + output.space(); + if (self.is_default) { + output.print("default"); + output.space(); + } + if (self.exported_names) { + if (self.exported_names.length === 1 && + self.exported_names[0].name.name === "*" && + !self.exported_names[0].name.quote) { + self.exported_names[0].print(output); + } else { + output.print("{"); + self.exported_names.forEach(function(name_export, i) { + output.space(); + name_export.print(output); + if (i < self.exported_names.length - 1) { + output.print(","); + } + }); + output.space(); + output.print("}"); + } + } else if (self.exported_value) { + self.exported_value.print(output); + } else if (self.exported_definition) { + self.exported_definition.print(output); + if (self.exported_definition instanceof AST_Definitions) return; + } + if (self.module_name) { + output.space(); + output.print("from"); + output.space(); + self.module_name.print(output); + } + if (self.attributes) { + output.print("with"); + self.attributes.print(output); + } + if (self.exported_value + && !(self.exported_value instanceof AST_Defun || + self.exported_value instanceof AST_Function || + self.exported_value instanceof AST_Class) + || self.module_name + || self.exported_names + ) { + output.semicolon(); + } + }); + + function parenthesize_for_noin(node, output, noin) { + var parens = false; + // need to take some precautions here: + // https://github.com/mishoo/UglifyJS2/issues/60 + if (noin) { + parens = walk(node, node => { + // Don't go into scopes -- except arrow functions: + // https://github.com/terser/terser/issues/1019#issuecomment-877642607 + if (node instanceof AST_Scope && !(node instanceof AST_Arrow)) { + return true; + } + if ( + node instanceof AST_Binary && node.operator == "in" + || node instanceof AST_PrivateIn + ) { + return walk_abort; // makes walk() return true + } + }); + } + node.print(output, parens); + } + + DEFPRINT(AST_VarDefLike, function(self, output) { + self.name.print(output); + if (self.value) { + output.space(); + output.print("="); + output.space(); + var p = output.parent(1); + var noin = p instanceof AST_For || p instanceof AST_ForIn; + parenthesize_for_noin(self.value, output, noin); + } + }); + + /* -----[ other expressions ]----- */ + DEFPRINT(AST_Call, function(self, output) { + self.expression.print(output); + if (self instanceof AST_New && self.args.length === 0) + return; + if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) { + output.add_mapping(self.start); + } + if (self.optional) output.print("?."); + output.with_parens(function() { + self.args.forEach(function(expr, i) { + if (i) output.comma(); + expr.print(output); + }); + }); + }); + DEFPRINT(AST_New, function(self, output) { + output.print("new"); + output.space(); + AST_Call.prototype._codegen(self, output); + }); + + AST_Sequence.DEFMETHOD("_do_print", function(output) { + this.expressions.forEach(function(node, index) { + if (index > 0) { + output.comma(); + if (output.should_break()) { + output.newline(); + output.indent(); + } + } + node.print(output); + }); + }); + DEFPRINT(AST_Sequence, function(self, output) { + self._do_print(output); + // var p = output.parent(); + // if (p instanceof AST_Statement) { + // output.with_indent(output.next_indent(), function(){ + // self._do_print(output); + // }); + // } else { + // self._do_print(output); + // } + }); + DEFPRINT(AST_Dot, function(self, output) { + var expr = self.expression; + expr.print(output); + var prop = self.property; + var print_computed = ALL_RESERVED_WORDS.has(prop) + ? output.option("ie8") + : !is_identifier_string( + prop, + output.option("ecma") >= 2015 && !output.option("safari10") + ); + + if (self.optional) output.print("?."); + + if (print_computed) { + output.print("["); + output.add_mapping(self.end); + output.print_string(prop); + output.print("]"); + } else { + if (expr instanceof AST_Number && expr.getValue() >= 0) { + if (!/[xa-f.)]/i.test(output.last())) { + output.print("."); + } + } + if (!self.optional) output.print("."); + // the name after dot would be mapped about here. + output.add_mapping(self.end); + output.print_name(prop); + } + }); + DEFPRINT(AST_DotHash, function(self, output) { + var expr = self.expression; + expr.print(output); + var prop = self.property; + + if (self.optional) output.print("?"); + output.print(".#"); + output.add_mapping(self.end); + output.print_name(prop); + }); + DEFPRINT(AST_Sub, function(self, output) { + self.expression.print(output); + if (self.optional) output.print("?."); + output.print("["); + self.property.print(output); + output.print("]"); + }); + DEFPRINT(AST_Chain, function(self, output) { + self.expression.print(output); + }); + DEFPRINT(AST_UnaryPrefix, function(self, output) { + var op = self.operator; + if (op === "--" && output.last().endsWith("!")) { + // avoid printing " + output.print(" "); + } else { + // the space is optional depending on "beautify" + output.space(); + } + output.print(op); + output.space(); + self.right.print(output); + }); + DEFPRINT(AST_Conditional, function(self, output) { + self.condition.print(output); + output.space(); + output.print("?"); + output.space(); + self.consequent.print(output); + output.space(); + output.colon(); + self.alternative.print(output); + }); + + /* -----[ literals ]----- */ + DEFPRINT(AST_Array, function(self, output) { + output.with_square(function() { + var a = self.elements, len = a.length; + if (len > 0) output.space(); + a.forEach(function(exp, i) { + if (i) output.comma(); + exp.print(output); + // If the final element is a hole, we need to make sure it + // doesn't look like a trailing comma, by inserting an actual + // trailing comma. + if (i === len - 1 && exp instanceof AST_Hole) + output.comma(); + }); + if (len > 0) output.space(); + }); + }); + DEFPRINT(AST_Object, function(self, output) { + if (self.properties.length > 0) output.with_block(function() { + self.properties.forEach(function(prop, i) { + if (i) { + output.print(","); + output.newline(); + } + output.indent(); + prop.print(output); + }); + output.newline(); + }); + else print_braced_empty(self, output); + }); + DEFPRINT(AST_Class, function(self, output) { + output.print("class"); + output.space(); + if (self.name) { + self.name.print(output); + output.space(); + } + if (self.extends) { + var parens = ( + !(self.extends instanceof AST_SymbolRef) + && !(self.extends instanceof AST_PropAccess) + && !(self.extends instanceof AST_ClassExpression) + && !(self.extends instanceof AST_Function) + ); + output.print("extends"); + if (parens) { + output.print("("); + } else { + output.space(); + } + self.extends.print(output); + if (parens) { + output.print(")"); + } else { + output.space(); + } + } + if (self.properties.length > 0) output.with_block(function() { + self.properties.forEach(function(prop, i) { + if (i) { + output.newline(); + } + output.indent(); + prop.print(output); + }); + output.newline(); + }); + else output.print("{}"); + }); + DEFPRINT(AST_NewTarget, function(self, output) { + output.print("new.target"); + }); + + /** Prints a prop name. Returns whether it can be used as a shorthand. */ + function print_property_name(key, quote, output) { + if (output.option("quote_keys")) { + output.print_string(key); + return false; + } + if ("" + +key == key && key >= 0) { + if (output.option("keep_numbers")) { + output.print(key); + return false; + } + output.print(make_num(key)); + return false; + } + var print_string = ALL_RESERVED_WORDS.has(key) + ? output.option("ie8") + : ( + output.option("ecma") < 2015 || output.option("safari10") + ? !is_basic_identifier_string(key) + : !is_identifier_string(key, true) + ); + if (print_string || (quote && output.option("keep_quoted_props"))) { + output.print_string(key, quote); + return false; + } + output.print_name(key); + return true; + } + + DEFPRINT(AST_ObjectKeyVal, function(self, output) { + function get_name(self) { + var def = self.definition(); + return def ? def.mangled_name || def.name : self.name; + } + + const try_shorthand = output.option("shorthand") && !(self.key instanceof AST_Node); + if ( + try_shorthand + && self.value instanceof AST_Symbol + && get_name(self.value) === self.key + && !ALL_RESERVED_WORDS.has(self.key) + ) { + const was_shorthand = print_property_name(self.key, self.quote, output); + if (!was_shorthand) { + output.colon(); + self.value.print(output); + } + } else if ( + try_shorthand + && self.value instanceof AST_DefaultAssign + && self.value.left instanceof AST_Symbol + && get_name(self.value.left) === self.key + ) { + const was_shorthand = print_property_name(self.key, self.quote, output); + if (!was_shorthand) { + output.colon(); + self.value.left.print(output); + } + output.space(); + output.print("="); + output.space(); + self.value.right.print(output); + } else { + if (!(self.key instanceof AST_Node)) { + print_property_name(self.key, self.quote, output); + } else { + output.with_square(function() { + self.key.print(output); + }); + } + output.colon(); + self.value.print(output); + } + }); + DEFPRINT(AST_ClassPrivateProperty, (self, output) => { + if (self.static) { + output.print("static"); + output.space(); + } + + output.print("#"); + + print_property_name(self.key.name, undefined, output); + + if (self.value) { + output.print("="); + self.value.print(output); + } + + output.semicolon(); + }); + DEFPRINT(AST_ClassProperty, (self, output) => { + if (self.static) { + output.print("static"); + output.space(); + } + + if (self.key instanceof AST_SymbolClassProperty) { + print_property_name(self.key.name, self.quote, output); + } else { + output.print("["); + self.key.print(output); + output.print("]"); + } + + if (self.value) { + output.print("="); + self.value.print(output); + } + + output.semicolon(); + }); + AST_ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, is_private, output) { + var self = this; + if (self.static) { + output.print("static"); + output.space(); + } + if (type) { + output.print(type); + output.space(); + } + if (self.key instanceof AST_SymbolMethod) { + if (is_private) output.print("#"); + print_property_name(self.key.name, self.quote, output); + self.key.add_source_map(output); + } else { + output.with_square(function() { + self.key.print(output); + }); + } + self.value._do_print(output, true); + }); + DEFPRINT(AST_ObjectSetter, function(self, output) { + self._print_getter_setter("set", false, output); + }); + DEFPRINT(AST_ObjectGetter, function(self, output) { + self._print_getter_setter("get", false, output); + }); + DEFPRINT(AST_PrivateSetter, function(self, output) { + self._print_getter_setter("set", true, output); + }); + DEFPRINT(AST_PrivateGetter, function(self, output) { + self._print_getter_setter("get", true, output); + }); + DEFPRINT(AST_ConciseMethod, function(self, output) { + var type; + if (self.value.is_generator && self.value.async) { + type = "async*"; + } else if (self.value.is_generator) { + type = "*"; + } else if (self.value.async) { + type = "async"; + } + self._print_getter_setter(type, false, output); + }); + DEFPRINT(AST_PrivateMethod, function(self, output) { + var type; + if (self.value.is_generator && self.value.async) { + type = "async*"; + } else if (self.value.is_generator) { + type = "*"; + } else if (self.value.async) { + type = "async"; + } + self._print_getter_setter(type, true, output); + }); + DEFPRINT(AST_PrivateIn, function(self, output) { + self.key.print(output); + output.space(); + output.print("in"); + output.space(); + self.value.print(output); + }); + DEFPRINT(AST_SymbolPrivateProperty, function(self, output) { + output.print("#" + self.name); + }); + DEFPRINT(AST_ClassStaticBlock, function (self, output) { + output.print("static"); + output.space(); + print_braced(self, output); + }); + AST_Symbol.DEFMETHOD("_do_print", function(output) { + var def = this.definition(); + output.print_name(def ? def.mangled_name || def.name : this.name); + }); + DEFPRINT(AST_Symbol, function (self, output) { + self._do_print(output); + }); + DEFPRINT(AST_Hole, noop); + DEFPRINT(AST_This, function(self, output) { + output.print("this"); + }); + DEFPRINT(AST_Super, function(self, output) { + output.print("super"); + }); + DEFPRINT(AST_Constant, function(self, output) { + output.print(self.getValue()); + }); + DEFPRINT(AST_String, function(self, output) { + output.print_string(self.getValue(), self.quote, output.in_directive); + }); + DEFPRINT(AST_Number, function(self, output) { + if ((output.option("keep_numbers") || output.use_asm) && self.raw) { + output.print(self.raw); + } else { + output.print(make_num(self.getValue())); + } + }); + DEFPRINT(AST_BigInt, function(self, output) { + if (output.option("keep_numbers") && self.raw) { + output.print(self.raw); + } else { + output.print(self.getValue() + "n"); + } + }); + + const r_slash_script = /(<\s*\/\s*script)/i; + const r_starts_with_script = /^\s*script/i; + const slash_script_replace = (_, $1) => $1.replace("/", "\\/"); + DEFPRINT(AST_RegExp, function(self, output) { + let { source, flags } = self.getValue(); + source = regexp_source_fix(source); + flags = flags ? sort_regexp_flags(flags) : ""; + + // Avoid outputting end of script tag + source = source.replace(r_slash_script, slash_script_replace); + if (r_starts_with_script.test(source) && output.last().endsWith("<")) { + output.print(" "); + } + + output.print(output.to_utf8(`/${source}/${flags}`, false, true)); + + const parent = output.parent(); + if ( + parent instanceof AST_Binary + && /^\w/.test(parent.operator) + && parent.left === self + ) { + output.print(" "); + } + }); + + /** if, for, while, may or may not have braces surrounding its body */ + function print_maybe_braced_body(stat, output) { + if (output.option("braces")) { + make_block(stat, output); + } else { + if (!stat || stat instanceof AST_EmptyStatement) + output.force_semicolon(); + else if ((stat instanceof AST_DefinitionsLike && !(stat instanceof AST_Var)) || stat instanceof AST_Class) + make_block(stat, output); + else + stat.print(output); + } + } + + function best_of(a) { + var best = a[0], len = best.length; + for (var i = 1; i < a.length; ++i) { + if (a[i].length < len) { + best = a[i]; + len = best.length; + } + } + return best; + } + + function make_num(num) { + var str = num.toString(10).replace(/^0\./, ".").replace("e+", "e"); + var candidates = [ str ]; + if (Math.floor(num) === num) { + if (num < 0) { + candidates.push("-0x" + (-num).toString(16).toLowerCase()); + } else { + candidates.push("0x" + num.toString(16).toLowerCase()); + } + } + var match, len, digits; + if (match = /^\.0+/.exec(str)) { + len = match[0].length; + digits = str.slice(len); + candidates.push(digits + "e-" + (digits.length + len - 1)); + } else if (match = /0+$/.exec(str)) { + len = match[0].length; + candidates.push(str.slice(0, -len) + "e" + len); + } else if (match = /^(\d)\.(\d+)e(-?\d+)$/.exec(str)) { + candidates.push(match[1] + match[2] + "e" + (match[3] - match[2].length)); + } + return best_of(candidates); + } + + function make_block(stmt, output) { + if (!stmt || stmt instanceof AST_EmptyStatement) + output.print("{}"); + else if (stmt instanceof AST_BlockStatement) + stmt.print(output); + else output.with_block(function() { + output.indent(); + stmt.print(output); + output.newline(); + }); + } + + /* -----[ source map generators ]----- */ + + function DEFMAP(nodetype, generator) { + nodetype.forEach(function(nodetype) { + nodetype.DEFMETHOD("add_source_map", generator); + }); + } + + DEFMAP([ + // We could easily add info for ALL nodes, but it seems to me that + // would be quite wasteful, hence this noop in the base class. + AST_Node, + // since the label symbol will mark it + AST_LabeledStatement, + AST_Toplevel, + ], noop); + + // XXX: I'm not exactly sure if we need it for all of these nodes, + // or if we should add even more. + DEFMAP([ + AST_Array, + AST_BlockStatement, + AST_Catch, + AST_Class, + AST_Constant, + AST_Debugger, + AST_DefinitionsLike, + AST_Directive, + AST_Finally, + AST_Jump, + AST_Lambda, + AST_New, + AST_Object, + AST_StatementWithBody, + AST_Symbol, + AST_Switch, + AST_SwitchBranch, + AST_TemplateString, + AST_TemplateSegment, + AST_Try, + ], function(output) { + output.add_mapping(this.start); + }); + + DEFMAP([ + AST_ObjectGetter, + AST_ObjectSetter, + AST_PrivateGetter, + AST_PrivateSetter, + AST_ConciseMethod, + AST_PrivateMethod, + ], function(output) { + output.add_mapping(this.start, false /*name handled below*/); + }); + + DEFMAP([ + AST_SymbolMethod, + AST_SymbolPrivateProperty + ], function(output) { + const tok_type = this.end && this.end.type; + if (tok_type === "name" || tok_type === "privatename") { + output.add_mapping(this.end, this.name); + } else { + output.add_mapping(this.end); + } + }); + + DEFMAP([ AST_ObjectProperty ], function(output) { + output.add_mapping(this.start, this.key); + }); +})(); + +export { + OutputStream, +}; diff --git a/node_modules/terser/lib/parse.js b/node_modules/terser/lib/parse.js new file mode 100644 index 0000000..8bdf282 --- /dev/null +++ b/node_modules/terser/lib/parse.js @@ -0,0 +1,3620 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + Parser based on parse-js (http://marijn.haverbeke.nl/parse-js/). + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +"use strict"; + +import { + characters, + defaults, + makePredicate, + set_annotation, +} from "./utils/index.js"; +import { + AST_Accessor, + AST_Array, + AST_Arrow, + AST_Assign, + AST_Await, + AST_BigInt, + AST_Binary, + AST_BlockStatement, + AST_Break, + AST_Call, + AST_Case, + AST_Catch, + AST_Chain, + AST_ClassExpression, + AST_ClassPrivateProperty, + AST_ClassProperty, + AST_ClassStaticBlock, + AST_ConciseMethod, + AST_PrivateIn, + AST_PrivateGetter, + AST_PrivateMethod, + AST_PrivateSetter, + AST_Conditional, + AST_Const, + AST_Continue, + AST_Debugger, + AST_Default, + AST_DefaultAssign, + AST_DefClass, + AST_Definitions, + AST_DefinitionsLike, + AST_Defun, + AST_Destructuring, + AST_Directive, + AST_Do, + AST_Dot, + AST_DotHash, + AST_EmptyStatement, + AST_Expansion, + AST_Export, + AST_False, + AST_Finally, + AST_For, + AST_ForIn, + AST_ForOf, + AST_Function, + AST_Hole, + AST_If, + AST_Import, + AST_ImportMeta, + AST_IterationStatement, + AST_Label, + AST_LabeledStatement, + AST_LabelRef, + AST_Let, + AST_NameMapping, + AST_New, + AST_NewTarget, + AST_Null, + AST_Number, + AST_Object, + AST_ObjectGetter, + AST_ObjectKeyVal, + AST_ObjectProperty, + AST_ObjectSetter, + AST_PrefixedTemplateString, + AST_PropAccess, + AST_RegExp, + AST_Return, + AST_Sequence, + AST_SimpleStatement, + AST_String, + AST_Sub, + AST_Super, + AST_Switch, + AST_SymbolCatch, + AST_SymbolClass, + AST_SymbolClassProperty, + AST_SymbolConst, + AST_SymbolDeclaration, + AST_SymbolDefClass, + AST_SymbolDefun, + AST_SymbolExport, + AST_SymbolExportForeign, + AST_SymbolFunarg, + AST_SymbolImport, + AST_SymbolImportForeign, + AST_SymbolLambda, + AST_SymbolLet, + AST_SymbolMethod, + AST_SymbolRef, + AST_SymbolVar, + AST_SymbolUsing, + AST_TemplateSegment, + AST_TemplateString, + AST_This, + AST_SymbolPrivateProperty, + AST_Throw, + AST_Token, + AST_Toplevel, + AST_True, + AST_Try, + AST_TryBlock, + AST_UnaryPostfix, + AST_UnaryPrefix, + AST_Using, + AST_UsingDef, + AST_Var, + AST_VarDef, + AST_While, + AST_With, + AST_Yield, + _INLINE, + _NOINLINE, + _PURE, + _KEY, + _MANGLEPROP, +} from "./ast.js"; + +var LATEST_RAW = ""; // Only used for numbers and template strings +var TEMPLATE_RAWS = new Map(); // Raw template strings + +var KEYWORDS = "break case catch class const continue debugger default delete do else export extends finally for function if in instanceof let new return switch throw try typeof var void while with"; +var KEYWORDS_ATOM = "false null true"; +var RESERVED_WORDS = "enum import super this " + KEYWORDS_ATOM + " " + KEYWORDS; +var ALL_RESERVED_WORDS = "implements interface package private protected public static " + RESERVED_WORDS; +var KEYWORDS_BEFORE_EXPRESSION = "return new delete throw else case yield await"; + +KEYWORDS = makePredicate(KEYWORDS); +RESERVED_WORDS = makePredicate(RESERVED_WORDS); +KEYWORDS_BEFORE_EXPRESSION = makePredicate(KEYWORDS_BEFORE_EXPRESSION); +KEYWORDS_ATOM = makePredicate(KEYWORDS_ATOM); +ALL_RESERVED_WORDS = makePredicate(ALL_RESERVED_WORDS); + +var OPERATOR_CHARS = makePredicate(characters("+-*&%=<>!?|~^")); + +var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i; +var RE_OCT_NUMBER = /^0[0-7]+$/; +var RE_ES6_OCT_NUMBER = /^0o[0-7]+$/i; +var RE_BIN_NUMBER = /^0b[01]+$/i; +var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i; +var RE_BIG_INT = /^(0[xob])?[0-9a-f]+n$/i; + +var RE_KEYWORD_RELATIONAL_OPERATORS = /in(?:stanceof)?/y; + +var OPERATORS = makePredicate([ + "in", + "instanceof", + "typeof", + "new", + "void", + "delete", + "++", + "--", + "+", + "-", + "!", + "~", + "&", + "|", + "^", + "*", + "**", + "/", + "%", + ">>", + "<<", + ">>>", + "<", + ">", + "<=", + ">=", + "==", + "===", + "!=", + "!==", + "?", + "=", + "+=", + "-=", + "||=", + "&&=", + "??=", + "/=", + "*=", + "**=", + "%=", + ">>=", + "<<=", + ">>>=", + "|=", + "^=", + "&=", + "&&", + "??", + "||", +]); + +var WHITESPACE_CHARS = makePredicate(characters(" \u00a0\n\r\t\f\u000b\u200b\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000\uFEFF")); + +var NEWLINE_CHARS = makePredicate(characters("\n\r\u2028\u2029")); + +var PUNC_AFTER_EXPRESSION = makePredicate(characters(";]),:")); + +var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,;:")); + +var PUNC_CHARS = makePredicate(characters("[]{}(),;:")); + +/* -----[ Tokenizer ]----- */ + +// surrogate safe regexps adapted from https://github.com/mathiasbynens/unicode-8.0.0/tree/89b412d8a71ecca9ed593d9e9fa073ab64acfebe/Binary_Property +var UNICODE = { + ID_Start: /[$A-Z_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]/, + ID_Continue: /(?:[$0-9A-Z_a-z\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B4\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF])+/, +}; + +function get_full_char(str, pos) { + if (is_surrogate_pair_head(str.charCodeAt(pos))) { + if (is_surrogate_pair_tail(str.charCodeAt(pos + 1))) { + return str.charAt(pos) + str.charAt(pos + 1); + } + } else if (is_surrogate_pair_tail(str.charCodeAt(pos))) { + if (is_surrogate_pair_head(str.charCodeAt(pos - 1))) { + return str.charAt(pos - 1) + str.charAt(pos); + } + } + return str.charAt(pos); +} + +function get_full_char_code(str, pos) { + // https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates + if (is_surrogate_pair_head(str.charCodeAt(pos))) { + return 0x10000 + (str.charCodeAt(pos) - 0xd800 << 10) + str.charCodeAt(pos + 1) - 0xdc00; + } + return str.charCodeAt(pos); +} + +function get_full_char_length(str) { + var surrogates = 0; + + for (var i = 0; i < str.length; i++) { + if (is_surrogate_pair_head(str.charCodeAt(i)) && is_surrogate_pair_tail(str.charCodeAt(i + 1))) { + surrogates++; + i++; + } + } + + return str.length - surrogates; +} + +function from_char_code(code) { + // Based on https://github.com/mathiasbynens/String.fromCodePoint/blob/master/fromcodepoint.js + if (code > 0xFFFF) { + code -= 0x10000; + return (String.fromCharCode((code >> 10) + 0xD800) + + String.fromCharCode((code % 0x400) + 0xDC00)); + } + return String.fromCharCode(code); +} + +function is_surrogate_pair_head(code) { + return code >= 0xd800 && code <= 0xdbff; +} + +function is_surrogate_pair_tail(code) { + return code >= 0xdc00 && code <= 0xdfff; +} + +function is_digit(code) { + return code >= 48 && code <= 57; +} + +function is_identifier_start(ch) { + return UNICODE.ID_Start.test(ch); +} + +function is_identifier_char(ch) { + return UNICODE.ID_Continue.test(ch); +} + +const BASIC_IDENT = /^[a-z_$][a-z0-9_$]*$/i; + +function is_basic_identifier_string(str) { + return BASIC_IDENT.test(str); +} + +function is_identifier_string(str, allow_surrogates) { + if (BASIC_IDENT.test(str)) { + return true; + } + if (!allow_surrogates && /[\ud800-\udfff]/.test(str)) { + return false; + } + var match = UNICODE.ID_Start.exec(str); + if (!match || match.index !== 0) { + return false; + } + + str = str.slice(match[0].length); + if (!str) { + return true; + } + + match = UNICODE.ID_Continue.exec(str); + return !!match && match[0].length === str.length; +} + +function parse_js_number(num, allow_e = true) { + if (!allow_e && num.includes("e")) { + return NaN; + } + if (RE_HEX_NUMBER.test(num)) { + return parseInt(num.substr(2), 16); + } else if (RE_OCT_NUMBER.test(num)) { + return parseInt(num.substr(1), 8); + } else if (RE_ES6_OCT_NUMBER.test(num)) { + return parseInt(num.substr(2), 8); + } else if (RE_BIN_NUMBER.test(num)) { + return parseInt(num.substr(2), 2); + } else if (RE_DEC_NUMBER.test(num)) { + return parseFloat(num); + } else { + var val = parseFloat(num); + if (val == num) return val; + } +} + +class JS_Parse_Error extends Error { + constructor(message, filename, line, col, pos) { + super(); + + this.name = "SyntaxError"; + this.message = message; + this.filename = filename; + this.line = line; + this.col = col; + this.pos = pos; + } +} + +function js_error(message, filename, line, col, pos) { + throw new JS_Parse_Error(message, filename, line, col, pos); +} + +function is_token(token, type, val) { + return token.type == type && (val == null || token.value == val); +} + +var EX_EOF = {}; + +function tokenizer($TEXT, filename, html5_comments, shebang) { + var S = { + text : $TEXT, + filename : filename, + pos : 0, + tokpos : 0, + line : 1, + tokline : 0, + col : 0, + tokcol : 0, + newline_before : false, + regex_allowed : false, + brace_counter : 0, + template_braces : [], + comments_before : [], + directives : {}, + directive_stack : [] + }; + + function peek() { return get_full_char(S.text, S.pos); } + + // Used because parsing ?. involves a lookahead for a digit + function is_option_chain_op() { + const must_be_dot = S.text.charCodeAt(S.pos + 1) === 46; + if (!must_be_dot) return false; + + const cannot_be_digit = S.text.charCodeAt(S.pos + 2); + return cannot_be_digit < 48 || cannot_be_digit > 57; + } + + function next(signal_eof, in_string) { + var ch = get_full_char(S.text, S.pos++); + if (signal_eof && !ch) + throw EX_EOF; + if (NEWLINE_CHARS.has(ch)) { + S.newline_before = S.newline_before || !in_string; + ++S.line; + S.col = 0; + if (ch == "\r" && peek() == "\n") { + // treat a \r\n sequence as a single \n + ++S.pos; + ch = "\n"; + } + } else { + if (ch.length > 1) { + ++S.pos; + ++S.col; + } + ++S.col; + } + return ch; + } + + function forward(i) { + while (i--) next(); + } + + function looking_at(str) { + return S.text.substr(S.pos, str.length) == str; + } + + function find_eol() { + var text = S.text; + for (var i = S.pos, n = S.text.length; i < n; ++i) { + var ch = text[i]; + if (NEWLINE_CHARS.has(ch)) + return i; + } + return -1; + } + + function find(what, signal_eof) { + var pos = S.text.indexOf(what, S.pos); + if (signal_eof && pos == -1) throw EX_EOF; + return pos; + } + + function start_token() { + S.tokline = S.line; + S.tokcol = S.col; + S.tokpos = S.pos; + } + + var prev_was_dot = false; + var previous_token = null; + function token(type, value, is_comment) { + S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX.has(value)) || + (type == "keyword" && KEYWORDS_BEFORE_EXPRESSION.has(value)) || + (type == "punc" && PUNC_BEFORE_EXPRESSION.has(value))) || + (type == "arrow"); + if (type == "punc" && (value == "." || value == "?.")) { + prev_was_dot = true; + } else if (!is_comment) { + prev_was_dot = false; + } + const line = S.tokline; + const col = S.tokcol; + const pos = S.tokpos; + const nlb = S.newline_before; + const file = filename; + let comments_before = []; + let comments_after = []; + + if (!is_comment) { + comments_before = S.comments_before; + comments_after = S.comments_before = []; + } + S.newline_before = false; + const tok = new AST_Token(type, value, line, col, pos, nlb, comments_before, comments_after, file); + + if (!is_comment) previous_token = tok; + return tok; + } + + function skip_whitespace() { + while (WHITESPACE_CHARS.has(peek())) + next(); + } + + function peek_next_token_start_or_newline() { + var pos = S.pos; + for (var in_multiline_comment = false; pos < S.text.length; ) { + var ch = get_full_char(S.text, pos); + if (NEWLINE_CHARS.has(ch)) { + return { char: ch, pos: pos }; + } else if (in_multiline_comment) { + if (ch == "*" && get_full_char(S.text, pos + 1) == "/") { + pos += 2; + in_multiline_comment = false; + } else { + pos++; + } + } else if (!WHITESPACE_CHARS.has(ch)) { + if (ch == "/") { + var next_ch = get_full_char(S.text, pos + 1); + if (next_ch == "/") { + pos = find_eol(); + return { char: get_full_char(S.text, pos), pos: pos }; + } else if (next_ch == "*") { + in_multiline_comment = true; + pos += 2; + continue; + } + } + return { char: ch, pos: pos }; + } else { + pos++; + } + } + return { char: null, pos: pos }; + } + + function ch_starts_binding_identifier(ch, pos) { + if (ch == "\\") { + return true; + } else if (is_identifier_start(ch)) { + RE_KEYWORD_RELATIONAL_OPERATORS.lastIndex = pos; + if (RE_KEYWORD_RELATIONAL_OPERATORS.test(S.text)) { + var after = get_full_char(S.text, RE_KEYWORD_RELATIONAL_OPERATORS.lastIndex); + if (!is_identifier_char(after) && after != "\\") { + // "in" or "instanceof" are keywords, not binding identifiers + return false; + } + } + return true; + } + return false; + } + + function read_while(pred) { + var ret = "", ch, i = 0; + while ((ch = peek()) && pred(ch, i++)) + ret += next(); + return ret; + } + + function parse_error(err) { + js_error(err, filename, S.tokline, S.tokcol, S.tokpos); + } + + function read_num(prefix) { + var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".", is_big_int = false, numeric_separator = false; + var num = read_while(function(ch, i) { + if (is_big_int) return false; + + var code = ch.charCodeAt(0); + switch (code) { + case 95: // _ + return (numeric_separator = true); + case 98: case 66: // bB + return (has_x = true); // Can occur in hex sequence, don't return false yet + case 111: case 79: // oO + case 120: case 88: // xX + return has_x ? false : (has_x = true); + case 101: case 69: // eE + return has_x ? true : has_e ? false : (has_e = after_e = true); + case 45: // - + return after_e || (i == 0 && !prefix); + case 43: // + + return after_e; + case (after_e = false, 46): // . + return (!has_dot && !has_x && !has_e) ? (has_dot = true) : false; + case 110: // n + is_big_int = true; + return true; + } + + return ( + code >= 48 && code <= 57 // 0-9 + || code >= 97 && code <= 102 // a-f + || code >= 65 && code <= 70 // A-F + ); + }); + if (prefix) num = prefix + num; + + LATEST_RAW = num; + + if (RE_OCT_NUMBER.test(num) && next_token.has_directive("use strict")) { + parse_error("Legacy octal literals are not allowed in strict mode"); + } + if (numeric_separator) { + if (num.endsWith("_")) { + parse_error("Numeric separators are not allowed at the end of numeric literals"); + } else if (num.includes("__")) { + parse_error("Only one underscore is allowed as numeric separator"); + } + num = num.replace(/_/g, ""); + } + if (is_big_int) { + const without_n = num.slice(0, -1); + const allow_e = RE_HEX_NUMBER.test(without_n); + const valid = parse_js_number(without_n, allow_e); + if (!has_dot && RE_BIG_INT.test(num) && !isNaN(valid)) + return token("big_int", without_n); + parse_error("Invalid or unexpected token"); + } + var valid = parse_js_number(num); + if (!isNaN(valid)) { + return token("num", valid); + } else { + parse_error("Invalid syntax: " + num); + } + } + + function is_octal(ch) { + return ch >= "0" && ch <= "7"; + } + + function read_escaped_char(in_string, strict_hex, template_string) { + var ch = next(true, in_string); + switch (ch.charCodeAt(0)) { + case 110 : return "\n"; + case 114 : return "\r"; + case 116 : return "\t"; + case 98 : return "\b"; + case 118 : return "\u000b"; // \v + case 102 : return "\f"; + case 120 : return String.fromCharCode(hex_bytes(2, strict_hex)); // \x + case 117 : // \u + if (peek() == "{") { + next(true); + if (peek() === "}") + parse_error("Expecting hex-character between {}"); + while (peek() == "0") next(true); // No significance + var result, length = find("}", true) - S.pos; + // Avoid 32 bit integer overflow (1 << 32 === 1) + // We know first character isn't 0 and thus out of range anyway + if (length > 6 || (result = hex_bytes(length, strict_hex)) > 0x10FFFF) { + parse_error("Unicode reference out of bounds"); + } + next(true); + return from_char_code(result); + } + return String.fromCharCode(hex_bytes(4, strict_hex)); + case 10 : return ""; // newline + case 13 : // \r + if (peek() == "\n") { // DOS newline + next(true, in_string); + return ""; + } + } + if (is_octal(ch)) { + if (template_string && strict_hex) { + const represents_null_character = ch === "0" && !is_octal(peek()); + if (!represents_null_character) { + parse_error("Octal escape sequences are not allowed in template strings"); + } + } + return read_octal_escape_sequence(ch, strict_hex); + } + return ch; + } + + function read_octal_escape_sequence(ch, strict_octal) { + // Read + var p = peek(); + if (p >= "0" && p <= "7") { + ch += next(true); + if (ch[0] <= "3" && (p = peek()) >= "0" && p <= "7") + ch += next(true); + } + + // Parse + if (ch === "0") return "\0"; + if (ch.length > 0 && next_token.has_directive("use strict") && strict_octal) + parse_error("Legacy octal escape sequences are not allowed in strict mode"); + return String.fromCharCode(parseInt(ch, 8)); + } + + function hex_bytes(n, strict_hex) { + var num = 0; + for (; n > 0; --n) { + if (!strict_hex && isNaN(parseInt(peek(), 16))) { + return parseInt(num, 16) || ""; + } + var digit = next(true); + if (isNaN(parseInt(digit, 16))) + parse_error("Invalid hex-character pattern in string"); + num += digit; + } + return parseInt(num, 16); + } + + var read_string = with_eof_error("Unterminated string constant", function() { + const start_pos = S.pos; + var quote = next(), ret = []; + for (;;) { + var ch = next(true, true); + if (ch == "\\") ch = read_escaped_char(true, true); + else if (ch == "\r" || ch == "\n") parse_error("Unterminated string constant"); + else if (ch == quote) break; + ret.push(ch); + } + var tok = token("string", ret.join("")); + LATEST_RAW = S.text.slice(start_pos, S.pos); + tok.quote = quote; + return tok; + }); + + var read_template_characters = with_eof_error("Unterminated template", function(begin) { + if (begin) { + S.template_braces.push(S.brace_counter); + } + var content = "", raw = "", ch, tok; + next(true, true); + while ((ch = next(true, true)) != "`") { + if (ch == "\r") { + if (peek() == "\n") ++S.pos; + ch = "\n"; + } else if (ch == "$" && peek() == "{") { + next(true, true); + S.brace_counter++; + tok = token(begin ? "template_head" : "template_cont", content); + TEMPLATE_RAWS.set(tok, raw); + tok.template_end = false; + return tok; + } + + raw += ch; + if (ch == "\\") { + var tmp = S.pos; + var prev_is_tag = previous_token && (previous_token.type === "name" || previous_token.type === "punc" && (previous_token.value === ")" || previous_token.value === "]")); + ch = read_escaped_char(true, !prev_is_tag, true); + raw += S.text.substr(tmp, S.pos - tmp); + } + + content += ch; + } + S.template_braces.pop(); + tok = token(begin ? "template_head" : "template_cont", content); + TEMPLATE_RAWS.set(tok, raw); + tok.template_end = true; + return tok; + }); + + function skip_line_comment(type) { + var regex_allowed = S.regex_allowed; + var i = find_eol(), ret; + if (i == -1) { + ret = S.text.substr(S.pos); + S.pos = S.text.length; + } else { + ret = S.text.substring(S.pos, i); + S.pos = i; + } + S.col = S.tokcol + (S.pos - S.tokpos); + S.comments_before.push(token(type, ret, true)); + S.regex_allowed = regex_allowed; + return next_token; + } + + var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function() { + var regex_allowed = S.regex_allowed; + var i = find("*/", true); + var text = S.text.substring(S.pos, i).replace(/\r\n|\r|\u2028|\u2029/g, "\n"); + // update stream position + forward(get_full_char_length(text) /* text length doesn't count \r\n as 2 char while S.pos - i does */ + 2); + S.comments_before.push(token("comment2", text, true)); + S.newline_before = S.newline_before || text.includes("\n"); + S.regex_allowed = regex_allowed; + return next_token; + }); + + var read_name = function () { + let start = S.pos, end = start - 1, ch = "c"; + + while ( + (ch = S.text.charAt(++end)) + && (ch >= "a" && ch <= "z" || ch >= "A" && ch <= "Z") + ); + + // 0x7F is very rare in actual code, so we compare it to "~" (0x7E) + if (end > start + 1 && ch && ch !== "\\" && !is_identifier_char(ch) && ch <= "~") { + S.pos += end - start; + S.col += end - start; + return S.text.slice(start, S.pos); + } + + return read_name_hard(); + }; + + var read_name_hard = with_eof_error("Unterminated identifier name", function() { + var name = [], ch, escaped = false; + var read_escaped_identifier_char = function() { + escaped = true; + next(); + if (peek() !== "u") { + parse_error("Expecting UnicodeEscapeSequence -- uXXXX or u{XXXX}"); + } + return read_escaped_char(false, true); + }; + + // Read first character (ID_Start) + if ((ch = peek()) === "\\") { + ch = read_escaped_identifier_char(); + if (!is_identifier_start(ch)) { + parse_error("First identifier char is an invalid identifier char"); + } + } else if (is_identifier_start(ch)) { + next(); + } else { + return ""; + } + + name.push(ch); + + // Read ID_Continue + while ((ch = peek()) != null) { + if ((ch = peek()) === "\\") { + ch = read_escaped_identifier_char(); + if (!is_identifier_char(ch)) { + parse_error("Invalid escaped identifier char"); + } + } else { + if (!is_identifier_char(ch)) { + break; + } + next(); + } + name.push(ch); + } + const name_str = name.join(""); + if (RESERVED_WORDS.has(name_str) && escaped) { + parse_error("Escaped characters are not allowed in keywords"); + } + return name_str; + }); + + var read_regexp = with_eof_error("Unterminated regular expression", function(source) { + var prev_backslash = false, ch, in_class = false; + while ((ch = next(true))) if (NEWLINE_CHARS.has(ch)) { + parse_error("Unexpected line terminator"); + } else if (prev_backslash) { + if (/^[\u0000-\u007F]$/.test(ch)) { + source += "\\" + ch; + } else { + // Remove the useless slash before the escape, but only for characters that won't be added to regexp syntax + source += ch; + } + prev_backslash = false; + } else if (ch == "[") { + in_class = true; + source += ch; + } else if (ch == "]" && in_class) { + in_class = false; + source += ch; + } else if (ch == "/" && !in_class) { + break; + } else if (ch == "\\") { + prev_backslash = true; + } else { + source += ch; + } + const flags = read_name(); + return token("regexp", "/" + source + "/" + flags); + }); + + function read_operator(prefix) { + function grow(op) { + if (!peek()) return op; + var bigger = op + peek(); + if (OPERATORS.has(bigger)) { + next(); + return grow(bigger); + } else { + return op; + } + } + return token("operator", grow(prefix || next())); + } + + function handle_slash() { + next(); + switch (peek()) { + case "/": + next(); + return skip_line_comment("comment1"); + case "*": + next(); + return skip_multiline_comment(); + } + return S.regex_allowed ? read_regexp("") : read_operator("/"); + } + + function handle_eq_sign() { + next(); + if (peek() === ">") { + next(); + return token("arrow", "=>"); + } else { + return read_operator("="); + } + } + + function handle_dot() { + next(); + if (is_digit(peek().charCodeAt(0))) { + return read_num("."); + } + if (peek() === ".") { + next(); // Consume second dot + next(); // Consume third dot + return token("expand", "..."); + } + + return token("punc", "."); + } + + function read_word() { + var word = read_name(); + if (prev_was_dot) return token("name", word); + return KEYWORDS_ATOM.has(word) ? token("atom", word) + : !KEYWORDS.has(word) ? token("name", word) + : OPERATORS.has(word) ? token("operator", word) + : token("keyword", word); + } + + function read_private_word() { + next(); + return token("privatename", read_name()); + } + + function with_eof_error(eof_error, cont) { + return function(x) { + try { + return cont(x); + } catch(ex) { + if (ex === EX_EOF) parse_error(eof_error); + else throw ex; + } + }; + } + + function next_token(force_regexp) { + if (force_regexp != null) + return read_regexp(force_regexp); + if (shebang && S.pos == 0 && looking_at("#!")) { + start_token(); + forward(2); + skip_line_comment("comment5"); + } + for (;;) { + skip_whitespace(); + start_token(); + if (html5_comments) { + if (looking_at("") && S.newline_before) { + forward(3); + skip_line_comment("comment4"); + continue; + } + } + var ch = peek(); + if (!ch) return token("eof"); + var code = ch.charCodeAt(0); + switch (code) { + case 34: case 39: return read_string(); + case 46: return handle_dot(); + case 47: { + var tok = handle_slash(); + if (tok === next_token) continue; + return tok; + } + case 61: return handle_eq_sign(); + case 63: { + if (!is_option_chain_op()) break; // Handled below + + next(); // ? + next(); // . + + return token("punc", "?."); + } + case 96: return read_template_characters(true); + case 123: + S.brace_counter++; + break; + case 125: + S.brace_counter--; + if (S.template_braces.length > 0 + && S.template_braces[S.template_braces.length - 1] === S.brace_counter) + return read_template_characters(false); + break; + } + if (is_digit(code)) return read_num(); + if (PUNC_CHARS.has(ch)) return token("punc", next()); + if (OPERATOR_CHARS.has(ch)) return read_operator(); + if (code == 92 || is_identifier_start(ch)) return read_word(); + if (code == 35) return read_private_word(); + break; + } + parse_error("Unexpected character '" + ch + "'"); + } + + next_token.next = next; + next_token.peek = peek; + + next_token.context = function(nc) { + if (nc) S = nc; + return S; + }; + + next_token.add_directive = function(directive) { + S.directive_stack[S.directive_stack.length - 1].push(directive); + + if (S.directives[directive] === undefined) { + S.directives[directive] = 1; + } else { + S.directives[directive]++; + } + }; + + next_token.push_directives_stack = function() { + S.directive_stack.push([]); + }; + + next_token.pop_directives_stack = function() { + var directives = S.directive_stack[S.directive_stack.length - 1]; + + for (var i = 0; i < directives.length; i++) { + S.directives[directives[i]]--; + } + + S.directive_stack.pop(); + }; + + next_token.has_directive = function(directive) { + return S.directives[directive] > 0; + }; + + next_token.peek_next_token_start_or_newline = peek_next_token_start_or_newline; + next_token.ch_starts_binding_identifier = ch_starts_binding_identifier; + + return next_token; + +} + +/* -----[ Parser (constants) ]----- */ + +var UNARY_PREFIX = makePredicate([ + "typeof", + "void", + "delete", + "--", + "++", + "!", + "~", + "-", + "+" +]); + +var UNARY_POSTFIX = makePredicate([ "--", "++" ]); + +var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "??=", "&&=", "||=", "/=", "*=", "**=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]); + +var LOGICAL_ASSIGNMENT = makePredicate([ "??=", "&&=", "||=" ]); + +var PRECEDENCE = (function(a, ret) { + for (var i = 0; i < a.length; ++i) { + for (const op of a[i]) { + ret[op] = i + 1; + } + } + return ret; +})( + [ + ["||"], + ["??"], + ["&&"], + ["|"], + ["^"], + ["&"], + ["==", "===", "!=", "!=="], + ["<", ">", "<=", ">=", "in", "instanceof"], + [">>", "<<", ">>>"], + ["+", "-"], + ["*", "/", "%"], + ["**"] + ], + {} +); + +var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "big_int", "string", "regexp", "name"]); + +/* -----[ Parser ]----- */ + +function parse($TEXT, options) { + // maps start tokens to count of comments found outside of their parens + // Example: /* I count */ ( /* I don't */ foo() ) + // Useful because comments_before property of call with parens outside + // contains both comments inside and outside these parens. Used to find the + // right #__PURE__ comments for an expression + const outer_comments_before_counts = new WeakMap(); + + options = defaults(options, { + bare_returns : false, + ecma : null, // Legacy + expression : false, + filename : null, + html5_comments : true, + module : false, + shebang : true, + strict : false, + toplevel : null, + }, true); + + var S = { + input : (typeof $TEXT == "string" + ? tokenizer($TEXT, options.filename, + options.html5_comments, options.shebang) + : $TEXT), + token : null, + prev : null, + peeked : null, + in_function : 0, + in_async : -1, + in_generator : -1, + in_directives : true, + in_loop : 0, + labels : [] + }; + + S.token = next(); + + function is(type, value) { + return is_token(S.token, type, value); + } + + function peek() { return S.peeked || (S.peeked = S.input()); } + + function next() { + S.prev = S.token; + + if (!S.peeked) peek(); + S.token = S.peeked; + S.peeked = null; + S.in_directives = S.in_directives && ( + S.token.type == "string" || is("punc", ";") + ); + return S.token; + } + + function prev() { + return S.prev; + } + + function croak(msg, line, col, pos) { + var ctx = S.input.context(); + js_error(msg, + ctx.filename, + line != null ? line : ctx.tokline, + col != null ? col : ctx.tokcol, + pos != null ? pos : ctx.tokpos); + } + + function token_error(token, msg) { + croak(msg, token.line, token.col); + } + + function unexpected(token) { + if (token == null) + token = S.token; + token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")"); + } + + function expect_token(type, val) { + if (is(type, val)) { + return next(); + } + token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»"); + } + + function expect(punc) { return expect_token("punc", punc); } + + function has_newline_before(token) { + return token.nlb || !token.comments_before.every((comment) => !comment.nlb); + } + + function can_insert_semicolon() { + return !options.strict + && (is("eof") || is("punc", "}") || has_newline_before(S.token)); + } + + function is_in_generator() { + return S.in_generator === S.in_function; + } + + function is_in_async() { + return S.in_async === S.in_function; + } + + function can_await() { + return ( + S.in_async === S.in_function + || S.in_function === 0 && S.input.has_directive("use strict") + ); + } + + function semicolon(optional) { + if (is("punc", ";")) next(); + else if (!optional && !can_insert_semicolon()) unexpected(); + } + + function parenthesised() { + expect("("); + var exp = expression(true); + expect(")"); + return exp; + } + + function embed_tokens(parser) { + return function _embed_tokens_wrapper(...args) { + const start = S.token; + const expr = parser(...args); + expr.start = start; + expr.end = prev(); + return expr; + }; + } + + function handle_regexp() { + if (is("operator", "/") || is("operator", "/=")) { + S.peeked = null; + S.token = S.input(S.token.value.substr(1)); // force regexp + } + } + + var statement = embed_tokens(function statement(is_export_default, is_for_body, is_if_body) { + handle_regexp(); + switch (S.token.type) { + case "string": + if (S.in_directives) { + var token = peek(); + if (!LATEST_RAW.includes("\\") + && (is_token(token, "punc", ";") + || is_token(token, "punc", "}") + || has_newline_before(token) + || is_token(token, "eof"))) { + S.input.add_directive(S.token.value); + } else { + S.in_directives = false; + } + } + var dir = S.in_directives, stat = simple_statement(); + return dir && stat.body instanceof AST_String ? new AST_Directive(stat.body) : stat; + case "template_head": + case "num": + case "big_int": + case "regexp": + case "operator": + case "atom": + return simple_statement(); + + case "name": + if (S.token.value == "async" && is_token(peek(), "keyword", "function")) { + next(); + next(); + if (is_for_body) { + croak("functions are not allowed as the body of a loop"); + } + return function_(AST_Defun, false, true, is_export_default); + } + if (S.token.value == "import" && !is_token(peek(), "punc", "(") && !is_token(peek(), "punc", ".")) { + next(); + var node = import_statement(); + semicolon(); + return node; + } + if (S.token.value == "using" && is_token(peek(), "name") && !has_newline_before(peek())) { + next(); + var node = using_(); + semicolon(); + return node; + } + if (S.token.value == "await" && can_await() && is_token(peek(), "name", "using") && !has_newline_before(peek())) { + var next_next = S.input.peek_next_token_start_or_newline(); + if (S.input.ch_starts_binding_identifier(next_next.char, next_next.pos)) { + next(); + // The "using" token will be consumed by the await_using_ function. + var node = await_using_(); + semicolon(); + return node; + } + } + return is_token(peek(), "punc", ":") + ? labeled_statement() + : simple_statement(); + + case "privatename": + if(!S.in_class) + croak("Private field must be used in an enclosing class"); + return simple_statement(); + + case "punc": + switch (S.token.value) { + case "{": + return new AST_BlockStatement({ + start : S.token, + body : block_(), + end : prev() + }); + case "[": + case "(": + return simple_statement(); + case ";": + S.in_directives = false; + next(); + return new AST_EmptyStatement(); + default: + unexpected(); + } + + case "keyword": + switch (S.token.value) { + case "break": + next(); + return break_cont(AST_Break); + + case "continue": + next(); + return break_cont(AST_Continue); + + case "debugger": + next(); + semicolon(); + return new AST_Debugger(); + + case "do": + next(); + var body = in_loop(statement); + expect_token("keyword", "while"); + var condition = parenthesised(); + semicolon(true); + return new AST_Do({ + body : body, + condition : condition + }); + + case "while": + next(); + return new AST_While({ + condition : parenthesised(), + body : in_loop(function() { return statement(false, true); }) + }); + + case "for": + next(); + return for_(); + + case "class": + next(); + if (is_for_body) { + croak("classes are not allowed as the body of a loop"); + } + if (is_if_body) { + croak("classes are not allowed as the body of an if"); + } + return class_(AST_DefClass, is_export_default); + + case "function": + next(); + if (is_for_body) { + croak("functions are not allowed as the body of a loop"); + } + return function_(AST_Defun, false, false, is_export_default); + + case "if": + next(); + return if_(); + + case "return": + if (S.in_function == 0 && !options.bare_returns) + croak("'return' outside of function"); + next(); + var value = null; + if (is("punc", ";")) { + next(); + } else if (!can_insert_semicolon()) { + value = expression(true); + semicolon(); + } + return new AST_Return({ + value: value + }); + + case "switch": + next(); + return new AST_Switch({ + expression : parenthesised(), + body : in_loop(switch_body_) + }); + + case "throw": + next(); + if (has_newline_before(S.token)) + croak("Illegal newline after 'throw'"); + var value = expression(true); + semicolon(); + return new AST_Throw({ + value: value + }); + + case "try": + next(); + return try_(); + + case "var": + next(); + var node = var_(); + semicolon(); + return node; + + case "let": + next(); + var node = let_(); + semicolon(); + return node; + + case "const": + next(); + var node = const_(); + semicolon(); + return node; + + case "with": + if (S.input.has_directive("use strict")) { + croak("Strict mode may not include a with statement"); + } + next(); + return new AST_With({ + expression : parenthesised(), + body : statement() + }); + + case "export": + if (!is_token(peek(), "punc", "(")) { + next(); + var node = export_statement(); + if (is("punc", ";")) semicolon(); + return node; + } + } + } + unexpected(); + }); + + function labeled_statement() { + var label = as_symbol(AST_Label); + if (label.name === "await" && is_in_async()) { + token_error(S.prev, "await cannot be used as label inside async function"); + } + if (S.labels.some((l) => l.name === label.name)) { + // ECMA-262, 12.12: An ECMAScript program is considered + // syntactically incorrect if it contains a + // LabelledStatement that is enclosed by a + // LabelledStatement with the same Identifier as label. + croak("Label " + label.name + " defined twice"); + } + expect(":"); + S.labels.push(label); + var stat = statement(); + S.labels.pop(); + if (!(stat instanceof AST_IterationStatement)) { + // check for `continue` that refers to this label. + // those should be reported as syntax errors. + // https://github.com/mishoo/UglifyJS2/issues/287 + label.references.forEach(function(ref) { + if (ref instanceof AST_Continue) { + ref = ref.label.start; + croak("Continue label `" + label.name + "` refers to non-IterationStatement.", + ref.line, ref.col, ref.pos); + } + }); + } + return new AST_LabeledStatement({ body: stat, label: label }); + } + + function simple_statement(tmp) { + return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) }); + } + + function break_cont(type) { + var label = null, ldef; + if (!can_insert_semicolon()) { + label = as_symbol(AST_LabelRef, true); + } + if (label != null) { + ldef = S.labels.find((l) => l.name === label.name); + if (!ldef) + croak("Undefined label " + label.name); + label.thedef = ldef; + } else if (S.in_loop == 0) + croak(type.TYPE + " not inside a loop or switch"); + semicolon(); + var stat = new type({ label: label }); + if (ldef) ldef.references.push(stat); + return stat; + } + + function for_() { + var for_await_error = "`for await` invalid in this context"; + var await_tok = S.token; + if (await_tok.type == "name" && await_tok.value == "await") { + if (!can_await()) { + token_error(await_tok, for_await_error); + } + next(); + } else { + await_tok = false; + } + expect("("); + var init = null; + if (!is("punc", ";")) { + init = + is("keyword", "var") ? (next(), var_(true)) : + is("keyword", "let") ? (next(), let_(true)) : + is("keyword", "const") ? (next(), const_(true)) : + is("name", "using") && is_token(peek(), "name") && (peek().value != "of" || S.input.peek_next_token_start_or_newline().char == "=") ? (next(), using_(true)) : + is("name", "await") && can_await() && is_token(peek(), "name", "using") ? (next(), await_using_(true)) : + expression(true, true); + var is_in = is("operator", "in"); + var is_of = is("name", "of"); + if (await_tok && !is_of) { + token_error(await_tok, for_await_error); + } + if (is_in || is_of) { + if (init instanceof AST_DefinitionsLike) { + if (init.definitions.length > 1) + token_error(init.start, "Only one variable declaration allowed in for..in loop"); + if (is_in && init instanceof AST_Using) { + token_error(init.start, "Invalid using declaration in for..in loop"); + } + } else if (!(is_assignable(init) || (init = to_destructuring(init)) instanceof AST_Destructuring)) { + token_error(init.start, "Invalid left-hand side in for..in loop"); + } + next(); + if (is_in) { + return for_in(init); + } else { + return for_of(init, !!await_tok); + } + } + } else if (await_tok) { + token_error(await_tok, for_await_error); + } + return regular_for(init); + } + + function regular_for(init) { + expect(";"); + var test = is("punc", ";") ? null : expression(true); + expect(";"); + var step = is("punc", ")") ? null : expression(true); + expect(")"); + return new AST_For({ + init : init, + condition : test, + step : step, + body : in_loop(function() { return statement(false, true); }) + }); + } + + function for_of(init, is_await) { + var lhs = init instanceof AST_DefinitionsLike ? init.definitions[0].name : null; + var obj = expression(true); + expect(")"); + return new AST_ForOf({ + await : is_await, + init : init, + name : lhs, + object : obj, + body : in_loop(function() { return statement(false, true); }) + }); + } + + function for_in(init) { + var obj = expression(true); + expect(")"); + return new AST_ForIn({ + init : init, + object : obj, + body : in_loop(function() { return statement(false, true); }) + }); + } + + var arrow_function = function(start, argnames, is_async) { + if (has_newline_before(S.token)) { + croak("Unexpected newline before arrow (=>)"); + } + + expect_token("arrow", "=>"); + + var body = _function_body(is("punc", "{"), false, is_async); + + return new AST_Arrow({ + start : start, + end : body.end, + async : is_async, + argnames : argnames, + body : body + }); + }; + + var function_ = function(ctor, is_generator, is_async, is_export_default) { + var in_statement = ctor === AST_Defun; + if (is("operator", "*")) { + is_generator = true; + next(); + } + + var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null; + if (in_statement && !name) { + if (is_export_default) { + ctor = AST_Function; + } else { + unexpected(); + } + } + + if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration)) + unexpected(prev()); + + var args = []; + var body = _function_body(true, is_generator, is_async, name, args); + return new ctor({ + start : args.start, + end : body.end, + is_generator: is_generator, + async : is_async, + name : name, + argnames: args, + body : body + }); + }; + + class UsedParametersTracker { + constructor(is_parameter, strict, duplicates_ok = false) { + this.is_parameter = is_parameter; + this.duplicates_ok = duplicates_ok; + this.parameters = new Set(); + this.duplicate = null; + this.default_assignment = false; + this.spread = false; + this.strict_mode = !!strict; + } + add_parameter(token) { + if (this.parameters.has(token.value)) { + if (this.duplicate === null) { + this.duplicate = token; + } + this.check_strict(); + } else { + this.parameters.add(token.value); + if (this.is_parameter) { + switch (token.value) { + case "arguments": + case "eval": + case "yield": + if (this.strict_mode) { + token_error(token, "Unexpected " + token.value + " identifier as parameter inside strict mode"); + } + break; + default: + if (RESERVED_WORDS.has(token.value)) { + unexpected(); + } + } + } + } + } + mark_default_assignment(token) { + if (this.default_assignment === false) { + this.default_assignment = token; + } + } + mark_spread(token) { + if (this.spread === false) { + this.spread = token; + } + } + mark_strict_mode() { + this.strict_mode = true; + } + is_strict() { + return this.default_assignment !== false || this.spread !== false || this.strict_mode; + } + check_strict() { + if (this.is_strict() && this.duplicate !== null && !this.duplicates_ok) { + token_error(this.duplicate, "Parameter " + this.duplicate.value + " was used already"); + } + } + } + + function parameters(params) { + var used_parameters = new UsedParametersTracker(true, S.input.has_directive("use strict")); + + expect("("); + + while (!is("punc", ")")) { + var param = parameter(used_parameters); + params.push(param); + + if (!is("punc", ")")) { + expect(","); + } + + if (param instanceof AST_Expansion) { + break; + } + } + + next(); + } + + function parameter(used_parameters, symbol_type) { + var param; + var expand = false; + if (used_parameters === undefined) { + used_parameters = new UsedParametersTracker(true, S.input.has_directive("use strict")); + } + if (is("expand", "...")) { + expand = S.token; + used_parameters.mark_spread(S.token); + next(); + } + param = binding_element(used_parameters, symbol_type); + + if (is("operator", "=") && expand === false) { + used_parameters.mark_default_assignment(S.token); + next(); + param = new AST_DefaultAssign({ + start: param.start, + left: param, + operator: "=", + right: expression(false), + end: S.token + }); + } + + if (expand !== false) { + if (!is("punc", ")")) { + unexpected(); + } + param = new AST_Expansion({ + start: expand, + expression: param, + end: expand + }); + } + used_parameters.check_strict(); + + return param; + } + + function binding_element(used_parameters, symbol_type) { + var elements = []; + var first = true; + var is_expand = false; + var expand_token; + var first_token = S.token; + if (used_parameters === undefined) { + const strict = S.input.has_directive("use strict"); + const duplicates_ok = symbol_type === AST_SymbolVar; + used_parameters = new UsedParametersTracker(false, strict, duplicates_ok); + } + symbol_type = symbol_type === undefined ? AST_SymbolFunarg : symbol_type; + if (is("punc", "[")) { + next(); + while (!is("punc", "]")) { + if (first) { + first = false; + } else { + expect(","); + } + + if (is("expand", "...")) { + is_expand = true; + expand_token = S.token; + used_parameters.mark_spread(S.token); + next(); + } + if (is("punc")) { + switch (S.token.value) { + case ",": + elements.push(new AST_Hole({ + start: S.token, + end: S.token + })); + continue; + case "]": // Trailing comma after last element + break; + case "[": + case "{": + elements.push(binding_element(used_parameters, symbol_type)); + break; + default: + unexpected(); + } + } else if (is("name")) { + used_parameters.add_parameter(S.token); + elements.push(as_symbol(symbol_type)); + } else { + croak("Invalid function parameter"); + } + if (is("operator", "=") && is_expand === false) { + used_parameters.mark_default_assignment(S.token); + next(); + elements[elements.length - 1] = new AST_DefaultAssign({ + start: elements[elements.length - 1].start, + left: elements[elements.length - 1], + operator: "=", + right: expression(false), + end: S.token + }); + } + if (is_expand) { + if (!is("punc", "]")) { + croak("Rest element must be last element"); + } + elements[elements.length - 1] = new AST_Expansion({ + start: expand_token, + expression: elements[elements.length - 1], + end: expand_token + }); + } + } + expect("]"); + used_parameters.check_strict(); + return new AST_Destructuring({ + start: first_token, + names: elements, + is_array: true, + end: prev() + }); + } else if (is("punc", "{")) { + next(); + while (!is("punc", "}")) { + if (first) { + first = false; + } else { + expect(","); + } + if (is("expand", "...")) { + is_expand = true; + expand_token = S.token; + used_parameters.mark_spread(S.token); + next(); + } + if (is("name") && (is_token(peek(), "punc") || is_token(peek(), "operator")) && [",", "}", "="].includes(peek().value)) { + used_parameters.add_parameter(S.token); + var start = prev(); + var value = as_symbol(symbol_type); + if (is_expand) { + elements.push(new AST_Expansion({ + start: expand_token, + expression: value, + end: value.end, + })); + } else { + elements.push(new AST_ObjectKeyVal({ + start: start, + key: value.name, + value: value, + end: value.end, + })); + } + } else if (is("punc", "}")) { + continue; // Allow trailing hole + } else { + var property_token = S.token; + var property = as_property_name(); + if (property === null) { + unexpected(prev()); + } else if (prev().type === "name" && !is("punc", ":")) { + elements.push(new AST_ObjectKeyVal({ + start: prev(), + key: property, + value: new symbol_type({ + start: prev(), + name: property, + end: prev() + }), + end: prev() + })); + } else { + expect(":"); + elements.push(new AST_ObjectKeyVal({ + start: property_token, + quote: property_token.quote, + key: property, + value: binding_element(used_parameters, symbol_type), + end: prev() + })); + } + } + if (is_expand) { + if (!is("punc", "}")) { + croak("Rest element must be last element"); + } + } else if (is("operator", "=")) { + used_parameters.mark_default_assignment(S.token); + next(); + elements[elements.length - 1].value = new AST_DefaultAssign({ + start: elements[elements.length - 1].value.start, + left: elements[elements.length - 1].value, + operator: "=", + right: expression(false), + end: S.token + }); + } + } + expect("}"); + used_parameters.check_strict(); + return new AST_Destructuring({ + start: first_token, + names: elements, + is_array: false, + end: prev() + }); + } else if (is("name")) { + used_parameters.add_parameter(S.token); + return as_symbol(symbol_type); + } else { + croak("Invalid function parameter"); + } + } + + function params_or_seq_(allow_arrows, maybe_sequence) { + var spread_token; + var invalid_sequence; + var trailing_comma; + var a = []; + expect("("); + while (!is("punc", ")")) { + if (spread_token) unexpected(spread_token); + if (is("expand", "...")) { + spread_token = S.token; + if (maybe_sequence) invalid_sequence = S.token; + next(); + a.push(new AST_Expansion({ + start: prev(), + expression: expression(), + end: S.token, + })); + } else { + a.push(expression()); + } + if (!is("punc", ")")) { + expect(","); + if (is("punc", ")")) { + trailing_comma = prev(); + if (maybe_sequence) invalid_sequence = trailing_comma; + } + } + } + expect(")"); + if (allow_arrows && is("arrow", "=>")) { + if (spread_token && trailing_comma) unexpected(trailing_comma); + } else if (invalid_sequence) { + unexpected(invalid_sequence); + } + return a; + } + + function _function_body(block, generator, is_async, name, args) { + var loop = S.in_loop; + var labels = S.labels; + var current_generator = S.in_generator; + var current_async = S.in_async; + ++S.in_function; + if (generator) + S.in_generator = S.in_function; + if (is_async) + S.in_async = S.in_function; + if (args) parameters(args); + if (block) + S.in_directives = true; + S.in_loop = 0; + S.labels = []; + if (block) { + S.input.push_directives_stack(); + var a = block_(); + if (name) _verify_symbol(name); + if (args) args.forEach(_verify_symbol); + S.input.pop_directives_stack(); + } else { + var a = [new AST_Return({ + start: S.token, + value: expression(false), + end: S.token + })]; + } + --S.in_function; + S.in_loop = loop; + S.labels = labels; + S.in_generator = current_generator; + S.in_async = current_async; + return a; + } + + function _await_expression() { + // Previous token must be "await" and not be interpreted as an identifier + if (!can_await()) { + croak("Unexpected await expression outside async function", + S.prev.line, S.prev.col, S.prev.pos); + } + // the await expression is parsed as a unary expression in Babel + return new AST_Await({ + start: prev(), + end: S.token, + expression : maybe_unary(true), + }); + } + + function _yield_expression() { + var start = S.token; + var star = false; + var has_expression = true; + + // Attempt to get expression or star (and then the mandatory expression) + // behind yield on the same line. + // + // If nothing follows on the same line of the yieldExpression, + // it should default to the value `undefined` for yield to return. + // In that case, the `undefined` stored as `null` in ast. + // + // Note 1: It isn't allowed for yield* to close without an expression + // Note 2: If there is a nlb between yield and star, it is interpret as + // yield * + if ( + can_insert_semicolon() + || is("punc") && PUNC_AFTER_EXPRESSION.has(S.token.value) + || is("template_cont") + ) { + has_expression = false; + } else if (is("operator", "*")) { + star = true; + next(); + } + + return new AST_Yield({ + start : start, + is_star : star, + expression : has_expression ? expression() : null, + end : prev() + }); + } + + function if_() { + var cond = parenthesised(), body = statement(false, false, true), belse = null; + if (is("keyword", "else")) { + next(); + belse = statement(false, false, true); + } + return new AST_If({ + condition : cond, + body : body, + alternative : belse + }); + } + + function block_() { + expect("{"); + var a = []; + while (!is("punc", "}")) { + if (is("eof")) unexpected(); + a.push(statement()); + } + next(); + return a; + } + + function switch_body_() { + expect("{"); + var a = [], cur = null, branch = null, tmp; + while (!is("punc", "}")) { + if (is("eof")) unexpected(); + if (is("keyword", "case")) { + if (branch) branch.end = prev(); + cur = []; + branch = new AST_Case({ + start : (tmp = S.token, next(), tmp), + expression : expression(true), + body : cur + }); + a.push(branch); + expect(":"); + } else if (is("keyword", "default")) { + if (branch) branch.end = prev(); + cur = []; + branch = new AST_Default({ + start : (tmp = S.token, next(), expect(":"), tmp), + body : cur + }); + a.push(branch); + } else { + if (!cur) unexpected(); + cur.push(statement()); + } + } + if (branch) branch.end = prev(); + next(); + return a; + } + + function try_() { + var body, bcatch = null, bfinally = null; + body = new AST_TryBlock({ + start : S.token, + body : block_(), + end : prev(), + }); + if (is("keyword", "catch")) { + var start = S.token; + next(); + if (is("punc", "{")) { + var name = null; + } else { + expect("("); + var name = parameter(undefined, AST_SymbolCatch); + expect(")"); + } + bcatch = new AST_Catch({ + start : start, + argname : name, + body : block_(), + end : prev() + }); + } + if (is("keyword", "finally")) { + var start = S.token; + next(); + bfinally = new AST_Finally({ + start : start, + body : block_(), + end : prev() + }); + } + if (!bcatch && !bfinally) + croak("Missing catch/finally blocks"); + return new AST_Try({ + body : body, + bcatch : bcatch, + bfinally : bfinally + }); + } + + /** + * var + * vardef1 = 2, + * vardef2 = 3; + */ + function vardefs(no_in, kind) { + var var_defs = []; + var def; + for (;;) { + var sym_type = + kind === "var" ? AST_SymbolVar : + kind === "const" ? AST_SymbolConst : + kind === "let" ? AST_SymbolLet : + kind === "using" ? AST_SymbolUsing : + kind === "await using" ? AST_SymbolUsing : null; + var def_type = kind === "using" || kind === "await using" ? AST_UsingDef : AST_VarDef; + // var { a } = b + if (is("punc", "{") || is("punc", "[")) { + def = new def_type({ + start: S.token, + name: binding_element(undefined, sym_type), + value: is("operator", "=") ? (expect_token("operator", "="), expression(false, no_in)) : null, + end: prev() + }); + } else { + def = new def_type({ + start : S.token, + name : as_symbol(sym_type), + value : is("operator", "=") + ? (next(), expression(false, no_in)) + : !no_in && (kind === "const" || kind === "using" || kind === "await using") + ? croak("Missing initializer in " + kind + " declaration") : null, + end : prev() + }); + if (def.name.name == "import") croak("Unexpected token: import"); + } + var_defs.push(def); + if (!is("punc", ",")) + break; + next(); + } + return var_defs; + } + + var var_ = function(no_in) { + return new AST_Var({ + start : prev(), + definitions : vardefs(no_in, "var"), + end : prev() + }); + }; + + var let_ = function(no_in) { + return new AST_Let({ + start : prev(), + definitions : vardefs(no_in, "let"), + end : prev() + }); + }; + + var const_ = function(no_in) { + return new AST_Const({ + start : prev(), + definitions : vardefs(no_in, "const"), + end : prev() + }); + }; + + var using_ = function(no_in) { + return new AST_Using({ + start : prev(), + await : false, + definitions : vardefs(no_in, "using"), + end : prev() + }); + }; + + var await_using_ = function(no_in) { + // Assumption: When await_using_ is called, only the `await` token has been consumed. + return new AST_Using({ + start : prev(), + await : true, + definitions : (next(), vardefs(no_in, "await using")), + end : prev() + }); + }; + + var new_ = function(allow_calls) { + var start = S.token; + expect_token("operator", "new"); + if (is("punc", ".")) { + next(); + expect_token("name", "target"); + return subscripts(new AST_NewTarget({ + start : start, + end : prev() + }), allow_calls); + } + var newexp = expr_atom(false), args; + if (is("punc", "(")) { + next(); + args = expr_list(")", true); + } else { + args = []; + } + var call = new AST_New({ + start : start, + expression : newexp, + args : args, + end : prev() + }); + annotate(call); + return subscripts(call, allow_calls); + }; + + function as_atom_node() { + var tok = S.token, ret; + switch (tok.type) { + case "name": + ret = _make_symbol(AST_SymbolRef); + break; + case "num": + ret = new AST_Number({ + start: tok, + end: tok, + value: tok.value, + raw: LATEST_RAW + }); + break; + case "big_int": + ret = new AST_BigInt({ + start: tok, + end: tok, + value: tok.value, + raw: LATEST_RAW, + }); + break; + case "string": + ret = new AST_String({ + start : tok, + end : tok, + value : tok.value, + quote : tok.quote + }); + annotate(ret); + break; + case "regexp": + const [_, source, flags] = tok.value.match(/^\/(.*)\/(\w*)$/); + + ret = new AST_RegExp({ start: tok, end: tok, value: { source, flags } }); + break; + case "atom": + switch (tok.value) { + case "false": + ret = new AST_False({ start: tok, end: tok }); + break; + case "true": + ret = new AST_True({ start: tok, end: tok }); + break; + case "null": + ret = new AST_Null({ start: tok, end: tok }); + break; + } + break; + } + next(); + return ret; + } + + function to_fun_args(ex, default_seen_above) { + var insert_default = function(ex, default_value) { + if (default_value) { + return new AST_DefaultAssign({ + start: ex.start, + left: ex, + operator: "=", + right: default_value, + end: default_value.end + }); + } + return ex; + }; + if (ex instanceof AST_Object) { + return insert_default(new AST_Destructuring({ + start: ex.start, + end: ex.end, + is_array: false, + names: ex.properties.map(prop => to_fun_args(prop)) + }), default_seen_above); + } else if (ex instanceof AST_ObjectKeyVal) { + ex.value = to_fun_args(ex.value); + return insert_default(ex, default_seen_above); + } else if (ex instanceof AST_Hole) { + return ex; + } else if (ex instanceof AST_Destructuring) { + ex.names = ex.names.map(name => to_fun_args(name)); + return insert_default(ex, default_seen_above); + } else if (ex instanceof AST_SymbolRef) { + return insert_default(new AST_SymbolFunarg({ + name: ex.name, + start: ex.start, + end: ex.end + }), default_seen_above); + } else if (ex instanceof AST_Expansion) { + ex.expression = to_fun_args(ex.expression); + return insert_default(ex, default_seen_above); + } else if (ex instanceof AST_Array) { + return insert_default(new AST_Destructuring({ + start: ex.start, + end: ex.end, + is_array: true, + names: ex.elements.map(elm => to_fun_args(elm)) + }), default_seen_above); + } else if (ex instanceof AST_Assign) { + return insert_default(to_fun_args(ex.left, ex.right), default_seen_above); + } else if (ex instanceof AST_DefaultAssign) { + ex.left = to_fun_args(ex.left); + return ex; + } else { + croak("Invalid function parameter", ex.start.line, ex.start.col); + } + } + + var expr_atom = function(allow_calls, allow_arrows) { + if (is("operator", "new")) { + return new_(allow_calls); + } + if (is("name", "import") && is_token(peek(), "punc", ".")) { + return import_meta(allow_calls); + } + var start = S.token; + var peeked; + var async = is("name", "async") + && (peeked = peek()).value != "[" + && peeked.type != "arrow" + && as_atom_node(); + if (is("punc")) { + switch (S.token.value) { + case "(": + if (async && !allow_calls) break; + var exprs = params_or_seq_(allow_arrows, !async); + if (allow_arrows && is("arrow", "=>")) { + return arrow_function(start, exprs.map(e => to_fun_args(e)), !!async); + } + var ex = async ? new AST_Call({ + expression: async, + args: exprs + }) : to_expr_or_sequence(start, exprs); + if (ex.start) { + const outer_comments_before = start.comments_before.length; + outer_comments_before_counts.set(start, outer_comments_before); + ex.start.comments_before.unshift(...start.comments_before); + start.comments_before = ex.start.comments_before; + if (outer_comments_before == 0 && start.comments_before.length > 0) { + var comment = start.comments_before[0]; + if (!comment.nlb) { + comment.nlb = start.nlb; + start.nlb = false; + } + } + start.comments_after = ex.start.comments_after; + } + ex.start = start; + var end = prev(); + if (ex.end) { + end.comments_before = ex.end.comments_before; + ex.end.comments_after.push(...end.comments_after); + end.comments_after = ex.end.comments_after; + } + ex.end = end; + if (ex instanceof AST_Call) annotate(ex); + return subscripts(ex, allow_calls); + case "[": + return subscripts(array_(), allow_calls); + case "{": + return subscripts(object_or_destructuring_(), allow_calls); + } + if (!async) unexpected(); + } + if (allow_arrows && is("name") && is_token(peek(), "arrow")) { + var param = new AST_SymbolFunarg({ + name: S.token.value, + start: start, + end: start, + }); + next(); + return arrow_function(start, [param], !!async); + } + if (is("keyword", "function")) { + next(); + var func = function_(AST_Function, false, !!async); + func.start = start; + func.end = prev(); + return subscripts(func, allow_calls); + } + if (async) return subscripts(async, allow_calls); + if (is("keyword", "class")) { + next(); + var cls = class_(AST_ClassExpression); + cls.start = start; + cls.end = prev(); + return subscripts(cls, allow_calls); + } + if (is("template_head")) { + return subscripts(template_string(), allow_calls); + } + if (ATOMIC_START_TOKEN.has(S.token.type)) { + return subscripts(as_atom_node(), allow_calls); + } + unexpected(); + }; + + function template_string() { + var segments = [], start = S.token; + + segments.push(new AST_TemplateSegment({ + start: S.token, + raw: TEMPLATE_RAWS.get(S.token), + value: S.token.value, + end: S.token + })); + + while (!S.token.template_end) { + next(); + handle_regexp(); + segments.push(expression(true)); + + segments.push(new AST_TemplateSegment({ + start: S.token, + raw: TEMPLATE_RAWS.get(S.token), + value: S.token.value, + end: S.token + })); + } + next(); + + return new AST_TemplateString({ + start: start, + segments: segments, + end: S.token + }); + } + + function expr_list(closing, allow_trailing_comma, allow_empty) { + var first = true, a = []; + while (!is("punc", closing)) { + if (first) first = false; else expect(","); + if (allow_trailing_comma && is("punc", closing)) break; + if (is("punc", ",") && allow_empty) { + a.push(new AST_Hole({ start: S.token, end: S.token })); + } else if (is("expand", "...")) { + next(); + a.push(new AST_Expansion({start: prev(), expression: expression(),end: S.token})); + } else { + a.push(expression(false)); + } + } + next(); + return a; + } + + var array_ = embed_tokens(function() { + expect("["); + return new AST_Array({ + elements: expr_list("]", !options.strict, true) + }); + }); + + var create_accessor = embed_tokens((is_generator, is_async) => { + return function_(AST_Accessor, is_generator, is_async); + }); + + var object_or_destructuring_ = embed_tokens(function object_or_destructuring_() { + var start = S.token, first = true, a = []; + expect("{"); + while (!is("punc", "}")) { + if (first) first = false; else expect(","); + if (!options.strict && is("punc", "}")) + // allow trailing comma + break; + + start = S.token; + if (start.type == "expand") { + next(); + a.push(new AST_Expansion({ + start: start, + expression: expression(false), + end: prev(), + })); + continue; + } + if(is("privatename")) { + croak("private fields are not allowed in an object"); + } + var name = as_property_name(); + var value; + + // Check property and fetch value + if (!is("punc", ":")) { + var concise = object_or_class_property(name, start); + if (concise) { + a.push(concise); + continue; + } + + value = new AST_SymbolRef({ + start: prev(), + name: name, + end: prev() + }); + } else if (name === null) { + unexpected(prev()); + } else { + next(); // `:` - see first condition + value = expression(false); + } + + // Check for default value and alter value accordingly if necessary + if (is("operator", "=")) { + next(); + value = new AST_Assign({ + start: start, + left: value, + operator: "=", + right: expression(false), + logical: false, + end: prev() + }); + } + + // Create property + const kv = new AST_ObjectKeyVal({ + start: start, + quote: start.quote, + key: name, + value: value, + end: prev() + }); + a.push(annotate(kv)); + } + next(); + return new AST_Object({ properties: a }); + }); + + function class_(KindOfClass, is_export_default) { + var start, method, class_name, extends_, properties = []; + + S.input.push_directives_stack(); // Push directive stack, but not scope stack + S.input.add_directive("use strict"); + + if (S.token.type == "name" && S.token.value != "extends") { + class_name = as_symbol(KindOfClass === AST_DefClass ? AST_SymbolDefClass : AST_SymbolClass); + } + + if (KindOfClass === AST_DefClass && !class_name) { + if (is_export_default) { + KindOfClass = AST_ClassExpression; + } else { + unexpected(); + } + } + + if (S.token.value == "extends") { + next(); + extends_ = expression(true); + } + + expect("{"); + // mark in class feild, + const save_in_class = S.in_class; + S.in_class = true; + while (is("punc", ";")) { next(); } // Leading semicolons are okay in class bodies. + while (!is("punc", "}")) { + start = S.token; + method = object_or_class_property(as_property_name(), start, true); + if (!method) { unexpected(); } + properties.push(method); + while (is("punc", ";")) { next(); } + } + // mark in class feild, + S.in_class = save_in_class; + + S.input.pop_directives_stack(); + + next(); + + return new KindOfClass({ + start: start, + name: class_name, + extends: extends_, + properties: properties, + end: prev(), + }); + } + + function object_or_class_property(name, start, is_class) { + const get_symbol_ast = (name, SymbolClass) => { + if (typeof name === "string") { + return new SymbolClass({ start, name, end: prev() }); + } else if (name === null) { + unexpected(); + } + return name; + }; + + var is_private = prev().type === "privatename"; + const is_not_method_start = () => + !is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("punc", ";") && !is("operator", "=") && !is_private; + + var is_async = false; + var is_static = false; + var is_generator = false; + var accessor_type = null; + + if (is_class && name === "static" && is_not_method_start()) { + const static_block = class_static_block(); + if (static_block != null) { + return static_block; + } + is_static = true; + name = as_property_name(); + } + if (name === "async" && is_not_method_start()) { + is_async = true; + name = as_property_name(); + } + if (prev().type === "operator" && prev().value === "*") { + is_generator = true; + name = as_property_name(); + } + if ((name === "get" || name === "set") && is_not_method_start()) { + accessor_type = name; + name = as_property_name(); + } + if (!is_private && prev().type === "privatename") { + is_private = true; + } + + const property_token = prev(); + + if (accessor_type != null) { + if (!is_private) { + const AccessorClass = accessor_type === "get" + ? AST_ObjectGetter + : AST_ObjectSetter; + + name = get_symbol_ast(name, AST_SymbolMethod); + return annotate(new AccessorClass({ + start, + static: is_static, + key: name, + quote: name instanceof AST_SymbolMethod ? property_token.quote : undefined, + value: create_accessor(), + end: prev() + })); + } else { + const AccessorClass = accessor_type === "get" + ? AST_PrivateGetter + : AST_PrivateSetter; + + return annotate(new AccessorClass({ + start, + static: is_static, + key: get_symbol_ast(name, AST_SymbolMethod), + value: create_accessor(), + end: prev(), + })); + } + } + + if (is("punc", "(")) { + name = get_symbol_ast(name, AST_SymbolMethod); + const AST_MethodVariant = is_private + ? AST_PrivateMethod + : AST_ConciseMethod; + var node = new AST_MethodVariant({ + start : start, + static : is_static, + key : name, + quote : name instanceof AST_SymbolMethod ? + property_token.quote : undefined, + value : create_accessor(is_generator, is_async), + end : prev() + }); + return annotate(node); + } + + if (is_class) { + const AST_SymbolVariant = is_private + ? AST_SymbolPrivateProperty + : AST_SymbolClassProperty; + const AST_ClassPropertyVariant = is_private + ? AST_ClassPrivateProperty + : AST_ClassProperty; + + const key = get_symbol_ast(name, AST_SymbolVariant); + const quote = key instanceof AST_SymbolClassProperty + ? property_token.quote + : undefined; + if (is("operator", "=")) { + next(); + return annotate( + new AST_ClassPropertyVariant({ + start, + static: is_static, + quote, + key, + value: expression(false), + end: prev() + }) + ); + } else if ( + is("name") + || is("privatename") + || is("punc", "[") + || is("operator", "*") + || is("punc", ";") + || is("punc", "}") + || is("string") + || is("num") + || is("big_int") + ) { + return annotate( + new AST_ClassPropertyVariant({ + start, + static: is_static, + quote, + key, + end: prev() + }) + ); + } + } + } + + function class_static_block() { + if (!is("punc", "{")) { + return null; + } + + const start = S.token; + const body = []; + + next(); + + while (!is("punc", "}")) { + body.push(statement()); + } + + next(); + + return new AST_ClassStaticBlock({ start, body, end: prev() }); + } + + function maybe_import_attributes() { + if ( + (is("keyword", "with") || is("name", "assert")) + && !has_newline_before(S.token) + ) { + next(); + return object_or_destructuring_(); + } + return null; + } + + function import_statement() { + var start = prev(); + + var imported_name; + var imported_names; + if (is("name")) { + imported_name = as_symbol(AST_SymbolImport); + } + + if (is("punc", ",")) { + next(); + } + + imported_names = map_names(true); + + if (imported_names || imported_name) { + expect_token("name", "from"); + } + var mod_str = S.token; + if (mod_str.type !== "string") { + unexpected(); + } + next(); + + const attributes = maybe_import_attributes(); + + return new AST_Import({ + start, + imported_name, + imported_names, + module_name: new AST_String({ + start: mod_str, + value: mod_str.value, + quote: mod_str.quote, + end: mod_str, + }), + attributes, + end: S.token, + }); + } + + function import_meta(allow_calls) { + var start = S.token; + expect_token("name", "import"); + expect_token("punc", "."); + expect_token("name", "meta"); + return subscripts(new AST_ImportMeta({ + start: start, + end: prev() + }), allow_calls); + } + + function map_name(is_import) { + function make_symbol(type, quote) { + return new type({ + name: as_property_name(), + quote: quote || undefined, + start: prev(), + end: prev() + }); + } + + var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign; + var type = is_import ? AST_SymbolImport : AST_SymbolExport; + var start = S.token; + var foreign_name; + var name; + + if (is_import) { + foreign_name = make_symbol(foreign_type, start.quote); + } else { + name = make_symbol(type, start.quote); + } + if (is("name", "as")) { + next(); // The "as" word + if (is_import) { + name = make_symbol(type); + } else { + foreign_name = make_symbol(foreign_type, S.token.quote); + } + } else { + if (is_import) { + name = new type(foreign_name); + } else { + foreign_name = new foreign_type(name); + } + } + + return new AST_NameMapping({ + start: start, + foreign_name: foreign_name, + name: name, + end: prev(), + }); + } + + function map_nameAsterisk(is_import, import_or_export_foreign_name) { + var foreign_type = is_import ? AST_SymbolImportForeign : AST_SymbolExportForeign; + var type = is_import ? AST_SymbolImport : AST_SymbolExport; + var start = S.token; + var name, foreign_name; + var end = prev(); + + if (is_import) { + name = import_or_export_foreign_name; + } else { + foreign_name = import_or_export_foreign_name; + } + + name = name || new type({ + start: start, + name: "*", + end: end, + }); + + foreign_name = foreign_name || new foreign_type({ + start: start, + name: "*", + end: end, + }); + + return new AST_NameMapping({ + start: start, + foreign_name: foreign_name, + name: name, + end: end, + }); + } + + function map_names(is_import) { + var names; + if (is("punc", "{")) { + next(); + names = []; + while (!is("punc", "}")) { + names.push(map_name(is_import)); + if (is("punc", ",")) { + next(); + } + } + next(); + } else if (is("operator", "*")) { + var name; + next(); + if (is("name", "as")) { + next(); // The "as" word + name = is_import ? as_symbol(AST_SymbolImport) : as_symbol_or_string(AST_SymbolExportForeign); + } + names = [map_nameAsterisk(is_import, name)]; + } + return names; + } + + function export_statement() { + var start = S.token; + var is_default; + var exported_names; + + if (is("keyword", "default")) { + is_default = true; + next(); + } else if (exported_names = map_names(false)) { + if (is("name", "from")) { + next(); + + var mod_str = S.token; + if (mod_str.type !== "string") { + unexpected(); + } + next(); + + const attributes = maybe_import_attributes(); + + return new AST_Export({ + start: start, + is_default: is_default, + exported_names: exported_names, + module_name: new AST_String({ + start: mod_str, + value: mod_str.value, + quote: mod_str.quote, + end: mod_str, + }), + end: prev(), + attributes + }); + } else { + return new AST_Export({ + start: start, + is_default: is_default, + exported_names: exported_names, + end: prev(), + }); + } + } + + var node; + var exported_value; + var exported_definition; + if (is("punc", "{") + || is_default + && (is("keyword", "class") || is("keyword", "function")) + && is_token(peek(), "punc")) { + exported_value = expression(false); + semicolon(); + } else if ((node = statement(is_default)) instanceof AST_Definitions && is_default) { + unexpected(node.start); + } else if ( + node instanceof AST_Definitions + || node instanceof AST_Defun + || node instanceof AST_DefClass + ) { + exported_definition = node; + } else if ( + node instanceof AST_ClassExpression + || node instanceof AST_Function + ) { + exported_value = node; + } else if (node instanceof AST_SimpleStatement) { + exported_value = node.body; + } else { + unexpected(node.start); + } + + return new AST_Export({ + start: start, + is_default: is_default, + exported_value: exported_value, + exported_definition: exported_definition, + end: prev(), + attributes: null + }); + } + + function as_property_name() { + var tmp = S.token; + switch (tmp.type) { + case "punc": + if (tmp.value === "[") { + next(); + var ex = expression(false); + expect("]"); + return ex; + } else unexpected(tmp); + case "operator": + if (tmp.value === "*") { + next(); + return null; + } + if (!["delete", "in", "instanceof", "new", "typeof", "void"].includes(tmp.value)) { + unexpected(tmp); + } + /* falls through */ + case "name": + case "privatename": + case "string": + case "keyword": + case "atom": + next(); + return tmp.value; + case "num": + case "big_int": + next(); + return "" + tmp.value; + default: + unexpected(tmp); + } + } + + function as_name() { + var tmp = S.token; + if (tmp.type != "name" && tmp.type != "privatename") unexpected(); + next(); + return tmp.value; + } + + function _make_symbol(type) { + var name = S.token.value; + return new (name == "this" ? AST_This : + name == "super" ? AST_Super : + type)({ + name : String(name), + start : S.token, + end : S.token + }); + } + + function _verify_symbol(sym) { + var name = sym.name; + if (is_in_generator() && name == "yield") { + token_error(sym.start, "Yield cannot be used as identifier inside generators"); + } + if (S.input.has_directive("use strict")) { + if (name == "yield") { + token_error(sym.start, "Unexpected yield identifier inside strict mode"); + } + if (sym instanceof AST_SymbolDeclaration && (name == "arguments" || name == "eval")) { + token_error(sym.start, "Unexpected " + name + " in strict mode"); + } + } + } + + function as_symbol(type, noerror) { + if (!is("name")) { + if (!noerror) croak("Name expected"); + return null; + } + var sym = _make_symbol(type); + _verify_symbol(sym); + next(); + return sym; + } + + function as_symbol_or_string(type) { + if (!is("name")) { + if (!is("string")) { + croak("Name or string expected"); + } + var tok = S.token; + var ret = new type({ + start : tok, + end : tok, + name : tok.value, + quote : tok.quote + }); + next(); + return ret; + } + var sym = _make_symbol(type); + _verify_symbol(sym); + next(); + return sym; + } + + // Annotate AST_Call, AST_Lambda or AST_New with the special comments + function annotate(node, before_token = node.start) { + var comments = before_token.comments_before; + const comments_outside_parens = outer_comments_before_counts.get(before_token); + var i = comments_outside_parens != null ? comments_outside_parens : comments.length; + while (--i >= 0) { + var comment = comments[i]; + if (/[@#]__/.test(comment.value)) { + if (/[@#]__PURE__/.test(comment.value)) { + set_annotation(node, _PURE); + break; + } + if (/[@#]__INLINE__/.test(comment.value)) { + set_annotation(node, _INLINE); + break; + } + if (/[@#]__NOINLINE__/.test(comment.value)) { + set_annotation(node, _NOINLINE); + break; + } + if (/[@#]__KEY__/.test(comment.value)) { + set_annotation(node, _KEY); + break; + } + if (/[@#]__MANGLE_PROP__/.test(comment.value)) { + set_annotation(node, _MANGLEPROP); + break; + } + } + } + return node; + } + + var subscripts = function(expr, allow_calls, is_chain) { + var start = expr.start; + if (is("punc", ".")) { + next(); + if(is("privatename") && !S.in_class) + croak("Private field must be used in an enclosing class"); + const AST_DotVariant = is("privatename") ? AST_DotHash : AST_Dot; + return annotate(subscripts(new AST_DotVariant({ + start : start, + expression : expr, + optional : false, + property : as_name(), + end : prev() + }), allow_calls, is_chain)); + } + if (is("punc", "[")) { + next(); + var prop = expression(true); + expect("]"); + return annotate(subscripts(new AST_Sub({ + start : start, + expression : expr, + optional : false, + property : prop, + end : prev() + }), allow_calls, is_chain)); + } + if (allow_calls && is("punc", "(")) { + next(); + var call = new AST_Call({ + start : start, + expression : expr, + optional : false, + args : call_args(), + end : prev() + }); + annotate(call); + return subscripts(call, true, is_chain); + } + + // Optional chain + if (is("punc", "?.")) { + next(); + + let chain_contents; + + if (allow_calls && is("punc", "(")) { + next(); + + const call = new AST_Call({ + start, + optional: true, + expression: expr, + args: call_args(), + end: prev() + }); + annotate(call); + + chain_contents = subscripts(call, true, true); + } else if (is("name") || is("privatename")) { + if(is("privatename") && !S.in_class) + croak("Private field must be used in an enclosing class"); + const AST_DotVariant = is("privatename") ? AST_DotHash : AST_Dot; + chain_contents = annotate(subscripts(new AST_DotVariant({ + start, + expression: expr, + optional: true, + property: as_name(), + end: prev() + }), allow_calls, true)); + } else if (is("punc", "[")) { + next(); + const property = expression(true); + expect("]"); + chain_contents = annotate(subscripts(new AST_Sub({ + start, + expression: expr, + optional: true, + property, + end: prev() + }), allow_calls, true)); + } + + if (!chain_contents) unexpected(); + + if (chain_contents instanceof AST_Chain) return chain_contents; + + return new AST_Chain({ + start, + expression: chain_contents, + end: prev() + }); + } + + if (is("template_head")) { + if (is_chain) { + // a?.b`c` is a syntax error + unexpected(); + } + + return subscripts(new AST_PrefixedTemplateString({ + start: start, + prefix: expr, + template_string: template_string(), + end: prev() + }), allow_calls); + } + return expr; + }; + + function call_args() { + var args = []; + while (!is("punc", ")")) { + if (is("expand", "...")) { + next(); + args.push(new AST_Expansion({ + start: prev(), + expression: expression(false), + end: prev() + })); + } else { + args.push(expression(false)); + } + if (!is("punc", ")")) { + expect(","); + } + } + next(); + return args; + } + + var maybe_unary = function(allow_calls, allow_arrows) { + var start = S.token; + if (start.type == "name" && start.value == "await" && can_await()) { + next(); + return _await_expression(); + } + if (is("operator") && UNARY_PREFIX.has(start.value)) { + next(); + handle_regexp(); + var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls)); + ex.start = start; + ex.end = prev(); + return ex; + } + var val = expr_atom(allow_calls, allow_arrows); + while (is("operator") && UNARY_POSTFIX.has(S.token.value) && !has_newline_before(S.token)) { + if (val instanceof AST_Arrow) unexpected(); + val = make_unary(AST_UnaryPostfix, S.token, val); + val.start = start; + val.end = S.token; + next(); + } + return val; + }; + + function make_unary(ctor, token, expr) { + var op = token.value; + switch (op) { + case "++": + case "--": + if (!is_assignable(expr)) + croak("Invalid use of " + op + " operator", token.line, token.col, token.pos); + break; + case "delete": + if (expr instanceof AST_SymbolRef && S.input.has_directive("use strict")) + croak("Calling delete on expression not allowed in strict mode", expr.start.line, expr.start.col, expr.start.pos); + break; + } + return new ctor({ operator: op, expression: expr }); + } + + var expr_op = function(left, min_prec, no_in) { + var op = is("operator") ? S.token.value : null; + if (op == "in" && no_in) op = null; + if (op == "**" && left instanceof AST_UnaryPrefix + /* unary token in front not allowed - parenthesis required */ + && !is_token(left.start, "punc", "(") + && left.operator !== "--" && left.operator !== "++") + unexpected(left.start); + var prec = op != null ? PRECEDENCE[op] : null; + if (prec != null && (prec > min_prec || (op === "**" && min_prec === prec))) { + next(); + var right = expr_ops(no_in, prec, true); + return expr_op(new AST_Binary({ + start : left.start, + left : left, + operator : op, + right : right, + end : right.end + }), min_prec, no_in); + } + return left; + }; + + function expr_ops(no_in, min_prec, allow_calls, allow_arrows) { + // maybe_unary won't return us a AST_SymbolPrivateProperty + if (!no_in && min_prec < PRECEDENCE["in"] && is("privatename")) { + if(!S.in_class) { + croak("Private field must be used in an enclosing class"); + } + + const start = S.token; + const key = new AST_SymbolPrivateProperty({ + start, + name: start.value, + end: start + }); + next(); + expect_token("operator", "in"); + + const private_in = new AST_PrivateIn({ + start, + key, + value: expr_ops(no_in, PRECEDENCE["in"], true), + end: prev() + }); + + return expr_op(private_in, 0, no_in); + } else { + return expr_op(maybe_unary(allow_calls, allow_arrows), min_prec, no_in); + } + } + + var maybe_conditional = function(no_in) { + var start = S.token; + var expr = expr_ops(no_in, 0, true, true); + if (is("operator", "?")) { + next(); + var yes = expression(false); + expect(":"); + return new AST_Conditional({ + start : start, + condition : expr, + consequent : yes, + alternative : expression(false, no_in), + end : prev() + }); + } + return expr; + }; + + function is_assignable(expr) { + return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef; + } + + function to_destructuring(node) { + if (node instanceof AST_Object) { + node = new AST_Destructuring({ + start: node.start, + names: node.properties.map(to_destructuring), + is_array: false, + end: node.end + }); + } else if (node instanceof AST_Array) { + var names = []; + + for (var i = 0; i < node.elements.length; i++) { + // Only allow expansion as last element + if (node.elements[i] instanceof AST_Expansion) { + if (i + 1 !== node.elements.length) { + token_error(node.elements[i].start, "Spread must the be last element in destructuring array"); + } + node.elements[i].expression = to_destructuring(node.elements[i].expression); + } + + names.push(to_destructuring(node.elements[i])); + } + + node = new AST_Destructuring({ + start: node.start, + names: names, + is_array: true, + end: node.end + }); + } else if (node instanceof AST_ObjectProperty) { + node.value = to_destructuring(node.value); + } else if (node instanceof AST_Assign) { + node = new AST_DefaultAssign({ + start: node.start, + left: node.left, + operator: "=", + right: node.right, + end: node.end + }); + } + return node; + } + + // In ES6, AssignmentExpression can also be an ArrowFunction + var maybe_assign = function(no_in) { + handle_regexp(); + var start = S.token; + + if (start.type == "name" && start.value == "yield") { + if (is_in_generator()) { + next(); + return _yield_expression(); + } else if (S.input.has_directive("use strict")) { + token_error(S.token, "Unexpected yield identifier inside strict mode"); + } + } + + var left = maybe_conditional(no_in); + var val = S.token.value; + + if (is("operator") && ASSIGNMENT.has(val)) { + if (is_assignable(left) || (left = to_destructuring(left)) instanceof AST_Destructuring) { + next(); + + return new AST_Assign({ + start : start, + left : left, + operator : val, + right : maybe_assign(no_in), + logical : LOGICAL_ASSIGNMENT.has(val), + end : prev() + }); + } + croak("Invalid assignment"); + } + return left; + }; + + var to_expr_or_sequence = function(start, exprs) { + if (exprs.length === 1) { + return exprs[0]; + } else if (exprs.length > 1) { + return new AST_Sequence({ start, expressions: exprs, end: peek() }); + } else { + croak("Invalid parenthesized expression"); + } + }; + + var expression = function(commas, no_in) { + var start = S.token; + var exprs = []; + while (true) { + exprs.push(maybe_assign(no_in)); + if (!commas || !is("punc", ",")) break; + next(); + commas = true; + } + return to_expr_or_sequence(start, exprs); + }; + + function in_loop(cont) { + ++S.in_loop; + var ret = cont(); + --S.in_loop; + return ret; + } + + if (options.expression) { + return expression(true); + } + + return (function parse_toplevel() { + var start = S.token; + var body = []; + S.input.push_directives_stack(); + if (options.module) S.input.add_directive("use strict"); + while (!is("eof")) { + body.push(statement()); + } + S.input.pop_directives_stack(); + var end = prev(); + var toplevel = options.toplevel; + if (toplevel) { + toplevel.body = toplevel.body.concat(body); + toplevel.end = end; + } else { + toplevel = new AST_Toplevel({ start: start, body: body, end: end }); + } + TEMPLATE_RAWS = new Map(); + return toplevel; + })(); + +} + +export { + get_full_char_code, + get_full_char, + is_identifier_char, + is_basic_identifier_string, + is_identifier_string, + is_surrogate_pair_head, + is_surrogate_pair_tail, + js_error, + JS_Parse_Error, + parse, + PRECEDENCE, + ALL_RESERVED_WORDS, + tokenizer, +}; diff --git a/node_modules/terser/lib/propmangle.js b/node_modules/terser/lib/propmangle.js new file mode 100644 index 0000000..265ade9 --- /dev/null +++ b/node_modules/terser/lib/propmangle.js @@ -0,0 +1,434 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +"use strict"; +/* global global, self */ + +import { + defaults, + push_uniq, + has_annotation, + clear_annotation, +} from "./utils/index.js"; +import { base54 } from "./scope.js"; +import { + AST_Binary, + AST_Call, + AST_ClassPrivateProperty, + AST_Conditional, + AST_Dot, + AST_DotHash, + AST_ObjectKeyVal, + AST_ObjectProperty, + AST_PrivateMethod, + AST_PrivateGetter, + AST_PrivateSetter, + AST_PrivateIn, + AST_Sequence, + AST_String, + AST_Sub, + TreeTransformer, + TreeWalker, + _KEY, + _MANGLEPROP, + + walk, +} from "./ast.js"; +import { domprops } from "../tools/domprops.js"; + +function find_builtins(reserved) { + domprops.forEach(add); + + // Compatibility fix for some standard defined globals not defined on every js environment + var new_globals = ["Symbol", "Map", "Promise", "Proxy", "Reflect", "Set", "WeakMap", "WeakSet"]; + var objects = {}; + var global_ref = typeof global === "object" ? global : self; + + new_globals.forEach(function (new_global) { + objects[new_global] = global_ref[new_global] || function() {}; + }); + + [ + "null", + "true", + "false", + "NaN", + "Infinity", + "-Infinity", + "undefined", + ].forEach(add); + [ Object, Array, Function, Number, + String, Boolean, Error, Math, + Date, RegExp, objects.Symbol, ArrayBuffer, + DataView, decodeURI, decodeURIComponent, + encodeURI, encodeURIComponent, eval, EvalError, + Float32Array, Float64Array, Int8Array, Int16Array, + Int32Array, isFinite, isNaN, JSON, objects.Map, parseFloat, + parseInt, objects.Promise, objects.Proxy, RangeError, ReferenceError, + objects.Reflect, objects.Set, SyntaxError, TypeError, Uint8Array, + Uint8ClampedArray, Uint16Array, Uint32Array, URIError, + objects.WeakMap, objects.WeakSet + ].forEach(function(ctor) { + Object.getOwnPropertyNames(ctor).map(add); + if (ctor.prototype) { + Object.getOwnPropertyNames(ctor.prototype).map(add); + } + }); + function add(name) { + reserved.add(name); + } +} + +function reserve_quoted_keys(ast, reserved) { + function add(name) { + push_uniq(reserved, name); + } + + ast.walk(new TreeWalker(function(node) { + if (node instanceof AST_ObjectKeyVal && node.quote) { + add(node.key); + } else if (node instanceof AST_ObjectProperty && node.quote) { + add(node.key.name); + } else if (node instanceof AST_Sub) { + addStrings(node.property, add); + } + })); +} + +function addStrings(node, add) { + node.walk(new TreeWalker(function(node) { + if (node instanceof AST_Sequence) { + addStrings(node.tail_node(), add); + } else if (node instanceof AST_String) { + add(node.value); + } else if (node instanceof AST_Conditional) { + addStrings(node.consequent, add); + addStrings(node.alternative, add); + } + return true; + })); +} + +function mangle_private_properties(ast, options) { + var cprivate = -1; + var private_cache = new Map(); + var nth_identifier = options.nth_identifier || base54; + + ast = ast.transform(new TreeTransformer(function(node) { + if ( + node instanceof AST_ClassPrivateProperty + || node instanceof AST_PrivateMethod + || node instanceof AST_PrivateGetter + || node instanceof AST_PrivateSetter + || node instanceof AST_PrivateIn + ) { + node.key.name = mangle_private(node.key.name); + } else if (node instanceof AST_DotHash) { + node.property = mangle_private(node.property); + } + })); + return ast; + + function mangle_private(name) { + let mangled = private_cache.get(name); + if (!mangled) { + mangled = nth_identifier.get(++cprivate); + private_cache.set(name, mangled); + } + + return mangled; + } +} + +function find_annotated_props(ast) { + var annotated_props = new Set(); + walk(ast, node => { + if ( + node instanceof AST_ClassPrivateProperty + || node instanceof AST_PrivateMethod + || node instanceof AST_PrivateGetter + || node instanceof AST_PrivateSetter + || node instanceof AST_DotHash + ) { + // handled by mangle_private_properties + } else if (node instanceof AST_ObjectKeyVal) { + if (typeof node.key == "string" && has_annotation(node, _MANGLEPROP)) { + annotated_props.add(node.key); + } + } else if (node instanceof AST_ObjectProperty) { + // setter or getter, since KeyVal is handled above + if (has_annotation(node, _MANGLEPROP)) { + annotated_props.add(node.key.name); + } + } else if (node instanceof AST_Dot) { + if (has_annotation(node, _MANGLEPROP)) { + annotated_props.add(node.property); + } + } else if (node instanceof AST_Sub) { + if (node.property instanceof AST_String && has_annotation(node, _MANGLEPROP)) { + annotated_props.add(node.property.value); + } + } + }); + return annotated_props; +} + +function mangle_properties(ast, options, annotated_props = find_annotated_props(ast)) { + options = defaults(options, { + builtins: false, + cache: null, + debug: false, + keep_quoted: false, + nth_identifier: base54, + only_cache: false, + regex: null, + reserved: null, + undeclared: false, + only_annotated: false, + }, true); + + var nth_identifier = options.nth_identifier; + + var reserved_option = options.reserved; + if (!Array.isArray(reserved_option)) reserved_option = [reserved_option]; + var reserved = new Set(reserved_option); + if (!options.builtins) find_builtins(reserved); + + var cname = -1; + + var cache; + if (options.cache) { + cache = options.cache.props; + } else { + cache = new Map(); + } + + var only_annotated = options.only_annotated; + var regex = options.regex && new RegExp(options.regex); + + // note debug is either false (disabled), or a string of the debug suffix to use (enabled). + // note debug may be enabled as an empty string, which is falsey. Also treat passing 'true' + // the same as passing an empty string. + var debug = options.debug !== false; + var debug_name_suffix; + if (debug) { + debug_name_suffix = (options.debug === true ? "" : options.debug); + } + + var names_to_mangle = new Set(); + var unmangleable = new Set(); + // Track each already-mangled name to prevent nth_identifier from generating + // the same name. + cache.forEach((mangled_name) => unmangleable.add(mangled_name)); + + var keep_quoted = !!options.keep_quoted; + + // step 1: find candidates to mangle + ast.walk(new TreeWalker(function(node) { + if ( + node instanceof AST_ClassPrivateProperty + || node instanceof AST_PrivateMethod + || node instanceof AST_PrivateGetter + || node instanceof AST_PrivateSetter + || node instanceof AST_DotHash + ) { + // handled by mangle_private_properties + } else if (node instanceof AST_ObjectKeyVal) { + if (typeof node.key == "string" && (!keep_quoted || !node.quote)) { + add(node.key); + } + } else if (node instanceof AST_ObjectProperty) { + // setter or getter, since KeyVal is handled above + if (!keep_quoted || !node.quote) { + add(node.key.name); + } + } else if (node instanceof AST_Dot) { + var declared = !!options.undeclared; + if (!declared) { + var root = node; + while (root.expression) { + root = root.expression; + } + declared = !(root.thedef && root.thedef.undeclared); + } + if (declared && + (!keep_quoted || !node.quote)) { + add(node.property); + } + } else if (node instanceof AST_Sub) { + if (!keep_quoted) { + addStrings(node.property, add); + } + } else if (node instanceof AST_Call + && node.expression.print_to_string() == "Object.defineProperty") { + addStrings(node.args[1], add); + } else if (node instanceof AST_Binary && node.operator === "in") { + addStrings(node.left, add); + } else if (node instanceof AST_String && has_annotation(node, _KEY)) { + add(node.value); + } + })); + + // step 2: transform the tree, renaming properties + return ast.transform(new TreeTransformer(function(node) { + if ( + node instanceof AST_ClassPrivateProperty + || node instanceof AST_PrivateMethod + || node instanceof AST_PrivateGetter + || node instanceof AST_PrivateSetter + || node instanceof AST_DotHash + ) { + // handled by mangle_private_properties + } else if (node instanceof AST_ObjectKeyVal) { + if (typeof node.key == "string" && (!keep_quoted || !node.quote)) { + node.key = mangle(node.key); + } + } else if (node instanceof AST_ObjectProperty) { + // setter, getter, method or class field + if (!keep_quoted || !node.quote) { + if (!node.computed_key()) { + node.key.name = mangle(node.key.name); + } + } + } else if (node instanceof AST_Dot) { + if (!keep_quoted || !node.quote) { + node.property = mangle(node.property); + } + } else if (!keep_quoted && node instanceof AST_Sub) { + node.property = mangleStrings(node.property); + } else if (node instanceof AST_Call + && node.expression.print_to_string() == "Object.defineProperty") { + node.args[1] = mangleStrings(node.args[1]); + } else if (node instanceof AST_Binary && node.operator === "in") { + node.left = mangleStrings(node.left); + } else if (node instanceof AST_String && has_annotation(node, _KEY)) { + // Clear _KEY annotation to prevent double mangling + clear_annotation(node, _KEY); + node.value = mangle(node.value); + } + })); + + // only function declarations after this line + + function can_mangle(name) { + if (unmangleable.has(name)) return false; + if (reserved.has(name)) return false; + if (options.only_cache) { + return cache.has(name); + } + if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false; + return true; + } + + function should_mangle(name) { + if (only_annotated && !annotated_props.has(name)) return false; + if (regex && !regex.test(name)) { + return annotated_props.has(name); + } + if (reserved.has(name)) return false; + return cache.has(name) + || names_to_mangle.has(name); + } + + function add(name) { + if (can_mangle(name)) { + names_to_mangle.add(name); + } + + if (!should_mangle(name)) { + unmangleable.add(name); + } + } + + function mangle(name) { + if (!should_mangle(name)) { + return name; + } + + var mangled = cache.get(name); + if (!mangled) { + if (debug) { + // debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_. + var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_"; + + if (can_mangle(debug_mangled)) { + mangled = debug_mangled; + } + } + + // either debug mode is off, or it is on and we could not use the mangled name + if (!mangled) { + do { + mangled = nth_identifier.get(++cname); + } while (!can_mangle(mangled)); + } + + cache.set(name, mangled); + } + return mangled; + } + + function mangleStrings(node) { + return node.transform(new TreeTransformer(function(node) { + if (node instanceof AST_Sequence) { + var last = node.expressions.length - 1; + node.expressions[last] = mangleStrings(node.expressions[last]); + } else if (node instanceof AST_String) { + // Clear _KEY annotation to prevent double mangling + clear_annotation(node, _KEY); + node.value = mangle(node.value); + } else if (node instanceof AST_Conditional) { + node.consequent = mangleStrings(node.consequent); + node.alternative = mangleStrings(node.alternative); + } + return node; + })); + } +} + +export { + reserve_quoted_keys, + mangle_properties, + mangle_private_properties, + find_annotated_props, +}; diff --git a/node_modules/terser/lib/scope.js b/node_modules/terser/lib/scope.js new file mode 100644 index 0000000..9c99302 --- /dev/null +++ b/node_modules/terser/lib/scope.js @@ -0,0 +1,1068 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +"use strict"; + +import { + defaults, + keep_name, + mergeSort, + push_uniq, + make_node, + return_false, + return_this, + return_true, + string_template, +} from "./utils/index.js"; +import { + AST_Arrow, + AST_Block, + AST_Call, + AST_Class, + AST_Conditional, + AST_DefClass, + AST_Defun, + AST_Destructuring, + AST_Dot, + AST_DotHash, + AST_Export, + AST_For, + AST_ForIn, + AST_ForOf, + AST_Function, + AST_Import, + AST_IterationStatement, + AST_Label, + AST_LabeledStatement, + AST_LabelRef, + AST_Lambda, + AST_LoopControl, + AST_NameMapping, + AST_Node, + AST_Scope, + AST_Sequence, + AST_String, + AST_Sub, + AST_Switch, + AST_SwitchBranch, + AST_Symbol, + AST_SymbolBlockDeclaration, + AST_SymbolCatch, + AST_SymbolClass, + AST_SymbolConst, + AST_SymbolDefClass, + AST_SymbolDefun, + AST_SymbolExport, + AST_SymbolFunarg, + AST_SymbolImport, + AST_SymbolLambda, + AST_SymbolLet, + AST_SymbolMethod, + AST_SymbolRef, + AST_SymbolUsing, + AST_SymbolVar, + AST_Toplevel, + AST_VarDef, + AST_With, + TreeWalker, + walk, + walk_abort +} from "./ast.js"; +import { + ALL_RESERVED_WORDS, + js_error, +} from "./parse.js"; + +const MASK_EXPORT_DONT_MANGLE = 1 << 0; +const MASK_EXPORT_WANT_MANGLE = 1 << 1; + +let function_defs = null; +let unmangleable_names = null; +/** + * When defined, there is a function declaration somewhere that's inside of a block. + * See https://tc39.es/ecma262/multipage/additional-ecmascript-features-for-web-browsers.html#sec-block-level-function-declarations-web-legacy-compatibility-semantics +*/ +let scopes_with_block_defuns = null; + +class SymbolDef { + constructor(scope, orig, init) { + this.name = orig.name; + this.orig = [ orig ]; + this.init = init; + this.eliminated = 0; + this.assignments = 0; + this.scope = scope; + this.replaced = 0; + this.global = false; + this.export = 0; + this.mangled_name = null; + this.undeclared = false; + this.id = SymbolDef.next_id++; + this.chained = false; + this.direct_access = false; + this.escaped = 0; + this.recursive_refs = 0; + this.references = []; + this.should_replace = undefined; + this.single_use = false; + this.fixed = false; + Object.seal(this); + } + fixed_value() { + if (!this.fixed || this.fixed instanceof AST_Node) return this.fixed; + return this.fixed(); + } + unmangleable(options) { + if (!options) options = {}; + + if ( + function_defs && + function_defs.has(this.id) && + keep_name(options.keep_fnames, this.orig[0].name) + ) return true; + + return this.global && !options.toplevel + || (this.export & MASK_EXPORT_DONT_MANGLE) + || this.undeclared + || !options.eval && this.scope.pinned() + || (this.orig[0] instanceof AST_SymbolLambda + || this.orig[0] instanceof AST_SymbolDefun) && keep_name(options.keep_fnames, this.orig[0].name) + || this.orig[0] instanceof AST_SymbolMethod + || (this.orig[0] instanceof AST_SymbolClass + || this.orig[0] instanceof AST_SymbolDefClass) && keep_name(options.keep_classnames, this.orig[0].name); + } + mangle(options) { + const cache = options.cache && options.cache.props; + if (this.global && cache && cache.has(this.name)) { + this.mangled_name = cache.get(this.name); + } else if (!this.mangled_name && !this.unmangleable(options)) { + var s = this.scope; + var sym = this.orig[0]; + if (options.ie8 && sym instanceof AST_SymbolLambda) + s = s.parent_scope; + const redefinition = redefined_catch_def(this); + this.mangled_name = redefinition + ? redefinition.mangled_name || redefinition.name + : s.next_mangled(options, this); + if (this.global && cache) { + cache.set(this.name, this.mangled_name); + } + } + } +} + +SymbolDef.next_id = 1; + +function redefined_catch_def(def) { + if (def.orig[0] instanceof AST_SymbolCatch + && def.scope.is_block_scope() + ) { + return def.scope.get_defun_scope().variables.get(def.name); + } +} + +AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = undefined, toplevel = this } = {}) { + options = defaults(options, { + cache: null, + ie8: false, + safari10: false, + module: false, + }); + + if (!(toplevel instanceof AST_Toplevel)) { + throw new Error("Invalid toplevel scope"); + } + + // pass 1: setup scope chaining and handle definitions + var scope = this.parent_scope = parent_scope; + var labels = new Map(); + var defun = null; + var in_destructuring = null; + var for_scopes = []; + var tw = new TreeWalker((node, descend) => { + if (node.is_block_scope()) { + const save_scope = scope; + node.block_scope = scope = new AST_Scope(node); + scope._block_scope = true; + scope.init_scope_vars(save_scope); + scope.uses_with = save_scope.uses_with; + scope.uses_eval = save_scope.uses_eval; + + if (options.safari10) { + if (node instanceof AST_For || node instanceof AST_ForIn || node instanceof AST_ForOf) { + for_scopes.push(scope); + } + } + + if (node instanceof AST_Switch) { + // XXX: HACK! Ensure the switch expression gets the correct scope (the parent scope) and the body gets the contained scope + // AST_Switch has a scope within the body, but it itself "is a block scope" + // This means the switched expression has to belong to the outer scope + // while the body inside belongs to the switch itself. + // This is pretty nasty and warrants an AST change + const the_block_scope = scope; + scope = save_scope; + node.expression.walk(tw); + scope = the_block_scope; + for (let i = 0; i < node.body.length; i++) { + node.body[i].walk(tw); + } + } else { + descend(); + } + scope = save_scope; + return true; + } + if (node instanceof AST_Destructuring) { + const save_destructuring = in_destructuring; + in_destructuring = node; + descend(); + in_destructuring = save_destructuring; + return true; + } + if (node instanceof AST_Scope) { + node.init_scope_vars(scope); + var save_scope = scope; + var save_defun = defun; + var save_labels = labels; + defun = scope = node; + labels = new Map(); + descend(); + scope = save_scope; + defun = save_defun; + labels = save_labels; + return true; // don't descend again in TreeWalker + } + if (node instanceof AST_LabeledStatement) { + var l = node.label; + if (labels.has(l.name)) { + throw new Error(string_template("Label {name} defined twice", l)); + } + labels.set(l.name, l); + descend(); + labels.delete(l.name); + return true; // no descend again + } + if (node instanceof AST_With) { + for (var s = scope; s; s = s.parent_scope) + s.uses_with = true; + return; + } + if (node instanceof AST_Symbol) { + node.scope = scope; + } + if (node instanceof AST_Label) { + node.thedef = node; + node.references = []; + } + if (node instanceof AST_SymbolLambda) { + defun.def_function(node, node.name == "arguments" ? undefined : defun); + } else if (node instanceof AST_SymbolDefun) { + // Careful here, the scope where this should be defined is + // the parent scope. The reason is that we enter a new + // scope when we encounter the AST_Defun node (which is + // instanceof AST_Scope) but we get to the symbol a bit + // later. + const closest_scope = defun.parent_scope; + + // In strict mode, function definitions are block-scoped + node.scope = tw.directives["use strict"] + ? closest_scope + : closest_scope.get_defun_scope(); + + mark_export(node.scope.def_function(node, defun), 1); + } else if (node instanceof AST_SymbolClass) { + mark_export(defun.def_variable(node, defun), 1); + } else if (node instanceof AST_SymbolImport) { + scope.def_variable(node); + } else if (node instanceof AST_SymbolDefClass) { + // This deals with the name of the class being available + // inside the class. + mark_export((node.scope = defun.parent_scope).def_function(node, defun), 1); + } else if ( + node instanceof AST_SymbolVar + || node instanceof AST_SymbolLet + || node instanceof AST_SymbolConst + || node instanceof AST_SymbolUsing + || node instanceof AST_SymbolCatch + ) { + var def; + if (node instanceof AST_SymbolBlockDeclaration) { + def = scope.def_variable(node, null); + } else { + def = defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined); + } + if (!def.orig.every((sym) => { + if (sym === node) return true; + if (node instanceof AST_SymbolBlockDeclaration) { + return sym instanceof AST_SymbolLambda; + } + return !(sym instanceof AST_SymbolLet || sym instanceof AST_SymbolConst || sym instanceof AST_SymbolUsing); + })) { + js_error( + `"${node.name}" is redeclared`, + node.start.file, + node.start.line, + node.start.col, + node.start.pos + ); + } + if (!(node instanceof AST_SymbolFunarg)) mark_export(def, 2); + if (defun !== scope) { + node.mark_enclosed(); + var def = scope.find_variable(node); + if (node.thedef !== def) { + node.thedef = def; + node.reference(); + } + } + } else if (node instanceof AST_LabelRef) { + var sym = labels.get(node.name); + if (!sym) throw new Error(string_template("Undefined label {name} [{line},{col}]", { + name: node.name, + line: node.start.line, + col: node.start.col + })); + node.thedef = sym; + } + if (!(scope instanceof AST_Toplevel) && (node instanceof AST_Export || node instanceof AST_Import)) { + js_error( + `"${node.TYPE}" statement may only appear at the top level`, + node.start.file, + node.start.line, + node.start.col, + node.start.pos + ); + } + }); + + if (options.module) { + tw.directives["use strict"] = true; + } + + this.walk(tw); + + function mark_export(def, level) { + if (in_destructuring) { + var i = 0; + do { + level++; + } while (tw.parent(i++) !== in_destructuring); + } + var node = tw.parent(level); + if (def.export = node instanceof AST_Export ? MASK_EXPORT_DONT_MANGLE : 0) { + var exported = node.exported_definition; + if ((exported instanceof AST_Defun || exported instanceof AST_DefClass) && node.is_default) { + def.export = MASK_EXPORT_WANT_MANGLE; + } + } + } + + // pass 2: find back references and eval + const is_toplevel = this instanceof AST_Toplevel; + if (is_toplevel) { + this.globals = new Map(); + } + + var tw = new TreeWalker(node => { + if (node instanceof AST_LoopControl && node.label) { + node.label.thedef.references.push(node); + return true; + } + if (node instanceof AST_SymbolRef) { + var name = node.name; + if (name == "eval" && tw.parent() instanceof AST_Call) { + for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) { + s.uses_eval = true; + } + } + var sym; + if (tw.parent() instanceof AST_NameMapping && tw.parent(1).module_name + || !(sym = node.scope.find_variable(name))) { + + sym = toplevel.def_global(node); + if (node instanceof AST_SymbolExport) sym.export = MASK_EXPORT_DONT_MANGLE; + } else if (sym.scope instanceof AST_Lambda && name == "arguments") { + sym.scope.get_defun_scope().uses_arguments = true; + } + node.thedef = sym; + node.reference(); + if (node.scope.is_block_scope() + && !(sym.orig[0] instanceof AST_SymbolBlockDeclaration)) { + node.scope = node.scope.get_defun_scope(); + } + return true; + } + // ensure mangling works if catch reuses a scope variable + var def; + if (node instanceof AST_SymbolCatch && (def = redefined_catch_def(node.definition()))) { + var s = node.scope; + while (s) { + push_uniq(s.enclosed, def); + if (s === def.scope) break; + s = s.parent_scope; + } + } + }); + this.walk(tw); + + // pass 3: work around IE8 and Safari catch scope bugs + if (options.ie8 || options.safari10) { + walk(this, node => { + if (node instanceof AST_SymbolCatch) { + var name = node.name; + var refs = node.thedef.references; + var scope = node.scope.get_defun_scope(); + var def = scope.find_variable(name) + || toplevel.globals.get(name) + || scope.def_variable(node); + refs.forEach(function(ref) { + ref.thedef = def; + ref.reference(); + }); + node.thedef = def; + node.reference(); + return true; + } + }); + } + + // pass 4: add symbol definitions to loop scopes + // Safari/Webkit bug workaround - loop init let variable shadowing argument. + // https://github.com/mishoo/UglifyJS2/issues/1753 + // https://bugs.webkit.org/show_bug.cgi?id=171041 + if (options.safari10) { + for (const scope of for_scopes) { + scope.parent_scope.variables.forEach(function(def) { + push_uniq(scope.enclosed, def); + }); + } + } +}); + +AST_Toplevel.DEFMETHOD("def_global", function(node) { + var globals = this.globals, name = node.name; + if (globals.has(name)) { + return globals.get(name); + } else { + var g = new SymbolDef(this, node); + g.undeclared = true; + g.global = true; + globals.set(name, g); + return g; + } +}); + +AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope) { + this.variables = new Map(); // map name to AST_SymbolVar (variables defined in this scope; includes functions) + this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement + this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval` + this.parent_scope = parent_scope; // the parent scope + this.enclosed = []; // a list of variables from this or outer scope(s) that are referenced from this or inner scopes + this.cname = -1; // the current index for mangling functions/variables +}); + +AST_Scope.DEFMETHOD("conflicting_def", function (name) { + return ( + this.enclosed.find(def => def.name === name) + || this.variables.has(name) + || (this.parent_scope && this.parent_scope.conflicting_def(name)) + ); +}); + +AST_Scope.DEFMETHOD("conflicting_def_shallow", function (name) { + return ( + this.enclosed.find(def => def.name === name) + || this.variables.has(name) + ); +}); + +AST_Scope.DEFMETHOD("add_child_scope", function (scope) { + // `scope` is going to be moved into `this` right now. + // Update the required scopes' information + + if (scope.parent_scope === this) return; + + scope.parent_scope = this; + + // Propagate to this.uses_arguments from arrow functions + if ((scope instanceof AST_Arrow) && (this instanceof AST_Lambda && !this.uses_arguments)) { + this.uses_arguments = walk(scope, node => { + if ( + node instanceof AST_SymbolRef + && node.scope instanceof AST_Lambda + && node.name === "arguments" + ) { + return walk_abort; + } + + if (node instanceof AST_Lambda && !(node instanceof AST_Arrow)) { + return true; + } + }); + } + + this.uses_with = this.uses_with || scope.uses_with; + this.uses_eval = this.uses_eval || scope.uses_eval; + + const scope_ancestry = (() => { + const ancestry = []; + let cur = this; + do { + ancestry.push(cur); + } while ((cur = cur.parent_scope)); + ancestry.reverse(); + return ancestry; + })(); + + const new_scope_enclosed_set = new Set(scope.enclosed); + const to_enclose = []; + for (const scope_topdown of scope_ancestry) { + to_enclose.forEach(e => push_uniq(scope_topdown.enclosed, e)); + for (const def of scope_topdown.variables.values()) { + if (new_scope_enclosed_set.has(def)) { + push_uniq(to_enclose, def); + push_uniq(scope_topdown.enclosed, def); + } + } + } +}); + +function find_scopes_visible_from(scopes) { + const found_scopes = new Set(); + + for (const scope of new Set(scopes)) { + (function bubble_up(scope) { + if (scope == null || found_scopes.has(scope)) return; + + found_scopes.add(scope); + + bubble_up(scope.parent_scope); + })(scope); + } + + return [...found_scopes]; +} + +// Creates a symbol during compression +AST_Scope.DEFMETHOD("create_symbol", function(SymClass, { + source, + tentative_name, + scope, + conflict_scopes = [scope], + init = null +} = {}) { + let symbol_name; + + conflict_scopes = find_scopes_visible_from(conflict_scopes); + + if (tentative_name) { + // Implement hygiene (no new names are conflicting with existing names) + tentative_name = + symbol_name = + tentative_name.replace(/(?:^[^a-z_$]|[^a-z0-9_$])/ig, "_"); + + let i = 0; + while (conflict_scopes.find(s => s.conflicting_def_shallow(symbol_name))) { + symbol_name = tentative_name + "$" + i++; + } + } + + if (!symbol_name) { + throw new Error("No symbol name could be generated in create_symbol()"); + } + + const symbol = make_node(SymClass, source, { + name: symbol_name, + scope + }); + + this.def_variable(symbol, init || null); + + symbol.mark_enclosed(); + + return symbol; +}); + + +AST_Node.DEFMETHOD("is_block_scope", return_false); +AST_Class.DEFMETHOD("is_block_scope", return_false); +AST_Lambda.DEFMETHOD("is_block_scope", return_false); +AST_Toplevel.DEFMETHOD("is_block_scope", return_false); +AST_SwitchBranch.DEFMETHOD("is_block_scope", return_false); +AST_Block.DEFMETHOD("is_block_scope", return_true); +AST_Scope.DEFMETHOD("is_block_scope", function () { + return this._block_scope || false; +}); +AST_IterationStatement.DEFMETHOD("is_block_scope", return_true); + +AST_Lambda.DEFMETHOD("init_scope_vars", function() { + AST_Scope.prototype.init_scope_vars.apply(this, arguments); + this.uses_arguments = false; + this.def_variable(new AST_SymbolFunarg({ + name: "arguments", + start: this.start, + end: this.end + })); +}); + +AST_Arrow.DEFMETHOD("init_scope_vars", function() { + AST_Scope.prototype.init_scope_vars.apply(this, arguments); + this.uses_arguments = false; +}); + +AST_Symbol.DEFMETHOD("mark_enclosed", function() { + var def = this.definition(); + var s = this.scope; + while (s) { + push_uniq(s.enclosed, def); + if (s === def.scope) break; + s = s.parent_scope; + } +}); + +AST_Symbol.DEFMETHOD("reference", function() { + this.definition().references.push(this); + this.mark_enclosed(); +}); + +AST_Scope.DEFMETHOD("find_variable", function(name) { + if (name instanceof AST_Symbol) name = name.name; + return this.variables.get(name) + || (this.parent_scope && this.parent_scope.find_variable(name)); +}); + +AST_Scope.DEFMETHOD("def_function", function(symbol, init) { + var def = this.def_variable(symbol, init); + if (!def.init || def.init instanceof AST_Defun) def.init = init; + return def; +}); + +AST_Scope.DEFMETHOD("def_variable", function(symbol, init) { + var def = this.variables.get(symbol.name); + if (def) { + def.orig.push(symbol); + if (def.init && (def.scope !== symbol.scope || def.init instanceof AST_Function)) { + def.init = init; + } + } else { + def = new SymbolDef(this, symbol, init); + this.variables.set(symbol.name, def); + def.global = !this.parent_scope; + } + return symbol.thedef = def; +}); + +function next_mangled(scope, options) { + let defun_scope; + if ( + scopes_with_block_defuns + && (defun_scope = scope.get_defun_scope()) + && scopes_with_block_defuns.has(defun_scope) + ) { + scope = defun_scope; + } + + var ext = scope.enclosed; + var nth_identifier = options.nth_identifier; + out: while (true) { + var m = nth_identifier.get(++scope.cname); + if (ALL_RESERVED_WORDS.has(m)) continue; // skip over "do" + + // https://github.com/mishoo/UglifyJS2/issues/242 -- do not + // shadow a name reserved from mangling. + if (options.reserved.has(m)) continue; + + // Functions with short names might collide with base54 output + // and therefore cause collisions when keep_fnames is true. + if (unmangleable_names && unmangleable_names.has(m)) continue out; + + // we must ensure that the mangled name does not shadow a name + // from some parent scope that is referenced in this or in + // inner scopes. + for (let i = ext.length; --i >= 0;) { + const def = ext[i]; + const name = def.mangled_name || (def.unmangleable(options) && def.name); + if (m == name) continue out; + } + return m; + } +} + +AST_Scope.DEFMETHOD("next_mangled", function(options) { + return next_mangled(this, options); +}); + +AST_Toplevel.DEFMETHOD("next_mangled", function(options) { + let name; + const mangled_names = this.mangled_names; + do { + name = next_mangled(this, options); + } while (mangled_names.has(name)); + return name; +}); + +AST_Function.DEFMETHOD("next_mangled", function(options, def) { + // #179, #326 + // in Safari strict mode, something like (function x(x){...}) is a syntax error; + // a function expression's argument cannot shadow the function expression's name + + var tricky_def = def.orig[0] instanceof AST_SymbolFunarg && this.name && this.name.definition(); + + // the function's mangled_name is null when keep_fnames is true + var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null; + + while (true) { + var name = next_mangled(this, options); + if (!tricky_name || tricky_name != name) + return name; + } +}); + +AST_Symbol.DEFMETHOD("unmangleable", function(options) { + var def = this.definition(); + return !def || def.unmangleable(options); +}); + +// labels are always mangleable +AST_Label.DEFMETHOD("unmangleable", return_false); + +AST_Symbol.DEFMETHOD("unreferenced", function() { + return !this.definition().references.length && !this.scope.pinned(); +}); + +AST_Symbol.DEFMETHOD("definition", function() { + return this.thedef; +}); + +AST_Symbol.DEFMETHOD("global", function() { + return this.thedef.global; +}); + +/** + * Format the mangler options (if any) into their appropriate types + */ +export function format_mangler_options(options) { + options = defaults(options, { + eval : false, + nth_identifier : base54, + ie8 : false, + keep_classnames: false, + keep_fnames : false, + module : false, + reserved : [], + toplevel : false, + }); + if (options.module) options.toplevel = true; + if (!Array.isArray(options.reserved) + && !(options.reserved instanceof Set) + ) { + options.reserved = []; + } + options.reserved = new Set(options.reserved); + // Never mangle arguments + options.reserved.add("arguments"); + return options; +} + +AST_Toplevel.DEFMETHOD("mangle_names", function(options) { + options = format_mangler_options(options); + var nth_identifier = options.nth_identifier; + + // We only need to mangle declaration nodes. Special logic wired + // into the code generator will display the mangled name if it's + // present (and for AST_SymbolRef-s it'll use the mangled name of + // the AST_SymbolDeclaration that it points to). + var lname = -1; + var to_mangle = []; + + if (options.keep_fnames) { + function_defs = new Set(); + } + + const mangled_names = this.mangled_names = new Set(); + unmangleable_names = new Set(); + + if (options.cache) { + this.globals.forEach(collect); + if (options.cache.props) { + options.cache.props.forEach(function(mangled_name) { + mangled_names.add(mangled_name); + }); + } + } + + var tw = new TreeWalker(function(node, descend) { + if (node instanceof AST_LabeledStatement) { + // lname is incremented when we get to the AST_Label + var save_nesting = lname; + descend(); + lname = save_nesting; + return true; // don't descend again in TreeWalker + } + if ( + node instanceof AST_Defun + && !(tw.parent() instanceof AST_Scope) + ) { + scopes_with_block_defuns = scopes_with_block_defuns || new Set(); + scopes_with_block_defuns.add(node.parent_scope.get_defun_scope()); + } + if (node instanceof AST_Scope) { + node.variables.forEach(collect); + return; + } + if (node.is_block_scope()) { + node.block_scope.variables.forEach(collect); + return; + } + if ( + function_defs + && node instanceof AST_VarDef + && node.value instanceof AST_Lambda + && !node.value.name + && keep_name(options.keep_fnames, node.name.name) + ) { + function_defs.add(node.name.definition().id); + return; + } + if (node instanceof AST_Label) { + let name; + do { + name = nth_identifier.get(++lname); + } while (ALL_RESERVED_WORDS.has(name)); + node.mangled_name = name; + return true; + } + if (!(options.ie8 || options.safari10) && node instanceof AST_SymbolCatch) { + to_mangle.push(node.definition()); + return; + } + }); + + this.walk(tw); + + if (options.keep_fnames || options.keep_classnames) { + // Collect a set of short names which are unmangleable, + // for use in avoiding collisions in next_mangled. + to_mangle.forEach(def => { + if (def.name.length < 6 && def.unmangleable(options)) { + unmangleable_names.add(def.name); + } + }); + } + + to_mangle.forEach(def => { def.mangle(options); }); + + function_defs = null; + unmangleable_names = null; + scopes_with_block_defuns = null; + + function collect(symbol) { + if (symbol.export & MASK_EXPORT_DONT_MANGLE) { + unmangleable_names.add(symbol.name); + } else if (!options.reserved.has(symbol.name)) { + to_mangle.push(symbol); + } + } +}); + +AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) { + const cache = options.cache && options.cache.props; + const avoid = new Set(); + options.reserved.forEach(to_avoid); + this.globals.forEach(add_def); + this.walk(new TreeWalker(function(node) { + if (node instanceof AST_Scope) node.variables.forEach(add_def); + if (node instanceof AST_SymbolCatch) add_def(node.definition()); + })); + return avoid; + + function to_avoid(name) { + avoid.add(name); + } + + function add_def(def) { + var name = def.name; + if (def.global && cache && cache.has(name)) name = cache.get(name); + else if (!def.unmangleable(options)) return; + to_avoid(name); + } +}); + +AST_Toplevel.DEFMETHOD("expand_names", function(options) { + options = format_mangler_options(options); + var nth_identifier = options.nth_identifier; + if (nth_identifier.reset && nth_identifier.sort) { + nth_identifier.reset(); + nth_identifier.sort(); + } + var avoid = this.find_colliding_names(options); + var cname = 0; + this.globals.forEach(rename); + this.walk(new TreeWalker(function(node) { + if (node instanceof AST_Scope) node.variables.forEach(rename); + if (node instanceof AST_SymbolCatch) rename(node.definition()); + })); + + function next_name() { + var name; + do { + name = nth_identifier.get(cname++); + } while (avoid.has(name) || ALL_RESERVED_WORDS.has(name)); + return name; + } + + function rename(def) { + if (def.global && options.cache) return; + if (def.unmangleable(options)) return; + if (options.reserved.has(def.name)) return; + const redefinition = redefined_catch_def(def); + const name = def.name = redefinition ? redefinition.name : next_name(); + def.orig.forEach(function(sym) { + sym.name = name; + }); + def.references.forEach(function(sym) { + sym.name = name; + }); + } +}); + +AST_Node.DEFMETHOD("tail_node", return_this); +AST_Sequence.DEFMETHOD("tail_node", function() { + return this.expressions[this.expressions.length - 1]; +}); + +AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) { + options = format_mangler_options(options); + var nth_identifier = options.nth_identifier; + if (!nth_identifier.reset || !nth_identifier.consider || !nth_identifier.sort) { + // If the identifier mangler is invariant, skip computing character frequency. + return; + } + nth_identifier.reset(); + + try { + AST_Node.prototype.print = function(stream, force_parens) { + this._print(stream, force_parens); + if (this instanceof AST_Symbol && !this.unmangleable(options)) { + nth_identifier.consider(this.name, -1); + } else if (options.properties) { + if (this instanceof AST_DotHash) { + nth_identifier.consider("#" + this.property, -1); + } else if (this instanceof AST_Dot) { + nth_identifier.consider(this.property, -1); + } else if (this instanceof AST_Sub) { + skip_string(this.property); + } + } + }; + nth_identifier.consider(this.print_to_string(), 1); + } finally { + AST_Node.prototype.print = AST_Node.prototype._print; + } + nth_identifier.sort(); + + function skip_string(node) { + if (node instanceof AST_String) { + nth_identifier.consider(node.value, -1); + } else if (node instanceof AST_Conditional) { + skip_string(node.consequent); + skip_string(node.alternative); + } else if (node instanceof AST_Sequence) { + skip_string(node.tail_node()); + } + } +}); + +const base54 = (() => { + const leading = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_".split(""); + const digits = "0123456789".split(""); + let chars; + let frequency; + function reset() { + frequency = new Map(); + leading.forEach(function(ch) { + frequency.set(ch, 0); + }); + digits.forEach(function(ch) { + frequency.set(ch, 0); + }); + } + function consider(str, delta) { + for (var i = str.length; --i >= 0;) { + frequency.set(str[i], frequency.get(str[i]) + delta); + } + } + function compare(a, b) { + return frequency.get(b) - frequency.get(a); + } + function sort() { + chars = mergeSort(leading, compare).concat(mergeSort(digits, compare)); + } + // Ensure this is in a usable initial state. + reset(); + sort(); + function base54(num) { + var ret = "", base = 54; + num++; + do { + num--; + ret += chars[num % base]; + num = Math.floor(num / base); + base = 64; + } while (num > 0); + return ret; + } + + return { + get: base54, + consider, + reset, + sort + }; +})(); + +export { + base54, + SymbolDef, +}; diff --git a/node_modules/terser/lib/size.js b/node_modules/terser/lib/size.js new file mode 100644 index 0000000..6b047d3 --- /dev/null +++ b/node_modules/terser/lib/size.js @@ -0,0 +1,505 @@ +import { + AST_Accessor, + AST_Array, + AST_Arrow, + AST_Await, + AST_BigInt, + AST_Binary, + AST_Block, + AST_Break, + AST_Call, + AST_Case, + AST_Class, + AST_ClassStaticBlock, + AST_ClassPrivateProperty, + AST_ClassProperty, + AST_ConciseMethod, + AST_Conditional, + AST_Const, + AST_Continue, + AST_Debugger, + AST_Default, + AST_Defun, + AST_Destructuring, + AST_Directive, + AST_Do, + AST_Dot, + AST_DotHash, + AST_EmptyStatement, + AST_Expansion, + AST_Export, + AST_False, + AST_For, + AST_ForIn, + AST_Function, + AST_Hole, + AST_If, + AST_Import, + AST_ImportMeta, + AST_Infinity, + AST_LabeledStatement, + AST_Let, + AST_NameMapping, + AST_NaN, + AST_New, + AST_NewTarget, + AST_Node, + AST_Null, + AST_Number, + AST_Object, + AST_ObjectKeyVal, + AST_ObjectGetter, + AST_ObjectSetter, + AST_PrivateGetter, + AST_PrivateMethod, + AST_PrivateSetter, + AST_PrivateIn, + AST_RegExp, + AST_Return, + AST_Sequence, + AST_String, + AST_Sub, + AST_Super, + AST_Switch, + AST_Symbol, + AST_SymbolClassProperty, + AST_SymbolExportForeign, + AST_SymbolImportForeign, + AST_SymbolRef, + AST_SymbolDeclaration, + AST_TemplateSegment, + AST_TemplateString, + AST_This, + AST_Throw, + AST_Toplevel, + AST_True, + AST_Try, + AST_Catch, + AST_Finally, + AST_Unary, + AST_Undefined, + AST_Using, + AST_Var, + AST_VarDefLike, + AST_While, + AST_With, + AST_Yield, + walk_parent +} from "./ast.js"; +import { first_in_statement } from "./utils/first_in_statement.js"; + +let mangle_options = undefined; +AST_Node.prototype.size = function (compressor, stack) { + mangle_options = compressor && compressor._mangle_options; + + let size = 0; + walk_parent(this, (node, info) => { + size += node._size(info); + + // Braceless arrow functions have fake "return" statements + if (node instanceof AST_Arrow && node.is_braceless()) { + size += node.body[0].value._size(info); + return true; + } + }, stack || (compressor && compressor.stack)); + + // just to save a bit of memory + mangle_options = undefined; + + return size; +}; + +AST_Node.prototype._size = () => 0; + +AST_Debugger.prototype._size = () => 8; + +AST_Directive.prototype._size = function () { + // TODO string encoding stuff + return 2 + this.value.length; +}; + +/** Count commas/semicolons necessary to show a list of expressions/statements */ +const list_overhead = (array) => array.length && array.length - 1; + +AST_Block.prototype._size = function () { + return 2 + list_overhead(this.body); +}; + +AST_Toplevel.prototype._size = function() { + return list_overhead(this.body); +}; + +AST_EmptyStatement.prototype._size = () => 1; + +AST_LabeledStatement.prototype._size = () => 2; // x: + +AST_Do.prototype._size = () => 9; + +AST_While.prototype._size = () => 7; + +AST_For.prototype._size = () => 8; + +AST_ForIn.prototype._size = () => 8; +// AST_ForOf inherits ^ + +AST_With.prototype._size = () => 6; + +AST_Expansion.prototype._size = () => 3; + +const lambda_modifiers = func => + (func.is_generator ? 1 : 0) + (func.async ? 6 : 0); + +AST_Accessor.prototype._size = function () { + return lambda_modifiers(this) + 4 + list_overhead(this.argnames) + list_overhead(this.body); +}; + +AST_Function.prototype._size = function (info) { + const first = !!first_in_statement(info); + return (first * 2) + lambda_modifiers(this) + 12 + list_overhead(this.argnames) + list_overhead(this.body); +}; + +AST_Defun.prototype._size = function () { + return lambda_modifiers(this) + 13 + list_overhead(this.argnames) + list_overhead(this.body); +}; + +AST_Arrow.prototype._size = function () { + let args_and_arrow = 2 + list_overhead(this.argnames); + + if ( + !( + this.argnames.length === 1 + && this.argnames[0] instanceof AST_Symbol + ) + ) { + args_and_arrow += 2; // parens around the args + } + + const body_overhead = this.is_braceless() ? 0 : list_overhead(this.body) + 2; + + return lambda_modifiers(this) + args_and_arrow + body_overhead; +}; + +AST_Destructuring.prototype._size = () => 2; + +AST_TemplateString.prototype._size = function () { + return 2 + (Math.floor(this.segments.length / 2) * 3); /* "${}" */ +}; + +AST_TemplateSegment.prototype._size = function () { + return this.value.length; +}; + +AST_Return.prototype._size = function () { + return this.value ? 7 : 6; +}; + +AST_Throw.prototype._size = () => 6; + +AST_Break.prototype._size = function () { + return this.label ? 6 : 5; +}; + +AST_Continue.prototype._size = function () { + return this.label ? 9 : 8; +}; + +AST_If.prototype._size = () => 4; + +AST_Switch.prototype._size = function () { + return 8 + list_overhead(this.body); +}; + +AST_Case.prototype._size = function () { + return 5 + list_overhead(this.body); +}; + +AST_Default.prototype._size = function () { + return 8 + list_overhead(this.body); +}; + +AST_Try.prototype._size = () => 3; + +AST_Catch.prototype._size = function () { + let size = 7 + list_overhead(this.body); + if (this.argname) { + size += 2; + } + return size; +}; + +AST_Finally.prototype._size = function () { + return 7 + list_overhead(this.body); +}; + +AST_Var.prototype._size = function () { + return 4 + list_overhead(this.definitions); +}; + +AST_Let.prototype._size = function () { + return 4 + list_overhead(this.definitions); +}; + +AST_Const.prototype._size = function () { + return 6 + list_overhead(this.definitions); +}; + +AST_Using.prototype._size = function () { + const await_size = this.await ? 6 : 0; + return await_size + 6 + list_overhead(this.definitions); +}; + +AST_VarDefLike.prototype._size = function () { + return this.value ? 1 : 0; +}; + +AST_NameMapping.prototype._size = function () { + // foreign name isn't mangled + return this.name ? 4 : 0; +}; + +AST_Import.prototype._size = function () { + // import + let size = 6; + + if (this.imported_name) size += 1; + + // from + if (this.imported_name || this.imported_names) size += 5; + + // braces, and the commas + if (this.imported_names) { + size += 2 + list_overhead(this.imported_names); + } + + return size; +}; + +AST_ImportMeta.prototype._size = () => 11; + +AST_Export.prototype._size = function () { + let size = 7 + (this.is_default ? 8 : 0); + + if (this.exported_value) { + size += this.exported_value._size(); + } + + if (this.exported_names) { + // Braces and commas + size += 2 + list_overhead(this.exported_names); + } + + if (this.module_name) { + // "from " + size += 5; + } + + return size; +}; + +AST_Call.prototype._size = function () { + if (this.optional) { + return 4 + list_overhead(this.args); + } + return 2 + list_overhead(this.args); +}; + +AST_New.prototype._size = function () { + return 6 + list_overhead(this.args); +}; + +AST_Sequence.prototype._size = function () { + return list_overhead(this.expressions); +}; + +AST_Dot.prototype._size = function () { + if (this.optional) { + return this.property.length + 2; + } + return this.property.length + 1; +}; + +AST_DotHash.prototype._size = function () { + if (this.optional) { + return this.property.length + 3; + } + return this.property.length + 2; +}; + +AST_Sub.prototype._size = function () { + return this.optional ? 4 : 2; +}; + +AST_Unary.prototype._size = function () { + if (this.operator === "typeof") return 7; + if (this.operator === "void") return 5; + return this.operator.length; +}; + +AST_Binary.prototype._size = function (info) { + if (this.operator === "in") return 4; + + let size = this.operator.length; + + if ( + (this.operator === "+" || this.operator === "-") + && this.right instanceof AST_Unary && this.right.operator === this.operator + ) { + // 1+ +a > needs space between the + + size += 1; + } + + if (this.needs_parens(info)) { + size += 2; + } + + return size; +}; + +AST_Conditional.prototype._size = () => 3; + +AST_Array.prototype._size = function () { + return 2 + list_overhead(this.elements); +}; + +AST_Object.prototype._size = function (info) { + let base = 2; + if (first_in_statement(info)) { + base += 2; // parens + } + return base + list_overhead(this.properties); +}; + +/*#__INLINE__*/ +const key_size = key => + typeof key === "string" ? key.length : 0; + +AST_ObjectKeyVal.prototype._size = function () { + return key_size(this.key) + 1; +}; + +/*#__INLINE__*/ +const static_size = is_static => is_static ? 7 : 0; + +AST_ObjectGetter.prototype._size = function () { + return 5 + static_size(this.static) + key_size(this.key); +}; + +AST_ObjectSetter.prototype._size = function () { + return 5 + static_size(this.static) + key_size(this.key); +}; + +AST_ConciseMethod.prototype._size = function () { + return static_size(this.static) + key_size(this.key); +}; + +AST_PrivateMethod.prototype._size = function () { + return AST_ConciseMethod.prototype._size.call(this) + 1; +}; + +AST_PrivateGetter.prototype._size = function () { + return AST_ConciseMethod.prototype._size.call(this) + 4; +}; + +AST_PrivateSetter.prototype._size = function () { + return AST_ConciseMethod.prototype._size.call(this) + 4; +}; + +AST_PrivateIn.prototype._size = function () { + return 5; // "#", and " in " +}; + +AST_Class.prototype._size = function () { + return ( + (this.name ? 8 : 7) + + (this.extends ? 8 : 0) + ); +}; + +AST_ClassStaticBlock.prototype._size = function () { + // "static{}" + semicolons + return 8 + list_overhead(this.body); +}; + +AST_ClassProperty.prototype._size = function () { + return ( + static_size(this.static) + + (typeof this.key === "string" ? this.key.length + 2 : 0) + + (this.value ? 1 : 0) + ); +}; + +AST_ClassPrivateProperty.prototype._size = function () { + return AST_ClassProperty.prototype._size.call(this) + 1; +}; + +AST_Symbol.prototype._size = function () { + if (!(mangle_options && this.thedef && !this.thedef.unmangleable(mangle_options))) { + return this.name.length; + } else { + return 1; + } +}; + +// TODO take propmangle into account +AST_SymbolClassProperty.prototype._size = function () { + return this.name.length; +}; + +AST_SymbolRef.prototype._size = AST_SymbolDeclaration.prototype._size = function () { + if (this.name === "arguments") return 9; + + return AST_Symbol.prototype._size.call(this); +}; + +AST_NewTarget.prototype._size = () => 10; + +AST_SymbolImportForeign.prototype._size = function () { + return this.name.length; +}; + +AST_SymbolExportForeign.prototype._size = function () { + return this.name.length; +}; + +AST_This.prototype._size = () => 4; + +AST_Super.prototype._size = () => 5; + +AST_String.prototype._size = function () { + return this.value.length + 2; +}; + +AST_Number.prototype._size = function () { + const { value } = this; + if (value === 0) return 1; + if (value > 0 && Math.floor(value) === value) { + return Math.floor(Math.log10(value) + 1); + } + return value.toString().length; +}; + +AST_BigInt.prototype._size = function () { + return this.value.length; +}; + +AST_RegExp.prototype._size = function () { + return this.value.toString().length; +}; + +AST_Null.prototype._size = () => 4; + +AST_NaN.prototype._size = () => 3; + +AST_Undefined.prototype._size = () => 6; // "void 0" + +AST_Hole.prototype._size = () => 0; // comma is taken into account by list_overhead() + +AST_Infinity.prototype._size = () => 8; + +AST_True.prototype._size = () => 4; + +AST_False.prototype._size = () => 5; + +AST_Await.prototype._size = () => 6; + +AST_Yield.prototype._size = () => 6; diff --git a/node_modules/terser/lib/sourcemap.js b/node_modules/terser/lib/sourcemap.js new file mode 100644 index 0000000..101c748 --- /dev/null +++ b/node_modules/terser/lib/sourcemap.js @@ -0,0 +1,148 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +"use strict"; + +import {SourceMapConsumer, SourceMapGenerator} from "@jridgewell/source-map"; +import {defaults, HOP} from "./utils/index.js"; + +// a small wrapper around source-map and @jridgewell/source-map +function* SourceMap(options) { + options = defaults(options, { + file : null, + root : null, + orig : null, + files: {}, + }); + + var orig_map; + var generator = new SourceMapGenerator({ + file : options.file, + sourceRoot : options.root + }); + + let sourcesContent = {__proto__: null}; + let files = options.files; + for (var name in files) if (HOP(files, name)) { + sourcesContent[name] = files[name]; + } + if (options.orig) { + // We support both @jridgewell/source-map (which has a sync + // SourceMapConsumer) and source-map (which has an async + // SourceMapConsumer). + orig_map = yield new SourceMapConsumer(options.orig); + if (orig_map.sourcesContent) { + orig_map.sources.forEach(function(source, i) { + var content = orig_map.sourcesContent[i]; + if (content) { + sourcesContent[source] = content; + } + }); + } + } + + function add(source, gen_line, gen_col, orig_line, orig_col, name) { + let generatedPos = { line: gen_line, column: gen_col }; + + if (orig_map) { + var info = orig_map.originalPositionFor({ + line: orig_line, + column: orig_col + }); + if (info.source === null) { + generator.addMapping({ + generated: generatedPos, + original: null, + source: null, + name: null + }); + return; + } + source = info.source; + orig_line = info.line; + orig_col = info.column; + name = info.name || name; + } + generator.addMapping({ + generated : generatedPos, + original : { line: orig_line, column: orig_col }, + source : source, + name : name + }); + generator.setSourceContent(source, sourcesContent[source]); + } + + function clean(map) { + const allNull = map.sourcesContent && map.sourcesContent.every(c => c == null); + if (allNull) delete map.sourcesContent; + if (map.file === undefined) delete map.file; + if (map.sourceRoot === undefined) delete map.sourceRoot; + return map; + } + + function getDecoded() { + if (!generator.toDecodedMap) return null; + return clean(generator.toDecodedMap()); + } + + function getEncoded() { + return clean(generator.toJSON()); + } + + function destroy() { + // @jridgewell/source-map's SourceMapConsumer does not need to be + // manually freed. + if (orig_map && orig_map.destroy) orig_map.destroy(); + } + + return { + add, + getDecoded, + getEncoded, + destroy, + }; +} + +export { + SourceMap, +}; diff --git a/node_modules/terser/lib/transform.js b/node_modules/terser/lib/transform.js new file mode 100644 index 0000000..9c96bd1 --- /dev/null +++ b/node_modules/terser/lib/transform.js @@ -0,0 +1,323 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +"use strict"; + +import { + AST_Array, + AST_Await, + AST_Binary, + AST_PrivateIn, + AST_Block, + AST_Call, + AST_Case, + AST_Catch, + AST_Chain, + AST_Class, + AST_ClassStaticBlock, + AST_Conditional, + AST_DefinitionsLike, + AST_Destructuring, + AST_Do, + AST_Exit, + AST_Expansion, + AST_Export, + AST_For, + AST_ForIn, + AST_If, + AST_Import, + AST_LabeledStatement, + AST_Lambda, + AST_LoopControl, + AST_NameMapping, + AST_Node, + AST_Number, + AST_Object, + AST_ObjectProperty, + AST_PrefixedTemplateString, + AST_PropAccess, + AST_Sequence, + AST_SimpleStatement, + AST_Sub, + AST_Switch, + AST_TemplateString, + AST_Try, + AST_Unary, + AST_VarDefLike, + AST_While, + AST_With, + AST_Yield, +} from "./ast.js"; +import { + MAP as do_list, + noop, +} from "./utils/index.js"; + +function def_transform(node, descend) { + node.DEFMETHOD("transform", function(tw, in_list) { + let transformed = undefined; + tw.push(this); + if (tw.before) transformed = tw.before(this, descend, in_list); + if (transformed === undefined) { + transformed = this; + descend(transformed, tw); + if (tw.after) { + const after_ret = tw.after(transformed, in_list); + if (after_ret !== undefined) transformed = after_ret; + } + } + tw.pop(); + return transformed; + }); +} + +def_transform(AST_Node, noop); + +def_transform(AST_LabeledStatement, function(self, tw) { + self.label = self.label.transform(tw); + self.body = self.body.transform(tw); +}); + +def_transform(AST_SimpleStatement, function(self, tw) { + self.body = self.body.transform(tw); +}); + +def_transform(AST_Block, function(self, tw) { + self.body = do_list(self.body, tw); +}); + +def_transform(AST_Do, function(self, tw) { + self.body = self.body.transform(tw); + self.condition = self.condition.transform(tw); +}); + +def_transform(AST_While, function(self, tw) { + self.condition = self.condition.transform(tw); + self.body = self.body.transform(tw); +}); + +def_transform(AST_For, function(self, tw) { + if (self.init) self.init = self.init.transform(tw); + if (self.condition) self.condition = self.condition.transform(tw); + if (self.step) self.step = self.step.transform(tw); + self.body = self.body.transform(tw); +}); + +def_transform(AST_ForIn, function(self, tw) { + self.init = self.init.transform(tw); + self.object = self.object.transform(tw); + self.body = self.body.transform(tw); +}); + +def_transform(AST_With, function(self, tw) { + self.expression = self.expression.transform(tw); + self.body = self.body.transform(tw); +}); + +def_transform(AST_Exit, function(self, tw) { + if (self.value) self.value = self.value.transform(tw); +}); + +def_transform(AST_LoopControl, function(self, tw) { + if (self.label) self.label = self.label.transform(tw); +}); + +def_transform(AST_If, function(self, tw) { + self.condition = self.condition.transform(tw); + self.body = self.body.transform(tw); + if (self.alternative) self.alternative = self.alternative.transform(tw); +}); + +def_transform(AST_Switch, function(self, tw) { + self.expression = self.expression.transform(tw); + self.body = do_list(self.body, tw); +}); + +def_transform(AST_Case, function(self, tw) { + self.expression = self.expression.transform(tw); + self.body = do_list(self.body, tw); +}); + +def_transform(AST_Try, function(self, tw) { + self.body = self.body.transform(tw); + if (self.bcatch) self.bcatch = self.bcatch.transform(tw); + if (self.bfinally) self.bfinally = self.bfinally.transform(tw); +}); + +def_transform(AST_Catch, function(self, tw) { + if (self.argname) self.argname = self.argname.transform(tw); + self.body = do_list(self.body, tw); +}); + +def_transform(AST_DefinitionsLike, function(self, tw) { + self.definitions = do_list(self.definitions, tw); +}); + +def_transform(AST_VarDefLike, function(self, tw) { + self.name = self.name.transform(tw); + if (self.value) self.value = self.value.transform(tw); +}); + +def_transform(AST_Destructuring, function(self, tw) { + self.names = do_list(self.names, tw); +}); + +def_transform(AST_Lambda, function(self, tw) { + if (self.name) self.name = self.name.transform(tw); + self.argnames = do_list(self.argnames, tw, /* allow_splicing */ false); + if (self.body instanceof AST_Node) { + self.body = self.body.transform(tw); + } else { + self.body = do_list(self.body, tw); + } +}); + +def_transform(AST_Call, function(self, tw) { + self.expression = self.expression.transform(tw); + self.args = do_list(self.args, tw, /* allow_splicing */ false); +}); + +def_transform(AST_Sequence, function(self, tw) { + const result = do_list(self.expressions, tw); + self.expressions = result.length + ? result + : [new AST_Number({ value: 0 })]; +}); + +def_transform(AST_PropAccess, function(self, tw) { + self.expression = self.expression.transform(tw); +}); + +def_transform(AST_Sub, function(self, tw) { + self.expression = self.expression.transform(tw); + self.property = self.property.transform(tw); +}); + +def_transform(AST_Chain, function(self, tw) { + self.expression = self.expression.transform(tw); +}); + +def_transform(AST_Yield, function(self, tw) { + if (self.expression) self.expression = self.expression.transform(tw); +}); + +def_transform(AST_Await, function(self, tw) { + self.expression = self.expression.transform(tw); +}); + +def_transform(AST_Unary, function(self, tw) { + self.expression = self.expression.transform(tw); +}); + +def_transform(AST_Binary, function(self, tw) { + self.left = self.left.transform(tw); + self.right = self.right.transform(tw); +}); + +def_transform(AST_PrivateIn, function(self, tw) { + self.key = self.key.transform(tw); + self.value = self.value.transform(tw); +}); + +def_transform(AST_Conditional, function(self, tw) { + self.condition = self.condition.transform(tw); + self.consequent = self.consequent.transform(tw); + self.alternative = self.alternative.transform(tw); +}); + +def_transform(AST_Array, function(self, tw) { + self.elements = do_list(self.elements, tw); +}); + +def_transform(AST_Object, function(self, tw) { + self.properties = do_list(self.properties, tw); +}); + +def_transform(AST_ObjectProperty, function(self, tw) { + if (self.key instanceof AST_Node) { + self.key = self.key.transform(tw); + } + if (self.value) self.value = self.value.transform(tw); +}); + +def_transform(AST_Class, function(self, tw) { + if (self.name) self.name = self.name.transform(tw); + if (self.extends) self.extends = self.extends.transform(tw); + self.properties = do_list(self.properties, tw); +}); + +def_transform(AST_ClassStaticBlock, function(self, tw) { + self.body = do_list(self.body, tw); +}); + +def_transform(AST_Expansion, function(self, tw) { + self.expression = self.expression.transform(tw); +}); + +def_transform(AST_NameMapping, function(self, tw) { + self.foreign_name = self.foreign_name.transform(tw); + self.name = self.name.transform(tw); +}); + +def_transform(AST_Import, function(self, tw) { + if (self.imported_name) self.imported_name = self.imported_name.transform(tw); + if (self.imported_names) do_list(self.imported_names, tw); + self.module_name = self.module_name.transform(tw); +}); + +def_transform(AST_Export, function(self, tw) { + if (self.exported_definition) self.exported_definition = self.exported_definition.transform(tw); + if (self.exported_value) self.exported_value = self.exported_value.transform(tw); + if (self.exported_names) do_list(self.exported_names, tw); + if (self.module_name) self.module_name = self.module_name.transform(tw); +}); + +def_transform(AST_TemplateString, function(self, tw) { + self.segments = do_list(self.segments, tw); +}); + +def_transform(AST_PrefixedTemplateString, function(self, tw) { + self.prefix = self.prefix.transform(tw); + self.template_string = self.template_string.transform(tw); +}); + diff --git a/node_modules/terser/lib/utils/first_in_statement.js b/node_modules/terser/lib/utils/first_in_statement.js new file mode 100644 index 0000000..6aa4628 --- /dev/null +++ b/node_modules/terser/lib/utils/first_in_statement.js @@ -0,0 +1,53 @@ +import { + AST_Binary, + AST_Conditional, + AST_Chain, + AST_Dot, + AST_Object, + AST_Sequence, + AST_Statement, + AST_Sub, + AST_UnaryPostfix, + AST_PrefixedTemplateString +} from "../ast.js"; + +// return true if the node at the top of the stack (that means the +// innermost node in the current output) is lexically the first in +// a statement. +function first_in_statement(stack) { + let node = stack.parent(-1); + for (let i = 0, p; p = stack.parent(i); i++) { + if (p instanceof AST_Statement && p.body === node) + return true; + if ((p instanceof AST_Sequence && p.expressions[0] === node) || + (p.TYPE === "Call" && p.expression === node) || + (p instanceof AST_PrefixedTemplateString && p.prefix === node) || + (p instanceof AST_Dot && p.expression === node) || + (p instanceof AST_Sub && p.expression === node) || + (p instanceof AST_Chain && p.expression === node) || + (p instanceof AST_Conditional && p.condition === node) || + (p instanceof AST_Binary && p.left === node) || + (p instanceof AST_UnaryPostfix && p.expression === node) + ) { + node = p; + } else { + return false; + } + } +} + +// Returns whether the leftmost item in the expression is an object +function left_is_object(node) { + if (node instanceof AST_Object) return true; + if (node instanceof AST_Sequence) return left_is_object(node.expressions[0]); + if (node.TYPE === "Call") return left_is_object(node.expression); + if (node instanceof AST_PrefixedTemplateString) return left_is_object(node.prefix); + if (node instanceof AST_Dot || node instanceof AST_Sub) return left_is_object(node.expression); + if (node instanceof AST_Chain) return left_is_object(node.expression); + if (node instanceof AST_Conditional) return left_is_object(node.condition); + if (node instanceof AST_Binary) return left_is_object(node.left); + if (node instanceof AST_UnaryPostfix) return left_is_object(node.expression); + return false; +} + +export { first_in_statement, left_is_object }; diff --git a/node_modules/terser/lib/utils/index.js b/node_modules/terser/lib/utils/index.js new file mode 100644 index 0000000..65fa989 --- /dev/null +++ b/node_modules/terser/lib/utils/index.js @@ -0,0 +1,295 @@ +/*********************************************************************** + + A JavaScript tokenizer / parser / beautifier / compressor. + https://github.com/mishoo/UglifyJS2 + + -------------------------------- (C) --------------------------------- + + Author: Mihai Bazon + + http://mihai.bazon.net/blog + + Distributed under the BSD license: + + Copyright 2012 (c) Mihai Bazon + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + + * 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. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY + EXPRESS 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 THE COPYRIGHT HOLDER 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. + + ***********************************************************************/ + +"use strict"; + +import { AST_Node } from "../ast.js"; + +function characters(str) { + return str.split(""); +} + +function member(name, array) { + return array.includes(name); +} + +class DefaultsError extends Error { + constructor(msg, defs) { + super(); + + this.name = "DefaultsError"; + this.message = msg; + this.defs = defs; + } +} + +function defaults(args, defs, croak) { + if (args === true) { + args = {}; + } else if (args != null && typeof args === "object") { + args = {...args}; + } + + const ret = args || {}; + + if (croak) for (const i in ret) if (HOP(ret, i) && !HOP(defs, i)) { + throw new DefaultsError("`" + i + "` is not a supported option", defs); + } + + for (const i in defs) if (HOP(defs, i)) { + if (!args || !HOP(args, i)) { + ret[i] = defs[i]; + } else if (i === "ecma") { + let ecma = args[i] | 0; + if (ecma > 5 && ecma < 2015) ecma += 2009; + ret[i] = ecma; + } else { + ret[i] = (args && HOP(args, i)) ? args[i] : defs[i]; + } + } + + return ret; +} + +function noop() {} +function return_false() { return false; } +function return_true() { return true; } +function return_this() { return this; } +function return_null() { return null; } + +var MAP = (function() { + function MAP(a, tw, allow_splicing = true) { + const new_a = []; + + for (let i = 0; i < a.length; ++i) { + let item = a[i]; + let ret = item.transform(tw, allow_splicing); + + if (ret instanceof AST_Node) { + new_a.push(ret); + } else if (ret instanceof Splice) { + new_a.push(...ret.v); + } + } + + return new_a; + } + + MAP.splice = function(val) { return new Splice(val); }; + MAP.skip = {}; + function Splice(val) { this.v = val; } + return MAP; +})(); + +function make_node(ctor, orig, props) { + if (!props) props = {}; + if (orig) { + if (!props.start) props.start = orig.start; + if (!props.end) props.end = orig.end; + } + return new ctor(props); +} + +function push_uniq(array, el) { + if (!array.includes(el)) + array.push(el); +} + +function string_template(text, props) { + return text.replace(/{(.+?)}/g, function(str, p) { + return props && props[p]; + }); +} + +function remove(array, el) { + for (var i = array.length; --i >= 0;) { + if (array[i] === el) array.splice(i, 1); + } +} + +function mergeSort(array, cmp) { + if (array.length < 2) return array.slice(); + function merge(a, b) { + var r = [], ai = 0, bi = 0, i = 0; + while (ai < a.length && bi < b.length) { + cmp(a[ai], b[bi]) <= 0 + ? r[i++] = a[ai++] + : r[i++] = b[bi++]; + } + if (ai < a.length) r.push.apply(r, a.slice(ai)); + if (bi < b.length) r.push.apply(r, b.slice(bi)); + return r; + } + function _ms(a) { + if (a.length <= 1) + return a; + var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m); + left = _ms(left); + right = _ms(right); + return merge(left, right); + } + return _ms(array); +} + +function makePredicate(words) { + if (!Array.isArray(words)) words = words.split(" "); + + return new Set(words.sort()); +} + +function map_add(map, key, value) { + if (map.has(key)) { + map.get(key).push(value); + } else { + map.set(key, [ value ]); + } +} + +function map_from_object(obj) { + var map = new Map(); + for (var key in obj) { + if (HOP(obj, key) && key.charAt(0) === "$") { + map.set(key.substr(1), obj[key]); + } + } + return map; +} + +function map_to_object(map) { + var obj = Object.create(null); + map.forEach(function (value, key) { + obj["$" + key] = value; + }); + return obj; +} + +function HOP(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +function keep_name(keep_setting, name) { + return keep_setting === true + || (keep_setting instanceof RegExp && keep_setting.test(name)); +} + +var lineTerminatorEscape = { + "\0": "0", + "\n": "n", + "\r": "r", + "\u2028": "u2028", + "\u2029": "u2029", +}; +function regexp_source_fix(source) { + // V8 does not escape line terminators in regexp patterns in node 12 + // We'll also remove literal \0 + return source.replace(/[\0\n\r\u2028\u2029]/g, function (match, offset) { + var escaped = source[offset - 1] == "\\" + && (source[offset - 2] != "\\" + || /(?:^|[^\\])(?:\\{2})*$/.test(source.slice(0, offset - 1))); + return (escaped ? "" : "\\") + lineTerminatorEscape[match]; + }); +} + +// Subset of regexps that is not going to cause regexp based DDOS +// https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS +const re_safe_regexp = /^[\\/|\0\s\w^$.[\]()]*$/; + +/** Check if the regexp is safe for Terser to create without risking a RegExp DOS */ +export const regexp_is_safe = (source) => re_safe_regexp.test(source); + +const all_flags = "dgimsuyv"; +function sort_regexp_flags(flags) { + const existing_flags = new Set(flags.split("")); + let out = ""; + for (const flag of all_flags) { + if (existing_flags.has(flag)) { + out += flag; + existing_flags.delete(flag); + } + } + if (existing_flags.size) { + // Flags Terser doesn't know about + existing_flags.forEach(flag => { out += flag; }); + } + return out; +} + +function has_annotation(node, annotation) { + return node._annotations & annotation; +} + +function set_annotation(node, annotation) { + node._annotations |= annotation; +} + +function clear_annotation(node, annotation) { + node._annotations &= ~annotation; +} + +export { + characters, + defaults, + HOP, + keep_name, + make_node, + makePredicate, + map_add, + map_from_object, + map_to_object, + MAP, + member, + mergeSort, + noop, + push_uniq, + regexp_source_fix, + remove, + return_false, + return_null, + return_this, + return_true, + sort_regexp_flags, + string_template, + has_annotation, + set_annotation, + clear_annotation, +}; diff --git a/node_modules/terser/main.js b/node_modules/terser/main.js new file mode 100644 index 0000000..56ab363 --- /dev/null +++ b/node_modules/terser/main.js @@ -0,0 +1,27 @@ +import "./lib/transform.js"; +import "./lib/mozilla-ast.js"; +import { minify } from "./lib/minify.js"; + +export { minify, minify_sync } from "./lib/minify.js"; +export { run_cli as _run_cli } from "./lib/cli.js"; + +export async function _default_options() { + const defs = {}; + + Object.keys(infer_options({ 0: 0 })).forEach((component) => { + const options = infer_options({ + [component]: {0: 0} + }); + + if (options) defs[component] = options; + }); + return defs; +} + +async function infer_options(options) { + try { + await minify("", options); + } catch (error) { + return error.defs; + } +} diff --git a/node_modules/terser/package.json b/node_modules/terser/package.json new file mode 100644 index 0000000..f22291e --- /dev/null +++ b/node_modules/terser/package.json @@ -0,0 +1,154 @@ +{ + "name": "terser", + "description": "JavaScript parser, mangler/compressor and beautifier toolkit for ES6+", + "homepage": "https://terser.org", + "author": "Mihai Bazon (http://lisperator.net/)", + "license": "BSD-2-Clause", + "version": "5.44.0", + "engines": { + "node": ">=10" + }, + "maintainers": [ + "Fábio Santos " + ], + "repository": "https://github.com/terser/terser", + "main": "dist/bundle.min.js", + "type": "module", + "module": "./main.js", + "exports": { + ".": [ + { + "types": "./tools/terser.d.ts", + "import": "./main.js", + "require": "./dist/bundle.min.js" + }, + "./dist/bundle.min.js" + ], + "./package": "./package.json", + "./package.json": "./package.json", + "./bin/terser": "./bin/terser" + }, + "types": "tools/terser.d.ts", + "bin": { + "terser": "bin/terser" + }, + "files": [ + "bin", + "dist", + "lib", + "tools", + "LICENSE", + "README.md", + "CHANGELOG.md", + "PATRONS.md", + "main.js" + ], + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "devDependencies": { + "@ls-lint/ls-lint": "^1.11.2", + "astring": "^1.8.5", + "eslint": "^7.32.0", + "eslump": "^3.0.0", + "esm": "^3.2.25", + "mocha": "^9.2.0", + "pre-commit": "^1.2.2", + "rollup": "^2.79.2", + "semver": "^7.5.1", + "source-map": "~0.8.0-beta.0" + }, + "scripts": { + "test": "node test/compress.js && mocha test/mocha", + "test:compress": "node test/compress.js", + "test:mocha": "mocha test/mocha", + "lint": "eslint lib", + "lint-fix": "eslint --fix lib", + "ls-lint": "ls-lint", + "build": "rollup --config --silent", + "prepare": "npm run build", + "postversion": "echo 'Remember to update the changelog!'" + }, + "keywords": [ + "uglify", + "terser", + "uglify-es", + "uglify-js", + "minify", + "minifier", + "javascript", + "ecmascript", + "es5", + "es6", + "es7", + "es8", + "es2015", + "es2016", + "es2017", + "async", + "await" + ], + "eslintConfig": { + "parserOptions": { + "sourceType": "module", + "ecmaVersion": 2020 + }, + "env": { + "node": true, + "browser": true, + "es2020": true + }, + "globals": { + "describe": false, + "it": false, + "require": false, + "before": false, + "after": false, + "global": false, + "process": false + }, + "rules": { + "brace-style": [ + "error", + "1tbs", + { + "allowSingleLine": true + } + ], + "quotes": [ + "error", + "double", + "avoid-escape" + ], + "no-debugger": "error", + "no-undef": "error", + "no-unused-vars": [ + "error", + { + "varsIgnorePattern": "^_", + "argsIgnorePattern": "^_" + } + ], + "no-tabs": "error", + "semi": [ + "error", + "always" + ], + "no-extra-semi": "error", + "no-irregular-whitespace": "error", + "space-before-blocks": [ + "error", + "always" + ] + } + }, + "pre-commit": [ + "build", + "lint-fix", + "ls-lint", + "test" + ] +} diff --git a/node_modules/terser/tools/domprops.js b/node_modules/terser/tools/domprops.js new file mode 100644 index 0000000..74fb6d2 --- /dev/null +++ b/node_modules/terser/tools/domprops.js @@ -0,0 +1,9026 @@ +export var domprops = [ + "$&", + "$'", + "$*", + "$+", + "$1", + "$2", + "$3", + "$4", + "$5", + "$6", + "$7", + "$8", + "$9", + "$_", + "$`", + "$input", + "-moz-animation", + "-moz-animation-delay", + "-moz-animation-direction", + "-moz-animation-duration", + "-moz-animation-fill-mode", + "-moz-animation-iteration-count", + "-moz-animation-name", + "-moz-animation-play-state", + "-moz-animation-timing-function", + "-moz-appearance", + "-moz-backface-visibility", + "-moz-border-end", + "-moz-border-end-color", + "-moz-border-end-style", + "-moz-border-end-width", + "-moz-border-image", + "-moz-border-start", + "-moz-border-start-color", + "-moz-border-start-style", + "-moz-border-start-width", + "-moz-box-align", + "-moz-box-direction", + "-moz-box-flex", + "-moz-box-ordinal-group", + "-moz-box-orient", + "-moz-box-pack", + "-moz-box-sizing", + "-moz-float-edge", + "-moz-font-feature-settings", + "-moz-font-language-override", + "-moz-force-broken-image-icon", + "-moz-hyphens", + "-moz-image-region", + "-moz-margin-end", + "-moz-margin-start", + "-moz-orient", + "-moz-osx-font-smoothing", + "-moz-outline-radius", + "-moz-outline-radius-bottomleft", + "-moz-outline-radius-bottomright", + "-moz-outline-radius-topleft", + "-moz-outline-radius-topright", + "-moz-padding-end", + "-moz-padding-start", + "-moz-perspective", + "-moz-perspective-origin", + "-moz-tab-size", + "-moz-text-size-adjust", + "-moz-transform", + "-moz-transform-origin", + "-moz-transform-style", + "-moz-transition", + "-moz-transition-delay", + "-moz-transition-duration", + "-moz-transition-property", + "-moz-transition-timing-function", + "-moz-user-focus", + "-moz-user-input", + "-moz-user-modify", + "-moz-user-select", + "-moz-window-dragging", + "-webkit-align-content", + "-webkit-align-items", + "-webkit-align-self", + "-webkit-animation", + "-webkit-animation-delay", + "-webkit-animation-direction", + "-webkit-animation-duration", + "-webkit-animation-fill-mode", + "-webkit-animation-iteration-count", + "-webkit-animation-name", + "-webkit-animation-play-state", + "-webkit-animation-timing-function", + "-webkit-appearance", + "-webkit-backface-visibility", + "-webkit-background-clip", + "-webkit-background-origin", + "-webkit-background-size", + "-webkit-border-bottom-left-radius", + "-webkit-border-bottom-right-radius", + "-webkit-border-image", + "-webkit-border-radius", + "-webkit-border-top-left-radius", + "-webkit-border-top-right-radius", + "-webkit-box-align", + "-webkit-box-direction", + "-webkit-box-flex", + "-webkit-box-ordinal-group", + "-webkit-box-orient", + "-webkit-box-pack", + "-webkit-box-shadow", + "-webkit-box-sizing", + "-webkit-clip-path", + "-webkit-filter", + "-webkit-flex", + "-webkit-flex-basis", + "-webkit-flex-direction", + "-webkit-flex-flow", + "-webkit-flex-grow", + "-webkit-flex-shrink", + "-webkit-flex-wrap", + "-webkit-font-feature-settings", + "-webkit-justify-content", + "-webkit-line-clamp", + "-webkit-mask", + "-webkit-mask-clip", + "-webkit-mask-composite", + "-webkit-mask-image", + "-webkit-mask-origin", + "-webkit-mask-position", + "-webkit-mask-position-x", + "-webkit-mask-position-y", + "-webkit-mask-repeat", + "-webkit-mask-size", + "-webkit-order", + "-webkit-perspective", + "-webkit-perspective-origin", + "-webkit-text-fill-color", + "-webkit-text-security", + "-webkit-text-size-adjust", + "-webkit-text-stroke", + "-webkit-text-stroke-color", + "-webkit-text-stroke-width", + "-webkit-transform", + "-webkit-transform-origin", + "-webkit-transform-style", + "-webkit-transition", + "-webkit-transition-delay", + "-webkit-transition-duration", + "-webkit-transition-property", + "-webkit-transition-timing-function", + "-webkit-user-select", + "@@iterator", + "ABORT_ERR", + "ACTIVE", + "ACTIVE_ATTRIBUTES", + "ACTIVE_TEXTURE", + "ACTIVE_UNIFORMS", + "ACTIVE_UNIFORM_BLOCKS", + "ADDITION", + "ALIASED_LINE_WIDTH_RANGE", + "ALIASED_POINT_SIZE_RANGE", + "ALL", + "ALLOW_KEYBOARD_INPUT", + "ALLPASS", + "ALPHA", + "ALPHA_BITS", + "ALREADY_SIGNALED", + "ALT_MASK", + "ALWAYS", + "ANY_SAMPLES_PASSED", + "ANY_SAMPLES_PASSED_CONSERVATIVE", + "ANY_TYPE", + "ANY_UNORDERED_NODE_TYPE", + "ARRAY_BUFFER", + "ARRAY_BUFFER_BINDING", + "ATTACHED_SHADERS", + "ATTRIBUTE_NODE", + "AT_TARGET", + "AbortController", + "AbortSignal", + "AbsoluteOrientationSensor", + "AbstractRange", + "Accelerometer", + "AddSearchProvider", + "AggregateError", + "AnalyserNode", + "Animation", + "AnimationEffect", + "AnimationEvent", + "AnimationPlaybackEvent", + "AnimationTimeline", + "AnonXMLHttpRequest", + "Any", + "AnyPermissions", + "ApplicationCache", + "ApplicationCacheErrorEvent", + "Array", + "ArrayBuffer", + "ArrayType", + "Atomics", + "Attr", + "Audio", + "AudioBuffer", + "AudioBufferSourceNode", + "AudioContext", + "AudioData", + "AudioDecoder", + "AudioDestinationNode", + "AudioEncoder", + "AudioListener", + "AudioNode", + "AudioParam", + "AudioParamMap", + "AudioProcessingEvent", + "AudioScheduledSourceNode", + "AudioSinkInfo", + "AudioStreamTrack", + "AudioWorklet", + "AudioWorkletNode", + "AuthenticatorAssertionResponse", + "AuthenticatorAttestationResponse", + "AuthenticatorResponse", + "AutocompleteErrorEvent", + "BACK", + "BAD_BOUNDARYPOINTS_ERR", + "BAD_REQUEST", + "BANDPASS", + "BLEND", + "BLEND_COLOR", + "BLEND_DST_ALPHA", + "BLEND_DST_RGB", + "BLEND_EQUATION", + "BLEND_EQUATION_ALPHA", + "BLEND_EQUATION_RGB", + "BLEND_SRC_ALPHA", + "BLEND_SRC_RGB", + "BLUE", + "BLUE_BITS", + "BLUR", + "BOOL", + "BOOLEAN_TYPE", + "BOOL_VEC2", + "BOOL_VEC3", + "BOOL_VEC4", + "BOTH", + "BROWSER_DEFAULT_WEBGL", + "BUBBLING_PHASE", + "BUFFER_SIZE", + "BUFFER_USAGE", + "BYTE", + "BYTES_PER_ELEMENT", + "BackgroundFetchManager", + "BackgroundFetchRecord", + "BackgroundFetchRegistration", + "BarProp", + "BarcodeDetector", + "BaseAudioContext", + "BaseHref", + "BatteryManager", + "BeforeInstallPromptEvent", + "BeforeLoadEvent", + "BeforeUnloadEvent", + "BigInt", + "BigInt64Array", + "BigUint64Array", + "BiquadFilterNode", + "Blob", + "BlobEvent", + "Bluetooth", + "BluetoothCharacteristicProperties", + "BluetoothDevice", + "BluetoothRemoteGATTCharacteristic", + "BluetoothRemoteGATTDescriptor", + "BluetoothRemoteGATTServer", + "BluetoothRemoteGATTService", + "BluetoothUUID", + "Boolean", + "BroadcastChannel", + "BrowserCaptureMediaStreamTrack", + "BrowserInfo", + "ByteLengthQueuingStrategy", + "CAPTURING_PHASE", + "CCW", + "CDATASection", + "CDATA_SECTION_NODE", + "CHANGE", + "CHARSET_RULE", + "CHECKING", + "CLAMP_TO_EDGE", + "CLICK", + "CLOSED", + "CLOSING", + "COLOR", + "COLOR_ATTACHMENT0", + "COLOR_ATTACHMENT1", + "COLOR_ATTACHMENT10", + "COLOR_ATTACHMENT11", + "COLOR_ATTACHMENT12", + "COLOR_ATTACHMENT13", + "COLOR_ATTACHMENT14", + "COLOR_ATTACHMENT15", + "COLOR_ATTACHMENT2", + "COLOR_ATTACHMENT3", + "COLOR_ATTACHMENT4", + "COLOR_ATTACHMENT5", + "COLOR_ATTACHMENT6", + "COLOR_ATTACHMENT7", + "COLOR_ATTACHMENT8", + "COLOR_ATTACHMENT9", + "COLOR_BUFFER_BIT", + "COLOR_CLEAR_VALUE", + "COLOR_WRITEMASK", + "COMMENT_NODE", + "COMPARE_REF_TO_TEXTURE", + "COMPILE_STATUS", + "COMPLETION_STATUS_KHR", + "COMPRESSED_RGBA_S3TC_DXT1_EXT", + "COMPRESSED_RGBA_S3TC_DXT3_EXT", + "COMPRESSED_RGBA_S3TC_DXT5_EXT", + "COMPRESSED_RGB_S3TC_DXT1_EXT", + "COMPRESSED_TEXTURE_FORMATS", + "COMPUTE", + "CONDITION_SATISFIED", + "CONFIGURATION_UNSUPPORTED", + "CONNECTING", + "CONSTANT_ALPHA", + "CONSTANT_COLOR", + "CONSTRAINT_ERR", + "CONTEXT_LOST_WEBGL", + "CONTROL_MASK", + "COPY_DST", + "COPY_READ_BUFFER", + "COPY_READ_BUFFER_BINDING", + "COPY_SRC", + "COPY_WRITE_BUFFER", + "COPY_WRITE_BUFFER_BINDING", + "COUNTER_STYLE_RULE", + "CSS", + "CSS2Properties", + "CSSAnimation", + "CSSCharsetRule", + "CSSConditionRule", + "CSSContainerRule", + "CSSCounterStyleRule", + "CSSFontFaceRule", + "CSSFontFeatureValuesRule", + "CSSFontPaletteValuesRule", + "CSSGroupingRule", + "CSSImageValue", + "CSSImportRule", + "CSSKeyframeRule", + "CSSKeyframesRule", + "CSSKeywordValue", + "CSSLayerBlockRule", + "CSSLayerStatementRule", + "CSSMarginRule", + "CSSMathClamp", + "CSSMathInvert", + "CSSMathMax", + "CSSMathMin", + "CSSMathNegate", + "CSSMathProduct", + "CSSMathSum", + "CSSMathValue", + "CSSMatrixComponent", + "CSSMediaRule", + "CSSMozDocumentRule", + "CSSNameSpaceRule", + "CSSNamespaceRule", + "CSSNestedDeclarations", + "CSSNumericArray", + "CSSNumericValue", + "CSSPageDescriptors", + "CSSPageRule", + "CSSPerspective", + "CSSPositionTryDescriptors", + "CSSPositionTryRule", + "CSSPositionValue", + "CSSPrimitiveValue", + "CSSPropertyRule", + "CSSRotate", + "CSSRule", + "CSSRuleList", + "CSSScale", + "CSSScopeRule", + "CSSSkew", + "CSSSkewX", + "CSSSkewY", + "CSSStartingStyleRule", + "CSSStyleDeclaration", + "CSSStyleRule", + "CSSStyleSheet", + "CSSStyleValue", + "CSSSupportsRule", + "CSSTransformComponent", + "CSSTransformValue", + "CSSTransition", + "CSSTranslate", + "CSSUnitValue", + "CSSUnknownRule", + "CSSUnparsedValue", + "CSSValue", + "CSSValueList", + "CSSVariableReferenceValue", + "CSSVariablesDeclaration", + "CSSVariablesRule", + "CSSViewTransitionRule", + "CSSViewportRule", + "CSS_ATTR", + "CSS_CM", + "CSS_COUNTER", + "CSS_CUSTOM", + "CSS_DEG", + "CSS_DIMENSION", + "CSS_EMS", + "CSS_EXS", + "CSS_FILTER_BLUR", + "CSS_FILTER_BRIGHTNESS", + "CSS_FILTER_CONTRAST", + "CSS_FILTER_CUSTOM", + "CSS_FILTER_DROP_SHADOW", + "CSS_FILTER_GRAYSCALE", + "CSS_FILTER_HUE_ROTATE", + "CSS_FILTER_INVERT", + "CSS_FILTER_OPACITY", + "CSS_FILTER_REFERENCE", + "CSS_FILTER_SATURATE", + "CSS_FILTER_SEPIA", + "CSS_GRAD", + "CSS_HZ", + "CSS_IDENT", + "CSS_IN", + "CSS_INHERIT", + "CSS_KHZ", + "CSS_MATRIX", + "CSS_MATRIX3D", + "CSS_MM", + "CSS_MS", + "CSS_NUMBER", + "CSS_PC", + "CSS_PERCENTAGE", + "CSS_PERSPECTIVE", + "CSS_PRIMITIVE_VALUE", + "CSS_PT", + "CSS_PX", + "CSS_RAD", + "CSS_RECT", + "CSS_RGBCOLOR", + "CSS_ROTATE", + "CSS_ROTATE3D", + "CSS_ROTATEX", + "CSS_ROTATEY", + "CSS_ROTATEZ", + "CSS_S", + "CSS_SCALE", + "CSS_SCALE3D", + "CSS_SCALEX", + "CSS_SCALEY", + "CSS_SCALEZ", + "CSS_SKEW", + "CSS_SKEWX", + "CSS_SKEWY", + "CSS_STRING", + "CSS_TRANSLATE", + "CSS_TRANSLATE3D", + "CSS_TRANSLATEX", + "CSS_TRANSLATEY", + "CSS_TRANSLATEZ", + "CSS_UNKNOWN", + "CSS_URI", + "CSS_VALUE_LIST", + "CSS_VH", + "CSS_VMAX", + "CSS_VMIN", + "CSS_VW", + "CULL_FACE", + "CULL_FACE_MODE", + "CURRENT_PROGRAM", + "CURRENT_QUERY", + "CURRENT_VERTEX_ATTRIB", + "CUSTOM", + "CW", + "Cache", + "CacheStorage", + "CanvasCaptureMediaStream", + "CanvasCaptureMediaStreamTrack", + "CanvasGradient", + "CanvasPattern", + "CanvasRenderingContext2D", + "CaptureController", + "CaretPosition", + "ChannelMergerNode", + "ChannelSplitterNode", + "ChapterInformation", + "CharacterBoundsUpdateEvent", + "CharacterData", + "ClientRect", + "ClientRectList", + "Clipboard", + "ClipboardEvent", + "ClipboardItem", + "CloseEvent", + "CloseWatcher", + "Collator", + "ColorArray", + "ColorValue", + "CommandEvent", + "Comment", + "CompileError", + "CompositionEvent", + "CompressionStream", + "Console", + "ConstantSourceNode", + "ContentVisibilityAutoStateChangeEvent", + "ContextFilter", + "ContextType", + "Controllers", + "ConvolverNode", + "CookieChangeEvent", + "CookieStore", + "CookieStoreManager", + "CountQueuingStrategy", + "Counter", + "CreateType", + "Credential", + "CredentialsContainer", + "CropTarget", + "Crypto", + "CryptoKey", + "CustomElementRegistry", + "CustomEvent", + "CustomStateSet", + "DATABASE_ERR", + "DATA_CLONE_ERR", + "DATA_ERR", + "DBLCLICK", + "DECR", + "DECR_WRAP", + "DELETE_STATUS", + "DEPTH", + "DEPTH24_STENCIL8", + "DEPTH32F_STENCIL8", + "DEPTH_ATTACHMENT", + "DEPTH_BITS", + "DEPTH_BUFFER_BIT", + "DEPTH_CLEAR_VALUE", + "DEPTH_COMPONENT", + "DEPTH_COMPONENT16", + "DEPTH_COMPONENT24", + "DEPTH_COMPONENT32F", + "DEPTH_FUNC", + "DEPTH_RANGE", + "DEPTH_STENCIL", + "DEPTH_STENCIL_ATTACHMENT", + "DEPTH_TEST", + "DEPTH_WRITEMASK", + "DEVICE_INELIGIBLE", + "DIRECTION_DOWN", + "DIRECTION_LEFT", + "DIRECTION_RIGHT", + "DIRECTION_UP", + "DISABLED", + "DISPATCH_REQUEST_ERR", + "DITHER", + "DOCUMENT_FRAGMENT_NODE", + "DOCUMENT_NODE", + "DOCUMENT_POSITION_CONTAINED_BY", + "DOCUMENT_POSITION_CONTAINS", + "DOCUMENT_POSITION_DISCONNECTED", + "DOCUMENT_POSITION_FOLLOWING", + "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC", + "DOCUMENT_POSITION_PRECEDING", + "DOCUMENT_TYPE_NODE", + "DOMCursor", + "DOMError", + "DOMException", + "DOMImplementation", + "DOMImplementationLS", + "DOMMatrix", + "DOMMatrixReadOnly", + "DOMParser", + "DOMPoint", + "DOMPointReadOnly", + "DOMQuad", + "DOMRect", + "DOMRectList", + "DOMRectReadOnly", + "DOMRequest", + "DOMSTRING_SIZE_ERR", + "DOMSettableTokenList", + "DOMStringList", + "DOMStringMap", + "DOMTokenList", + "DOMTransactionEvent", + "DOM_DELTA_LINE", + "DOM_DELTA_PAGE", + "DOM_DELTA_PIXEL", + "DOM_INPUT_METHOD_DROP", + "DOM_INPUT_METHOD_HANDWRITING", + "DOM_INPUT_METHOD_IME", + "DOM_INPUT_METHOD_KEYBOARD", + "DOM_INPUT_METHOD_MULTIMODAL", + "DOM_INPUT_METHOD_OPTION", + "DOM_INPUT_METHOD_PASTE", + "DOM_INPUT_METHOD_SCRIPT", + "DOM_INPUT_METHOD_UNKNOWN", + "DOM_INPUT_METHOD_VOICE", + "DOM_KEY_LOCATION_JOYSTICK", + "DOM_KEY_LOCATION_LEFT", + "DOM_KEY_LOCATION_MOBILE", + "DOM_KEY_LOCATION_NUMPAD", + "DOM_KEY_LOCATION_RIGHT", + "DOM_KEY_LOCATION_STANDARD", + "DOM_VK_0", + "DOM_VK_1", + "DOM_VK_2", + "DOM_VK_3", + "DOM_VK_4", + "DOM_VK_5", + "DOM_VK_6", + "DOM_VK_7", + "DOM_VK_8", + "DOM_VK_9", + "DOM_VK_A", + "DOM_VK_ACCEPT", + "DOM_VK_ADD", + "DOM_VK_ALT", + "DOM_VK_ALTGR", + "DOM_VK_AMPERSAND", + "DOM_VK_ASTERISK", + "DOM_VK_AT", + "DOM_VK_ATTN", + "DOM_VK_B", + "DOM_VK_BACKSPACE", + "DOM_VK_BACK_QUOTE", + "DOM_VK_BACK_SLASH", + "DOM_VK_BACK_SPACE", + "DOM_VK_C", + "DOM_VK_CANCEL", + "DOM_VK_CAPS_LOCK", + "DOM_VK_CIRCUMFLEX", + "DOM_VK_CLEAR", + "DOM_VK_CLOSE_BRACKET", + "DOM_VK_CLOSE_CURLY_BRACKET", + "DOM_VK_CLOSE_PAREN", + "DOM_VK_COLON", + "DOM_VK_COMMA", + "DOM_VK_CONTEXT_MENU", + "DOM_VK_CONTROL", + "DOM_VK_CONVERT", + "DOM_VK_CRSEL", + "DOM_VK_CTRL", + "DOM_VK_D", + "DOM_VK_DECIMAL", + "DOM_VK_DELETE", + "DOM_VK_DIVIDE", + "DOM_VK_DOLLAR", + "DOM_VK_DOUBLE_QUOTE", + "DOM_VK_DOWN", + "DOM_VK_E", + "DOM_VK_EISU", + "DOM_VK_END", + "DOM_VK_ENTER", + "DOM_VK_EQUALS", + "DOM_VK_EREOF", + "DOM_VK_ESCAPE", + "DOM_VK_EXCLAMATION", + "DOM_VK_EXECUTE", + "DOM_VK_EXSEL", + "DOM_VK_F", + "DOM_VK_F1", + "DOM_VK_F10", + "DOM_VK_F11", + "DOM_VK_F12", + "DOM_VK_F13", + "DOM_VK_F14", + "DOM_VK_F15", + "DOM_VK_F16", + "DOM_VK_F17", + "DOM_VK_F18", + "DOM_VK_F19", + "DOM_VK_F2", + "DOM_VK_F20", + "DOM_VK_F21", + "DOM_VK_F22", + "DOM_VK_F23", + "DOM_VK_F24", + "DOM_VK_F25", + "DOM_VK_F26", + "DOM_VK_F27", + "DOM_VK_F28", + "DOM_VK_F29", + "DOM_VK_F3", + "DOM_VK_F30", + "DOM_VK_F31", + "DOM_VK_F32", + "DOM_VK_F33", + "DOM_VK_F34", + "DOM_VK_F35", + "DOM_VK_F36", + "DOM_VK_F4", + "DOM_VK_F5", + "DOM_VK_F6", + "DOM_VK_F7", + "DOM_VK_F8", + "DOM_VK_F9", + "DOM_VK_FINAL", + "DOM_VK_FRONT", + "DOM_VK_G", + "DOM_VK_GREATER_THAN", + "DOM_VK_H", + "DOM_VK_HANGUL", + "DOM_VK_HANJA", + "DOM_VK_HASH", + "DOM_VK_HELP", + "DOM_VK_HK_TOGGLE", + "DOM_VK_HOME", + "DOM_VK_HYPHEN_MINUS", + "DOM_VK_I", + "DOM_VK_INSERT", + "DOM_VK_J", + "DOM_VK_JUNJA", + "DOM_VK_K", + "DOM_VK_KANA", + "DOM_VK_KANJI", + "DOM_VK_L", + "DOM_VK_LEFT", + "DOM_VK_LEFT_TAB", + "DOM_VK_LESS_THAN", + "DOM_VK_M", + "DOM_VK_META", + "DOM_VK_MODECHANGE", + "DOM_VK_MULTIPLY", + "DOM_VK_N", + "DOM_VK_NONCONVERT", + "DOM_VK_NUMPAD0", + "DOM_VK_NUMPAD1", + "DOM_VK_NUMPAD2", + "DOM_VK_NUMPAD3", + "DOM_VK_NUMPAD4", + "DOM_VK_NUMPAD5", + "DOM_VK_NUMPAD6", + "DOM_VK_NUMPAD7", + "DOM_VK_NUMPAD8", + "DOM_VK_NUMPAD9", + "DOM_VK_NUM_LOCK", + "DOM_VK_O", + "DOM_VK_OEM_1", + "DOM_VK_OEM_102", + "DOM_VK_OEM_2", + "DOM_VK_OEM_3", + "DOM_VK_OEM_4", + "DOM_VK_OEM_5", + "DOM_VK_OEM_6", + "DOM_VK_OEM_7", + "DOM_VK_OEM_8", + "DOM_VK_OEM_COMMA", + "DOM_VK_OEM_MINUS", + "DOM_VK_OEM_PERIOD", + "DOM_VK_OEM_PLUS", + "DOM_VK_OPEN_BRACKET", + "DOM_VK_OPEN_CURLY_BRACKET", + "DOM_VK_OPEN_PAREN", + "DOM_VK_P", + "DOM_VK_PA1", + "DOM_VK_PAGEDOWN", + "DOM_VK_PAGEUP", + "DOM_VK_PAGE_DOWN", + "DOM_VK_PAGE_UP", + "DOM_VK_PAUSE", + "DOM_VK_PERCENT", + "DOM_VK_PERIOD", + "DOM_VK_PIPE", + "DOM_VK_PLAY", + "DOM_VK_PLUS", + "DOM_VK_PRINT", + "DOM_VK_PRINTSCREEN", + "DOM_VK_PROCESSKEY", + "DOM_VK_PROPERITES", + "DOM_VK_Q", + "DOM_VK_QUESTION_MARK", + "DOM_VK_QUOTE", + "DOM_VK_R", + "DOM_VK_REDO", + "DOM_VK_RETURN", + "DOM_VK_RIGHT", + "DOM_VK_S", + "DOM_VK_SCROLL_LOCK", + "DOM_VK_SELECT", + "DOM_VK_SEMICOLON", + "DOM_VK_SEPARATOR", + "DOM_VK_SHIFT", + "DOM_VK_SLASH", + "DOM_VK_SLEEP", + "DOM_VK_SPACE", + "DOM_VK_SUBTRACT", + "DOM_VK_T", + "DOM_VK_TAB", + "DOM_VK_TILDE", + "DOM_VK_U", + "DOM_VK_UNDERSCORE", + "DOM_VK_UNDO", + "DOM_VK_UNICODE", + "DOM_VK_UP", + "DOM_VK_V", + "DOM_VK_VOLUME_DOWN", + "DOM_VK_VOLUME_MUTE", + "DOM_VK_VOLUME_UP", + "DOM_VK_W", + "DOM_VK_WIN", + "DOM_VK_WINDOW", + "DOM_VK_WIN_ICO_00", + "DOM_VK_WIN_ICO_CLEAR", + "DOM_VK_WIN_ICO_HELP", + "DOM_VK_WIN_OEM_ATTN", + "DOM_VK_WIN_OEM_AUTO", + "DOM_VK_WIN_OEM_BACKTAB", + "DOM_VK_WIN_OEM_CLEAR", + "DOM_VK_WIN_OEM_COPY", + "DOM_VK_WIN_OEM_CUSEL", + "DOM_VK_WIN_OEM_ENLW", + "DOM_VK_WIN_OEM_FINISH", + "DOM_VK_WIN_OEM_FJ_JISHO", + "DOM_VK_WIN_OEM_FJ_LOYA", + "DOM_VK_WIN_OEM_FJ_MASSHOU", + "DOM_VK_WIN_OEM_FJ_ROYA", + "DOM_VK_WIN_OEM_FJ_TOUROKU", + "DOM_VK_WIN_OEM_JUMP", + "DOM_VK_WIN_OEM_PA1", + "DOM_VK_WIN_OEM_PA2", + "DOM_VK_WIN_OEM_PA3", + "DOM_VK_WIN_OEM_RESET", + "DOM_VK_WIN_OEM_WSCTRL", + "DOM_VK_X", + "DOM_VK_XF86XK_ADD_FAVORITE", + "DOM_VK_XF86XK_APPLICATION_LEFT", + "DOM_VK_XF86XK_APPLICATION_RIGHT", + "DOM_VK_XF86XK_AUDIO_CYCLE_TRACK", + "DOM_VK_XF86XK_AUDIO_FORWARD", + "DOM_VK_XF86XK_AUDIO_LOWER_VOLUME", + "DOM_VK_XF86XK_AUDIO_MEDIA", + "DOM_VK_XF86XK_AUDIO_MUTE", + "DOM_VK_XF86XK_AUDIO_NEXT", + "DOM_VK_XF86XK_AUDIO_PAUSE", + "DOM_VK_XF86XK_AUDIO_PLAY", + "DOM_VK_XF86XK_AUDIO_PREV", + "DOM_VK_XF86XK_AUDIO_RAISE_VOLUME", + "DOM_VK_XF86XK_AUDIO_RANDOM_PLAY", + "DOM_VK_XF86XK_AUDIO_RECORD", + "DOM_VK_XF86XK_AUDIO_REPEAT", + "DOM_VK_XF86XK_AUDIO_REWIND", + "DOM_VK_XF86XK_AUDIO_STOP", + "DOM_VK_XF86XK_AWAY", + "DOM_VK_XF86XK_BACK", + "DOM_VK_XF86XK_BACK_FORWARD", + "DOM_VK_XF86XK_BATTERY", + "DOM_VK_XF86XK_BLUE", + "DOM_VK_XF86XK_BLUETOOTH", + "DOM_VK_XF86XK_BOOK", + "DOM_VK_XF86XK_BRIGHTNESS_ADJUST", + "DOM_VK_XF86XK_CALCULATOR", + "DOM_VK_XF86XK_CALENDAR", + "DOM_VK_XF86XK_CD", + "DOM_VK_XF86XK_CLOSE", + "DOM_VK_XF86XK_COMMUNITY", + "DOM_VK_XF86XK_CONTRAST_ADJUST", + "DOM_VK_XF86XK_COPY", + "DOM_VK_XF86XK_CUT", + "DOM_VK_XF86XK_CYCLE_ANGLE", + "DOM_VK_XF86XK_DISPLAY", + "DOM_VK_XF86XK_DOCUMENTS", + "DOM_VK_XF86XK_DOS", + "DOM_VK_XF86XK_EJECT", + "DOM_VK_XF86XK_EXCEL", + "DOM_VK_XF86XK_EXPLORER", + "DOM_VK_XF86XK_FAVORITES", + "DOM_VK_XF86XK_FINANCE", + "DOM_VK_XF86XK_FORWARD", + "DOM_VK_XF86XK_FRAME_BACK", + "DOM_VK_XF86XK_FRAME_FORWARD", + "DOM_VK_XF86XK_GAME", + "DOM_VK_XF86XK_GO", + "DOM_VK_XF86XK_GREEN", + "DOM_VK_XF86XK_HIBERNATE", + "DOM_VK_XF86XK_HISTORY", + "DOM_VK_XF86XK_HOME_PAGE", + "DOM_VK_XF86XK_HOT_LINKS", + "DOM_VK_XF86XK_I_TOUCH", + "DOM_VK_XF86XK_KBD_BRIGHTNESS_DOWN", + "DOM_VK_XF86XK_KBD_BRIGHTNESS_UP", + "DOM_VK_XF86XK_KBD_LIGHT_ON_OFF", + "DOM_VK_XF86XK_LAUNCH0", + "DOM_VK_XF86XK_LAUNCH1", + "DOM_VK_XF86XK_LAUNCH2", + "DOM_VK_XF86XK_LAUNCH3", + "DOM_VK_XF86XK_LAUNCH4", + "DOM_VK_XF86XK_LAUNCH5", + "DOM_VK_XF86XK_LAUNCH6", + "DOM_VK_XF86XK_LAUNCH7", + "DOM_VK_XF86XK_LAUNCH8", + "DOM_VK_XF86XK_LAUNCH9", + "DOM_VK_XF86XK_LAUNCH_A", + "DOM_VK_XF86XK_LAUNCH_B", + "DOM_VK_XF86XK_LAUNCH_C", + "DOM_VK_XF86XK_LAUNCH_D", + "DOM_VK_XF86XK_LAUNCH_E", + "DOM_VK_XF86XK_LAUNCH_F", + "DOM_VK_XF86XK_LIGHT_BULB", + "DOM_VK_XF86XK_LOG_OFF", + "DOM_VK_XF86XK_MAIL", + "DOM_VK_XF86XK_MAIL_FORWARD", + "DOM_VK_XF86XK_MARKET", + "DOM_VK_XF86XK_MEETING", + "DOM_VK_XF86XK_MEMO", + "DOM_VK_XF86XK_MENU_KB", + "DOM_VK_XF86XK_MENU_PB", + "DOM_VK_XF86XK_MESSENGER", + "DOM_VK_XF86XK_MON_BRIGHTNESS_DOWN", + "DOM_VK_XF86XK_MON_BRIGHTNESS_UP", + "DOM_VK_XF86XK_MUSIC", + "DOM_VK_XF86XK_MY_COMPUTER", + "DOM_VK_XF86XK_MY_SITES", + "DOM_VK_XF86XK_NEW", + "DOM_VK_XF86XK_NEWS", + "DOM_VK_XF86XK_OFFICE_HOME", + "DOM_VK_XF86XK_OPEN", + "DOM_VK_XF86XK_OPEN_URL", + "DOM_VK_XF86XK_OPTION", + "DOM_VK_XF86XK_PASTE", + "DOM_VK_XF86XK_PHONE", + "DOM_VK_XF86XK_PICTURES", + "DOM_VK_XF86XK_POWER_DOWN", + "DOM_VK_XF86XK_POWER_OFF", + "DOM_VK_XF86XK_RED", + "DOM_VK_XF86XK_REFRESH", + "DOM_VK_XF86XK_RELOAD", + "DOM_VK_XF86XK_REPLY", + "DOM_VK_XF86XK_ROCKER_DOWN", + "DOM_VK_XF86XK_ROCKER_ENTER", + "DOM_VK_XF86XK_ROCKER_UP", + "DOM_VK_XF86XK_ROTATE_WINDOWS", + "DOM_VK_XF86XK_ROTATION_KB", + "DOM_VK_XF86XK_ROTATION_PB", + "DOM_VK_XF86XK_SAVE", + "DOM_VK_XF86XK_SCREEN_SAVER", + "DOM_VK_XF86XK_SCROLL_CLICK", + "DOM_VK_XF86XK_SCROLL_DOWN", + "DOM_VK_XF86XK_SCROLL_UP", + "DOM_VK_XF86XK_SEARCH", + "DOM_VK_XF86XK_SEND", + "DOM_VK_XF86XK_SHOP", + "DOM_VK_XF86XK_SPELL", + "DOM_VK_XF86XK_SPLIT_SCREEN", + "DOM_VK_XF86XK_STANDBY", + "DOM_VK_XF86XK_START", + "DOM_VK_XF86XK_STOP", + "DOM_VK_XF86XK_SUBTITLE", + "DOM_VK_XF86XK_SUPPORT", + "DOM_VK_XF86XK_SUSPEND", + "DOM_VK_XF86XK_TASK_PANE", + "DOM_VK_XF86XK_TERMINAL", + "DOM_VK_XF86XK_TIME", + "DOM_VK_XF86XK_TOOLS", + "DOM_VK_XF86XK_TOP_MENU", + "DOM_VK_XF86XK_TO_DO_LIST", + "DOM_VK_XF86XK_TRAVEL", + "DOM_VK_XF86XK_USER1KB", + "DOM_VK_XF86XK_USER2KB", + "DOM_VK_XF86XK_USER_PB", + "DOM_VK_XF86XK_UWB", + "DOM_VK_XF86XK_VENDOR_HOME", + "DOM_VK_XF86XK_VIDEO", + "DOM_VK_XF86XK_VIEW", + "DOM_VK_XF86XK_WAKE_UP", + "DOM_VK_XF86XK_WEB_CAM", + "DOM_VK_XF86XK_WHEEL_BUTTON", + "DOM_VK_XF86XK_WLAN", + "DOM_VK_XF86XK_WORD", + "DOM_VK_XF86XK_WWW", + "DOM_VK_XF86XK_XFER", + "DOM_VK_XF86XK_YELLOW", + "DOM_VK_XF86XK_ZOOM_IN", + "DOM_VK_XF86XK_ZOOM_OUT", + "DOM_VK_Y", + "DOM_VK_Z", + "DOM_VK_ZOOM", + "DONE", + "DONT_CARE", + "DOWNLOADING", + "DRAGDROP", + "DRAW_BUFFER0", + "DRAW_BUFFER1", + "DRAW_BUFFER10", + "DRAW_BUFFER11", + "DRAW_BUFFER12", + "DRAW_BUFFER13", + "DRAW_BUFFER14", + "DRAW_BUFFER15", + "DRAW_BUFFER2", + "DRAW_BUFFER3", + "DRAW_BUFFER4", + "DRAW_BUFFER5", + "DRAW_BUFFER6", + "DRAW_BUFFER7", + "DRAW_BUFFER8", + "DRAW_BUFFER9", + "DRAW_FRAMEBUFFER", + "DRAW_FRAMEBUFFER_BINDING", + "DST_ALPHA", + "DST_COLOR", + "DYNAMIC_COPY", + "DYNAMIC_DRAW", + "DYNAMIC_READ", + "DataChannel", + "DataTransfer", + "DataTransferItem", + "DataTransferItemList", + "DataView", + "Date", + "DateTimeFormat", + "DecompressionStream", + "DelayNode", + "DelegatedInkTrailPresenter", + "DeprecationReportBody", + "DesktopNotification", + "DesktopNotificationCenter", + "Details", + "DeviceLightEvent", + "DeviceMotionEvent", + "DeviceMotionEventAcceleration", + "DeviceMotionEventRotationRate", + "DeviceOrientationEvent", + "DeviceProximityEvent", + "DeviceStorage", + "DeviceStorageChangeEvent", + "Directory", + "DisplayNames", + "Document", + "DocumentFragment", + "DocumentPictureInPicture", + "DocumentPictureInPictureEvent", + "DocumentTimeline", + "DocumentType", + "DragEvent", + "DurationFormat", + "DynamicsCompressorNode", + "E", + "ELEMENT_ARRAY_BUFFER", + "ELEMENT_ARRAY_BUFFER_BINDING", + "ELEMENT_NODE", + "EMPTY", + "ENCODING_ERR", + "ENDED", + "END_TO_END", + "END_TO_START", + "ENTITY_NODE", + "ENTITY_REFERENCE_NODE", + "EPSILON", + "EQUAL", + "EQUALPOWER", + "ERROR", + "EXPONENTIAL_DISTANCE", + "EditContext", + "Element", + "ElementInternals", + "ElementQuery", + "EncodedAudioChunk", + "EncodedVideoChunk", + "EnterPictureInPictureEvent", + "Entity", + "EntityReference", + "Error", + "ErrorEvent", + "EvalError", + "Event", + "EventCounts", + "EventException", + "EventSource", + "EventTarget", + "Exception", + "ExtensionContext", + "ExtensionDisabledReason", + "ExtensionInfo", + "ExtensionInstallType", + "ExtensionType", + "External", + "EyeDropper", + "FASTEST", + "FIDOSDK", + "FILTER_ACCEPT", + "FILTER_INTERRUPT", + "FILTER_REJECT", + "FILTER_SKIP", + "FINISHED_STATE", + "FIRST_ORDERED_NODE_TYPE", + "FLOAT", + "FLOAT_32_UNSIGNED_INT_24_8_REV", + "FLOAT_MAT2", + "FLOAT_MAT2x3", + "FLOAT_MAT2x4", + "FLOAT_MAT3", + "FLOAT_MAT3x2", + "FLOAT_MAT3x4", + "FLOAT_MAT4", + "FLOAT_MAT4x2", + "FLOAT_MAT4x3", + "FLOAT_VEC2", + "FLOAT_VEC3", + "FLOAT_VEC4", + "FOCUS", + "FONT_FACE_RULE", + "FONT_FEATURE_VALUES_RULE", + "FRAGMENT", + "FRAGMENT_SHADER", + "FRAGMENT_SHADER_DERIVATIVE_HINT", + "FRAGMENT_SHADER_DERIVATIVE_HINT_OES", + "FRAMEBUFFER", + "FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE", + "FRAMEBUFFER_ATTACHMENT_BLUE_SIZE", + "FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING", + "FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE", + "FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE", + "FRAMEBUFFER_ATTACHMENT_GREEN_SIZE", + "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME", + "FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE", + "FRAMEBUFFER_ATTACHMENT_RED_SIZE", + "FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE", + "FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE", + "FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER", + "FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL", + "FRAMEBUFFER_BINDING", + "FRAMEBUFFER_COMPLETE", + "FRAMEBUFFER_DEFAULT", + "FRAMEBUFFER_INCOMPLETE_ATTACHMENT", + "FRAMEBUFFER_INCOMPLETE_DIMENSIONS", + "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT", + "FRAMEBUFFER_INCOMPLETE_MULTISAMPLE", + "FRAMEBUFFER_UNSUPPORTED", + "FRONT", + "FRONT_AND_BACK", + "FRONT_FACE", + "FUNC_ADD", + "FUNC_REVERSE_SUBTRACT", + "FUNC_SUBTRACT", + "FeaturePolicy", + "FeaturePolicyViolationReportBody", + "FederatedCredential", + "Feed", + "FeedEntry", + "Fence", + "FencedFrameConfig", + "File", + "FileError", + "FileList", + "FileReader", + "FileSystem", + "FileSystemDirectoryEntry", + "FileSystemDirectoryHandle", + "FileSystemDirectoryReader", + "FileSystemEntry", + "FileSystemFileEntry", + "FileSystemFileHandle", + "FileSystemHandle", + "FileSystemWritableFileStream", + "FinalizationRegistry", + "FindInPage", + "Float16Array", + "Float32Array", + "Float64Array", + "FocusEvent", + "FontData", + "FontFace", + "FontFaceSet", + "FontFaceSetLoadEvent", + "FormData", + "FormDataEvent", + "FragmentDirective", + "Function", + "GENERATE_MIPMAP_HINT", + "GEQUAL", + "GPU", + "GPUAdapter", + "GPUAdapterInfo", + "GPUBindGroup", + "GPUBindGroupLayout", + "GPUBuffer", + "GPUBufferUsage", + "GPUCanvasContext", + "GPUColorWrite", + "GPUCommandBuffer", + "GPUCommandEncoder", + "GPUCompilationInfo", + "GPUCompilationMessage", + "GPUComputePassEncoder", + "GPUComputePipeline", + "GPUDevice", + "GPUDeviceLostInfo", + "GPUError", + "GPUExternalTexture", + "GPUInternalError", + "GPUMapMode", + "GPUOutOfMemoryError", + "GPUPipelineError", + "GPUPipelineLayout", + "GPUQuerySet", + "GPUQueue", + "GPURenderBundle", + "GPURenderBundleEncoder", + "GPURenderPassEncoder", + "GPURenderPipeline", + "GPUSampler", + "GPUShaderModule", + "GPUShaderStage", + "GPUSupportedFeatures", + "GPUSupportedLimits", + "GPUTexture", + "GPUTextureUsage", + "GPUTextureView", + "GPUUncapturedErrorEvent", + "GPUValidationError", + "GREATER", + "GREEN", + "GREEN_BITS", + "GainNode", + "Gamepad", + "GamepadAxisMoveEvent", + "GamepadButton", + "GamepadButtonEvent", + "GamepadEvent", + "GamepadHapticActuator", + "GamepadPose", + "Geolocation", + "GeolocationCoordinates", + "GeolocationPosition", + "GeolocationPositionError", + "GestureEvent", + "GetInfo", + "Global", + "GravitySensor", + "Gyroscope", + "HALF_FLOAT", + "HAVE_CURRENT_DATA", + "HAVE_ENOUGH_DATA", + "HAVE_FUTURE_DATA", + "HAVE_METADATA", + "HAVE_NOTHING", + "HEADERS_RECEIVED", + "HID", + "HIDConnectionEvent", + "HIDDEN", + "HIDDevice", + "HIDInputReportEvent", + "HIERARCHY_REQUEST_ERR", + "HIGHPASS", + "HIGHSHELF", + "HIGH_FLOAT", + "HIGH_INT", + "HORIZONTAL", + "HORIZONTAL_AXIS", + "HRTF", + "HTMLAllCollection", + "HTMLAnchorElement", + "HTMLAppletElement", + "HTMLAreaElement", + "HTMLAudioElement", + "HTMLBRElement", + "HTMLBaseElement", + "HTMLBaseFontElement", + "HTMLBlockquoteElement", + "HTMLBodyElement", + "HTMLButtonElement", + "HTMLCanvasElement", + "HTMLCollection", + "HTMLCommandElement", + "HTMLContentElement", + "HTMLDListElement", + "HTMLDataElement", + "HTMLDataListElement", + "HTMLDetailsElement", + "HTMLDialogElement", + "HTMLDirectoryElement", + "HTMLDivElement", + "HTMLDocument", + "HTMLElement", + "HTMLEmbedElement", + "HTMLFencedFrameElement", + "HTMLFieldSetElement", + "HTMLFontElement", + "HTMLFormControlsCollection", + "HTMLFormElement", + "HTMLFrameElement", + "HTMLFrameSetElement", + "HTMLHRElement", + "HTMLHeadElement", + "HTMLHeadingElement", + "HTMLHtmlElement", + "HTMLIFrameElement", + "HTMLImageElement", + "HTMLInputElement", + "HTMLIsIndexElement", + "HTMLKeygenElement", + "HTMLLIElement", + "HTMLLabelElement", + "HTMLLegendElement", + "HTMLLinkElement", + "HTMLMapElement", + "HTMLMarqueeElement", + "HTMLMediaElement", + "HTMLMenuElement", + "HTMLMenuItemElement", + "HTMLMetaElement", + "HTMLMeterElement", + "HTMLModElement", + "HTMLOListElement", + "HTMLObjectElement", + "HTMLOptGroupElement", + "HTMLOptionElement", + "HTMLOptionsCollection", + "HTMLOutputElement", + "HTMLParagraphElement", + "HTMLParamElement", + "HTMLPictureElement", + "HTMLPreElement", + "HTMLProgressElement", + "HTMLPropertiesCollection", + "HTMLQuoteElement", + "HTMLScriptElement", + "HTMLSelectElement", + "HTMLShadowElement", + "HTMLSlotElement", + "HTMLSourceElement", + "HTMLSpanElement", + "HTMLStyleElement", + "HTMLTableCaptionElement", + "HTMLTableCellElement", + "HTMLTableColElement", + "HTMLTableElement", + "HTMLTableRowElement", + "HTMLTableSectionElement", + "HTMLTemplateElement", + "HTMLTextAreaElement", + "HTMLTimeElement", + "HTMLTitleElement", + "HTMLTrackElement", + "HTMLUListElement", + "HTMLUnknownElement", + "HTMLVideoElement", + "HashChangeEvent", + "Headers", + "Highlight", + "HighlightRegistry", + "History", + "Hz", + "ICE_CHECKING", + "ICE_CLOSED", + "ICE_COMPLETED", + "ICE_CONNECTED", + "ICE_FAILED", + "ICE_GATHERING", + "ICE_WAITING", + "IDBCursor", + "IDBCursorWithValue", + "IDBDatabase", + "IDBDatabaseException", + "IDBFactory", + "IDBFileHandle", + "IDBFileRequest", + "IDBIndex", + "IDBKeyRange", + "IDBMutableFile", + "IDBObjectStore", + "IDBOpenDBRequest", + "IDBRequest", + "IDBTransaction", + "IDBVersionChangeEvent", + "IDLE", + "IIRFilterNode", + "IMPLEMENTATION_COLOR_READ_FORMAT", + "IMPLEMENTATION_COLOR_READ_TYPE", + "IMPORT_RULE", + "INCR", + "INCR_WRAP", + "INDEX", + "INDEX_SIZE_ERR", + "INDIRECT", + "INT", + "INTERLEAVED_ATTRIBS", + "INT_2_10_10_10_REV", + "INT_SAMPLER_2D", + "INT_SAMPLER_2D_ARRAY", + "INT_SAMPLER_3D", + "INT_SAMPLER_CUBE", + "INT_VEC2", + "INT_VEC3", + "INT_VEC4", + "INUSE_ATTRIBUTE_ERR", + "INVALID_ACCESS_ERR", + "INVALID_CHARACTER_ERR", + "INVALID_ENUM", + "INVALID_EXPRESSION_ERR", + "INVALID_FRAMEBUFFER_OPERATION", + "INVALID_INDEX", + "INVALID_MODIFICATION_ERR", + "INVALID_NODE_TYPE_ERR", + "INVALID_OPERATION", + "INVALID_STATE_ERR", + "INVALID_VALUE", + "INVERSE_DISTANCE", + "INVERT", + "IceCandidate", + "IconInfo", + "IdentityCredential", + "IdentityCredentialError", + "IdentityProvider", + "IdleDeadline", + "IdleDetector", + "Image", + "ImageBitmap", + "ImageBitmapRenderingContext", + "ImageCapture", + "ImageData", + "ImageDataType", + "ImageDecoder", + "ImageTrack", + "ImageTrackList", + "Infinity", + "Ink", + "InputDeviceCapabilities", + "InputDeviceInfo", + "InputEvent", + "InputMethodContext", + "InstallTrigger", + "InstallTriggerImpl", + "Instance", + "Int16Array", + "Int32Array", + "Int8Array", + "Intent", + "InternalError", + "IntersectionObserver", + "IntersectionObserverEntry", + "Intl", + "IsSearchProviderInstalled", + "Iterator", + "JSON", + "JSTag", + "KEEP", + "KEYDOWN", + "KEYFRAMES_RULE", + "KEYFRAME_RULE", + "KEYPRESS", + "KEYUP", + "KeyEvent", + "Keyboard", + "KeyboardEvent", + "KeyboardLayoutMap", + "KeyframeEffect", + "LENGTHADJUST_SPACING", + "LENGTHADJUST_SPACINGANDGLYPHS", + "LENGTHADJUST_UNKNOWN", + "LEQUAL", + "LESS", + "LINEAR", + "LINEAR_DISTANCE", + "LINEAR_MIPMAP_LINEAR", + "LINEAR_MIPMAP_NEAREST", + "LINES", + "LINE_LOOP", + "LINE_STRIP", + "LINE_WIDTH", + "LINK_STATUS", + "LIVE", + "LN10", + "LN2", + "LOADED", + "LOADING", + "LOG10E", + "LOG2E", + "LOWPASS", + "LOWSHELF", + "LOW_FLOAT", + "LOW_INT", + "LSException", + "LSParserFilter", + "LUMINANCE", + "LUMINANCE_ALPHA", + "LanguageCode", + "LargestContentfulPaint", + "LaunchParams", + "LaunchQueue", + "LaunchType", + "LayoutShift", + "LayoutShiftAttribution", + "LinearAccelerationSensor", + "LinkError", + "ListFormat", + "LocalMediaStream", + "Locale", + "Location", + "Lock", + "LockManager", + "MAP_READ", + "MAP_WRITE", + "MARGIN_RULE", + "MAX", + "MAX_3D_TEXTURE_SIZE", + "MAX_ARRAY_TEXTURE_LAYERS", + "MAX_CAPTURE_VISIBLE_TAB_CALLS_PER_SECOND", + "MAX_CLIENT_WAIT_TIMEOUT_WEBGL", + "MAX_COLOR_ATTACHMENTS", + "MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS", + "MAX_COMBINED_TEXTURE_IMAGE_UNITS", + "MAX_COMBINED_UNIFORM_BLOCKS", + "MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS", + "MAX_CUBE_MAP_TEXTURE_SIZE", + "MAX_DRAW_BUFFERS", + "MAX_ELEMENTS_INDICES", + "MAX_ELEMENTS_VERTICES", + "MAX_ELEMENT_INDEX", + "MAX_FRAGMENT_INPUT_COMPONENTS", + "MAX_FRAGMENT_UNIFORM_BLOCKS", + "MAX_FRAGMENT_UNIFORM_COMPONENTS", + "MAX_FRAGMENT_UNIFORM_VECTORS", + "MAX_PROGRAM_TEXEL_OFFSET", + "MAX_RENDERBUFFER_SIZE", + "MAX_SAFE_INTEGER", + "MAX_SAMPLES", + "MAX_SERVER_WAIT_TIMEOUT", + "MAX_TEXTURE_IMAGE_UNITS", + "MAX_TEXTURE_LOD_BIAS", + "MAX_TEXTURE_MAX_ANISOTROPY_EXT", + "MAX_TEXTURE_SIZE", + "MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS", + "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", + "MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS", + "MAX_UNIFORM_BLOCK_SIZE", + "MAX_UNIFORM_BUFFER_BINDINGS", + "MAX_VALUE", + "MAX_VARYING_COMPONENTS", + "MAX_VARYING_VECTORS", + "MAX_VERTEX_ATTRIBS", + "MAX_VERTEX_OUTPUT_COMPONENTS", + "MAX_VERTEX_TEXTURE_IMAGE_UNITS", + "MAX_VERTEX_UNIFORM_BLOCKS", + "MAX_VERTEX_UNIFORM_COMPONENTS", + "MAX_VERTEX_UNIFORM_VECTORS", + "MAX_VIEWPORT_DIMS", + "MEDIA_ERR_ABORTED", + "MEDIA_ERR_DECODE", + "MEDIA_ERR_ENCRYPTED", + "MEDIA_ERR_NETWORK", + "MEDIA_ERR_SRC_NOT_SUPPORTED", + "MEDIA_KEYERR_CLIENT", + "MEDIA_KEYERR_DOMAIN", + "MEDIA_KEYERR_HARDWARECHANGE", + "MEDIA_KEYERR_OUTPUT", + "MEDIA_KEYERR_SERVICE", + "MEDIA_KEYERR_UNKNOWN", + "MEDIA_RULE", + "MEDIUM_FLOAT", + "MEDIUM_INT", + "META_MASK", + "MIDIAccess", + "MIDIConnectionEvent", + "MIDIInput", + "MIDIInputMap", + "MIDIMessageEvent", + "MIDIOutput", + "MIDIOutputMap", + "MIDIPort", + "MIN", + "MIN_PROGRAM_TEXEL_OFFSET", + "MIN_SAFE_INTEGER", + "MIN_VALUE", + "MIRRORED_REPEAT", + "MODE_ASYNCHRONOUS", + "MODE_SYNCHRONOUS", + "MODIFICATION", + "MOUSEDOWN", + "MOUSEDRAG", + "MOUSEMOVE", + "MOUSEOUT", + "MOUSEOVER", + "MOUSEUP", + "MOZ_KEYFRAMES_RULE", + "MOZ_KEYFRAME_RULE", + "MOZ_SOURCE_CURSOR", + "MOZ_SOURCE_ERASER", + "MOZ_SOURCE_KEYBOARD", + "MOZ_SOURCE_MOUSE", + "MOZ_SOURCE_PEN", + "MOZ_SOURCE_TOUCH", + "MOZ_SOURCE_UNKNOWN", + "MSGESTURE_FLAG_BEGIN", + "MSGESTURE_FLAG_CANCEL", + "MSGESTURE_FLAG_END", + "MSGESTURE_FLAG_INERTIA", + "MSGESTURE_FLAG_NONE", + "MSPOINTER_TYPE_MOUSE", + "MSPOINTER_TYPE_PEN", + "MSPOINTER_TYPE_TOUCH", + "MS_ASYNC_CALLBACK_STATUS_ASSIGN_DELEGATE", + "MS_ASYNC_CALLBACK_STATUS_CANCEL", + "MS_ASYNC_CALLBACK_STATUS_CHOOSEANY", + "MS_ASYNC_CALLBACK_STATUS_ERROR", + "MS_ASYNC_CALLBACK_STATUS_JOIN", + "MS_ASYNC_OP_STATUS_CANCELED", + "MS_ASYNC_OP_STATUS_ERROR", + "MS_ASYNC_OP_STATUS_SUCCESS", + "MS_MANIPULATION_STATE_ACTIVE", + "MS_MANIPULATION_STATE_CANCELLED", + "MS_MANIPULATION_STATE_COMMITTED", + "MS_MANIPULATION_STATE_DRAGGING", + "MS_MANIPULATION_STATE_INERTIA", + "MS_MANIPULATION_STATE_PRESELECT", + "MS_MANIPULATION_STATE_SELECTING", + "MS_MANIPULATION_STATE_STOPPED", + "MS_MEDIA_ERR_ENCRYPTED", + "MS_MEDIA_KEYERR_CLIENT", + "MS_MEDIA_KEYERR_DOMAIN", + "MS_MEDIA_KEYERR_HARDWARECHANGE", + "MS_MEDIA_KEYERR_OUTPUT", + "MS_MEDIA_KEYERR_SERVICE", + "MS_MEDIA_KEYERR_UNKNOWN", + "Map", + "Math", + "MathMLElement", + "MediaCapabilities", + "MediaCapabilitiesInfo", + "MediaController", + "MediaDeviceInfo", + "MediaDevices", + "MediaElementAudioSourceNode", + "MediaEncryptedEvent", + "MediaError", + "MediaKeyError", + "MediaKeyEvent", + "MediaKeyMessageEvent", + "MediaKeyNeededEvent", + "MediaKeySession", + "MediaKeyStatusMap", + "MediaKeySystemAccess", + "MediaKeys", + "MediaList", + "MediaMetadata", + "MediaQueryList", + "MediaQueryListEvent", + "MediaRecorder", + "MediaRecorderErrorEvent", + "MediaSession", + "MediaSettingsRange", + "MediaSource", + "MediaSourceHandle", + "MediaStream", + "MediaStreamAudioDestinationNode", + "MediaStreamAudioSourceNode", + "MediaStreamEvent", + "MediaStreamTrack", + "MediaStreamTrackAudioSourceNode", + "MediaStreamTrackAudioStats", + "MediaStreamTrackEvent", + "MediaStreamTrackGenerator", + "MediaStreamTrackProcessor", + "MediaStreamTrackVideoStats", + "Memory", + "MessageChannel", + "MessageEvent", + "MessagePort", + "MessageSender", + "Methods", + "MimeType", + "MimeTypeArray", + "Module", + "MouseEvent", + "MouseScrollEvent", + "MozAnimation", + "MozAnimationDelay", + "MozAnimationDirection", + "MozAnimationDuration", + "MozAnimationFillMode", + "MozAnimationIterationCount", + "MozAnimationName", + "MozAnimationPlayState", + "MozAnimationTimingFunction", + "MozAppearance", + "MozBackfaceVisibility", + "MozBinding", + "MozBorderBottomColors", + "MozBorderEnd", + "MozBorderEndColor", + "MozBorderEndStyle", + "MozBorderEndWidth", + "MozBorderImage", + "MozBorderLeftColors", + "MozBorderRightColors", + "MozBorderStart", + "MozBorderStartColor", + "MozBorderStartStyle", + "MozBorderStartWidth", + "MozBorderTopColors", + "MozBoxAlign", + "MozBoxDirection", + "MozBoxFlex", + "MozBoxOrdinalGroup", + "MozBoxOrient", + "MozBoxPack", + "MozBoxSizing", + "MozCSSKeyframeRule", + "MozCSSKeyframesRule", + "MozColumnCount", + "MozColumnFill", + "MozColumnGap", + "MozColumnRule", + "MozColumnRuleColor", + "MozColumnRuleStyle", + "MozColumnRuleWidth", + "MozColumnWidth", + "MozColumns", + "MozContactChangeEvent", + "MozFloatEdge", + "MozFontFeatureSettings", + "MozFontLanguageOverride", + "MozForceBrokenImageIcon", + "MozHyphens", + "MozImageRegion", + "MozMarginEnd", + "MozMarginStart", + "MozMmsEvent", + "MozMmsMessage", + "MozMobileMessageThread", + "MozOSXFontSmoothing", + "MozOrient", + "MozOsxFontSmoothing", + "MozOutlineRadius", + "MozOutlineRadiusBottomleft", + "MozOutlineRadiusBottomright", + "MozOutlineRadiusTopleft", + "MozOutlineRadiusTopright", + "MozPaddingEnd", + "MozPaddingStart", + "MozPerspective", + "MozPerspectiveOrigin", + "MozPowerManager", + "MozSettingsEvent", + "MozSmsEvent", + "MozSmsMessage", + "MozStackSizing", + "MozTabSize", + "MozTextAlignLast", + "MozTextDecorationColor", + "MozTextDecorationLine", + "MozTextDecorationStyle", + "MozTextSizeAdjust", + "MozTransform", + "MozTransformOrigin", + "MozTransformStyle", + "MozTransition", + "MozTransitionDelay", + "MozTransitionDuration", + "MozTransitionProperty", + "MozTransitionTimingFunction", + "MozUserFocus", + "MozUserInput", + "MozUserModify", + "MozUserSelect", + "MozWindowDragging", + "MozWindowShadow", + "MutationEvent", + "MutationObserver", + "MutationRecord", + "MutedInfo", + "MutedInfoReason", + "NAMESPACE_ERR", + "NAMESPACE_RULE", + "NEAREST", + "NEAREST_MIPMAP_LINEAR", + "NEAREST_MIPMAP_NEAREST", + "NEGATIVE_INFINITY", + "NETWORK_EMPTY", + "NETWORK_ERR", + "NETWORK_IDLE", + "NETWORK_LOADED", + "NETWORK_LOADING", + "NETWORK_NO_SOURCE", + "NEVER", + "NEW", + "NEXT", + "NEXT_NO_DUPLICATE", + "NICEST", + "NODE_AFTER", + "NODE_BEFORE", + "NODE_BEFORE_AND_AFTER", + "NODE_INSIDE", + "NONE", + "NON_TRANSIENT_ERR", + "NOTATION_NODE", + "NOTCH", + "NOTEQUAL", + "NOT_ALLOWED_ERR", + "NOT_FOUND_ERR", + "NOT_READABLE_ERR", + "NOT_SUPPORTED_ERR", + "NO_DATA_ALLOWED_ERR", + "NO_ERR", + "NO_ERROR", + "NO_MODIFICATION_ALLOWED_ERR", + "NUMBER_TYPE", + "NUM_COMPRESSED_TEXTURE_FORMATS", + "NaN", + "NamedNodeMap", + "NavigateEvent", + "Navigation", + "NavigationActivation", + "NavigationCurrentEntryChangeEvent", + "NavigationDestination", + "NavigationHistoryEntry", + "NavigationPreloadManager", + "NavigationTransition", + "Navigator", + "NavigatorLogin", + "NavigatorManagedData", + "NavigatorUAData", + "NearbyLinks", + "NetworkInformation", + "Node", + "NodeFilter", + "NodeIterator", + "NodeList", + "NotRestoredReasonDetails", + "NotRestoredReasons", + "Notation", + "Notification", + "NotifyPaintEvent", + "Number", + "NumberFormat", + "OBJECT_TYPE", + "OBSOLETE", + "OK", + "ONE", + "ONE_MINUS_CONSTANT_ALPHA", + "ONE_MINUS_CONSTANT_COLOR", + "ONE_MINUS_DST_ALPHA", + "ONE_MINUS_DST_COLOR", + "ONE_MINUS_SRC_ALPHA", + "ONE_MINUS_SRC_COLOR", + "OPEN", + "OPENED", + "OPENING", + "ORDERED_NODE_ITERATOR_TYPE", + "ORDERED_NODE_SNAPSHOT_TYPE", + "OTHER_ERROR", + "OTPCredential", + "OUT_OF_MEMORY", + "Object", + "OfflineAudioCompletionEvent", + "OfflineAudioContext", + "OfflineResourceList", + "OffscreenCanvas", + "OffscreenCanvasRenderingContext2D", + "OnClickData", + "OnInstalledReason", + "OnPerformanceWarningCategory", + "OnPerformanceWarningSeverity", + "OnRestartRequiredReason", + "Option", + "OrientationSensor", + "OscillatorNode", + "OverconstrainedError", + "OverflowEvent", + "PACK_ALIGNMENT", + "PACK_ROW_LENGTH", + "PACK_SKIP_PIXELS", + "PACK_SKIP_ROWS", + "PAGE_RULE", + "PARSE_ERR", + "PATHSEG_ARC_ABS", + "PATHSEG_ARC_REL", + "PATHSEG_CLOSEPATH", + "PATHSEG_CURVETO_CUBIC_ABS", + "PATHSEG_CURVETO_CUBIC_REL", + "PATHSEG_CURVETO_CUBIC_SMOOTH_ABS", + "PATHSEG_CURVETO_CUBIC_SMOOTH_REL", + "PATHSEG_CURVETO_QUADRATIC_ABS", + "PATHSEG_CURVETO_QUADRATIC_REL", + "PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS", + "PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL", + "PATHSEG_LINETO_ABS", + "PATHSEG_LINETO_HORIZONTAL_ABS", + "PATHSEG_LINETO_HORIZONTAL_REL", + "PATHSEG_LINETO_REL", + "PATHSEG_LINETO_VERTICAL_ABS", + "PATHSEG_LINETO_VERTICAL_REL", + "PATHSEG_MOVETO_ABS", + "PATHSEG_MOVETO_REL", + "PATHSEG_UNKNOWN", + "PATH_EXISTS_ERR", + "PEAKING", + "PERMISSION_DENIED", + "PERSISTENT", + "PI", + "PIXEL_PACK_BUFFER", + "PIXEL_PACK_BUFFER_BINDING", + "PIXEL_UNPACK_BUFFER", + "PIXEL_UNPACK_BUFFER_BINDING", + "PLAYING_STATE", + "POINTS", + "POLYGON_OFFSET_FACTOR", + "POLYGON_OFFSET_FILL", + "POLYGON_OFFSET_UNITS", + "POSITION_UNAVAILABLE", + "POSITIVE_INFINITY", + "PREV", + "PREV_NO_DUPLICATE", + "PROCESSING_INSTRUCTION_NODE", + "PageChangeEvent", + "PageRevealEvent", + "PageSettings", + "PageSwapEvent", + "PageTransitionEvent", + "PaintRequest", + "PaintRequestList", + "PannerNode", + "PasswordCredential", + "Path2D", + "PaymentAddress", + "PaymentInstruments", + "PaymentManager", + "PaymentMethodChangeEvent", + "PaymentRequest", + "PaymentRequestUpdateEvent", + "PaymentResponse", + "Performance", + "PerformanceElementTiming", + "PerformanceEntry", + "PerformanceEventTiming", + "PerformanceLongAnimationFrameTiming", + "PerformanceLongTaskTiming", + "PerformanceMark", + "PerformanceMeasure", + "PerformanceNavigation", + "PerformanceNavigationTiming", + "PerformanceObserver", + "PerformanceObserverEntryList", + "PerformancePaintTiming", + "PerformanceResourceTiming", + "PerformanceScriptTiming", + "PerformanceServerTiming", + "PerformanceTiming", + "PeriodicSyncManager", + "PeriodicWave", + "PermissionStatus", + "Permissions", + "PhotoCapabilities", + "PictureInPictureEvent", + "PictureInPictureWindow", + "PlatformArch", + "PlatformInfo", + "PlatformNaclArch", + "PlatformOs", + "Plugin", + "PluginArray", + "PluralRules", + "PointerEvent", + "PopStateEvent", + "PopupBlockedEvent", + "Port", + "Presentation", + "PresentationAvailability", + "PresentationConnection", + "PresentationConnectionAvailableEvent", + "PresentationConnectionCloseEvent", + "PresentationConnectionList", + "PresentationReceiver", + "PresentationRequest", + "PressureObserver", + "PressureRecord", + "ProcessingInstruction", + "Profiler", + "ProgressEvent", + "Promise", + "PromiseRejectionEvent", + "PropertyNodeList", + "ProtectedAudience", + "Proxy", + "PublicKeyCredential", + "PushManager", + "PushSubscription", + "PushSubscriptionOptions", + "Q", + "QUERY_RESOLVE", + "QUERY_RESULT", + "QUERY_RESULT_AVAILABLE", + "QUOTA_ERR", + "QUOTA_EXCEEDED_ERR", + "QueryInterface", + "R11F_G11F_B10F", + "R16F", + "R16I", + "R16UI", + "R32F", + "R32I", + "R32UI", + "R8", + "R8I", + "R8UI", + "R8_SNORM", + "RASTERIZER_DISCARD", + "READ", + "READ_BUFFER", + "READ_FRAMEBUFFER", + "READ_FRAMEBUFFER_BINDING", + "READ_ONLY", + "READ_ONLY_ERR", + "READ_WRITE", + "RED", + "RED_BITS", + "RED_INTEGER", + "REMOVAL", + "RENDERBUFFER", + "RENDERBUFFER_ALPHA_SIZE", + "RENDERBUFFER_BINDING", + "RENDERBUFFER_BLUE_SIZE", + "RENDERBUFFER_DEPTH_SIZE", + "RENDERBUFFER_GREEN_SIZE", + "RENDERBUFFER_HEIGHT", + "RENDERBUFFER_INTERNAL_FORMAT", + "RENDERBUFFER_RED_SIZE", + "RENDERBUFFER_SAMPLES", + "RENDERBUFFER_STENCIL_SIZE", + "RENDERBUFFER_WIDTH", + "RENDERER", + "RENDERING_INTENT_ABSOLUTE_COLORIMETRIC", + "RENDERING_INTENT_AUTO", + "RENDERING_INTENT_PERCEPTUAL", + "RENDERING_INTENT_RELATIVE_COLORIMETRIC", + "RENDERING_INTENT_SATURATION", + "RENDERING_INTENT_UNKNOWN", + "RENDER_ATTACHMENT", + "REPEAT", + "REPLACE", + "RG", + "RG16F", + "RG16I", + "RG16UI", + "RG32F", + "RG32I", + "RG32UI", + "RG8", + "RG8I", + "RG8UI", + "RG8_SNORM", + "RGB", + "RGB10_A2", + "RGB10_A2UI", + "RGB16F", + "RGB16I", + "RGB16UI", + "RGB32F", + "RGB32I", + "RGB32UI", + "RGB565", + "RGB5_A1", + "RGB8", + "RGB8I", + "RGB8UI", + "RGB8_SNORM", + "RGB9_E5", + "RGBA", + "RGBA16F", + "RGBA16I", + "RGBA16UI", + "RGBA32F", + "RGBA32I", + "RGBA32UI", + "RGBA4", + "RGBA8", + "RGBA8I", + "RGBA8UI", + "RGBA8_SNORM", + "RGBA_INTEGER", + "RGBColor", + "RGB_INTEGER", + "RG_INTEGER", + "ROTATION_CLOCKWISE", + "ROTATION_COUNTERCLOCKWISE", + "RTCCertificate", + "RTCDTMFSender", + "RTCDTMFToneChangeEvent", + "RTCDataChannel", + "RTCDataChannelEvent", + "RTCDtlsTransport", + "RTCEncodedAudioFrame", + "RTCEncodedVideoFrame", + "RTCError", + "RTCErrorEvent", + "RTCIceCandidate", + "RTCIceTransport", + "RTCPeerConnection", + "RTCPeerConnectionIceErrorEvent", + "RTCPeerConnectionIceEvent", + "RTCRtpReceiver", + "RTCRtpScriptTransform", + "RTCRtpSender", + "RTCRtpTransceiver", + "RTCSctpTransport", + "RTCSessionDescription", + "RTCStatsReport", + "RTCTrackEvent", + "RadioNodeList", + "Range", + "RangeError", + "RangeException", + "ReadableByteStreamController", + "ReadableStream", + "ReadableStreamBYOBReader", + "ReadableStreamBYOBRequest", + "ReadableStreamDefaultController", + "ReadableStreamDefaultReader", + "RecordErrorEvent", + "Rect", + "ReferenceError", + "Reflect", + "RegExp", + "RelativeOrientationSensor", + "RelativeTimeFormat", + "RemotePlayback", + "Report", + "ReportBody", + "ReportingObserver", + "Request", + "RequestUpdateCheckStatus", + "ResizeObserver", + "ResizeObserverEntry", + "ResizeObserverSize", + "Response", + "RuntimeError", + "SAMPLER_2D", + "SAMPLER_2D_ARRAY", + "SAMPLER_2D_ARRAY_SHADOW", + "SAMPLER_2D_SHADOW", + "SAMPLER_3D", + "SAMPLER_BINDING", + "SAMPLER_CUBE", + "SAMPLER_CUBE_SHADOW", + "SAMPLES", + "SAMPLE_ALPHA_TO_COVERAGE", + "SAMPLE_BUFFERS", + "SAMPLE_COVERAGE", + "SAMPLE_COVERAGE_INVERT", + "SAMPLE_COVERAGE_VALUE", + "SAWTOOTH", + "SCHEDULED_STATE", + "SCISSOR_BOX", + "SCISSOR_TEST", + "SCROLL_PAGE_DOWN", + "SCROLL_PAGE_UP", + "SDP_ANSWER", + "SDP_OFFER", + "SDP_PRANSWER", + "SECURITY_ERR", + "SELECT", + "SEPARATE_ATTRIBS", + "SERIALIZE_ERR", + "SEVERITY_ERROR", + "SEVERITY_FATAL_ERROR", + "SEVERITY_WARNING", + "SHADER_COMPILER", + "SHADER_TYPE", + "SHADING_LANGUAGE_VERSION", + "SHIFT_MASK", + "SHORT", + "SHOWING", + "SHOW_ALL", + "SHOW_ATTRIBUTE", + "SHOW_CDATA_SECTION", + "SHOW_COMMENT", + "SHOW_DOCUMENT", + "SHOW_DOCUMENT_FRAGMENT", + "SHOW_DOCUMENT_TYPE", + "SHOW_ELEMENT", + "SHOW_ENTITY", + "SHOW_ENTITY_REFERENCE", + "SHOW_NOTATION", + "SHOW_PROCESSING_INSTRUCTION", + "SHOW_TEXT", + "SIGNALED", + "SIGNED_NORMALIZED", + "SINE", + "SOUNDFIELD", + "SQLException", + "SQRT1_2", + "SQRT2", + "SQUARE", + "SRC_ALPHA", + "SRC_ALPHA_SATURATE", + "SRC_COLOR", + "SRGB", + "SRGB8", + "SRGB8_ALPHA8", + "START_TO_END", + "START_TO_START", + "STATIC_COPY", + "STATIC_DRAW", + "STATIC_READ", + "STENCIL", + "STENCIL_ATTACHMENT", + "STENCIL_BACK_FAIL", + "STENCIL_BACK_FUNC", + "STENCIL_BACK_PASS_DEPTH_FAIL", + "STENCIL_BACK_PASS_DEPTH_PASS", + "STENCIL_BACK_REF", + "STENCIL_BACK_VALUE_MASK", + "STENCIL_BACK_WRITEMASK", + "STENCIL_BITS", + "STENCIL_BUFFER_BIT", + "STENCIL_CLEAR_VALUE", + "STENCIL_FAIL", + "STENCIL_FUNC", + "STENCIL_INDEX", + "STENCIL_INDEX8", + "STENCIL_PASS_DEPTH_FAIL", + "STENCIL_PASS_DEPTH_PASS", + "STENCIL_REF", + "STENCIL_TEST", + "STENCIL_VALUE_MASK", + "STENCIL_WRITEMASK", + "STORAGE", + "STORAGE_BINDING", + "STREAM_COPY", + "STREAM_DRAW", + "STREAM_READ", + "STRING_TYPE", + "STYLE_RULE", + "SUBPIXEL_BITS", + "SUPPORTS_RULE", + "SVGAElement", + "SVGAltGlyphDefElement", + "SVGAltGlyphElement", + "SVGAltGlyphItemElement", + "SVGAngle", + "SVGAnimateColorElement", + "SVGAnimateElement", + "SVGAnimateMotionElement", + "SVGAnimateTransformElement", + "SVGAnimatedAngle", + "SVGAnimatedBoolean", + "SVGAnimatedEnumeration", + "SVGAnimatedInteger", + "SVGAnimatedLength", + "SVGAnimatedLengthList", + "SVGAnimatedNumber", + "SVGAnimatedNumberList", + "SVGAnimatedPreserveAspectRatio", + "SVGAnimatedRect", + "SVGAnimatedString", + "SVGAnimatedTransformList", + "SVGAnimationElement", + "SVGCircleElement", + "SVGClipPathElement", + "SVGColor", + "SVGComponentTransferFunctionElement", + "SVGCursorElement", + "SVGDefsElement", + "SVGDescElement", + "SVGDiscardElement", + "SVGDocument", + "SVGElement", + "SVGElementInstance", + "SVGElementInstanceList", + "SVGEllipseElement", + "SVGException", + "SVGFEBlendElement", + "SVGFEColorMatrixElement", + "SVGFEComponentTransferElement", + "SVGFECompositeElement", + "SVGFEConvolveMatrixElement", + "SVGFEDiffuseLightingElement", + "SVGFEDisplacementMapElement", + "SVGFEDistantLightElement", + "SVGFEDropShadowElement", + "SVGFEFloodElement", + "SVGFEFuncAElement", + "SVGFEFuncBElement", + "SVGFEFuncGElement", + "SVGFEFuncRElement", + "SVGFEGaussianBlurElement", + "SVGFEImageElement", + "SVGFEMergeElement", + "SVGFEMergeNodeElement", + "SVGFEMorphologyElement", + "SVGFEOffsetElement", + "SVGFEPointLightElement", + "SVGFESpecularLightingElement", + "SVGFESpotLightElement", + "SVGFETileElement", + "SVGFETurbulenceElement", + "SVGFilterElement", + "SVGFontElement", + "SVGFontFaceElement", + "SVGFontFaceFormatElement", + "SVGFontFaceNameElement", + "SVGFontFaceSrcElement", + "SVGFontFaceUriElement", + "SVGForeignObjectElement", + "SVGGElement", + "SVGGeometryElement", + "SVGGlyphElement", + "SVGGlyphRefElement", + "SVGGradientElement", + "SVGGraphicsElement", + "SVGHKernElement", + "SVGImageElement", + "SVGLength", + "SVGLengthList", + "SVGLineElement", + "SVGLinearGradientElement", + "SVGMPathElement", + "SVGMarkerElement", + "SVGMaskElement", + "SVGMatrix", + "SVGMetadataElement", + "SVGMissingGlyphElement", + "SVGNumber", + "SVGNumberList", + "SVGPaint", + "SVGPathElement", + "SVGPathSeg", + "SVGPathSegArcAbs", + "SVGPathSegArcRel", + "SVGPathSegClosePath", + "SVGPathSegCurvetoCubicAbs", + "SVGPathSegCurvetoCubicRel", + "SVGPathSegCurvetoCubicSmoothAbs", + "SVGPathSegCurvetoCubicSmoothRel", + "SVGPathSegCurvetoQuadraticAbs", + "SVGPathSegCurvetoQuadraticRel", + "SVGPathSegCurvetoQuadraticSmoothAbs", + "SVGPathSegCurvetoQuadraticSmoothRel", + "SVGPathSegLinetoAbs", + "SVGPathSegLinetoHorizontalAbs", + "SVGPathSegLinetoHorizontalRel", + "SVGPathSegLinetoRel", + "SVGPathSegLinetoVerticalAbs", + "SVGPathSegLinetoVerticalRel", + "SVGPathSegList", + "SVGPathSegMovetoAbs", + "SVGPathSegMovetoRel", + "SVGPatternElement", + "SVGPoint", + "SVGPointList", + "SVGPolygonElement", + "SVGPolylineElement", + "SVGPreserveAspectRatio", + "SVGRadialGradientElement", + "SVGRect", + "SVGRectElement", + "SVGRenderingIntent", + "SVGSVGElement", + "SVGScriptElement", + "SVGSetElement", + "SVGStopElement", + "SVGStringList", + "SVGStyleElement", + "SVGSwitchElement", + "SVGSymbolElement", + "SVGTRefElement", + "SVGTSpanElement", + "SVGTextContentElement", + "SVGTextElement", + "SVGTextPathElement", + "SVGTextPositioningElement", + "SVGTitleElement", + "SVGTransform", + "SVGTransformList", + "SVGUnitTypes", + "SVGUseElement", + "SVGVKernElement", + "SVGViewElement", + "SVGViewSpec", + "SVGZoomAndPan", + "SVGZoomEvent", + "SVG_ANGLETYPE_DEG", + "SVG_ANGLETYPE_GRAD", + "SVG_ANGLETYPE_RAD", + "SVG_ANGLETYPE_UNKNOWN", + "SVG_ANGLETYPE_UNSPECIFIED", + "SVG_CHANNEL_A", + "SVG_CHANNEL_B", + "SVG_CHANNEL_G", + "SVG_CHANNEL_R", + "SVG_CHANNEL_UNKNOWN", + "SVG_COLORTYPE_CURRENTCOLOR", + "SVG_COLORTYPE_RGBCOLOR", + "SVG_COLORTYPE_RGBCOLOR_ICCCOLOR", + "SVG_COLORTYPE_UNKNOWN", + "SVG_EDGEMODE_DUPLICATE", + "SVG_EDGEMODE_NONE", + "SVG_EDGEMODE_UNKNOWN", + "SVG_EDGEMODE_WRAP", + "SVG_FEBLEND_MODE_COLOR", + "SVG_FEBLEND_MODE_COLOR_BURN", + "SVG_FEBLEND_MODE_COLOR_DODGE", + "SVG_FEBLEND_MODE_DARKEN", + "SVG_FEBLEND_MODE_DIFFERENCE", + "SVG_FEBLEND_MODE_EXCLUSION", + "SVG_FEBLEND_MODE_HARD_LIGHT", + "SVG_FEBLEND_MODE_HUE", + "SVG_FEBLEND_MODE_LIGHTEN", + "SVG_FEBLEND_MODE_LUMINOSITY", + "SVG_FEBLEND_MODE_MULTIPLY", + "SVG_FEBLEND_MODE_NORMAL", + "SVG_FEBLEND_MODE_OVERLAY", + "SVG_FEBLEND_MODE_SATURATION", + "SVG_FEBLEND_MODE_SCREEN", + "SVG_FEBLEND_MODE_SOFT_LIGHT", + "SVG_FEBLEND_MODE_UNKNOWN", + "SVG_FECOLORMATRIX_TYPE_HUEROTATE", + "SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA", + "SVG_FECOLORMATRIX_TYPE_MATRIX", + "SVG_FECOLORMATRIX_TYPE_SATURATE", + "SVG_FECOLORMATRIX_TYPE_UNKNOWN", + "SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE", + "SVG_FECOMPONENTTRANSFER_TYPE_GAMMA", + "SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY", + "SVG_FECOMPONENTTRANSFER_TYPE_LINEAR", + "SVG_FECOMPONENTTRANSFER_TYPE_TABLE", + "SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN", + "SVG_FECOMPOSITE_OPERATOR_ARITHMETIC", + "SVG_FECOMPOSITE_OPERATOR_ATOP", + "SVG_FECOMPOSITE_OPERATOR_IN", + "SVG_FECOMPOSITE_OPERATOR_LIGHTER", + "SVG_FECOMPOSITE_OPERATOR_OUT", + "SVG_FECOMPOSITE_OPERATOR_OVER", + "SVG_FECOMPOSITE_OPERATOR_UNKNOWN", + "SVG_FECOMPOSITE_OPERATOR_XOR", + "SVG_INVALID_VALUE_ERR", + "SVG_LENGTHTYPE_CM", + "SVG_LENGTHTYPE_EMS", + "SVG_LENGTHTYPE_EXS", + "SVG_LENGTHTYPE_IN", + "SVG_LENGTHTYPE_MM", + "SVG_LENGTHTYPE_NUMBER", + "SVG_LENGTHTYPE_PC", + "SVG_LENGTHTYPE_PERCENTAGE", + "SVG_LENGTHTYPE_PT", + "SVG_LENGTHTYPE_PX", + "SVG_LENGTHTYPE_UNKNOWN", + "SVG_MARKERUNITS_STROKEWIDTH", + "SVG_MARKERUNITS_UNKNOWN", + "SVG_MARKERUNITS_USERSPACEONUSE", + "SVG_MARKER_ORIENT_ANGLE", + "SVG_MARKER_ORIENT_AUTO", + "SVG_MARKER_ORIENT_AUTO_START_REVERSE", + "SVG_MARKER_ORIENT_UNKNOWN", + "SVG_MASKTYPE_ALPHA", + "SVG_MASKTYPE_LUMINANCE", + "SVG_MATRIX_NOT_INVERTABLE", + "SVG_MEETORSLICE_MEET", + "SVG_MEETORSLICE_SLICE", + "SVG_MEETORSLICE_UNKNOWN", + "SVG_MORPHOLOGY_OPERATOR_DILATE", + "SVG_MORPHOLOGY_OPERATOR_ERODE", + "SVG_MORPHOLOGY_OPERATOR_UNKNOWN", + "SVG_PAINTTYPE_CURRENTCOLOR", + "SVG_PAINTTYPE_NONE", + "SVG_PAINTTYPE_RGBCOLOR", + "SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR", + "SVG_PAINTTYPE_UNKNOWN", + "SVG_PAINTTYPE_URI", + "SVG_PAINTTYPE_URI_CURRENTCOLOR", + "SVG_PAINTTYPE_URI_NONE", + "SVG_PAINTTYPE_URI_RGBCOLOR", + "SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR", + "SVG_PRESERVEASPECTRATIO_NONE", + "SVG_PRESERVEASPECTRATIO_UNKNOWN", + "SVG_PRESERVEASPECTRATIO_XMAXYMAX", + "SVG_PRESERVEASPECTRATIO_XMAXYMID", + "SVG_PRESERVEASPECTRATIO_XMAXYMIN", + "SVG_PRESERVEASPECTRATIO_XMIDYMAX", + "SVG_PRESERVEASPECTRATIO_XMIDYMID", + "SVG_PRESERVEASPECTRATIO_XMIDYMIN", + "SVG_PRESERVEASPECTRATIO_XMINYMAX", + "SVG_PRESERVEASPECTRATIO_XMINYMID", + "SVG_PRESERVEASPECTRATIO_XMINYMIN", + "SVG_SPREADMETHOD_PAD", + "SVG_SPREADMETHOD_REFLECT", + "SVG_SPREADMETHOD_REPEAT", + "SVG_SPREADMETHOD_UNKNOWN", + "SVG_STITCHTYPE_NOSTITCH", + "SVG_STITCHTYPE_STITCH", + "SVG_STITCHTYPE_UNKNOWN", + "SVG_TRANSFORM_MATRIX", + "SVG_TRANSFORM_ROTATE", + "SVG_TRANSFORM_SCALE", + "SVG_TRANSFORM_SKEWX", + "SVG_TRANSFORM_SKEWY", + "SVG_TRANSFORM_TRANSLATE", + "SVG_TRANSFORM_UNKNOWN", + "SVG_TURBULENCE_TYPE_FRACTALNOISE", + "SVG_TURBULENCE_TYPE_TURBULENCE", + "SVG_TURBULENCE_TYPE_UNKNOWN", + "SVG_UNIT_TYPE_OBJECTBOUNDINGBOX", + "SVG_UNIT_TYPE_UNKNOWN", + "SVG_UNIT_TYPE_USERSPACEONUSE", + "SVG_WRONG_TYPE_ERR", + "SVG_ZOOMANDPAN_DISABLE", + "SVG_ZOOMANDPAN_MAGNIFY", + "SVG_ZOOMANDPAN_UNKNOWN", + "SYNC_CONDITION", + "SYNC_FENCE", + "SYNC_FLAGS", + "SYNC_FLUSH_COMMANDS_BIT", + "SYNC_GPU_COMMANDS_COMPLETE", + "SYNC_STATUS", + "SYNTAX_ERR", + "SavedPages", + "Scheduler", + "Scheduling", + "Screen", + "ScreenDetailed", + "ScreenDetails", + "ScreenOrientation", + "Script", + "ScriptProcessorNode", + "ScrollAreaEvent", + "ScrollTimeline", + "SecurityPolicyViolationEvent", + "Segmenter", + "Selection", + "Sensor", + "SensorErrorEvent", + "Serial", + "SerialPort", + "ServiceWorker", + "ServiceWorkerContainer", + "ServiceWorkerRegistration", + "SessionDescription", + "Set", + "ShadowRoot", + "SharedArrayBuffer", + "SharedStorage", + "SharedStorageWorklet", + "SharedWorker", + "SharingState", + "SimpleGestureEvent", + "SnapEvent", + "SourceBuffer", + "SourceBufferList", + "SpeechSynthesis", + "SpeechSynthesisErrorEvent", + "SpeechSynthesisEvent", + "SpeechSynthesisUtterance", + "SpeechSynthesisVoice", + "StaticRange", + "StereoPannerNode", + "StopIteration", + "Storage", + "StorageBucket", + "StorageBucketManager", + "StorageEvent", + "StorageManager", + "String", + "StructType", + "StylePropertyMap", + "StylePropertyMapReadOnly", + "StyleSheet", + "StyleSheetList", + "SubmitEvent", + "SubtleCrypto", + "Symbol", + "SyncManager", + "SyntaxError", + "TAB_ID_NONE", + "TAB_INDEX_NONE", + "TEMPORARY", + "TEXTPATH_METHODTYPE_ALIGN", + "TEXTPATH_METHODTYPE_STRETCH", + "TEXTPATH_METHODTYPE_UNKNOWN", + "TEXTPATH_SPACINGTYPE_AUTO", + "TEXTPATH_SPACINGTYPE_EXACT", + "TEXTPATH_SPACINGTYPE_UNKNOWN", + "TEXTURE", + "TEXTURE0", + "TEXTURE1", + "TEXTURE10", + "TEXTURE11", + "TEXTURE12", + "TEXTURE13", + "TEXTURE14", + "TEXTURE15", + "TEXTURE16", + "TEXTURE17", + "TEXTURE18", + "TEXTURE19", + "TEXTURE2", + "TEXTURE20", + "TEXTURE21", + "TEXTURE22", + "TEXTURE23", + "TEXTURE24", + "TEXTURE25", + "TEXTURE26", + "TEXTURE27", + "TEXTURE28", + "TEXTURE29", + "TEXTURE3", + "TEXTURE30", + "TEXTURE31", + "TEXTURE4", + "TEXTURE5", + "TEXTURE6", + "TEXTURE7", + "TEXTURE8", + "TEXTURE9", + "TEXTURE_2D", + "TEXTURE_2D_ARRAY", + "TEXTURE_3D", + "TEXTURE_BASE_LEVEL", + "TEXTURE_BINDING", + "TEXTURE_BINDING_2D", + "TEXTURE_BINDING_2D_ARRAY", + "TEXTURE_BINDING_3D", + "TEXTURE_BINDING_CUBE_MAP", + "TEXTURE_COMPARE_FUNC", + "TEXTURE_COMPARE_MODE", + "TEXTURE_CUBE_MAP", + "TEXTURE_CUBE_MAP_NEGATIVE_X", + "TEXTURE_CUBE_MAP_NEGATIVE_Y", + "TEXTURE_CUBE_MAP_NEGATIVE_Z", + "TEXTURE_CUBE_MAP_POSITIVE_X", + "TEXTURE_CUBE_MAP_POSITIVE_Y", + "TEXTURE_CUBE_MAP_POSITIVE_Z", + "TEXTURE_IMMUTABLE_FORMAT", + "TEXTURE_IMMUTABLE_LEVELS", + "TEXTURE_MAG_FILTER", + "TEXTURE_MAX_ANISOTROPY_EXT", + "TEXTURE_MAX_LEVEL", + "TEXTURE_MAX_LOD", + "TEXTURE_MIN_FILTER", + "TEXTURE_MIN_LOD", + "TEXTURE_WRAP_R", + "TEXTURE_WRAP_S", + "TEXTURE_WRAP_T", + "TEXT_NODE", + "TIMEOUT", + "TIMEOUT_ERR", + "TIMEOUT_EXPIRED", + "TIMEOUT_IGNORED", + "TOO_LARGE_ERR", + "TRANSACTION_INACTIVE_ERR", + "TRANSFORM_FEEDBACK", + "TRANSFORM_FEEDBACK_ACTIVE", + "TRANSFORM_FEEDBACK_BINDING", + "TRANSFORM_FEEDBACK_BUFFER", + "TRANSFORM_FEEDBACK_BUFFER_BINDING", + "TRANSFORM_FEEDBACK_BUFFER_MODE", + "TRANSFORM_FEEDBACK_BUFFER_SIZE", + "TRANSFORM_FEEDBACK_BUFFER_START", + "TRANSFORM_FEEDBACK_PAUSED", + "TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN", + "TRANSFORM_FEEDBACK_VARYINGS", + "TRIANGLE", + "TRIANGLES", + "TRIANGLE_FAN", + "TRIANGLE_STRIP", + "TYPE_BACK_FORWARD", + "TYPE_ERR", + "TYPE_MISMATCH_ERR", + "TYPE_NAVIGATE", + "TYPE_RELOAD", + "TYPE_RESERVED", + "Tab", + "TabStatus", + "Table", + "Tag", + "TaskAttributionTiming", + "TaskController", + "TaskPriorityChangeEvent", + "TaskSignal", + "Text", + "TextDecoder", + "TextDecoderStream", + "TextEncoder", + "TextEncoderStream", + "TextEvent", + "TextFormat", + "TextFormatUpdateEvent", + "TextMetrics", + "TextTrack", + "TextTrackCue", + "TextTrackCueList", + "TextTrackList", + "TextUpdateEvent", + "TimeEvent", + "TimeRanges", + "ToggleEvent", + "Touch", + "TouchEvent", + "TouchList", + "TrackEvent", + "TransformStream", + "TransformStreamDefaultController", + "TransitionEvent", + "TreeWalker", + "TrustedHTML", + "TrustedScript", + "TrustedScriptURL", + "TrustedTypePolicy", + "TrustedTypePolicyFactory", + "TypeError", + "TypedObject", + "U2F", + "UIEvent", + "UNCACHED", + "UNIFORM", + "UNIFORM_ARRAY_STRIDE", + "UNIFORM_BLOCK_ACTIVE_UNIFORMS", + "UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES", + "UNIFORM_BLOCK_BINDING", + "UNIFORM_BLOCK_DATA_SIZE", + "UNIFORM_BLOCK_INDEX", + "UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER", + "UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER", + "UNIFORM_BUFFER", + "UNIFORM_BUFFER_BINDING", + "UNIFORM_BUFFER_OFFSET_ALIGNMENT", + "UNIFORM_BUFFER_SIZE", + "UNIFORM_BUFFER_START", + "UNIFORM_IS_ROW_MAJOR", + "UNIFORM_MATRIX_STRIDE", + "UNIFORM_OFFSET", + "UNIFORM_SIZE", + "UNIFORM_TYPE", + "UNKNOWN_ERR", + "UNKNOWN_RULE", + "UNMASKED_RENDERER_WEBGL", + "UNMASKED_VENDOR_WEBGL", + "UNORDERED_NODE_ITERATOR_TYPE", + "UNORDERED_NODE_SNAPSHOT_TYPE", + "UNPACK_ALIGNMENT", + "UNPACK_COLORSPACE_CONVERSION_WEBGL", + "UNPACK_FLIP_Y_WEBGL", + "UNPACK_IMAGE_HEIGHT", + "UNPACK_PREMULTIPLY_ALPHA_WEBGL", + "UNPACK_ROW_LENGTH", + "UNPACK_SKIP_IMAGES", + "UNPACK_SKIP_PIXELS", + "UNPACK_SKIP_ROWS", + "UNSCHEDULED_STATE", + "UNSENT", + "UNSIGNALED", + "UNSIGNED_BYTE", + "UNSIGNED_INT", + "UNSIGNED_INT_10F_11F_11F_REV", + "UNSIGNED_INT_24_8", + "UNSIGNED_INT_2_10_10_10_REV", + "UNSIGNED_INT_5_9_9_9_REV", + "UNSIGNED_INT_SAMPLER_2D", + "UNSIGNED_INT_SAMPLER_2D_ARRAY", + "UNSIGNED_INT_SAMPLER_3D", + "UNSIGNED_INT_SAMPLER_CUBE", + "UNSIGNED_INT_VEC2", + "UNSIGNED_INT_VEC3", + "UNSIGNED_INT_VEC4", + "UNSIGNED_NORMALIZED", + "UNSIGNED_SHORT", + "UNSIGNED_SHORT_4_4_4_4", + "UNSIGNED_SHORT_5_5_5_1", + "UNSIGNED_SHORT_5_6_5", + "UNSPECIFIED_EVENT_TYPE_ERR", + "UPDATEREADY", + "URIError", + "URL", + "URLPattern", + "URLSearchParams", + "URLUnencoded", + "URL_MISMATCH_ERR", + "USB", + "USBAlternateInterface", + "USBConfiguration", + "USBConnectionEvent", + "USBDevice", + "USBEndpoint", + "USBInTransferResult", + "USBInterface", + "USBIsochronousInTransferPacket", + "USBIsochronousInTransferResult", + "USBIsochronousOutTransferPacket", + "USBIsochronousOutTransferResult", + "USBOutTransferResult", + "UTC", + "Uint16Array", + "Uint32Array", + "Uint8Array", + "Uint8ClampedArray", + "UpdateFilter", + "UpdatePropertyName", + "UserActivation", + "UserMessageHandler", + "UserMessageHandlersNamespace", + "UserProximityEvent", + "VALIDATE_STATUS", + "VALIDATION_ERR", + "VARIABLES_RULE", + "VENDOR", + "VERSION", + "VERSION_CHANGE", + "VERSION_ERR", + "VERTEX", + "VERTEX_ARRAY_BINDING", + "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING", + "VERTEX_ATTRIB_ARRAY_DIVISOR", + "VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE", + "VERTEX_ATTRIB_ARRAY_ENABLED", + "VERTEX_ATTRIB_ARRAY_INTEGER", + "VERTEX_ATTRIB_ARRAY_NORMALIZED", + "VERTEX_ATTRIB_ARRAY_POINTER", + "VERTEX_ATTRIB_ARRAY_SIZE", + "VERTEX_ATTRIB_ARRAY_STRIDE", + "VERTEX_ATTRIB_ARRAY_TYPE", + "VERTEX_SHADER", + "VERTICAL", + "VERTICAL_AXIS", + "VER_ERR", + "VIEWPORT", + "VIEWPORT_RULE", + "VRDisplay", + "VRDisplayCapabilities", + "VRDisplayEvent", + "VREyeParameters", + "VRFieldOfView", + "VRFrameData", + "VRPose", + "VRStageParameters", + "VTTCue", + "VTTRegion", + "ValidityState", + "VideoColorSpace", + "VideoDecoder", + "VideoEncoder", + "VideoFrame", + "VideoPlaybackQuality", + "VideoStreamTrack", + "ViewTimeline", + "ViewTransition", + "ViewTransitionTypeSet", + "ViewType", + "VirtualKeyboard", + "VirtualKeyboardGeometryChangeEvent", + "VisibilityStateEntry", + "VisualViewport", + "WAIT_FAILED", + "WEBKIT_FILTER_RULE", + "WEBKIT_KEYFRAMES_RULE", + "WEBKIT_KEYFRAME_RULE", + "WEBKIT_REGION_RULE", + "WGSLLanguageFeatures", + "WINDOW_ID_CURRENT", + "WINDOW_ID_NONE", + "WRITE", + "WRONG_DOCUMENT_ERR", + "WakeLock", + "WakeLockSentinel", + "WasmAnyRef", + "WaveShaperNode", + "WeakMap", + "WeakRef", + "WeakSet", + "WebAssembly", + "WebGL2RenderingContext", + "WebGLActiveInfo", + "WebGLBuffer", + "WebGLContextEvent", + "WebGLFramebuffer", + "WebGLObject", + "WebGLProgram", + "WebGLQuery", + "WebGLRenderbuffer", + "WebGLRenderingContext", + "WebGLSampler", + "WebGLShader", + "WebGLShaderPrecisionFormat", + "WebGLSync", + "WebGLTexture", + "WebGLTransformFeedback", + "WebGLUniformLocation", + "WebGLVertexArray", + "WebGLVertexArrayObject", + "WebKitAnimationEvent", + "WebKitBlobBuilder", + "WebKitCSSFilterRule", + "WebKitCSSFilterValue", + "WebKitCSSKeyframeRule", + "WebKitCSSKeyframesRule", + "WebKitCSSMatrix", + "WebKitCSSRegionRule", + "WebKitCSSTransformValue", + "WebKitDataCue", + "WebKitGamepad", + "WebKitMediaKeyError", + "WebKitMediaKeyMessageEvent", + "WebKitMediaKeySession", + "WebKitMediaKeys", + "WebKitMediaSource", + "WebKitMutationObserver", + "WebKitNamespace", + "WebKitPlaybackTargetAvailabilityEvent", + "WebKitPoint", + "WebKitShadowRoot", + "WebKitSourceBuffer", + "WebKitSourceBufferList", + "WebKitTransitionEvent", + "WebSocket", + "WebSocketError", + "WebSocketStream", + "WebTransport", + "WebTransportBidirectionalStream", + "WebTransportDatagramDuplexStream", + "WebTransportError", + "WebTransportReceiveStream", + "WebTransportSendStream", + "WebkitAlignContent", + "WebkitAlignItems", + "WebkitAlignSelf", + "WebkitAnimation", + "WebkitAnimationDelay", + "WebkitAnimationDirection", + "WebkitAnimationDuration", + "WebkitAnimationFillMode", + "WebkitAnimationIterationCount", + "WebkitAnimationName", + "WebkitAnimationPlayState", + "WebkitAnimationTimingFunction", + "WebkitAppearance", + "WebkitBackfaceVisibility", + "WebkitBackgroundClip", + "WebkitBackgroundOrigin", + "WebkitBackgroundSize", + "WebkitBorderBottomLeftRadius", + "WebkitBorderBottomRightRadius", + "WebkitBorderImage", + "WebkitBorderRadius", + "WebkitBorderTopLeftRadius", + "WebkitBorderTopRightRadius", + "WebkitBoxAlign", + "WebkitBoxDirection", + "WebkitBoxFlex", + "WebkitBoxOrdinalGroup", + "WebkitBoxOrient", + "WebkitBoxPack", + "WebkitBoxShadow", + "WebkitBoxSizing", + "WebkitClipPath", + "WebkitFilter", + "WebkitFlex", + "WebkitFlexBasis", + "WebkitFlexDirection", + "WebkitFlexFlow", + "WebkitFlexGrow", + "WebkitFlexShrink", + "WebkitFlexWrap", + "WebkitFontFeatureSettings", + "WebkitJustifyContent", + "WebkitLineClamp", + "WebkitMask", + "WebkitMaskClip", + "WebkitMaskComposite", + "WebkitMaskImage", + "WebkitMaskOrigin", + "WebkitMaskPosition", + "WebkitMaskPositionX", + "WebkitMaskPositionY", + "WebkitMaskRepeat", + "WebkitMaskSize", + "WebkitOrder", + "WebkitPerspective", + "WebkitPerspectiveOrigin", + "WebkitTextFillColor", + "WebkitTextSecurity", + "WebkitTextSizeAdjust", + "WebkitTextStroke", + "WebkitTextStrokeColor", + "WebkitTextStrokeWidth", + "WebkitTransform", + "WebkitTransformOrigin", + "WebkitTransformStyle", + "WebkitTransition", + "WebkitTransitionDelay", + "WebkitTransitionDuration", + "WebkitTransitionProperty", + "WebkitTransitionTimingFunction", + "WebkitUserSelect", + "WheelEvent", + "Window", + "WindowControlsOverlay", + "WindowControlsOverlayGeometryChangeEvent", + "WindowState", + "WindowType", + "Worker", + "Worklet", + "WritableStream", + "WritableStreamDefaultController", + "WritableStreamDefaultWriter", + "XMLDocument", + "XMLHttpRequest", + "XMLHttpRequestEventTarget", + "XMLHttpRequestException", + "XMLHttpRequestProgressEvent", + "XMLHttpRequestUpload", + "XMLSerializer", + "XMLStylesheetProcessingInstruction", + "XPathEvaluator", + "XPathException", + "XPathExpression", + "XPathNSResolver", + "XPathResult", + "XRAnchor", + "XRAnchorSet", + "XRBoundedReferenceSpace", + "XRCPUDepthInformation", + "XRCamera", + "XRDOMOverlayState", + "XRDepthInformation", + "XRFrame", + "XRHand", + "XRHitTestResult", + "XRHitTestSource", + "XRInputSource", + "XRInputSourceArray", + "XRInputSourceEvent", + "XRInputSourcesChangeEvent", + "XRJointPose", + "XRJointSpace", + "XRLayer", + "XRLightEstimate", + "XRLightProbe", + "XRPose", + "XRRay", + "XRReferenceSpace", + "XRReferenceSpaceEvent", + "XRRenderState", + "XRRigidTransform", + "XRSession", + "XRSessionEvent", + "XRSpace", + "XRSystem", + "XRTransientInputHitTestResult", + "XRTransientInputHitTestSource", + "XRView", + "XRViewerPose", + "XRViewport", + "XRWebGLBinding", + "XRWebGLDepthInformation", + "XRWebGLLayer", + "XSLTProcessor", + "ZERO", + "ZoomSettings", + "ZoomSettingsMode", + "ZoomSettingsScope", + "_XD0M_", + "_YD0M_", + "__REACT_DEVTOOLS_GLOBAL_HOOK__", + "__brand", + "__defineGetter__", + "__defineSetter__", + "__lookupGetter__", + "__lookupSetter__", + "__opera", + "__proto__", + "_browserjsran", + "a", + "aLink", + "abbr", + "abort", + "aborted", + "aboutConfigPrefs", + "abs", + "absolute", + "acceleration", + "accelerationIncludingGravity", + "accelerator", + "accent-color", + "accentColor", + "accept", + "acceptCharset", + "acceptNode", + "access", + "accessKey", + "accessKeyLabel", + "accuracy", + "acos", + "acosh", + "action", + "actionURL", + "actions", + "activated", + "activation", + "activationStart", + "active", + "activeCues", + "activeElement", + "activeSourceBuffers", + "activeSourceCount", + "activeTexture", + "activeVRDisplays", + "activityLog", + "actualBoundingBoxAscent", + "actualBoundingBoxDescent", + "actualBoundingBoxLeft", + "actualBoundingBoxRight", + "adAuctionComponents", + "adAuctionHeaders", + "add", + "addAll", + "addBehavior", + "addCandidate", + "addColorStop", + "addCue", + "addElement", + "addEventListener", + "addFilter", + "addFromString", + "addFromUri", + "addIceCandidate", + "addImport", + "addListener", + "addModule", + "addNamed", + "addPageRule", + "addPath", + "addPointer", + "addRange", + "addRegion", + "addRule", + "addSearchEngine", + "addSourceBuffer", + "addStream", + "addTextTrack", + "addTrack", + "addTransceiver", + "addWakeLockListener", + "added", + "addedNodes", + "additionalName", + "additiveSymbols", + "addons", + "address", + "addressLine", + "addressModeU", + "addressModeV", + "addressModeW", + "adoptNode", + "adoptedCallback", + "adoptedStyleSheets", + "adr", + "advance", + "after", + "alarms", + "album", + "alert", + "algorithm", + "align", + "align-content", + "align-items", + "align-self", + "alignContent", + "alignItems", + "alignSelf", + "alignmentBaseline", + "alinkColor", + "all", + "allSettled", + "allocationSize", + "allow", + "allowFullscreen", + "allowPaymentRequest", + "allowedDirections", + "allowedFeatures", + "allowedToPlay", + "allowsFeature", + "alpha", + "alphaMode", + "alphaToCoverageEnabled", + "alphabeticBaseline", + "alt", + "altGraphKey", + "altHtml", + "altKey", + "altLeft", + "alternate", + "alternateSetting", + "alternates", + "altitude", + "altitudeAccuracy", + "altitudeAngle", + "amplitude", + "ancestorOrigins", + "anchor", + "anchorNode", + "anchorOffset", + "anchorSpace", + "anchors", + "and", + "angle", + "angularAcceleration", + "angularVelocity", + "animVal", + "animate", + "animated", + "animatedInstanceRoot", + "animatedNormalizedPathSegList", + "animatedPathSegList", + "animatedPoints", + "animation", + "animation-composition", + "animation-delay", + "animation-direction", + "animation-duration", + "animation-fill-mode", + "animation-iteration-count", + "animation-name", + "animation-play-state", + "animation-timing-function", + "animationComposition", + "animationDelay", + "animationDirection", + "animationDuration", + "animationFillMode", + "animationIterationCount", + "animationName", + "animationPlayState", + "animationStartTime", + "animationTimingFunction", + "animationsPaused", + "anniversary", + "antialias", + "anticipatedRemoval", + "any", + "app", + "appCodeName", + "appMinorVersion", + "appName", + "appNotifications", + "appVersion", + "appearance", + "append", + "appendBuffer", + "appendChild", + "appendData", + "appendItem", + "appendMedium", + "appendNamed", + "appendRule", + "appendStream", + "appendWindowEnd", + "appendWindowStart", + "applets", + "applicationCache", + "applicationServerKey", + "apply", + "applyConstraints", + "applyElement", + "arc", + "arcTo", + "arch", + "architecture", + "archive", + "areas", + "arguments", + "ariaAtomic", + "ariaAutoComplete", + "ariaBrailleLabel", + "ariaBrailleRoleDescription", + "ariaBusy", + "ariaChecked", + "ariaColCount", + "ariaColIndex", + "ariaColIndexText", + "ariaColSpan", + "ariaCurrent", + "ariaDescription", + "ariaDisabled", + "ariaExpanded", + "ariaHasPopup", + "ariaHidden", + "ariaInvalid", + "ariaKeyShortcuts", + "ariaLabel", + "ariaLevel", + "ariaLive", + "ariaModal", + "ariaMultiLine", + "ariaMultiSelectable", + "ariaOrientation", + "ariaPlaceholder", + "ariaPosInSet", + "ariaPressed", + "ariaReadOnly", + "ariaRelevant", + "ariaRequired", + "ariaRoleDescription", + "ariaRowCount", + "ariaRowIndex", + "ariaRowIndexText", + "ariaRowSpan", + "ariaSelected", + "ariaSetSize", + "ariaSort", + "ariaValueMax", + "ariaValueMin", + "ariaValueNow", + "ariaValueText", + "arrayBuffer", + "arrayLayerCount", + "arrayStride", + "artist", + "artwork", + "as", + "asIntN", + "asUintN", + "ascentOverride", + "asin", + "asinh", + "aspect", + "aspect-ratio", + "aspectRatio", + "assert", + "assign", + "assignedElements", + "assignedNodes", + "assignedSlot", + "async", + "asyncDispose", + "asyncIterator", + "at", + "atEnd", + "atan", + "atan2", + "atanh", + "atob", + "attachEvent", + "attachInternals", + "attachShader", + "attachShadow", + "attachedElements", + "attachments", + "attack", + "attestationObject", + "attrChange", + "attrName", + "attributeChangedCallback", + "attributeFilter", + "attributeName", + "attributeNamespace", + "attributeOldValue", + "attributeStyleMap", + "attributes", + "attribution", + "attributionSrc", + "audioBitrateMode", + "audioBitsPerSecond", + "audioTracks", + "audioWorklet", + "authenticatedSignedWrites", + "authenticatorAttachment", + "authenticatorData", + "autoIncrement", + "autobuffer", + "autocapitalize", + "autocomplete", + "autocorrect", + "autofocus", + "automationRate", + "autoplay", + "availHeight", + "availLeft", + "availTop", + "availWidth", + "availability", + "available", + "averageLatency", + "aversion", + "ax", + "axes", + "axis", + "ay", + "azimuth", + "azimuthAngle", + "b", + "back", + "backdrop-filter", + "backdropFilter", + "backends", + "backface-visibility", + "backfaceVisibility", + "background", + "background-attachment", + "background-blend-mode", + "background-clip", + "background-color", + "background-image", + "background-origin", + "background-position", + "background-position-x", + "background-position-y", + "background-repeat", + "background-size", + "backgroundAttachment", + "backgroundBlendMode", + "backgroundClip", + "backgroundColor", + "backgroundFetch", + "backgroundImage", + "backgroundOrigin", + "backgroundPosition", + "backgroundPositionX", + "backgroundPositionY", + "backgroundRepeat", + "backgroundSize", + "badInput", + "badge", + "balance", + "baseArrayLayer", + "baseFrequencyX", + "baseFrequencyY", + "baseLatency", + "baseLayer", + "baseMipLevel", + "baseNode", + "baseOffset", + "basePalette", + "baseURI", + "baseVal", + "baseline-source", + "baselineShift", + "baselineSource", + "battery", + "bday", + "before", + "beginComputePass", + "beginElement", + "beginElementAt", + "beginOcclusionQuery", + "beginPath", + "beginQuery", + "beginRenderPass", + "beginTransformFeedback", + "beginningOfPassWriteIndex", + "behavior", + "behaviorCookie", + "behaviorPart", + "behaviorUrns", + "beta", + "bezierCurveTo", + "bgColor", + "bgProperties", + "bias", + "big", + "bigint64", + "biguint64", + "binaryType", + "bind", + "bindAttribLocation", + "bindBuffer", + "bindBufferBase", + "bindBufferRange", + "bindFramebuffer", + "bindGroupLayouts", + "bindRenderbuffer", + "bindSampler", + "bindTexture", + "bindTransformFeedback", + "bindVertexArray", + "binding", + "bitness", + "blend", + "blendColor", + "blendEquation", + "blendEquationSeparate", + "blendFunc", + "blendFuncSeparate", + "blink", + "blitFramebuffer", + "blob", + "block-size", + "blockDirection", + "blockSize", + "blockedURI", + "blocking", + "blockingDuration", + "blue", + "bluetooth", + "blur", + "body", + "bodyUsed", + "bold", + "bookmarks", + "booleanValue", + "border", + "border-block", + "border-block-color", + "border-block-end", + "border-block-end-color", + "border-block-end-style", + "border-block-end-width", + "border-block-start", + "border-block-start-color", + "border-block-start-style", + "border-block-start-width", + "border-block-style", + "border-block-width", + "border-bottom", + "border-bottom-color", + "border-bottom-left-radius", + "border-bottom-right-radius", + "border-bottom-style", + "border-bottom-width", + "border-collapse", + "border-color", + "border-end-end-radius", + "border-end-start-radius", + "border-image", + "border-image-outset", + "border-image-repeat", + "border-image-slice", + "border-image-source", + "border-image-width", + "border-inline", + "border-inline-color", + "border-inline-end", + "border-inline-end-color", + "border-inline-end-style", + "border-inline-end-width", + "border-inline-start", + "border-inline-start-color", + "border-inline-start-style", + "border-inline-start-width", + "border-inline-style", + "border-inline-width", + "border-left", + "border-left-color", + "border-left-style", + "border-left-width", + "border-radius", + "border-right", + "border-right-color", + "border-right-style", + "border-right-width", + "border-spacing", + "border-start-end-radius", + "border-start-start-radius", + "border-style", + "border-top", + "border-top-color", + "border-top-left-radius", + "border-top-right-radius", + "border-top-style", + "border-top-width", + "border-width", + "borderBlock", + "borderBlockColor", + "borderBlockEnd", + "borderBlockEndColor", + "borderBlockEndStyle", + "borderBlockEndWidth", + "borderBlockStart", + "borderBlockStartColor", + "borderBlockStartStyle", + "borderBlockStartWidth", + "borderBlockStyle", + "borderBlockWidth", + "borderBottom", + "borderBottomColor", + "borderBottomLeftRadius", + "borderBottomRightRadius", + "borderBottomStyle", + "borderBottomWidth", + "borderBoxSize", + "borderCollapse", + "borderColor", + "borderColorDark", + "borderColorLight", + "borderEndEndRadius", + "borderEndStartRadius", + "borderImage", + "borderImageOutset", + "borderImageRepeat", + "borderImageSlice", + "borderImageSource", + "borderImageWidth", + "borderInline", + "borderInlineColor", + "borderInlineEnd", + "borderInlineEndColor", + "borderInlineEndStyle", + "borderInlineEndWidth", + "borderInlineStart", + "borderInlineStartColor", + "borderInlineStartStyle", + "borderInlineStartWidth", + "borderInlineStyle", + "borderInlineWidth", + "borderLeft", + "borderLeftColor", + "borderLeftStyle", + "borderLeftWidth", + "borderRadius", + "borderRight", + "borderRightColor", + "borderRightStyle", + "borderRightWidth", + "borderSpacing", + "borderStartEndRadius", + "borderStartStartRadius", + "borderStyle", + "borderTop", + "borderTopColor", + "borderTopLeftRadius", + "borderTopRightRadius", + "borderTopStyle", + "borderTopWidth", + "borderWidth", + "bottom", + "bottomMargin", + "bound", + "boundElements", + "boundingClientRect", + "boundingHeight", + "boundingLeft", + "boundingRect", + "boundingTop", + "boundingWidth", + "bounds", + "boundsGeometry", + "box-decoration-break", + "box-shadow", + "box-sizing", + "boxDecorationBreak", + "boxShadow", + "boxSizing", + "brand", + "brands", + "break-after", + "break-before", + "break-inside", + "breakAfter", + "breakBefore", + "breakInside", + "broadcast", + "browser", + "browserLanguage", + "browserSettings", + "browsingData", + "browsingTopics", + "btoa", + "bubbles", + "buffer", + "bufferData", + "bufferDepth", + "bufferSize", + "bufferSubData", + "buffered", + "bufferedAmount", + "bufferedAmountLowThreshold", + "buffers", + "buildID", + "buildNumber", + "button", + "buttonID", + "buttons", + "byobRequest", + "byteLength", + "byteOffset", + "bytes", + "bytesPerRow", + "bytesWritten", + "c", + "cache", + "caches", + "call", + "caller", + "camera", + "canBeFormatted", + "canBeMounted", + "canBeShared", + "canConstructInDedicatedWorker", + "canGoBack", + "canGoForward", + "canHaveChildren", + "canHaveHTML", + "canInsertDTMF", + "canIntercept", + "canLoadAdAuctionFencedFrame", + "canLoadOpaqueURL", + "canMakePayment", + "canParse", + "canPlayType", + "canPresent", + "canShare", + "canTransition", + "canTrickleIceCandidates", + "cancel", + "cancelAndHoldAtTime", + "cancelAnimationFrame", + "cancelBubble", + "cancelIdleCallback", + "cancelScheduledValues", + "cancelVideoFrameCallback", + "cancelWatchAvailability", + "cancelable", + "candidate", + "canonicalUUID", + "canvas", + "cap", + "capabilities", + "caption", + "caption-side", + "captionSide", + "captivePortal", + "capture", + "captureEvents", + "captureStackTrace", + "captureStream", + "captureTab", + "captureVisibleTab", + "caret-color", + "caretBidiLevel", + "caretColor", + "caretPositionFromPoint", + "caretRangeFromPoint", + "cast", + "catch", + "category", + "cbrt", + "cd", + "ceil", + "cellIndex", + "cellPadding", + "cellSpacing", + "cells", + "ch", + "chOff", + "chain", + "challenge", + "changeType", + "changed", + "changedTouches", + "channel", + "channelCount", + "channelCountMode", + "channelInterpretation", + "chapterInfo", + "char", + "charAt", + "charCode", + "charCodeAt", + "charIndex", + "charLength", + "characterBounds", + "characterBoundsRangeStart", + "characterData", + "characterDataOldValue", + "characterSet", + "characteristic", + "charging", + "chargingTime", + "charset", + "check", + "checkDCE", + "checkEnclosure", + "checkFramebufferStatus", + "checkIntersection", + "checkValidity", + "checkVisibility", + "checked", + "childElementCount", + "childList", + "childNodes", + "children", + "chrome", + "ciphertext", + "cite", + "city", + "claimInterface", + "claimed", + "classList", + "className", + "classid", + "clear", + "clearAppBadge", + "clearAttributes", + "clearBuffer", + "clearBufferfi", + "clearBufferfv", + "clearBufferiv", + "clearBufferuiv", + "clearColor", + "clearData", + "clearDepth", + "clearHalt", + "clearImmediate", + "clearInterval", + "clearLiveSeekableRange", + "clearMarks", + "clearMaxGCPauseAccumulator", + "clearMeasures", + "clearOriginJoinedAdInterestGroups", + "clearParameters", + "clearRect", + "clearResourceTimings", + "clearShadow", + "clearStencil", + "clearTimeout", + "clearValue", + "clearWatch", + "click", + "clickCount", + "clientDataJSON", + "clientHeight", + "clientInformation", + "clientLeft", + "clientRect", + "clientRects", + "clientTop", + "clientWaitSync", + "clientWidth", + "clientX", + "clientY", + "clip", + "clip-path", + "clip-rule", + "clipBottom", + "clipLeft", + "clipPath", + "clipPathUnits", + "clipRight", + "clipRule", + "clipTop", + "clipboard", + "clipboardData", + "clonable", + "clone", + "cloneContents", + "cloneNode", + "cloneRange", + "close", + "closeCode", + "closePath", + "closed", + "closest", + "clz", + "clz32", + "cm", + "cmp", + "code", + "codeBase", + "codePointAt", + "codeType", + "codedHeight", + "codedRect", + "codedWidth", + "colSpan", + "collapse", + "collapseToEnd", + "collapseToStart", + "collapsed", + "collect", + "collections", + "colno", + "color", + "color-adjust", + "color-interpolation", + "color-interpolation-filters", + "color-scheme", + "colorAdjust", + "colorAttachments", + "colorDepth", + "colorFormats", + "colorInterpolation", + "colorInterpolationFilters", + "colorMask", + "colorScheme", + "colorSpace", + "colorType", + "cols", + "column-count", + "column-fill", + "column-gap", + "column-rule", + "column-rule-color", + "column-rule-style", + "column-rule-width", + "column-span", + "column-width", + "columnCount", + "columnFill", + "columnGap", + "columnNumber", + "columnRule", + "columnRuleColor", + "columnRuleStyle", + "columnRuleWidth", + "columnSpan", + "columnWidth", + "columns", + "command", + "commands", + "commit", + "commitLoadTime", + "commitPreferences", + "commitStyles", + "commonAncestorContainer", + "compact", + "compare", + "compareBoundaryPoints", + "compareDocumentPosition", + "compareEndPoints", + "compareExchange", + "compareNode", + "comparePoint", + "compatMode", + "compatible", + "compile", + "compileShader", + "compileStreaming", + "complete", + "completed", + "component", + "componentFromPoint", + "composed", + "composedPath", + "composite", + "compositionEndOffset", + "compositionStartOffset", + "compressedTexImage2D", + "compressedTexImage3D", + "compressedTexSubImage2D", + "compressedTexSubImage3D", + "compute", + "computedStyleMap", + "concat", + "conditionText", + "coneInnerAngle", + "coneOuterAngle", + "coneOuterGain", + "config", + "configurable", + "configuration", + "configurationName", + "configurationValue", + "configurations", + "configure", + "confirm", + "confirmComposition", + "confirmSiteSpecificTrackingException", + "confirmWebWideTrackingException", + "congestionControl", + "connect", + "connectEnd", + "connectNative", + "connectShark", + "connectStart", + "connected", + "connectedCallback", + "connection", + "connectionInfo", + "connectionList", + "connectionSpeed", + "connectionState", + "connections", + "console", + "consolidate", + "constants", + "constraint", + "constrictionActive", + "construct", + "constructor", + "contactID", + "contain", + "contain-intrinsic-block-size", + "contain-intrinsic-height", + "contain-intrinsic-inline-size", + "contain-intrinsic-size", + "contain-intrinsic-width", + "containIntrinsicBlockSize", + "containIntrinsicHeight", + "containIntrinsicInlineSize", + "containIntrinsicSize", + "containIntrinsicWidth", + "container", + "container-name", + "container-type", + "containerId", + "containerName", + "containerQuery", + "containerSrc", + "containerType", + "contains", + "containsNode", + "content", + "content-visibility", + "contentBoxSize", + "contentDocument", + "contentEditable", + "contentHint", + "contentOverflow", + "contentRect", + "contentScriptType", + "contentStyleType", + "contentType", + "contentVisibility", + "contentWindow", + "context", + "contextId", + "contextIds", + "contextMenu", + "contextMenus", + "contextType", + "contextTypes", + "contextmenu", + "contextualIdentities", + "continue", + "continuePrimaryKey", + "continuous", + "control", + "controlTransferIn", + "controlTransferOut", + "controller", + "controls", + "controlsList", + "convertPointFromNode", + "convertQuadFromNode", + "convertRectFromNode", + "convertToBlob", + "convertToSpecifiedUnits", + "cookie", + "cookieEnabled", + "cookieStore", + "cookies", + "coords", + "copyBufferSubData", + "copyBufferToBuffer", + "copyBufferToTexture", + "copyExternalImageToTexture", + "copyFromChannel", + "copyTexImage2D", + "copyTexSubImage2D", + "copyTexSubImage3D", + "copyTextureToBuffer", + "copyTextureToTexture", + "copyTo", + "copyToChannel", + "copyWithin", + "correspondingElement", + "correspondingUseElement", + "corruptedVideoFrames", + "cos", + "cosh", + "count", + "countReset", + "counter-increment", + "counter-reset", + "counter-set", + "counterIncrement", + "counterReset", + "counterSet", + "country", + "cpuClass", + "cpuSleepAllowed", + "cqb", + "cqh", + "cqi", + "cqmax", + "cqmin", + "cqw", + "create", + "createAnalyser", + "createAnchor", + "createAnswer", + "createAttribute", + "createAttributeNS", + "createAuctionNonce", + "createBidirectionalStream", + "createBindGroup", + "createBindGroupLayout", + "createBiquadFilter", + "createBuffer", + "createBufferSource", + "createCDATASection", + "createCSSStyleSheet", + "createCaption", + "createChannelMerger", + "createChannelSplitter", + "createCommandEncoder", + "createComment", + "createComputePipeline", + "createComputePipelineAsync", + "createConicGradient", + "createConstantSource", + "createContextualFragment", + "createControlRange", + "createConvolver", + "createDTMFSender", + "createDataChannel", + "createDelay", + "createDelayNode", + "createDocument", + "createDocumentFragment", + "createDocumentType", + "createDynamicsCompressor", + "createElement", + "createElementNS", + "createEncodedStreams", + "createEntityReference", + "createEvent", + "createEventObject", + "createExpression", + "createFramebuffer", + "createFunction", + "createGain", + "createGainNode", + "createHTML", + "createHTMLDocument", + "createIIRFilter", + "createImageBitmap", + "createImageData", + "createIndex", + "createJavaScriptNode", + "createLinearGradient", + "createMediaElementSource", + "createMediaKeys", + "createMediaStreamDestination", + "createMediaStreamSource", + "createMediaStreamTrackSource", + "createMutableFile", + "createNSResolver", + "createNodeIterator", + "createNotification", + "createObjectStore", + "createObjectURL", + "createOffer", + "createOscillator", + "createPanner", + "createPattern", + "createPeriodicWave", + "createPipelineLayout", + "createPolicy", + "createPopup", + "createProcessingInstruction", + "createProgram", + "createQuery", + "createQuerySet", + "createRadialGradient", + "createRange", + "createRangeCollection", + "createReader", + "createRenderBundleEncoder", + "createRenderPipeline", + "createRenderPipelineAsync", + "createRenderbuffer", + "createSVGAngle", + "createSVGLength", + "createSVGMatrix", + "createSVGNumber", + "createSVGPathSegArcAbs", + "createSVGPathSegArcRel", + "createSVGPathSegClosePath", + "createSVGPathSegCurvetoCubicAbs", + "createSVGPathSegCurvetoCubicRel", + "createSVGPathSegCurvetoCubicSmoothAbs", + "createSVGPathSegCurvetoCubicSmoothRel", + "createSVGPathSegCurvetoQuadraticAbs", + "createSVGPathSegCurvetoQuadraticRel", + "createSVGPathSegCurvetoQuadraticSmoothAbs", + "createSVGPathSegCurvetoQuadraticSmoothRel", + "createSVGPathSegLinetoAbs", + "createSVGPathSegLinetoHorizontalAbs", + "createSVGPathSegLinetoHorizontalRel", + "createSVGPathSegLinetoRel", + "createSVGPathSegLinetoVerticalAbs", + "createSVGPathSegLinetoVerticalRel", + "createSVGPathSegMovetoAbs", + "createSVGPathSegMovetoRel", + "createSVGPoint", + "createSVGRect", + "createSVGTransform", + "createSVGTransformFromMatrix", + "createSampler", + "createScript", + "createScriptProcessor", + "createScriptURL", + "createSession", + "createShader", + "createShaderModule", + "createShadowRoot", + "createStereoPanner", + "createStyleSheet", + "createTBody", + "createTFoot", + "createTHead", + "createTask", + "createTextNode", + "createTextRange", + "createTexture", + "createTouch", + "createTouchList", + "createTransformFeedback", + "createTreeWalker", + "createUnidirectionalStream", + "createVertexArray", + "createView", + "createWaveShaper", + "createWorklet", + "createWritable", + "creationTime", + "credentialless", + "credentials", + "criticalCHRestart", + "cropTo", + "crossOrigin", + "crossOriginIsolated", + "crypto", + "csi", + "csp", + "cssFloat", + "cssRules", + "cssText", + "cssValueType", + "ctrlKey", + "ctrlLeft", + "cues", + "cullFace", + "cullMode", + "currentCSSZoom", + "currentDirection", + "currentEntry", + "currentLocalDescription", + "currentNode", + "currentPage", + "currentRect", + "currentRemoteDescription", + "currentScale", + "currentScreen", + "currentScript", + "currentSrc", + "currentState", + "currentStyle", + "currentTarget", + "currentTime", + "currentTranslate", + "currentView", + "cursor", + "curve", + "customElements", + "customError", + "cx", + "cy", + "d", + "data", + "dataFld", + "dataFormatAs", + "dataLoss", + "dataLossMessage", + "dataPageSize", + "dataSrc", + "dataTransfer", + "database", + "databases", + "datagrams", + "dataset", + "dateTime", + "db", + "debug", + "debuggerEnabled", + "declarativeNetRequest", + "declare", + "decode", + "decodeAudioData", + "decodeQueueSize", + "decodeURI", + "decodeURIComponent", + "decodedBodySize", + "decoding", + "decodingInfo", + "decrypt", + "default", + "defaultCharset", + "defaultChecked", + "defaultMuted", + "defaultPlaybackRate", + "defaultPolicy", + "defaultPrevented", + "defaultQueue", + "defaultRequest", + "defaultSelected", + "defaultStatus", + "defaultURL", + "defaultValue", + "defaultView", + "defaultstatus", + "defer", + "define", + "defineMagicFunction", + "defineMagicVariable", + "defineProperties", + "defineProperty", + "deg", + "delay", + "delayTime", + "delegatesFocus", + "delete", + "deleteBuffer", + "deleteCaption", + "deleteCell", + "deleteContents", + "deleteData", + "deleteDatabase", + "deleteFramebuffer", + "deleteFromDocument", + "deleteIndex", + "deleteMedium", + "deleteObjectStore", + "deleteProgram", + "deleteProperty", + "deleteQuery", + "deleteRenderbuffer", + "deleteRow", + "deleteRule", + "deleteSampler", + "deleteShader", + "deleteSync", + "deleteTFoot", + "deleteTHead", + "deleteTexture", + "deleteTransformFeedback", + "deleteVertexArray", + "deleted", + "deliverChangeRecords", + "deliveredFrames", + "deliveredFramesDuration", + "delivery", + "deliveryInfo", + "deliveryStatus", + "deliveryTimestamp", + "deliveryType", + "delta", + "deltaMode", + "deltaX", + "deltaY", + "deltaZ", + "dependentLocality", + "deprecatedReplaceInURN", + "deprecatedRunAdAuctionEnforcesKAnonymity", + "deprecatedURNToURL", + "depthBias", + "depthBiasClamp", + "depthBiasSlopeScale", + "depthClearValue", + "depthCompare", + "depthDataFormat", + "depthFailOp", + "depthFar", + "depthFunc", + "depthLoadOp", + "depthMask", + "depthNear", + "depthOrArrayLayers", + "depthRange", + "depthReadOnly", + "depthStencil", + "depthStencilAttachment", + "depthStencilFormat", + "depthStoreOp", + "depthUsage", + "depthWriteEnabled", + "deref", + "deriveBits", + "deriveKey", + "descentOverride", + "description", + "deselectAll", + "designMode", + "desiredSize", + "destination", + "destinationURL", + "destroy", + "detach", + "detachEvent", + "detachShader", + "detached", + "detail", + "details", + "detect", + "detectLanguage", + "detune", + "device", + "deviceClass", + "deviceId", + "deviceMemory", + "devicePixelContentBoxSize", + "devicePixelRatio", + "deviceProtocol", + "deviceSubclass", + "deviceVersionMajor", + "deviceVersionMinor", + "deviceVersionSubminor", + "deviceXDPI", + "deviceYDPI", + "devtools", + "devtools_panels", + "didTimeout", + "difference", + "diffuseConstant", + "digest", + "dimension", + "dimensions", + "dir", + "dirName", + "direction", + "dirxml", + "disable", + "disablePictureInPicture", + "disableRemotePlayback", + "disableVertexAttribArray", + "disabled", + "discard", + "discardedFrames", + "dischargingTime", + "disconnect", + "disconnectShark", + "disconnectedCallback", + "dispatchEvent", + "dispatchWorkgroups", + "dispatchWorkgroupsIndirect", + "display", + "displayHeight", + "displayId", + "displayName", + "displayWidth", + "dispose", + "disposition", + "distanceModel", + "div", + "divisor", + "djsapi", + "djsproxy", + "dns", + "doImport", + "doNotTrack", + "doScroll", + "doctype", + "document", + "documentElement", + "documentId", + "documentIds", + "documentLifecycle", + "documentMode", + "documentOrigin", + "documentOrigins", + "documentPictureInPicture", + "documentURI", + "documentUrl", + "documentUrls", + "dolphin", + "dolphinGameCenter", + "dolphininfo", + "dolphinmeta", + "dom", + "domComplete", + "domContentLoadedEventEnd", + "domContentLoadedEventStart", + "domInteractive", + "domLoading", + "domOverlayState", + "domain", + "domainLookupEnd", + "domainLookupStart", + "dominant-baseline", + "dominantBaseline", + "done", + "dopplerFactor", + "dotAll", + "downDegrees", + "downlink", + "download", + "downloadRequest", + "downloadTotal", + "downloaded", + "downloads", + "dpcm", + "dpi", + "dppx", + "dragDrop", + "draggable", + "draw", + "drawArrays", + "drawArraysInstanced", + "drawArraysInstancedANGLE", + "drawBuffers", + "drawCustomFocusRing", + "drawElements", + "drawElementsInstanced", + "drawElementsInstancedANGLE", + "drawFocusIfNeeded", + "drawImage", + "drawImageFromRect", + "drawIndexed", + "drawIndexedIndirect", + "drawIndirect", + "drawRangeElements", + "drawSystemFocusRing", + "drawingBufferColorSpace", + "drawingBufferFormat", + "drawingBufferHeight", + "drawingBufferStorage", + "drawingBufferWidth", + "drop", + "dropEffect", + "droppedVideoFrames", + "dropzone", + "dstFactor", + "dtmf", + "dump", + "dumpProfile", + "duplex", + "duplicate", + "durability", + "duration", + "dvb", + "dvh", + "dvi", + "dvmax", + "dvmin", + "dvname", + "dvnum", + "dvw", + "dx", + "dy", + "dynamicId", + "dynsrc", + "e", + "edgeMode", + "editContext", + "effect", + "effectAllowed", + "effectiveDirective", + "effectiveType", + "effects", + "elapsedTime", + "element", + "elementFromPoint", + "elementTiming", + "elements", + "elementsFromPoint", + "elevation", + "ellipse", + "em", + "emHeightAscent", + "emHeightDescent", + "email", + "embeds", + "emit", + "emma", + "empty", + "empty-cells", + "emptyCells", + "emptyHTML", + "emptyScript", + "emulatedPosition", + "enable", + "enableBackground", + "enableDelegations", + "enableStyleSheetsForSet", + "enableVertexAttribArray", + "enabled", + "enabledFeatures", + "enabledPlugin", + "encode", + "encodeInto", + "encodeQueueSize", + "encodeURI", + "encodeURIComponent", + "encodedBodySize", + "encoding", + "encodingInfo", + "encrypt", + "enctype", + "end", + "endContainer", + "endElement", + "endElementAt", + "endOcclusionQuery", + "endOfPassWriteIndex", + "endOfStream", + "endOffset", + "endQuery", + "endTime", + "endTransformFeedback", + "ended", + "endpoint", + "endpointNumber", + "endpoints", + "endsWith", + "enqueue", + "enterKeyHint", + "entities", + "entries", + "entry", + "entryPoint", + "entryType", + "enumerable", + "enumerate", + "enumerateDevices", + "enumerateEditable", + "environmentBlendMode", + "equals", + "error", + "errorCode", + "errorDetail", + "errorText", + "escape", + "estimate", + "eval", + "evaluate", + "event", + "eventCounts", + "eventPhase", + "events", + "every", + "ex", + "exception", + "exchange", + "exec", + "execCommand", + "execCommandShowHelp", + "execScript", + "executeBundles", + "executionStart", + "exitFullscreen", + "exitPictureInPicture", + "exitPointerLock", + "exitPresent", + "exp", + "expand", + "expandEntityReferences", + "expando", + "expansion", + "expectedImprovement", + "experiments", + "expiration", + "expirationTime", + "expires", + "expiryDate", + "explicitOriginalTarget", + "expm1", + "exponent", + "exponentialRampToValueAtTime", + "exportKey", + "exports", + "extend", + "extension", + "extensionTypes", + "extensions", + "extentNode", + "extentOffset", + "external", + "externalResourcesRequired", + "externalTexture", + "extractContents", + "extractable", + "eye", + "f", + "f16round", + "face", + "factoryReset", + "failOp", + "failureReason", + "fallback", + "family", + "familyName", + "farthestViewportElement", + "fastSeek", + "fatal", + "featureId", + "featurePolicy", + "featureSettings", + "features", + "fence", + "fenceSync", + "fetch", + "fetchPriority", + "fetchStart", + "fftSize", + "fgColor", + "fieldOfView", + "file", + "fileCreatedDate", + "fileHandle", + "fileModifiedDate", + "fileName", + "fileSize", + "fileUpdatedDate", + "filename", + "files", + "filesystem", + "fill", + "fill-opacity", + "fill-rule", + "fillJointRadii", + "fillLightMode", + "fillOpacity", + "fillPoses", + "fillRect", + "fillRule", + "fillStyle", + "fillText", + "filter", + "filterResX", + "filterResY", + "filterUnits", + "filters", + "finally", + "find", + "findIndex", + "findLast", + "findLastIndex", + "findRule", + "findText", + "finish", + "finishDocumentLoadTime", + "finishLoadTime", + "finished", + "fireEvent", + "firesTouchEvents", + "firstChild", + "firstElementChild", + "firstInterimResponseStart", + "firstPage", + "firstPaintAfterLoadTime", + "firstPaintTime", + "firstUIEventTimestamp", + "fixed", + "flags", + "flat", + "flatMap", + "flex", + "flex-basis", + "flex-direction", + "flex-flow", + "flex-grow", + "flex-shrink", + "flex-wrap", + "flexBasis", + "flexDirection", + "flexFlow", + "flexGrow", + "flexShrink", + "flexWrap", + "flipX", + "flipY", + "float", + "float32", + "float64", + "flood-color", + "flood-opacity", + "floodColor", + "floodOpacity", + "floor", + "flush", + "focus", + "focusNode", + "focusOffset", + "font", + "font-family", + "font-feature-settings", + "font-kerning", + "font-language-override", + "font-optical-sizing", + "font-palette", + "font-size", + "font-size-adjust", + "font-stretch", + "font-style", + "font-synthesis", + "font-synthesis-position", + "font-synthesis-small-caps", + "font-synthesis-style", + "font-synthesis-weight", + "font-variant", + "font-variant-alternates", + "font-variant-caps", + "font-variant-east-asian", + "font-variant-ligatures", + "font-variant-numeric", + "font-variant-position", + "font-variation-settings", + "font-weight", + "fontBoundingBoxAscent", + "fontBoundingBoxDescent", + "fontFamily", + "fontFeatureSettings", + "fontKerning", + "fontLanguageOverride", + "fontOpticalSizing", + "fontPalette", + "fontSize", + "fontSizeAdjust", + "fontSmoothingEnabled", + "fontStretch", + "fontStyle", + "fontSynthesis", + "fontSynthesisPosition", + "fontSynthesisSmallCaps", + "fontSynthesisStyle", + "fontSynthesisWeight", + "fontVariant", + "fontVariantAlternates", + "fontVariantCaps", + "fontVariantEastAsian", + "fontVariantLigatures", + "fontVariantNumeric", + "fontVariantPosition", + "fontVariationSettings", + "fontWeight", + "fontcolor", + "fontfaces", + "fonts", + "fontsize", + "for", + "forEach", + "force", + "forceFallbackAdapter", + "forceRedraw", + "forced-color-adjust", + "forcedColorAdjust", + "forcedStyleAndLayoutDuration", + "forget", + "form", + "formAction", + "formData", + "formEnctype", + "formMethod", + "formNoValidate", + "formTarget", + "format", + "formatToParts", + "forms", + "forward", + "forwardX", + "forwardY", + "forwardZ", + "foundation", + "fr", + "fragment", + "fragmentDirective", + "frame", + "frameBorder", + "frameCount", + "frameElement", + "frameId", + "frameIds", + "frameSpacing", + "framebuffer", + "framebufferHeight", + "framebufferRenderbuffer", + "framebufferTexture2D", + "framebufferTextureLayer", + "framebufferWidth", + "frames", + "freeSpace", + "freeze", + "frequency", + "frequencyBinCount", + "from", + "fromAsync", + "fromBase64", + "fromCharCode", + "fromCodePoint", + "fromElement", + "fromEntries", + "fromFloat32Array", + "fromFloat64Array", + "fromHex", + "fromMatrix", + "fromPoint", + "fromQuad", + "fromRect", + "frontFace", + "fround", + "fullName", + "fullPath", + "fullRange", + "fullScreen", + "fullVersionList", + "fullscreen", + "fullscreenElement", + "fullscreenEnabled", + "fx", + "fy", + "g", + "gain", + "gamepad", + "gamma", + "gap", + "gatheringState", + "gatt", + "geckoProfiler", + "genderIdentity", + "generateCertificate", + "generateKey", + "generateMipmap", + "generateRequest", + "geolocation", + "gestureObject", + "get", + "getAcceptLanguages", + "getActiveAttrib", + "getActiveUniform", + "getActiveUniformBlockName", + "getActiveUniformBlockParameter", + "getActiveUniforms", + "getAdjacentText", + "getAll", + "getAllKeys", + "getAllResponseHeaders", + "getAllowlistForFeature", + "getAnimations", + "getAsFile", + "getAsFileSystemHandle", + "getAsString", + "getAttachedShaders", + "getAttribLocation", + "getAttribute", + "getAttributeNS", + "getAttributeNames", + "getAttributeNode", + "getAttributeNodeNS", + "getAttributeType", + "getAudioTracks", + "getAuthenticatorData", + "getAutoplayPolicy", + "getAvailability", + "getBBox", + "getBackgroundPage", + "getBadgeBackgroundColor", + "getBadgeText", + "getBadgeTextColor", + "getBattery", + "getBigInt64", + "getBigUint64", + "getBindGroupLayout", + "getBlob", + "getBookmark", + "getBoundingClientRect", + "getBounds", + "getBoxQuads", + "getBrowserInfo", + "getBufferParameter", + "getBufferSubData", + "getByteFrequencyData", + "getByteTimeDomainData", + "getCSSCanvasContext", + "getCTM", + "getCameraImage", + "getCandidateWindowClientRect", + "getCanonicalLocales", + "getCapabilities", + "getCaptureHandle", + "getChannelData", + "getCharNumAtPosition", + "getCharacteristic", + "getCharacteristics", + "getClientExtensionResults", + "getClientRect", + "getClientRects", + "getCoalescedEvents", + "getCompilationInfo", + "getCompositionAlternatives", + "getComputedStyle", + "getComputedTextLength", + "getComputedTiming", + "getConfiguration", + "getConstraints", + "getContext", + "getContextAttributes", + "getContexts", + "getContributingSources", + "getCounterValue", + "getCueAsHTML", + "getCueById", + "getCurrent", + "getCurrentPosition", + "getCurrentTexture", + "getCurrentTime", + "getData", + "getDatabaseNames", + "getDate", + "getDay", + "getDefaultComputedStyle", + "getDepthInMeters", + "getDepthInformation", + "getDescriptor", + "getDescriptors", + "getDestinationInsertionPoints", + "getDevices", + "getDirectory", + "getDirectoryHandle", + "getDisplayMedia", + "getDistributedNodes", + "getEditable", + "getElementById", + "getElementsByClassName", + "getElementsByName", + "getElementsByTagName", + "getElementsByTagNameNS", + "getEnclosureList", + "getEndPositionOfChar", + "getEntries", + "getEntriesByName", + "getEntriesByType", + "getError", + "getExtension", + "getExtentOfChar", + "getEyeParameters", + "getFeature", + "getFiberRoots", + "getFile", + "getFileHandle", + "getFiles", + "getFilesAndDirectories", + "getFingerprints", + "getFloat16", + "getFloat32", + "getFloat64", + "getFloatFrequencyData", + "getFloatTimeDomainData", + "getFloatValue", + "getFragDataLocation", + "getFrameData", + "getFrameId", + "getFramebufferAttachmentParameter", + "getFrequencyResponse", + "getFullYear", + "getGamepads", + "getHTML", + "getHeaderExtensionsToNegotiate", + "getHighEntropyValues", + "getHitTestResults", + "getHitTestResultsForTransientInput", + "getHours", + "getIdentityAssertion", + "getIds", + "getImageData", + "getIndexedParameter", + "getInfo", + "getInnerHTML", + "getInstalledRelatedApps", + "getInt16", + "getInt32", + "getInt8", + "getInterestGroupAdAuctionData", + "getInternalModuleRanges", + "getInternalformatParameter", + "getIntersectionList", + "getItem", + "getItems", + "getJointPose", + "getKey", + "getKeyframes", + "getLastFocused", + "getLayers", + "getLayoutMap", + "getLightEstimate", + "getLineDash", + "getLocalCandidates", + "getLocalParameters", + "getLocalStreams", + "getManagedConfiguration", + "getManifest", + "getMappedRange", + "getMarks", + "getMatchedCSSRules", + "getMaxGCPauseSinceClear", + "getMeasures", + "getMessage", + "getMetadata", + "getMilliseconds", + "getMinutes", + "getModifierState", + "getMonth", + "getName", + "getNamedItem", + "getNamedItemNS", + "getNativeFramebufferScaleFactor", + "getNegotiatedHeaderExtensions", + "getNestedConfigs", + "getNotifications", + "getNotifier", + "getNumberOfChars", + "getOffsetReferenceSpace", + "getOutputTimestamp", + "getOverrideHistoryNavigationMode", + "getOverrideStyle", + "getOwnPropertyDescriptor", + "getOwnPropertyDescriptors", + "getOwnPropertyNames", + "getOwnPropertySymbols", + "getPackageDirectoryEntry", + "getParameter", + "getParameters", + "getParent", + "getPathSegAtLength", + "getPermissionWarningsByManifest", + "getPhotoCapabilities", + "getPhotoSettings", + "getPlatformInfo", + "getPointAtLength", + "getPopup", + "getPorts", + "getPose", + "getPredictedEvents", + "getPreference", + "getPreferenceDefault", + "getPreferredCanvasFormat", + "getPresentationAttribute", + "getPreventDefault", + "getPrimaryService", + "getPrimaryServices", + "getProgramInfoLog", + "getProgramParameter", + "getPropertyCSSValue", + "getPropertyPriority", + "getPropertyShorthand", + "getPropertyType", + "getPropertyValue", + "getPrototypeOf", + "getPublicKey", + "getPublicKeyAlgorithm", + "getQuery", + "getQueryParameter", + "getRGBColorValue", + "getRandomValues", + "getRangeAt", + "getReader", + "getReceivers", + "getRectValue", + "getReflectionCubeMap", + "getRegistration", + "getRegistrations", + "getRemoteCandidates", + "getRemoteCertificates", + "getRemoteParameters", + "getRemoteStreams", + "getRenderbufferParameter", + "getResponseHeader", + "getRoot", + "getRootNode", + "getRotationOfChar", + "getSVGDocument", + "getSamplerParameter", + "getScreenCTM", + "getScreenDetails", + "getSeconds", + "getSelectedCandidatePair", + "getSelection", + "getSelf", + "getSenders", + "getService", + "getSetCookie", + "getSettings", + "getShaderInfoLog", + "getShaderParameter", + "getShaderPrecisionFormat", + "getShaderSource", + "getSignals", + "getSimpleDuration", + "getSiteIcons", + "getSources", + "getSpeculativeParserUrls", + "getStartPositionOfChar", + "getStartTime", + "getState", + "getStats", + "getStatusForPolicy", + "getStorageUpdates", + "getStreamById", + "getStringValue", + "getSubStringLength", + "getSubscription", + "getSubscriptions", + "getSupportedConstraints", + "getSupportedExtensions", + "getSupportedFormats", + "getSyncParameter", + "getSynchronizationSources", + "getTags", + "getTargetRanges", + "getTexParameter", + "getTextFormats", + "getTime", + "getTimezoneOffset", + "getTiming", + "getTitle", + "getTitlebarAreaRect", + "getTotalLength", + "getTrackById", + "getTracks", + "getTransceivers", + "getTransform", + "getTransformFeedbackVarying", + "getTransformToElement", + "getTransports", + "getType", + "getTypeMapping", + "getUILanguage", + "getURL", + "getUTCDate", + "getUTCDay", + "getUTCFullYear", + "getUTCHours", + "getUTCMilliseconds", + "getUTCMinutes", + "getUTCMonth", + "getUTCSeconds", + "getUint16", + "getUint32", + "getUint8", + "getUniform", + "getUniformBlockIndex", + "getUniformIndices", + "getUniformLocation", + "getUserInfo", + "getUserMedia", + "getUserSettings", + "getVRDisplays", + "getValues", + "getVarDate", + "getVariableValue", + "getVertexAttrib", + "getVertexAttribOffset", + "getVideoPlaybackQuality", + "getVideoTracks", + "getViewerPose", + "getViewport", + "getViews", + "getVoices", + "getWakeLockState", + "getWriter", + "getYear", + "getZoom", + "getZoomSettings", + "givenName", + "global", + "globalAlpha", + "globalCompositeOperation", + "globalPrivacyControl", + "globalThis", + "glyphOrientationHorizontal", + "glyphOrientationVertical", + "glyphRef", + "go", + "goBack", + "goForward", + "gpu", + "grabFrame", + "grad", + "gradientTransform", + "gradientUnits", + "grammars", + "green", + "grid", + "grid-area", + "grid-auto-columns", + "grid-auto-flow", + "grid-auto-rows", + "grid-column", + "grid-column-end", + "grid-column-gap", + "grid-column-start", + "grid-gap", + "grid-row", + "grid-row-end", + "grid-row-gap", + "grid-row-start", + "grid-template", + "grid-template-areas", + "grid-template-columns", + "grid-template-rows", + "gridArea", + "gridAutoColumns", + "gridAutoFlow", + "gridAutoRows", + "gridColumn", + "gridColumnEnd", + "gridColumnGap", + "gridColumnStart", + "gridGap", + "gridRow", + "gridRowEnd", + "gridRowGap", + "gridRowStart", + "gridTemplate", + "gridTemplateAreas", + "gridTemplateColumns", + "gridTemplateRows", + "gripSpace", + "group", + "groupBy", + "groupCollapsed", + "groupEnd", + "groupId", + "groups", + "grow", + "growable", + "guestProcessId", + "guestRenderFrameRoutingId", + "hadRecentInput", + "hand", + "handedness", + "hangingBaseline", + "hapticActuators", + "hardwareConcurrency", + "has", + "hasAttribute", + "hasAttributeNS", + "hasAttributes", + "hasBeenActive", + "hasChildNodes", + "hasComposition", + "hasDynamicOffset", + "hasEnrolledInstrument", + "hasExtension", + "hasExternalDisplay", + "hasFeature", + "hasFocus", + "hasIndices", + "hasInstance", + "hasLayout", + "hasOrientation", + "hasOwn", + "hasOwnProperty", + "hasPointerCapture", + "hasPosition", + "hasPrivateToken", + "hasReading", + "hasRedemptionRecord", + "hasRegExpGroups", + "hasStorageAccess", + "hasUAVisualTransition", + "hasUnpartitionedCookieAccess", + "hash", + "hashChange", + "head", + "headers", + "heading", + "height", + "hid", + "hidden", + "hide", + "hideFocus", + "hidePopover", + "high", + "highWaterMark", + "highlight", + "highlights", + "hint", + "hints", + "history", + "honorificPrefix", + "honorificSuffix", + "horizontalOverflow", + "host", + "hostCandidate", + "hostname", + "href", + "hrefTranslate", + "hreflang", + "hspace", + "html5TagCheckInerface", + "htmlFor", + "htmlText", + "httpEquiv", + "httpRequestStatusCode", + "hwTimestamp", + "hyphenate-character", + "hyphenateCharacter", + "hyphens", + "hypot", + "i18n", + "ic", + "iccId", + "iceConnectionState", + "iceGatheringState", + "iceTransport", + "icon", + "iconURL", + "id", + "identifier", + "identity", + "ideographicBaseline", + "idle", + "idpLoginUrl", + "ignoreBOM", + "ignoreCase", + "ignoreDepthValues", + "image", + "image-orientation", + "image-rendering", + "imageHeight", + "imageOrientation", + "imageRendering", + "imageSizes", + "imageSmoothingEnabled", + "imageSmoothingQuality", + "imageSrcset", + "imageWidth", + "images", + "ime-mode", + "imeMode", + "implementation", + "importExternalTexture", + "importKey", + "importNode", + "importStylesheet", + "imports", + "impp", + "imul", + "in", + "in1", + "in2", + "inBandMetadataTrackDispatchType", + "inIncognitoContext", + "inRange", + "includes", + "incognito", + "incomingBidirectionalStreams", + "incomingHighWaterMark", + "incomingMaxAge", + "incomingUnidirectionalStreams", + "incremental", + "indeterminate", + "index", + "indexNames", + "indexOf", + "indexedDB", + "indicate", + "indices", + "inert", + "inertiaDestinationX", + "inertiaDestinationY", + "info", + "inherits", + "init", + "initAnimationEvent", + "initBeforeLoadEvent", + "initClipboardEvent", + "initCloseEvent", + "initCommandEvent", + "initCompositionEvent", + "initCustomEvent", + "initData", + "initDataType", + "initDeviceMotionEvent", + "initDeviceOrientationEvent", + "initDragEvent", + "initErrorEvent", + "initEvent", + "initFocusEvent", + "initGestureEvent", + "initHashChangeEvent", + "initKeyEvent", + "initKeyboardEvent", + "initMSManipulationEvent", + "initMessageEvent", + "initMouseEvent", + "initMouseScrollEvent", + "initMouseWheelEvent", + "initMutationEvent", + "initNSMouseEvent", + "initOverflowEvent", + "initPageEvent", + "initPageTransitionEvent", + "initPointerEvent", + "initPopStateEvent", + "initProgressEvent", + "initScrollAreaEvent", + "initSimpleGestureEvent", + "initStorageEvent", + "initTextEvent", + "initTimeEvent", + "initTouchEvent", + "initTransitionEvent", + "initUIEvent", + "initWebKitAnimationEvent", + "initWebKitTransitionEvent", + "initWebKitWheelEvent", + "initWheelEvent", + "initialTime", + "initialValue", + "initialize", + "initiatorType", + "inject", + "ink", + "inline-size", + "inlineSize", + "inlineVerticalFieldOfView", + "inner", + "innerHTML", + "innerHeight", + "innerText", + "innerWidth", + "input", + "inputBuffer", + "inputEncoding", + "inputMethod", + "inputMode", + "inputSource", + "inputSources", + "inputType", + "inputs", + "insertAdjacentElement", + "insertAdjacentHTML", + "insertAdjacentText", + "insertBefore", + "insertCell", + "insertDTMF", + "insertData", + "insertDebugMarker", + "insertItemBefore", + "insertNode", + "insertRow", + "insertRule", + "inset", + "inset-block", + "inset-block-end", + "inset-block-start", + "inset-inline", + "inset-inline-end", + "inset-inline-start", + "insetBlock", + "insetBlockEnd", + "insetBlockStart", + "insetInline", + "insetInlineEnd", + "insetInlineStart", + "install", + "installing", + "instanceRoot", + "instantiate", + "instantiateStreaming", + "instruments", + "int16", + "int32", + "int8", + "integrity", + "interactionId", + "interactionMode", + "intercept", + "interfaceClass", + "interfaceName", + "interfaceNumber", + "interfaceProtocol", + "interfaceSubclass", + "interfaces", + "interimResults", + "internalSubset", + "interpretation", + "intersection", + "intersectionRatio", + "intersectionRect", + "intersectsNode", + "interval", + "invalidIteratorState", + "invalidateFramebuffer", + "invalidateSubFramebuffer", + "inverse", + "invertSelf", + "invoker", + "invokerType", + "is", + "is2D", + "isActive", + "isAllowedFileSchemeAccess", + "isAllowedIncognitoAccess", + "isAlternate", + "isArray", + "isAutoSelected", + "isBingCurrentSearchDefault", + "isBuffer", + "isCandidateWindowVisible", + "isChar", + "isCollapsed", + "isComposing", + "isConcatSpreadable", + "isConditionalMediationAvailable", + "isConfigSupported", + "isConnected", + "isContentEditable", + "isContentHandlerRegistered", + "isContextLost", + "isDefaultNamespace", + "isDirectory", + "isDisabled", + "isDisjointFrom", + "isEnabled", + "isEqual", + "isEqualNode", + "isExtended", + "isExtensible", + "isExternalCTAP2SecurityKeySupported", + "isFallbackAdapter", + "isFile", + "isFinite", + "isFirstPersonObserver", + "isFramebuffer", + "isFrozen", + "isGenerator", + "isHTML", + "isHistoryNavigation", + "isId", + "isIdentity", + "isInjected", + "isInputPending", + "isInteger", + "isInternal", + "isIntersecting", + "isLockFree", + "isMap", + "isMultiLine", + "isNaN", + "isOpen", + "isPointInFill", + "isPointInPath", + "isPointInRange", + "isPointInStroke", + "isPrefAlternate", + "isPresenting", + "isPrimary", + "isProgram", + "isPropertyImplicit", + "isProtocolHandlerRegistered", + "isPrototypeOf", + "isQuery", + "isRawJSON", + "isRenderbuffer", + "isSafeInteger", + "isSameEntry", + "isSameNode", + "isSampler", + "isScript", + "isScriptURL", + "isSealed", + "isSecureContext", + "isSessionSupported", + "isShader", + "isSubsetOf", + "isSupersetOf", + "isSupported", + "isSync", + "isTextEdit", + "isTexture", + "isTransformFeedback", + "isTrusted", + "isTypeSupported", + "isUserVerifyingPlatformAuthenticatorAvailable", + "isVertexArray", + "isView", + "isVisible", + "isWellFormed", + "isochronousTransferIn", + "isochronousTransferOut", + "isolation", + "italics", + "item", + "itemId", + "itemProp", + "itemRef", + "itemScope", + "itemType", + "itemValue", + "items", + "iterateNext", + "iterationComposite", + "iterator", + "javaEnabled", + "jitterBufferTarget", + "jobTitle", + "join", + "joinAdInterestGroup", + "jointName", + "json", + "justify-content", + "justify-items", + "justify-self", + "justifyContent", + "justifyItems", + "justifySelf", + "k1", + "k2", + "k3", + "k4", + "kHz", + "keepalive", + "kernelMatrix", + "kernelUnitLengthX", + "kernelUnitLengthY", + "kerning", + "key", + "keyCode", + "keyFor", + "keyIdentifier", + "keyLightEnabled", + "keyLocation", + "keyPath", + "keyStatuses", + "keySystem", + "keyText", + "keyUsage", + "keyboard", + "keys", + "keytype", + "kind", + "knee", + "knownSources", + "label", + "labels", + "lang", + "language", + "languages", + "largeArcFlag", + "lastChild", + "lastElementChild", + "lastError", + "lastEventId", + "lastIndex", + "lastIndexOf", + "lastInputTime", + "lastMatch", + "lastMessageSubject", + "lastMessageType", + "lastModified", + "lastModifiedDate", + "lastPage", + "lastParen", + "lastState", + "lastStyleSheetSet", + "latency", + "latitude", + "launchQueue", + "layerName", + "layerX", + "layerY", + "layout", + "layoutFlow", + "layoutGrid", + "layoutGridChar", + "layoutGridLine", + "layoutGridMode", + "layoutGridType", + "lbound", + "leaveAdInterestGroup", + "left", + "leftContext", + "leftDegrees", + "leftMargin", + "leftProjectionMatrix", + "leftViewMatrix", + "length", + "lengthAdjust", + "lengthComputable", + "letter-spacing", + "letterSpacing", + "level", + "lh", + "lighting-color", + "lightingColor", + "limitingConeAngle", + "limits", + "line", + "line-break", + "line-height", + "lineAlign", + "lineBreak", + "lineCap", + "lineDashOffset", + "lineGapOverride", + "lineHeight", + "lineJoin", + "lineNum", + "lineNumber", + "linePos", + "lineTo", + "lineWidth", + "linearAcceleration", + "linearRampToValueAtTime", + "linearVelocity", + "lineno", + "lines", + "link", + "linkColor", + "linkProgram", + "links", + "list", + "list-style", + "list-style-image", + "list-style-position", + "list-style-type", + "listStyle", + "listStyleImage", + "listStylePosition", + "listStyleType", + "listener", + "listeners", + "load", + "loadEventEnd", + "loadEventStart", + "loadOp", + "loadTime", + "loadTimes", + "loaded", + "loading", + "localDescription", + "localName", + "localService", + "localStorage", + "locale", + "localeCompare", + "location", + "locationbar", + "lock", + "locked", + "lockedFile", + "locks", + "lodMaxClamp", + "lodMinClamp", + "log", + "log10", + "log1p", + "log2", + "logicalXDPI", + "logicalYDPI", + "login", + "loglevel", + "longDesc", + "longitude", + "lookupNamespaceURI", + "lookupPrefix", + "loop", + "loopEnd", + "loopStart", + "looping", + "lost", + "low", + "lower", + "lowerBound", + "lowerOpen", + "lowsrc", + "lvb", + "lvh", + "lvi", + "lvmax", + "lvmin", + "lvw", + "m11", + "m12", + "m13", + "m14", + "m21", + "m22", + "m23", + "m24", + "m31", + "m32", + "m33", + "m34", + "m41", + "m42", + "m43", + "m44", + "magFilter", + "makeXRCompatible", + "managed", + "management", + "manifest", + "manufacturer", + "manufacturerName", + "map", + "mapAsync", + "mapState", + "mappedAtCreation", + "mapping", + "margin", + "margin-block", + "margin-block-end", + "margin-block-start", + "margin-bottom", + "margin-inline", + "margin-inline-end", + "margin-inline-start", + "margin-left", + "margin-right", + "margin-top", + "marginBlock", + "marginBlockEnd", + "marginBlockStart", + "marginBottom", + "marginHeight", + "marginInline", + "marginInlineEnd", + "marginInlineStart", + "marginLeft", + "marginRight", + "marginTop", + "marginWidth", + "mark", + "marker", + "marker-end", + "marker-mid", + "marker-offset", + "marker-start", + "markerEnd", + "markerHeight", + "markerMid", + "markerOffset", + "markerStart", + "markerUnits", + "markerWidth", + "marks", + "mask", + "mask-clip", + "mask-composite", + "mask-image", + "mask-mode", + "mask-origin", + "mask-position", + "mask-position-x", + "mask-position-y", + "mask-repeat", + "mask-size", + "mask-type", + "maskClip", + "maskComposite", + "maskContentUnits", + "maskImage", + "maskMode", + "maskOrigin", + "maskPosition", + "maskPositionX", + "maskPositionY", + "maskRepeat", + "maskSize", + "maskType", + "maskUnits", + "match", + "matchAll", + "matchMedia", + "matchMedium", + "matchPatterns", + "matches", + "math-depth", + "math-style", + "mathDepth", + "mathStyle", + "matrix", + "matrixTransform", + "max", + "max-block-size", + "max-height", + "max-inline-size", + "max-width", + "maxActions", + "maxAlternatives", + "maxAnisotropy", + "maxBindGroups", + "maxBindGroupsPlusVertexBuffers", + "maxBindingsPerBindGroup", + "maxBlockSize", + "maxBufferSize", + "maxByteLength", + "maxChannelCount", + "maxChannels", + "maxColorAttachmentBytesPerSample", + "maxColorAttachments", + "maxComputeInvocationsPerWorkgroup", + "maxComputeWorkgroupSizeX", + "maxComputeWorkgroupSizeY", + "maxComputeWorkgroupSizeZ", + "maxComputeWorkgroupStorageSize", + "maxComputeWorkgroupsPerDimension", + "maxConnectionsPerServer", + "maxDatagramSize", + "maxDecibels", + "maxDistance", + "maxDrawCount", + "maxDynamicStorageBuffersPerPipelineLayout", + "maxDynamicUniformBuffersPerPipelineLayout", + "maxHeight", + "maxInlineSize", + "maxInterStageShaderComponents", + "maxInterStageShaderVariables", + "maxLayers", + "maxLength", + "maxMessageSize", + "maxPacketLifeTime", + "maxRetransmits", + "maxSampledTexturesPerShaderStage", + "maxSamplersPerShaderStage", + "maxStorageBufferBindingSize", + "maxStorageBuffersPerShaderStage", + "maxStorageTexturesPerShaderStage", + "maxTextureArrayLayers", + "maxTextureDimension1D", + "maxTextureDimension2D", + "maxTextureDimension3D", + "maxTouchPoints", + "maxUniformBufferBindingSize", + "maxUniformBuffersPerShaderStage", + "maxValue", + "maxVertexAttributes", + "maxVertexBufferArrayStride", + "maxVertexBuffers", + "maxWidth", + "maximumLatency", + "measure", + "measureText", + "media", + "mediaCapabilities", + "mediaDevices", + "mediaElement", + "mediaGroup", + "mediaKeys", + "mediaSession", + "mediaStream", + "mediaText", + "meetOrSlice", + "memory", + "menubar", + "menus", + "menusChild", + "menusInternal", + "mergeAttributes", + "message", + "messageClass", + "messageHandlers", + "messageType", + "messages", + "metaKey", + "metadata", + "method", + "methodDetails", + "methodName", + "mid", + "mimeType", + "mimeTypes", + "min", + "min-block-size", + "min-height", + "min-inline-size", + "min-width", + "minBindingSize", + "minBlockSize", + "minDecibels", + "minFilter", + "minHeight", + "minInlineSize", + "minLength", + "minStorageBufferOffsetAlignment", + "minUniformBufferOffsetAlignment", + "minValue", + "minWidth", + "minimumLatency", + "mipLevel", + "mipLevelCount", + "mipmapFilter", + "miterLimit", + "mix-blend-mode", + "mixBlendMode", + "mm", + "mobile", + "mode", + "model", + "modify", + "module", + "mount", + "move", + "moveBy", + "moveEnd", + "moveFirst", + "moveFocusDown", + "moveFocusLeft", + "moveFocusRight", + "moveFocusUp", + "moveInSuccession", + "moveNext", + "moveRow", + "moveStart", + "moveTo", + "moveToBookmark", + "moveToElementText", + "moveToPoint", + "movementX", + "movementY", + "mozAdd", + "mozAnimationStartTime", + "mozAnon", + "mozApps", + "mozAudioCaptured", + "mozAudioChannelType", + "mozAutoplayEnabled", + "mozCancelAnimationFrame", + "mozCancelFullScreen", + "mozCancelRequestAnimationFrame", + "mozCaptureStream", + "mozCaptureStreamUntilEnded", + "mozClearDataAt", + "mozContact", + "mozContacts", + "mozCreateFileHandle", + "mozCurrentTransform", + "mozCurrentTransformInverse", + "mozCursor", + "mozDash", + "mozDashOffset", + "mozDecodedFrames", + "mozExitPointerLock", + "mozFillRule", + "mozFragmentEnd", + "mozFrameDelay", + "mozFullScreen", + "mozFullScreenElement", + "mozFullScreenEnabled", + "mozGetAll", + "mozGetAllKeys", + "mozGetAsFile", + "mozGetDataAt", + "mozGetMetadata", + "mozGetUserMedia", + "mozHasAudio", + "mozHasItem", + "mozHidden", + "mozImageSmoothingEnabled", + "mozIndexedDB", + "mozInnerScreenX", + "mozInnerScreenY", + "mozInputSource", + "mozIsTextField", + "mozItem", + "mozItemCount", + "mozItems", + "mozLength", + "mozLockOrientation", + "mozMatchesSelector", + "mozMovementX", + "mozMovementY", + "mozOpaque", + "mozOrientation", + "mozPaintCount", + "mozPaintedFrames", + "mozParsedFrames", + "mozPay", + "mozPointerLockElement", + "mozPresentedFrames", + "mozPreservesPitch", + "mozPressure", + "mozPrintCallback", + "mozRTCIceCandidate", + "mozRTCPeerConnection", + "mozRTCSessionDescription", + "mozRemove", + "mozRequestAnimationFrame", + "mozRequestFullScreen", + "mozRequestPointerLock", + "mozSetDataAt", + "mozSetImageElement", + "mozSourceNode", + "mozSrcObject", + "mozSystem", + "mozTCPSocket", + "mozTextStyle", + "mozTypesAt", + "mozUnlockOrientation", + "mozUserCancelled", + "mozVisibilityState", + "ms", + "msAnimation", + "msAnimationDelay", + "msAnimationDirection", + "msAnimationDuration", + "msAnimationFillMode", + "msAnimationIterationCount", + "msAnimationName", + "msAnimationPlayState", + "msAnimationStartTime", + "msAnimationTimingFunction", + "msBackfaceVisibility", + "msBlockProgression", + "msCSSOMElementFloatMetrics", + "msCaching", + "msCachingEnabled", + "msCancelRequestAnimationFrame", + "msCapsLockWarningOff", + "msClearImmediate", + "msClose", + "msContentZoomChaining", + "msContentZoomFactor", + "msContentZoomLimit", + "msContentZoomLimitMax", + "msContentZoomLimitMin", + "msContentZoomSnap", + "msContentZoomSnapPoints", + "msContentZoomSnapType", + "msContentZooming", + "msConvertURL", + "msCrypto", + "msDoNotTrack", + "msElementsFromPoint", + "msElementsFromRect", + "msExitFullscreen", + "msExtendedCode", + "msFillRule", + "msFirstPaint", + "msFlex", + "msFlexAlign", + "msFlexDirection", + "msFlexFlow", + "msFlexItemAlign", + "msFlexLinePack", + "msFlexNegative", + "msFlexOrder", + "msFlexPack", + "msFlexPositive", + "msFlexPreferredSize", + "msFlexWrap", + "msFlowFrom", + "msFlowInto", + "msFontFeatureSettings", + "msFullscreenElement", + "msFullscreenEnabled", + "msGetInputContext", + "msGetRegionContent", + "msGetUntransformedBounds", + "msGraphicsTrustStatus", + "msGridColumn", + "msGridColumnAlign", + "msGridColumnSpan", + "msGridColumns", + "msGridRow", + "msGridRowAlign", + "msGridRowSpan", + "msGridRows", + "msHidden", + "msHighContrastAdjust", + "msHyphenateLimitChars", + "msHyphenateLimitLines", + "msHyphenateLimitZone", + "msHyphens", + "msImageSmoothingEnabled", + "msImeAlign", + "msIndexedDB", + "msInterpolationMode", + "msIsStaticHTML", + "msKeySystem", + "msKeys", + "msLaunchUri", + "msLockOrientation", + "msManipulationViewsEnabled", + "msMatchMedia", + "msMatchesSelector", + "msMaxTouchPoints", + "msOrientation", + "msOverflowStyle", + "msPerspective", + "msPerspectiveOrigin", + "msPlayToDisabled", + "msPlayToPreferredSourceUri", + "msPlayToPrimary", + "msPointerEnabled", + "msRegionOverflow", + "msReleasePointerCapture", + "msRequestAnimationFrame", + "msRequestFullscreen", + "msSaveBlob", + "msSaveOrOpenBlob", + "msScrollChaining", + "msScrollLimit", + "msScrollLimitXMax", + "msScrollLimitXMin", + "msScrollLimitYMax", + "msScrollLimitYMin", + "msScrollRails", + "msScrollSnapPointsX", + "msScrollSnapPointsY", + "msScrollSnapType", + "msScrollSnapX", + "msScrollSnapY", + "msScrollTranslation", + "msSetImmediate", + "msSetMediaKeys", + "msSetPointerCapture", + "msTextCombineHorizontal", + "msTextSizeAdjust", + "msToBlob", + "msTouchAction", + "msTouchSelect", + "msTraceAsyncCallbackCompleted", + "msTraceAsyncCallbackStarting", + "msTraceAsyncOperationCompleted", + "msTraceAsyncOperationStarting", + "msTransform", + "msTransformOrigin", + "msTransformStyle", + "msTransition", + "msTransitionDelay", + "msTransitionDuration", + "msTransitionProperty", + "msTransitionTimingFunction", + "msUnlockOrientation", + "msUpdateAsyncCallbackRelation", + "msUserSelect", + "msVisibilityState", + "msWrapFlow", + "msWrapMargin", + "msWrapThrough", + "msWriteProfilerMark", + "msZoom", + "msZoomTo", + "mt", + "mul", + "multiEntry", + "multiSelectionObj", + "multiline", + "multiple", + "multiply", + "multiplySelf", + "multisample", + "multisampled", + "mutableFile", + "muted", + "n", + "nacl_arch", + "name", + "nameList", + "nameProp", + "namedItem", + "namedRecordset", + "names", + "namespaceURI", + "namespaces", + "nativeApplication", + "nativeMap", + "nativeObjectCreate", + "nativeSet", + "nativeWeakMap", + "naturalHeight", + "naturalWidth", + "navigate", + "navigation", + "navigationMode", + "navigationPreload", + "navigationStart", + "navigationType", + "navigator", + "near", + "nearestViewportElement", + "negative", + "negotiated", + "netscape", + "networkState", + "networkStatus", + "newScale", + "newState", + "newTranslate", + "newURL", + "newValue", + "newValueSpecifiedUnits", + "newVersion", + "newhome", + "next", + "nextElementSibling", + "nextHopProtocol", + "nextNode", + "nextPage", + "nextSibling", + "nickname", + "noHref", + "noModule", + "noResize", + "noShade", + "noValidate", + "noWrap", + "node", + "nodeName", + "nodeType", + "nodeValue", + "nonce", + "normDepthBufferFromNormView", + "normalize", + "normalizedPathSegList", + "normandyAddonStudy", + "notRestoredReasons", + "notationName", + "notations", + "note", + "noteGrainOn", + "noteOff", + "noteOn", + "notifications", + "notify", + "now", + "npnNegotiatedProtocol", + "numOctaves", + "number", + "numberOfChannels", + "numberOfFrames", + "numberOfInputs", + "numberOfItems", + "numberOfOutputs", + "numberValue", + "oMatchesSelector", + "object", + "object-fit", + "object-position", + "objectFit", + "objectPosition", + "objectStore", + "objectStoreNames", + "objectType", + "observe", + "occlusionQuerySet", + "of", + "off", + "offscreenBuffering", + "offset", + "offset-anchor", + "offset-distance", + "offset-path", + "offset-position", + "offset-rotate", + "offsetAnchor", + "offsetDistance", + "offsetHeight", + "offsetLeft", + "offsetNode", + "offsetParent", + "offsetPath", + "offsetPosition", + "offsetRotate", + "offsetTop", + "offsetWidth", + "offsetX", + "offsetY", + "ok", + "oldState", + "oldURL", + "oldValue", + "oldVersion", + "olderShadowRoot", + "omnibox", + "on", + "onActivated", + "onAdded", + "onAttached", + "onBoundsChanged", + "onBrowserUpdateAvailable", + "onClicked", + "onCommitFiberRoot", + "onCommitFiberUnmount", + "onConnect", + "onConnectExternal", + "onConnectNative", + "onCreated", + "onDetached", + "onDisabled", + "onEnabled", + "onFocusChanged", + "onHighlighted", + "onInstalled", + "onLine", + "onMessage", + "onMessageExternal", + "onMoved", + "onPerformanceWarning", + "onPostCommitFiberRoot", + "onRemoved", + "onReplaced", + "onRestartRequired", + "onStartup", + "onSubmittedWorkDone", + "onSuspend", + "onSuspendCanceled", + "onUninstalled", + "onUpdateAvailable", + "onUpdated", + "onUserScriptConnect", + "onUserScriptMessage", + "onUserSettingsChanged", + "onZoomChange", + "onabort", + "onabsolutedeviceorientation", + "onactivate", + "onactive", + "onaddsourcebuffer", + "onaddstream", + "onaddtrack", + "onafterprint", + "onafterscriptexecute", + "onafterupdate", + "onanimationcancel", + "onanimationend", + "onanimationiteration", + "onanimationstart", + "onappinstalled", + "onaudioend", + "onaudioprocess", + "onaudiostart", + "onautocomplete", + "onautocompleteerror", + "onauxclick", + "onbeforeactivate", + "onbeforecopy", + "onbeforecut", + "onbeforedeactivate", + "onbeforeeditfocus", + "onbeforeinput", + "onbeforeinstallprompt", + "onbeforematch", + "onbeforepaste", + "onbeforeprint", + "onbeforescriptexecute", + "onbeforetoggle", + "onbeforeunload", + "onbeforeupdate", + "onbeforexrselect", + "onbegin", + "onblocked", + "onblur", + "onbounce", + "onboundary", + "onbufferedamountlow", + "oncached", + "oncancel", + "oncandidatewindowhide", + "oncandidatewindowshow", + "oncandidatewindowupdate", + "oncanplay", + "oncanplaythrough", + "oncapturehandlechange", + "once", + "oncellchange", + "onchange", + "oncharacterboundsupdate", + "oncharacteristicvaluechanged", + "onchargingchange", + "onchargingtimechange", + "onchecking", + "onclick", + "onclose", + "onclosing", + "oncompassneedscalibration", + "oncomplete", + "oncompositionend", + "oncompositionstart", + "onconnect", + "onconnecting", + "onconnectionavailable", + "onconnectionstatechange", + "oncontentvisibilityautostatechange", + "oncontextlost", + "oncontextmenu", + "oncontextrestored", + "oncontrollerchange", + "oncontrolselect", + "oncopy", + "oncuechange", + "oncurrententrychange", + "oncurrentscreenchange", + "oncut", + "ondataavailable", + "ondatachannel", + "ondatasetchanged", + "ondatasetcomplete", + "ondblclick", + "ondeactivate", + "ondequeue", + "ondevicechange", + "ondevicelight", + "ondevicemotion", + "ondeviceorientation", + "ondeviceorientationabsolute", + "ondeviceproximity", + "ondischargingtimechange", + "ondisconnect", + "ondisplay", + "ondispose", + "ondownloading", + "ondrag", + "ondragend", + "ondragenter", + "ondragexit", + "ondragleave", + "ondragover", + "ondragstart", + "ondrop", + "ondurationchange", + "onemptied", + "onencrypted", + "onend", + "onended", + "onenter", + "onenterpictureinpicture", + "onerror", + "onerrorupdate", + "onexit", + "onfencedtreeclick", + "onfilterchange", + "onfinish", + "onfocus", + "onfocusin", + "onfocusout", + "onformdata", + "onfreeze", + "onfullscreenchange", + "onfullscreenerror", + "ongamepadconnected", + "ongamepaddisconnected", + "ongatheringstatechange", + "ongattserverdisconnected", + "ongeometrychange", + "ongesturechange", + "ongestureend", + "ongesturestart", + "ongotpointercapture", + "onhashchange", + "onhelp", + "onicecandidate", + "onicecandidateerror", + "oniceconnectionstatechange", + "onicegatheringstatechange", + "oninactive", + "oninput", + "oninputreport", + "oninputsourceschange", + "oninvalid", + "onkeydown", + "onkeypress", + "onkeystatuseschange", + "onkeyup", + "onlanguagechange", + "onlayoutcomplete", + "onleavepictureinpicture", + "onlevelchange", + "onload", + "onloadT", + "onloadeddata", + "onloadedmetadata", + "onloadend", + "onloading", + "onloadingdone", + "onloadingerror", + "onloadstart", + "onlosecapture", + "onlostpointercapture", + "only", + "onmanagedconfigurationchange", + "onmark", + "onmessage", + "onmessageerror", + "onmidimessage", + "onmousedown", + "onmouseenter", + "onmouseleave", + "onmousemove", + "onmouseout", + "onmouseover", + "onmouseup", + "onmousewheel", + "onmove", + "onmoveend", + "onmovestart", + "onmozfullscreenchange", + "onmozfullscreenerror", + "onmozorientationchange", + "onmozpointerlockchange", + "onmozpointerlockerror", + "onmscontentzoom", + "onmsfullscreenchange", + "onmsfullscreenerror", + "onmsgesturechange", + "onmsgesturedoubletap", + "onmsgestureend", + "onmsgesturehold", + "onmsgesturestart", + "onmsgesturetap", + "onmsgotpointercapture", + "onmsinertiastart", + "onmslostpointercapture", + "onmsmanipulationstatechanged", + "onmsneedkey", + "onmsorientationchange", + "onmspointercancel", + "onmspointerdown", + "onmspointerenter", + "onmspointerhover", + "onmspointerleave", + "onmspointermove", + "onmspointerout", + "onmspointerover", + "onmspointerup", + "onmssitemodejumplistitemremoved", + "onmsthumbnailclick", + "onmute", + "onnavigate", + "onnavigateerror", + "onnavigatesuccess", + "onnegotiationneeded", + "onnomatch", + "onnoupdate", + "onobsolete", + "onoffline", + "ononline", + "onopen", + "onorientationchange", + "onpagechange", + "onpagehide", + "onpagereveal", + "onpageshow", + "onpageswap", + "onpaste", + "onpause", + "onpayerdetailchange", + "onpaymentmethodchange", + "onplay", + "onplaying", + "onpluginstreamstart", + "onpointercancel", + "onpointerdown", + "onpointerenter", + "onpointerleave", + "onpointerlockchange", + "onpointerlockerror", + "onpointermove", + "onpointerout", + "onpointerover", + "onpointerrawupdate", + "onpointerup", + "onpopstate", + "onprerenderingchange", + "onprioritychange", + "onprocessorerror", + "onprogress", + "onpropertychange", + "onratechange", + "onreading", + "onreadystatechange", + "onreflectionchange", + "onrejectionhandled", + "onrelease", + "onremove", + "onremovesourcebuffer", + "onremovestream", + "onremovetrack", + "onrepeat", + "onreset", + "onresize", + "onresizeend", + "onresizestart", + "onresourcetimingbufferfull", + "onresult", + "onresume", + "onrowenter", + "onrowexit", + "onrowsdelete", + "onrowsinserted", + "onscreenschange", + "onscroll", + "onscrollend", + "onscrollsnapchange", + "onscrollsnapchanging", + "onsearch", + "onsecuritypolicyviolation", + "onseeked", + "onseeking", + "onselect", + "onselectedcandidatepairchange", + "onselectend", + "onselectionchange", + "onselectstart", + "onshippingaddresschange", + "onshippingoptionchange", + "onshow", + "onsignalingstatechange", + "onsinkchange", + "onslotchange", + "onsoundend", + "onsoundstart", + "onsourceclose", + "onsourceclosed", + "onsourceended", + "onsourceopen", + "onspeechend", + "onspeechstart", + "onsqueeze", + "onsqueezeend", + "onsqueezestart", + "onstalled", + "onstart", + "onstatechange", + "onstop", + "onstorage", + "onstoragecommit", + "onsubmit", + "onsuccess", + "onsuspend", + "onterminate", + "ontextformatupdate", + "ontextinput", + "ontextupdate", + "ontimeout", + "ontimeupdate", + "ontoggle", + "ontonechange", + "ontouchcancel", + "ontouchend", + "ontouchmove", + "ontouchstart", + "ontrack", + "ontransitioncancel", + "ontransitionend", + "ontransitionrun", + "ontransitionstart", + "onuncapturederror", + "onunhandledrejection", + "onunload", + "onunmute", + "onupdate", + "onupdateend", + "onupdatefound", + "onupdateready", + "onupdatestart", + "onupgradeneeded", + "onuserproximity", + "onversionchange", + "onvisibilitychange", + "onvoiceschanged", + "onvolumechange", + "onvrdisplayactivate", + "onvrdisplayconnect", + "onvrdisplaydeactivate", + "onvrdisplaydisconnect", + "onvrdisplaypresentchange", + "onwaiting", + "onwaitingforkey", + "onwarning", + "onwebkitanimationend", + "onwebkitanimationiteration", + "onwebkitanimationstart", + "onwebkitcurrentplaybacktargetiswirelesschanged", + "onwebkitfullscreenchange", + "onwebkitfullscreenerror", + "onwebkitkeyadded", + "onwebkitkeyerror", + "onwebkitkeymessage", + "onwebkitneedkey", + "onwebkitorientationchange", + "onwebkitplaybacktargetavailabilitychanged", + "onwebkitpointerlockchange", + "onwebkitpointerlockerror", + "onwebkitresourcetimingbufferfull", + "onwebkittransitionend", + "onwheel", + "onzoom", + "opacity", + "open", + "openCursor", + "openDatabase", + "openKeyCursor", + "openOptionsPage", + "openOrClosedShadowRoot", + "openPopup", + "opened", + "opener", + "opera", + "operation", + "operationType", + "operator", + "opr", + "optimum", + "options", + "or", + "order", + "orderX", + "orderY", + "ordered", + "org", + "organization", + "orient", + "orientAngle", + "orientType", + "orientation", + "orientationX", + "orientationY", + "orientationZ", + "origin", + "originAgentCluster", + "originalPolicy", + "originalTarget", + "orphans", + "os", + "oscpu", + "outerHTML", + "outerHeight", + "outerText", + "outerWidth", + "outgoingHighWaterMark", + "outgoingMaxAge", + "outline", + "outline-color", + "outline-offset", + "outline-style", + "outline-width", + "outlineColor", + "outlineOffset", + "outlineStyle", + "outlineWidth", + "outputBuffer", + "outputChannelCount", + "outputLatency", + "outputs", + "overflow", + "overflow-anchor", + "overflow-block", + "overflow-clip-margin", + "overflow-inline", + "overflow-wrap", + "overflow-x", + "overflow-y", + "overflowAnchor", + "overflowBlock", + "overflowClipMargin", + "overflowInline", + "overflowWrap", + "overflowX", + "overflowY", + "overlaysContent", + "overrideColors", + "overrideMimeType", + "oversample", + "overscroll-behavior", + "overscroll-behavior-block", + "overscroll-behavior-inline", + "overscroll-behavior-x", + "overscroll-behavior-y", + "overscrollBehavior", + "overscrollBehaviorBlock", + "overscrollBehaviorInline", + "overscrollBehaviorX", + "overscrollBehaviorY", + "ownKeys", + "ownerDocument", + "ownerElement", + "ownerNode", + "ownerRule", + "ownerSVGElement", + "owningElement", + "p1", + "p2", + "p3", + "p4", + "packetSize", + "packets", + "pad", + "padEnd", + "padStart", + "padding", + "padding-block", + "padding-block-end", + "padding-block-start", + "padding-bottom", + "padding-inline", + "padding-inline-end", + "padding-inline-start", + "padding-left", + "padding-right", + "padding-top", + "paddingBlock", + "paddingBlockEnd", + "paddingBlockStart", + "paddingBottom", + "paddingInline", + "paddingInlineEnd", + "paddingInlineStart", + "paddingLeft", + "paddingRight", + "paddingTop", + "page", + "page-break-after", + "page-break-before", + "page-break-inside", + "page-orientation", + "pageAction", + "pageBreakAfter", + "pageBreakBefore", + "pageBreakInside", + "pageCount", + "pageLeft", + "pageOrientation", + "pageT", + "pageTop", + "pageX", + "pageXOffset", + "pageY", + "pageYOffset", + "pages", + "paint-order", + "paintOrder", + "paintRequests", + "paintType", + "paintWorklet", + "palette", + "pan", + "panningModel", + "parameterData", + "parameters", + "parent", + "parentElement", + "parentNode", + "parentRule", + "parentStyleSheet", + "parentTextEdit", + "parentWindow", + "parse", + "parseAll", + "parseCreationOptionsFromJSON", + "parseFloat", + "parseFromString", + "parseHTMLUnsafe", + "parseInt", + "parseRequestOptionsFromJSON", + "part", + "participants", + "passOp", + "passive", + "password", + "pasteHTML", + "path", + "pathLength", + "pathSegList", + "pathSegType", + "pathSegTypeAsLetter", + "pathname", + "pattern", + "patternContentUnits", + "patternMismatch", + "patternTransform", + "patternUnits", + "pause", + "pauseAnimations", + "pauseDuration", + "pauseOnExit", + "pauseProfilers", + "pauseTransformFeedback", + "paused", + "payerEmail", + "payerName", + "payerPhone", + "paymentManager", + "pc", + "pdfViewerEnabled", + "peerIdentity", + "pending", + "pendingLocalDescription", + "pendingRemoteDescription", + "percent", + "performance", + "periodicSync", + "permission", + "permissionState", + "permissions", + "persist", + "persisted", + "persistentDeviceId", + "personalbar", + "perspective", + "perspective-origin", + "perspectiveOrigin", + "phone", + "phoneticFamilyName", + "phoneticGivenName", + "photo", + "pictureInPictureChild", + "pictureInPictureElement", + "pictureInPictureEnabled", + "pictureInPictureWindow", + "ping", + "pipeThrough", + "pipeTo", + "pitch", + "pixelBottom", + "pixelDepth", + "pixelHeight", + "pixelLeft", + "pixelRight", + "pixelStorei", + "pixelTop", + "pixelUnitToMillimeterX", + "pixelUnitToMillimeterY", + "pixelWidth", + "pkcs11", + "place-content", + "place-items", + "place-self", + "placeContent", + "placeItems", + "placeSelf", + "placeholder", + "platform", + "platformVersion", + "platforms", + "play", + "playEffect", + "playState", + "playbackRate", + "playbackState", + "playbackTime", + "played", + "playoutDelayHint", + "playsInline", + "plugins", + "pluginspage", + "pname", + "pointer-events", + "pointerBeforeReferenceNode", + "pointerEnabled", + "pointerEvents", + "pointerId", + "pointerLockElement", + "pointerType", + "points", + "pointsAtX", + "pointsAtY", + "pointsAtZ", + "polygonOffset", + "pop", + "popDebugGroup", + "popErrorScope", + "popover", + "popoverTargetAction", + "popoverTargetElement", + "populateMatrix", + "popupWindowFeatures", + "popupWindowName", + "popupWindowURI", + "port", + "port1", + "port2", + "ports", + "posBottom", + "posHeight", + "posLeft", + "posRight", + "posTop", + "posWidth", + "pose", + "position", + "position-anchor", + "position-area", + "positionAlign", + "positionAnchor", + "positionArea", + "positionX", + "positionY", + "positionZ", + "postError", + "postMessage", + "postTask", + "postalCode", + "poster", + "postscriptName", + "pow", + "powerEfficient", + "powerOff", + "powerPreference", + "preMultiplySelf", + "precision", + "preferredReflectionFormat", + "preferredStyleSheetSet", + "preferredStylesheetSet", + "prefix", + "preload", + "premultipliedAlpha", + "prepend", + "prerendering", + "presentation", + "presentationArea", + "presentationStyle", + "preserveAlpha", + "preserveAspectRatio", + "preserveAspectRatioString", + "preservesPitch", + "pressed", + "pressure", + "prevValue", + "preventDefault", + "preventExtensions", + "preventSilentAccess", + "previousElementSibling", + "previousNode", + "previousPage", + "previousPriority", + "previousRect", + "previousScale", + "previousSibling", + "previousTranslate", + "primaries", + "primaryKey", + "primaryLightDirection", + "primaryLightIntensity", + "primitive", + "primitiveType", + "primitiveUnits", + "principals", + "print", + "print-color-adjust", + "printColorAdjust", + "printPreview", + "priority", + "privacy", + "privateKey", + "privateToken", + "probablySupportsContext", + "probeSpace", + "process", + "processIceMessage", + "processingEnd", + "processingStart", + "processorOptions", + "product", + "productId", + "productName", + "productSub", + "profile", + "profileEnd", + "profiles", + "projectionMatrix", + "promise", + "prompt", + "properties", + "propertyIsEnumerable", + "propertyName", + "protectedAudience", + "protocol", + "protocolLong", + "prototype", + "provider", + "proxy", + "pseudoClass", + "pseudoElement", + "pt", + "publicId", + "publicKey", + "published", + "pulse", + "push", + "pushDebugGroup", + "pushErrorScope", + "pushManager", + "pushNotification", + "pushState", + "put", + "putImageData", + "px", + "quadraticCurveTo", + "qualifier", + "quaternion", + "query", + "queryCommandEnabled", + "queryCommandIndeterm", + "queryCommandState", + "queryCommandSupported", + "queryCommandText", + "queryCommandValue", + "queryFeatureSupport", + "queryLocalFonts", + "queryPermission", + "querySelector", + "querySelectorAll", + "querySet", + "queue", + "queueMicrotask", + "quote", + "quotes", + "r", + "r1", + "r2", + "race", + "rad", + "radiogroup", + "radius", + "radiusX", + "radiusY", + "random", + "randomUUID", + "range", + "rangeCount", + "rangeEnd", + "rangeMax", + "rangeMin", + "rangeOffset", + "rangeOverflow", + "rangeParent", + "rangeStart", + "rangeUnderflow", + "rate", + "ratio", + "raw", + "rawId", + "rawJSON", + "rawValueToMeters", + "rcap", + "rch", + "read", + "readAsArrayBuffer", + "readAsBinaryString", + "readAsBlob", + "readAsDataURL", + "readAsText", + "readBuffer", + "readEntries", + "readOnly", + "readPixels", + "readReportRequested", + "readText", + "readValue", + "readable", + "ready", + "readyState", + "reason", + "reasons", + "reboot", + "receiveFeatureReport", + "receivedAlert", + "receiver", + "receivers", + "recipient", + "recommendedViewportScale", + "reconnect", + "recordNumber", + "recordsAvailable", + "recordset", + "rect", + "red", + "redEyeReduction", + "redirect", + "redirectCount", + "redirectEnd", + "redirectStart", + "redirected", + "reduce", + "reduceRight", + "reduction", + "refDistance", + "refX", + "refY", + "referenceNode", + "referenceSpace", + "referrer", + "referrerPolicy", + "refresh", + "region", + "regionAnchorX", + "regionAnchorY", + "regionId", + "regions", + "register", + "registerContentHandler", + "registerElement", + "registerInternalModuleStart", + "registerInternalModuleStop", + "registerProperty", + "registerProtocolHandler", + "reject", + "rel", + "relList", + "relatedAddress", + "relatedNode", + "relatedPort", + "relatedTarget", + "relayProtocol", + "release", + "releaseCapture", + "releaseEvents", + "releaseInterface", + "releaseLock", + "releasePointerCapture", + "releaseShaderCompiler", + "released", + "reliability", + "reliable", + "reliableWrite", + "reload", + "rem", + "remainingSpace", + "remote", + "remoteDescription", + "remove", + "removeAllRanges", + "removeAttribute", + "removeAttributeNS", + "removeAttributeNode", + "removeBehavior", + "removeChild", + "removeCue", + "removeEntry", + "removeEventListener", + "removeFilter", + "removeImport", + "removeItem", + "removeListener", + "removeNamedItem", + "removeNamedItemNS", + "removeNode", + "removeParameter", + "removeProperty", + "removeRange", + "removeRegion", + "removeRule", + "removeSiteSpecificTrackingException", + "removeSourceBuffer", + "removeStream", + "removeTrack", + "removeVariable", + "removeWakeLockListener", + "removeWebWideTrackingException", + "removed", + "removedNodes", + "renderBlockingStatus", + "renderHeight", + "renderStart", + "renderState", + "renderTime", + "renderWidth", + "renderbufferStorage", + "renderbufferStorageMultisample", + "renderedBuffer", + "rendererInterfaces", + "renderers", + "renderingMode", + "renotify", + "repeat", + "repetitionCount", + "replace", + "replaceAdjacentText", + "replaceAll", + "replaceChild", + "replaceChildren", + "replaceData", + "replaceId", + "replaceItem", + "replaceNode", + "replaceState", + "replaceSync", + "replaceTrack", + "replaceWholeText", + "replaceWith", + "reportError", + "reportEvent", + "reportId", + "reportValidity", + "request", + "requestAdapter", + "requestAdapterInfo", + "requestAnimationFrame", + "requestAutocomplete", + "requestClose", + "requestData", + "requestDevice", + "requestFrame", + "requestFullscreen", + "requestHitTestSource", + "requestHitTestSourceForTransientInput", + "requestId", + "requestIdleCallback", + "requestLightProbe", + "requestMIDIAccess", + "requestMediaKeySystemAccess", + "requestPermission", + "requestPictureInPicture", + "requestPointerLock", + "requestPort", + "requestPresent", + "requestPresenter", + "requestReferenceSpace", + "requestSession", + "requestStart", + "requestStorageAccess", + "requestStorageAccessFor", + "requestSubmit", + "requestTime", + "requestUpdateCheck", + "requestVideoFrameCallback", + "requestViewportScale", + "requestWindow", + "requestingWindow", + "requireInteraction", + "required", + "requiredExtensions", + "requiredFeatures", + "requiredLimits", + "reset", + "resetLatency", + "resetPose", + "resetTransform", + "resizable", + "resize", + "resizeBy", + "resizeTo", + "resolve", + "resolveQuerySet", + "resolveTarget", + "resource", + "respond", + "respondWithNewView", + "response", + "responseBody", + "responseEnd", + "responseReady", + "responseStart", + "responseStatus", + "responseText", + "responseType", + "responseURL", + "responseXML", + "restart", + "restartAfterDelay", + "restartIce", + "restore", + "result", + "resultIndex", + "resultType", + "results", + "resume", + "resumeProfilers", + "resumeTransformFeedback", + "retry", + "returnValue", + "rev", + "reverse", + "reversed", + "revocable", + "revokeObjectURL", + "rex", + "rgbColor", + "ric", + "right", + "rightContext", + "rightDegrees", + "rightMargin", + "rightProjectionMatrix", + "rightViewMatrix", + "rlh", + "role", + "rolloffFactor", + "root", + "rootBounds", + "rootElement", + "rootMargin", + "rotate", + "rotateAxisAngle", + "rotateAxisAngleSelf", + "rotateFromVector", + "rotateFromVectorSelf", + "rotateSelf", + "rotation", + "rotationAngle", + "rotationRate", + "round", + "roundRect", + "row-gap", + "rowGap", + "rowIndex", + "rowSpan", + "rows", + "rowsPerImage", + "rtcpTransport", + "rtt", + "ruby-align", + "ruby-position", + "rubyAlign", + "rubyOverhang", + "rubyPosition", + "rules", + "run", + "runAdAuction", + "runtime", + "runtimeStyle", + "rx", + "ry", + "s", + "safari", + "sameDocument", + "sample", + "sampleCount", + "sampleCoverage", + "sampleInterval", + "sampleRate", + "sampleType", + "sampler", + "samplerParameterf", + "samplerParameteri", + "sandbox", + "save", + "saveAsPDF", + "saveData", + "scale", + "scale3d", + "scale3dSelf", + "scaleNonUniform", + "scaleNonUniformSelf", + "scaleSelf", + "scheduler", + "scheduling", + "scheme", + "scissor", + "scope", + "scopeName", + "scoped", + "screen", + "screenBrightness", + "screenEnabled", + "screenLeft", + "screenPixelToMillimeterX", + "screenPixelToMillimeterY", + "screenState", + "screenTop", + "screenX", + "screenY", + "screens", + "scriptURL", + "scripting", + "scripts", + "scroll", + "scroll-behavior", + "scroll-margin", + "scroll-margin-block", + "scroll-margin-block-end", + "scroll-margin-block-start", + "scroll-margin-bottom", + "scroll-margin-inline", + "scroll-margin-inline-end", + "scroll-margin-inline-start", + "scroll-margin-left", + "scroll-margin-right", + "scroll-margin-top", + "scroll-padding", + "scroll-padding-block", + "scroll-padding-block-end", + "scroll-padding-block-start", + "scroll-padding-bottom", + "scroll-padding-inline", + "scroll-padding-inline-end", + "scroll-padding-inline-start", + "scroll-padding-left", + "scroll-padding-right", + "scroll-padding-top", + "scroll-snap-align", + "scroll-snap-stop", + "scroll-snap-type", + "scrollAmount", + "scrollBehavior", + "scrollBy", + "scrollByLines", + "scrollByPages", + "scrollDelay", + "scrollHeight", + "scrollIntoView", + "scrollIntoViewIfNeeded", + "scrollLeft", + "scrollLeftMax", + "scrollMargin", + "scrollMarginBlock", + "scrollMarginBlockEnd", + "scrollMarginBlockStart", + "scrollMarginBottom", + "scrollMarginInline", + "scrollMarginInlineEnd", + "scrollMarginInlineStart", + "scrollMarginLeft", + "scrollMarginRight", + "scrollMarginTop", + "scrollMaxX", + "scrollMaxY", + "scrollPadding", + "scrollPaddingBlock", + "scrollPaddingBlockEnd", + "scrollPaddingBlockStart", + "scrollPaddingBottom", + "scrollPaddingInline", + "scrollPaddingInlineEnd", + "scrollPaddingInlineStart", + "scrollPaddingLeft", + "scrollPaddingRight", + "scrollPaddingTop", + "scrollRestoration", + "scrollSnapAlign", + "scrollSnapStop", + "scrollSnapType", + "scrollTo", + "scrollTop", + "scrollTopMax", + "scrollWidth", + "scrollX", + "scrollY", + "scrollbar-color", + "scrollbar-gutter", + "scrollbar-width", + "scrollbar3dLightColor", + "scrollbarArrowColor", + "scrollbarBaseColor", + "scrollbarColor", + "scrollbarDarkShadowColor", + "scrollbarFaceColor", + "scrollbarGutter", + "scrollbarHighlightColor", + "scrollbarShadowColor", + "scrollbarTrackColor", + "scrollbarWidth", + "scrollbars", + "scrolling", + "scrollingElement", + "sctp", + "sctpCauseCode", + "sdp", + "sdpLineNumber", + "sdpMLineIndex", + "sdpMid", + "seal", + "search", + "searchBox", + "searchBoxJavaBridge_", + "searchParams", + "sectionRowIndex", + "secureConnectionStart", + "security", + "seed", + "seek", + "seekToNextFrame", + "seekable", + "seeking", + "select", + "selectAllChildren", + "selectAlternateInterface", + "selectAudioOutput", + "selectConfiguration", + "selectNode", + "selectNodeContents", + "selectNodes", + "selectSingleNode", + "selectSubString", + "selectURL", + "selected", + "selectedIndex", + "selectedOptions", + "selectedStyleSheetSet", + "selectedStylesheetSet", + "selectedTrack", + "selection", + "selectionDirection", + "selectionEnd", + "selectionStart", + "selector", + "selectorText", + "self", + "send", + "sendAsBinary", + "sendBeacon", + "sendFeatureReport", + "sendMessage", + "sendNativeMessage", + "sendOrder", + "sendReport", + "sender", + "sentAlert", + "sentTimestamp", + "separator", + "serial", + "serialNumber", + "serializable", + "serializeToString", + "serverTiming", + "service", + "serviceWorker", + "session", + "sessionId", + "sessionStorage", + "sessions", + "set", + "setActionHandler", + "setActive", + "setAlpha", + "setAppBadge", + "setAttribute", + "setAttributeNS", + "setAttributeNode", + "setAttributeNodeNS", + "setAttributionReporting", + "setBadgeBackgroundColor", + "setBadgeText", + "setBadgeTextColor", + "setBaseAndExtent", + "setBigInt64", + "setBigUint64", + "setBindGroup", + "setBingCurrentSearchDefault", + "setBlendConstant", + "setCameraActive", + "setCapture", + "setCaptureHandleConfig", + "setCodecPreferences", + "setColor", + "setCompositeOperation", + "setConfiguration", + "setConsumer", + "setCurrentTime", + "setCustomValidity", + "setData", + "setDate", + "setDragImage", + "setEnabled", + "setEnd", + "setEndAfter", + "setEndBefore", + "setEndPoint", + "setExpires", + "setFillColor", + "setFilterRes", + "setFloat16", + "setFloat32", + "setFloat64", + "setFloatValue", + "setFocusBehavior", + "setFormValue", + "setFromBase64", + "setFromHex", + "setFullYear", + "setHTMLUnsafe", + "setHeaderExtensionsToNegotiate", + "setHeaderValue", + "setHours", + "setIcon", + "setIdentityProvider", + "setImmediate", + "setIndexBuffer", + "setInt16", + "setInt32", + "setInt8", + "setInterval", + "setItem", + "setKeyframes", + "setLineCap", + "setLineDash", + "setLineJoin", + "setLineWidth", + "setLiveSeekableRange", + "setLocalDescription", + "setMatrix", + "setMatrixValue", + "setMediaKeys", + "setMicrophoneActive", + "setMilliseconds", + "setMinutes", + "setMiterLimit", + "setMonth", + "setNamedItem", + "setNamedItemNS", + "setNonUserCodeExceptions", + "setOrientToAngle", + "setOrientToAuto", + "setOrientation", + "setOverrideHistoryNavigationMode", + "setPaint", + "setParameter", + "setParameters", + "setPeriodicWave", + "setPipeline", + "setPointerCapture", + "setPopup", + "setPosition", + "setPositionState", + "setPreference", + "setPriority", + "setPrivateToken", + "setProperty", + "setPrototypeOf", + "setRGBColor", + "setRGBColorICCColor", + "setRadius", + "setRangeText", + "setRemoteDescription", + "setReportEventDataForAutomaticBeacons", + "setRequestHeader", + "setResizable", + "setResourceTimingBufferSize", + "setRotate", + "setScale", + "setScissorRect", + "setSeconds", + "setSelectionRange", + "setServerCertificate", + "setShadow", + "setSharedStorageContext", + "setSignals", + "setSinkId", + "setSkewX", + "setSkewY", + "setStart", + "setStartAfter", + "setStartBefore", + "setStatus", + "setStdDeviation", + "setStencilReference", + "setStreams", + "setStrictMode", + "setStringValue", + "setStrokeColor", + "setSuggestResult", + "setTargetAtTime", + "setTargetValueAtTime", + "setTime", + "setTimeout", + "setTitle", + "setTransform", + "setTranslate", + "setUTCDate", + "setUTCFullYear", + "setUTCHours", + "setUTCMilliseconds", + "setUTCMinutes", + "setUTCMonth", + "setUTCSeconds", + "setUint16", + "setUint32", + "setUint8", + "setUninstallURL", + "setUpdateUrlData", + "setUri", + "setValidity", + "setValueAtTime", + "setValueCurveAtTime", + "setVariable", + "setVelocity", + "setVersion", + "setVertexBuffer", + "setViewport", + "setYear", + "setZoom", + "setZoomSettings", + "settingName", + "settingValue", + "sex", + "shaderLocation", + "shaderSource", + "shadowBlur", + "shadowColor", + "shadowOffsetX", + "shadowOffsetY", + "shadowRoot", + "shadowRootClonable", + "shadowRootDelegatesFocus", + "shadowRootMode", + "shadowRootSerializable", + "shape", + "shape-image-threshold", + "shape-margin", + "shape-outside", + "shape-rendering", + "shapeImageThreshold", + "shapeMargin", + "shapeOutside", + "shapeRendering", + "share", + "sharedStorage", + "sharedStorageWritable", + "sheet", + "shift", + "shiftKey", + "shiftLeft", + "shippingAddress", + "shippingOption", + "shippingType", + "show", + "showDirectoryPicker", + "showHelp", + "showModal", + "showModalDialog", + "showModelessDialog", + "showNotification", + "showOpenFilePicker", + "showPicker", + "showPopover", + "showSaveFilePicker", + "sidebar", + "sidebarAction", + "sign", + "signal", + "signalingState", + "signature", + "silent", + "sin", + "singleNodeValue", + "sinh", + "sinkId", + "sittingToStandingTransform", + "size", + "sizeAdjust", + "sizeToContent", + "sizeX", + "sizeZ", + "sizes", + "skewX", + "skewXSelf", + "skewY", + "skewYSelf", + "skipTransition", + "skipped", + "slice", + "slope", + "slot", + "slotAssignment", + "small", + "smil", + "smooth", + "smoothingTimeConstant", + "snapTargetBlock", + "snapTargetInline", + "snapToLines", + "snapshotItem", + "snapshotLength", + "some", + "sort", + "sortingCode", + "source", + "sourceBuffer", + "sourceBuffers", + "sourceCapabilities", + "sourceCharPosition", + "sourceFile", + "sourceFunctionName", + "sourceIndex", + "sourceMap", + "sourceURL", + "sources", + "spacing", + "span", + "speak", + "speakAs", + "speaking", + "species", + "specified", + "specularConstant", + "specularExponent", + "speechSynthesis", + "speed", + "speedOfSound", + "spellcheck", + "sphericalHarmonicsCoefficients", + "splice", + "split", + "splitText", + "spreadMethod", + "sqrt", + "src", + "srcElement", + "srcFactor", + "srcFilter", + "srcObject", + "srcUrn", + "srcdoc", + "srclang", + "srcset", + "stack", + "stackTraceLimit", + "stacktrace", + "stageParameters", + "standalone", + "standby", + "start", + "startContainer", + "startE", + "startIce", + "startLoadTime", + "startMessages", + "startNotifications", + "startOffset", + "startProfiling", + "startRendering", + "startShark", + "startTime", + "startViewTransition", + "startsWith", + "state", + "states", + "stats", + "status", + "statusCode", + "statusMessage", + "statusText", + "statusbar", + "stdDeviationX", + "stdDeviationY", + "stencilBack", + "stencilClearValue", + "stencilFront", + "stencilFunc", + "stencilFuncSeparate", + "stencilLoadOp", + "stencilMask", + "stencilMaskSeparate", + "stencilOp", + "stencilOpSeparate", + "stencilReadMask", + "stencilReadOnly", + "stencilStoreOp", + "stencilWriteMask", + "step", + "stepDown", + "stepMismatch", + "stepMode", + "stepUp", + "sticky", + "stitchTiles", + "stop", + "stop-color", + "stop-opacity", + "stopColor", + "stopImmediatePropagation", + "stopNotifications", + "stopOpacity", + "stopProfiling", + "stopPropagation", + "stopShark", + "stopped", + "storage", + "storageArea", + "storageBuckets", + "storageName", + "storageStatus", + "storageTexture", + "store", + "storeOp", + "storeSiteSpecificTrackingException", + "storeWebWideTrackingException", + "stpVersion", + "stream", + "streamErrorCode", + "streams", + "stretch", + "strike", + "string", + "stringValue", + "stringify", + "stripIndexFormat", + "stroke", + "stroke-dasharray", + "stroke-dashoffset", + "stroke-linecap", + "stroke-linejoin", + "stroke-miterlimit", + "stroke-opacity", + "stroke-width", + "strokeDasharray", + "strokeDashoffset", + "strokeLinecap", + "strokeLinejoin", + "strokeMiterlimit", + "strokeOpacity", + "strokeRect", + "strokeStyle", + "strokeText", + "strokeWidth", + "structuredClone", + "style", + "styleAndLayoutStart", + "styleFloat", + "styleMap", + "styleMedia", + "styleSheet", + "styleSheetSets", + "styleSheets", + "sub", + "subarray", + "subject", + "submit", + "submitFrame", + "submitter", + "subscribe", + "substr", + "substring", + "substringData", + "subtle", + "subtree", + "suffix", + "suffixes", + "summary", + "sup", + "supported", + "supportedContentEncodings", + "supportedEntryTypes", + "supportedValuesOf", + "supports", + "supportsFiber", + "supportsSession", + "supportsText", + "surfaceScale", + "surroundContents", + "suspend", + "suspendRedraw", + "svb", + "svh", + "svi", + "svmax", + "svmin", + "svw", + "swapCache", + "swapNode", + "sweepFlag", + "symbols", + "symmetricDifference", + "sync", + "syntax", + "sysexEnabled", + "system", + "systemCode", + "systemId", + "systemLanguage", + "systemXDPI", + "systemYDPI", + "tBodies", + "tFoot", + "tHead", + "tab", + "tab-size", + "tabId", + "tabIds", + "tabIndex", + "tabSize", + "table", + "table-layout", + "tableLayout", + "tableValues", + "tabs", + "tag", + "tagName", + "tagUrn", + "tags", + "taintEnabled", + "take", + "takePhoto", + "takeRecords", + "tan", + "tangentialPressure", + "tanh", + "target", + "targetAddressSpace", + "targetElement", + "targetRayMode", + "targetRaySpace", + "targetTouches", + "targetURL", + "targetX", + "targetY", + "targets", + "tcpType", + "tee", + "tel", + "telemetry", + "terminate", + "test", + "texImage2D", + "texImage3D", + "texParameterf", + "texParameteri", + "texStorage2D", + "texStorage3D", + "texSubImage2D", + "texSubImage3D", + "text", + "text-align", + "text-align-last", + "text-anchor", + "text-combine-upright", + "text-decoration", + "text-decoration-color", + "text-decoration-line", + "text-decoration-skip-ink", + "text-decoration-style", + "text-decoration-thickness", + "text-emphasis", + "text-emphasis-color", + "text-emphasis-position", + "text-emphasis-style", + "text-indent", + "text-justify", + "text-orientation", + "text-overflow", + "text-rendering", + "text-shadow", + "text-transform", + "text-underline-offset", + "text-underline-position", + "text-wrap", + "text-wrap-mode", + "text-wrap-style", + "textAlign", + "textAlignLast", + "textAnchor", + "textAutospace", + "textBaseline", + "textCombineUpright", + "textContent", + "textDecoration", + "textDecorationBlink", + "textDecorationColor", + "textDecorationLine", + "textDecorationLineThrough", + "textDecorationNone", + "textDecorationOverline", + "textDecorationSkipInk", + "textDecorationStyle", + "textDecorationThickness", + "textDecorationUnderline", + "textEmphasis", + "textEmphasisColor", + "textEmphasisPosition", + "textEmphasisStyle", + "textIndent", + "textJustify", + "textJustifyTrim", + "textKashida", + "textKashidaSpace", + "textLength", + "textOrientation", + "textOverflow", + "textRendering", + "textShadow", + "textTracks", + "textTransform", + "textUnderlineOffset", + "textUnderlinePosition", + "textWrap", + "textWrapMode", + "textWrapStyle", + "texture", + "theme", + "then", + "threadId", + "threshold", + "thresholds", + "throwIfAborted", + "tiltX", + "tiltY", + "time", + "timeEnd", + "timeLog", + "timeOrigin", + "timeRemaining", + "timeStamp", + "timecode", + "timeline", + "timelineTime", + "timeout", + "timestamp", + "timestampOffset", + "timestampWrites", + "timing", + "title", + "titlebarAreaRect", + "tlsChannelId", + "to", + "toArray", + "toBase64", + "toBlob", + "toDataURL", + "toDateString", + "toElement", + "toExponential", + "toFixed", + "toFloat32Array", + "toFloat64Array", + "toGMTString", + "toHex", + "toISOString", + "toJSON", + "toLocaleDateString", + "toLocaleFormat", + "toLocaleLowerCase", + "toLocaleString", + "toLocaleTimeString", + "toLocaleUpperCase", + "toLowerCase", + "toMatrix", + "toMethod", + "toPrecision", + "toPrimitive", + "toReversed", + "toSdp", + "toSorted", + "toSource", + "toSpliced", + "toStaticHTML", + "toString", + "toStringTag", + "toSum", + "toTimeString", + "toUTCString", + "toUpperCase", + "toWellFormed", + "toggle", + "toggleAttribute", + "toggleLongPressEnabled", + "togglePopover", + "toggleReaderMode", + "token", + "tone", + "toneBuffer", + "tooLong", + "tooShort", + "toolbar", + "top", + "topMargin", + "topSites", + "topology", + "total", + "totalFrameDelay", + "totalFrames", + "totalFramesDuration", + "totalVideoFrames", + "touch-action", + "touchAction", + "touched", + "touches", + "trace", + "track", + "trackVisibility", + "trackedAnchors", + "tracks", + "tran", + "transaction", + "transactions", + "transceiver", + "transfer", + "transferControlToOffscreen", + "transferFromImageBitmap", + "transferImageBitmap", + "transferIn", + "transferOut", + "transferSize", + "transferToFixedLength", + "transferToImageBitmap", + "transform", + "transform-box", + "transform-origin", + "transform-style", + "transformBox", + "transformFeedbackVaryings", + "transformOrigin", + "transformPoint", + "transformString", + "transformStyle", + "transformToDocument", + "transformToFragment", + "transition", + "transition-behavior", + "transition-delay", + "transition-duration", + "transition-property", + "transition-timing-function", + "transitionBehavior", + "transitionDelay", + "transitionDuration", + "transitionProperty", + "transitionTimingFunction", + "translate", + "translateSelf", + "translationX", + "translationY", + "transport", + "traverseTo", + "trim", + "trimEnd", + "trimLeft", + "trimRight", + "trimStart", + "trueSpeed", + "trunc", + "truncate", + "trustedTypes", + "try", + "turn", + "twist", + "type", + "typeDetail", + "typeMismatch", + "typeMustMatch", + "types", + "u2f", + "ubound", + "uint16", + "uint32", + "uint8", + "uint8Clamped", + "unadjustedMovement", + "unclippedDepth", + "unconfigure", + "undefined", + "underlineStyle", + "underlineThickness", + "unescape", + "uneval", + "ungroup", + "unicode", + "unicode-bidi", + "unicodeBidi", + "unicodeRange", + "unicodeSets", + "uniform1f", + "uniform1fv", + "uniform1i", + "uniform1iv", + "uniform1ui", + "uniform1uiv", + "uniform2f", + "uniform2fv", + "uniform2i", + "uniform2iv", + "uniform2ui", + "uniform2uiv", + "uniform3f", + "uniform3fv", + "uniform3i", + "uniform3iv", + "uniform3ui", + "uniform3uiv", + "uniform4f", + "uniform4fv", + "uniform4i", + "uniform4iv", + "uniform4ui", + "uniform4uiv", + "uniformBlockBinding", + "uniformMatrix2fv", + "uniformMatrix2x3fv", + "uniformMatrix2x4fv", + "uniformMatrix3fv", + "uniformMatrix3x2fv", + "uniformMatrix3x4fv", + "uniformMatrix4fv", + "uniformMatrix4x2fv", + "uniformMatrix4x3fv", + "uninstallSelf", + "union", + "unique", + "uniqueID", + "uniqueNumber", + "unit", + "unitType", + "units", + "unloadEventEnd", + "unloadEventStart", + "unlock", + "unmap", + "unmount", + "unobserve", + "unpackColorSpace", + "unpause", + "unpauseAnimations", + "unreadCount", + "unregister", + "unregisterContentHandler", + "unregisterProtocolHandler", + "unscopables", + "unselectable", + "unshift", + "unsubscribe", + "unsuspendRedraw", + "unsuspendRedrawAll", + "unwatch", + "unwrapKey", + "upDegrees", + "upX", + "upY", + "upZ", + "update", + "updateAdInterestGroups", + "updateCallbackDone", + "updateCharacterBounds", + "updateCommands", + "updateControlBounds", + "updateCurrentEntry", + "updateIce", + "updateInkTrailStartPoint", + "updateInterval", + "updatePlaybackRate", + "updateRangeEnd", + "updateRangeStart", + "updateRenderState", + "updateSelection", + "updateSelectionBounds", + "updateSettings", + "updateText", + "updateTiming", + "updateViaCache", + "updateWith", + "updated", + "updating", + "upgrade", + "upload", + "uploadTotal", + "uploaded", + "upper", + "upperBound", + "upperOpen", + "uri", + "url", + "urn", + "urns", + "usage", + "usages", + "usb", + "usbVersionMajor", + "usbVersionMinor", + "usbVersionSubminor", + "useCurrentView", + "useMap", + "useProgram", + "usedSpace", + "user-select", + "userActivation", + "userAgent", + "userAgentData", + "userChoice", + "userHandle", + "userHint", + "userInitiated", + "userLanguage", + "userSelect", + "userState", + "userVisibleOnly", + "username", + "usernameFragment", + "utterance", + "uuid", + "v8BreakIterator", + "vAlign", + "vLink", + "valid", + "validate", + "validateProgram", + "validationMessage", + "validity", + "value", + "valueAsDate", + "valueAsNumber", + "valueAsString", + "valueInSpecifiedUnits", + "valueMissing", + "valueOf", + "valueText", + "valueType", + "values", + "variable", + "variant", + "variationSettings", + "vb", + "vector-effect", + "vectorEffect", + "velocityAngular", + "velocityExpansion", + "velocityX", + "velocityY", + "vendor", + "vendorId", + "vendorSub", + "verify", + "version", + "vertex", + "vertexAttrib1f", + "vertexAttrib1fv", + "vertexAttrib2f", + "vertexAttrib2fv", + "vertexAttrib3f", + "vertexAttrib3fv", + "vertexAttrib4f", + "vertexAttrib4fv", + "vertexAttribDivisor", + "vertexAttribDivisorANGLE", + "vertexAttribI4i", + "vertexAttribI4iv", + "vertexAttribI4ui", + "vertexAttribI4uiv", + "vertexAttribIPointer", + "vertexAttribPointer", + "vertical", + "vertical-align", + "verticalAlign", + "verticalOverflow", + "vh", + "vi", + "vibrate", + "vibrationActuator", + "videoBitsPerSecond", + "videoHeight", + "videoTracks", + "videoWidth", + "view", + "viewBox", + "viewBoxString", + "viewDimension", + "viewFormats", + "viewTarget", + "viewTargetString", + "viewTransition", + "viewport", + "viewportAnchorX", + "viewportAnchorY", + "viewportElement", + "views", + "violatedDirective", + "virtualKeyboard", + "virtualKeyboardPolicy", + "visibility", + "visibilityState", + "visible", + "visibleRect", + "visualViewport", + "vlinkColor", + "vmax", + "vmin", + "voice", + "voiceURI", + "volume", + "vrml", + "vspace", + "vw", + "w", + "wait", + "waitAsync", + "waitSync", + "waiting", + "wake", + "wakeLock", + "wand", + "warmup", + "warn", + "wasAlternateProtocolAvailable", + "wasClean", + "wasDiscarded", + "wasFetchedViaSpdy", + "wasNpnNegotiated", + "watch", + "watchAvailability", + "watchPosition", + "webNavigation", + "webRequest", + "webdriver", + "webkitAddKey", + "webkitAlignContent", + "webkitAlignItems", + "webkitAlignSelf", + "webkitAnimation", + "webkitAnimationDelay", + "webkitAnimationDirection", + "webkitAnimationDuration", + "webkitAnimationFillMode", + "webkitAnimationIterationCount", + "webkitAnimationName", + "webkitAnimationPlayState", + "webkitAnimationTimingFunction", + "webkitAppearance", + "webkitAudioContext", + "webkitAudioDecodedByteCount", + "webkitAudioPannerNode", + "webkitBackfaceVisibility", + "webkitBackground", + "webkitBackgroundAttachment", + "webkitBackgroundClip", + "webkitBackgroundColor", + "webkitBackgroundImage", + "webkitBackgroundOrigin", + "webkitBackgroundPosition", + "webkitBackgroundPositionX", + "webkitBackgroundPositionY", + "webkitBackgroundRepeat", + "webkitBackgroundSize", + "webkitBackingStorePixelRatio", + "webkitBorderBottomLeftRadius", + "webkitBorderBottomRightRadius", + "webkitBorderImage", + "webkitBorderImageOutset", + "webkitBorderImageRepeat", + "webkitBorderImageSlice", + "webkitBorderImageSource", + "webkitBorderImageWidth", + "webkitBorderRadius", + "webkitBorderTopLeftRadius", + "webkitBorderTopRightRadius", + "webkitBoxAlign", + "webkitBoxDirection", + "webkitBoxFlex", + "webkitBoxOrdinalGroup", + "webkitBoxOrient", + "webkitBoxPack", + "webkitBoxShadow", + "webkitBoxSizing", + "webkitCancelAnimationFrame", + "webkitCancelFullScreen", + "webkitCancelKeyRequest", + "webkitCancelRequestAnimationFrame", + "webkitClearResourceTimings", + "webkitClipPath", + "webkitClosedCaptionsVisible", + "webkitConvertPointFromNodeToPage", + "webkitConvertPointFromPageToNode", + "webkitCreateShadowRoot", + "webkitCurrentFullScreenElement", + "webkitCurrentPlaybackTargetIsWireless", + "webkitDecodedFrameCount", + "webkitDirectionInvertedFromDevice", + "webkitDisplayingFullscreen", + "webkitDroppedFrameCount", + "webkitEnterFullScreen", + "webkitEnterFullscreen", + "webkitEntries", + "webkitExitFullScreen", + "webkitExitFullscreen", + "webkitExitPointerLock", + "webkitFilter", + "webkitFlex", + "webkitFlexBasis", + "webkitFlexDirection", + "webkitFlexFlow", + "webkitFlexGrow", + "webkitFlexShrink", + "webkitFlexWrap", + "webkitFontFeatureSettings", + "webkitFullScreenKeyboardInputAllowed", + "webkitFullscreenElement", + "webkitFullscreenEnabled", + "webkitGenerateKeyRequest", + "webkitGetAsEntry", + "webkitGetDatabaseNames", + "webkitGetEntries", + "webkitGetEntriesByName", + "webkitGetEntriesByType", + "webkitGetFlowByName", + "webkitGetGamepads", + "webkitGetImageDataHD", + "webkitGetNamedFlows", + "webkitGetRegionFlowRanges", + "webkitGetUserMedia", + "webkitHasClosedCaptions", + "webkitHidden", + "webkitIDBCursor", + "webkitIDBDatabase", + "webkitIDBDatabaseError", + "webkitIDBDatabaseException", + "webkitIDBFactory", + "webkitIDBIndex", + "webkitIDBKeyRange", + "webkitIDBObjectStore", + "webkitIDBRequest", + "webkitIDBTransaction", + "webkitImageSmoothingEnabled", + "webkitIndexedDB", + "webkitInitMessageEvent", + "webkitIsFullScreen", + "webkitJustifyContent", + "webkitKeys", + "webkitLineClamp", + "webkitLineDashOffset", + "webkitLockOrientation", + "webkitMask", + "webkitMaskClip", + "webkitMaskComposite", + "webkitMaskImage", + "webkitMaskOrigin", + "webkitMaskPosition", + "webkitMaskPositionX", + "webkitMaskPositionY", + "webkitMaskRepeat", + "webkitMaskSize", + "webkitMatchesSelector", + "webkitMediaStream", + "webkitNotifications", + "webkitOfflineAudioContext", + "webkitOrder", + "webkitOrientation", + "webkitPeerConnection00", + "webkitPersistentStorage", + "webkitPerspective", + "webkitPerspectiveOrigin", + "webkitPointerLockElement", + "webkitPostMessage", + "webkitPreservesPitch", + "webkitPutImageDataHD", + "webkitRTCPeerConnection", + "webkitRegionOverset", + "webkitRelativePath", + "webkitRequestAnimationFrame", + "webkitRequestFileSystem", + "webkitRequestFullScreen", + "webkitRequestFullscreen", + "webkitRequestPointerLock", + "webkitResolveLocalFileSystemURL", + "webkitSetMediaKeys", + "webkitSetResourceTimingBufferSize", + "webkitShadowRoot", + "webkitShowPlaybackTargetPicker", + "webkitSlice", + "webkitSpeechGrammar", + "webkitSpeechGrammarList", + "webkitSpeechRecognition", + "webkitSpeechRecognitionError", + "webkitSpeechRecognitionEvent", + "webkitStorageInfo", + "webkitSupportsFullscreen", + "webkitTemporaryStorage", + "webkitTextFillColor", + "webkitTextSecurity", + "webkitTextSizeAdjust", + "webkitTextStroke", + "webkitTextStrokeColor", + "webkitTextStrokeWidth", + "webkitTransform", + "webkitTransformOrigin", + "webkitTransformStyle", + "webkitTransition", + "webkitTransitionDelay", + "webkitTransitionDuration", + "webkitTransitionProperty", + "webkitTransitionTimingFunction", + "webkitURL", + "webkitUnlockOrientation", + "webkitUserSelect", + "webkitVideoDecodedByteCount", + "webkitVisibilityState", + "webkitWirelessVideoPlaybackDisabled", + "webkitdirectory", + "webkitdropzone", + "webstore", + "weight", + "wgslLanguageFeatures", + "whatToShow", + "wheelDelta", + "wheelDeltaX", + "wheelDeltaY", + "whenDefined", + "which", + "white-space", + "white-space-collapse", + "whiteSpace", + "whiteSpaceCollapse", + "wholeText", + "widows", + "width", + "will-change", + "willChange", + "willValidate", + "window", + "windowAttribution", + "windowControlsOverlay", + "windowId", + "windowIds", + "windows", + "with", + "withCredentials", + "withResolvers", + "word-break", + "word-spacing", + "word-wrap", + "wordBreak", + "wordSpacing", + "wordWrap", + "workerStart", + "worklet", + "wow64", + "wrap", + "wrapKey", + "writable", + "writableAuxiliaries", + "write", + "writeBuffer", + "writeMask", + "writeText", + "writeTexture", + "writeTimestamp", + "writeValue", + "writeValueWithResponse", + "writeValueWithoutResponse", + "writeWithoutResponse", + "writeln", + "writing-mode", + "writingMode", + "writingSuggestions", + "x", + "x1", + "x2", + "xChannelSelector", + "xmlEncoding", + "xmlStandalone", + "xmlVersion", + "xmlbase", + "xmllang", + "xmlspace", + "xor", + "xr", + "y", + "y1", + "y2", + "yChannelSelector", + "yandex", + "yield", + "z", + "z-index", + "zIndex", + "zoom", + "zoomAndPan", + "zoomRectScreen", +]; diff --git a/node_modules/terser/tools/exit.cjs b/node_modules/terser/tools/exit.cjs new file mode 100644 index 0000000..46a970b --- /dev/null +++ b/node_modules/terser/tools/exit.cjs @@ -0,0 +1,7 @@ +// workaround for tty output truncation upon process.exit() +// https://github.com/nodejs/node/issues/6456 + +[process.stdout, process.stderr].forEach((s) => { + s && s.isTTY && s._handle && s._handle.setBlocking && + s._handle.setBlocking(true) +}); diff --git a/node_modules/terser/tools/props.html b/node_modules/terser/tools/props.html new file mode 100644 index 0000000..fc2a426 --- /dev/null +++ b/node_modules/terser/tools/props.html @@ -0,0 +1,68 @@ + + + + + + + diff --git a/node_modules/terser/tools/terser.d.ts b/node_modules/terser/tools/terser.d.ts new file mode 100644 index 0000000..799de08 --- /dev/null +++ b/node_modules/terser/tools/terser.d.ts @@ -0,0 +1,217 @@ +/// + +import { SectionedSourceMapInput, EncodedSourceMap, DecodedSourceMap } from '@jridgewell/source-map'; + +export type ECMA = 5 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020; + +export type ConsoleProperty = keyof typeof console; +type DropConsoleOption = boolean | ConsoleProperty[]; + +export interface ParseOptions { + bare_returns?: boolean; + /** @deprecated legacy option. Currently, all supported EcmaScript is valid to parse. */ + ecma?: ECMA; + html5_comments?: boolean; + shebang?: boolean; +} + +export interface CompressOptions { + arguments?: boolean; + arrows?: boolean; + booleans_as_integers?: boolean; + booleans?: boolean; + collapse_vars?: boolean; + comparisons?: boolean; + computed_props?: boolean; + conditionals?: boolean; + dead_code?: boolean; + defaults?: boolean; + directives?: boolean; + drop_console?: DropConsoleOption; + drop_debugger?: boolean; + ecma?: ECMA; + evaluate?: boolean; + expression?: boolean; + global_defs?: object; + hoist_funs?: boolean; + hoist_props?: boolean; + hoist_vars?: boolean; + ie8?: boolean; + if_return?: boolean; + inline?: boolean | InlineFunctions; + join_vars?: boolean; + keep_classnames?: boolean | RegExp; + keep_fargs?: boolean; + keep_fnames?: boolean | RegExp; + keep_infinity?: boolean; + lhs_constants?: boolean; + loops?: boolean; + module?: boolean; + negate_iife?: boolean; + passes?: number; + properties?: boolean; + pure_funcs?: string[]; + pure_new?: boolean; + pure_getters?: boolean | 'strict'; + reduce_funcs?: boolean; + reduce_vars?: boolean; + sequences?: boolean | number; + side_effects?: boolean; + switches?: boolean; + toplevel?: boolean; + top_retain?: null | string | string[] | RegExp; + typeofs?: boolean; + unsafe_arrows?: boolean; + unsafe?: boolean; + unsafe_comps?: boolean; + unsafe_Function?: boolean; + unsafe_math?: boolean; + unsafe_symbols?: boolean; + unsafe_methods?: boolean; + unsafe_proto?: boolean; + unsafe_regexp?: boolean; + unsafe_undefined?: boolean; + unused?: boolean; +} + +export enum InlineFunctions { + Disabled = 0, + SimpleFunctions = 1, + WithArguments = 2, + WithArgumentsAndVariables = 3 +} + +export interface MangleOptions { + eval?: boolean; + keep_classnames?: boolean | RegExp; + keep_fnames?: boolean | RegExp; + module?: boolean; + nth_identifier?: SimpleIdentifierMangler | WeightedIdentifierMangler; + properties?: boolean | ManglePropertiesOptions; + reserved?: string[]; + safari10?: boolean; + toplevel?: boolean; +} + +/** + * An identifier mangler for which the output is invariant with respect to the source code. + */ +export interface SimpleIdentifierMangler { + /** + * Obtains the nth most favored (usually shortest) identifier to rename a variable to. + * The mangler will increment n and retry until the return value is not in use in scope, and is not a reserved word. + * This function is expected to be stable; Evaluating get(n) === get(n) should always return true. + * @param n The ordinal of the identifier. + */ + get(n: number): string; +} + +/** + * An identifier mangler that leverages character frequency analysis to determine identifier precedence. + */ +export interface WeightedIdentifierMangler extends SimpleIdentifierMangler { + /** + * Modifies the internal weighting of the input characters by the specified delta. + * Will be invoked on the entire printed AST, and then deduct mangleable identifiers. + * @param chars The characters to modify the weighting of. + * @param delta The numeric weight to add to the characters. + */ + consider(chars: string, delta: number): number; + /** + * Resets character weights. + */ + reset(): void; + /** + * Sorts identifiers by character frequency, in preparation for calls to get(n). + */ + sort(): void; +} + +export interface ManglePropertiesOptions { + builtins?: boolean; + debug?: boolean; + keep_quoted?: boolean | 'strict'; + nth_identifier?: SimpleIdentifierMangler | WeightedIdentifierMangler; + regex?: RegExp | string; + reserved?: string[]; +} + +export interface FormatOptions { + ascii_only?: boolean; + /** @deprecated Not implemented anymore */ + beautify?: boolean; + braces?: boolean; + comments?: boolean | 'all' | 'some' | RegExp | ( (node: any, comment: { + value: string, + type: 'comment1' | 'comment2' | 'comment3' | 'comment4', + pos: number, + line: number, + col: number, + }) => boolean ); + ecma?: ECMA; + ie8?: boolean; + keep_numbers?: boolean; + indent_level?: number; + indent_start?: number; + inline_script?: boolean; + keep_quoted_props?: boolean; + max_line_len?: number | false; + preamble?: string; + preserve_annotations?: boolean; + quote_keys?: boolean; + quote_style?: OutputQuoteStyle; + safari10?: boolean; + semicolons?: boolean; + shebang?: boolean; + shorthand?: boolean; + source_map?: SourceMapOptions; + webkit?: boolean; + width?: number; + wrap_iife?: boolean; + wrap_func_args?: boolean; +} + +export enum OutputQuoteStyle { + PreferDouble = 0, + AlwaysSingle = 1, + AlwaysDouble = 2, + AlwaysOriginal = 3 +} + +export interface MinifyOptions { + compress?: boolean | CompressOptions; + ecma?: ECMA; + enclose?: boolean | string; + ie8?: boolean; + keep_classnames?: boolean | RegExp; + keep_fnames?: boolean | RegExp; + mangle?: boolean | MangleOptions; + module?: boolean; + nameCache?: object; + format?: FormatOptions; + /** @deprecated */ + output?: FormatOptions; + parse?: ParseOptions; + safari10?: boolean; + sourceMap?: boolean | SourceMapOptions; + toplevel?: boolean; +} + +export interface MinifyOutput { + code?: string; + map?: EncodedSourceMap | string; + decoded_map?: DecodedSourceMap | null; +} + +export interface SourceMapOptions { + /** Source map object, 'inline' or source map file content */ + content?: SectionedSourceMapInput | string; + includeSources?: boolean; + filename?: string; + root?: string; + asObject?: boolean; + url?: string | 'inline'; +} + +export function minify(files: string | string[] | { [file: string]: string }, options?: MinifyOptions): Promise; +export function minify_sync(files: string | string[] | { [file: string]: string }, options?: MinifyOptions): MinifyOutput; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..b4422a6 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,669 @@ +{ + "name": "workspace", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "workspace", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "sharp": "^0.34.4", + "terser": "^5.44.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.5.0.tgz", + "integrity": "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@img/colour": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", + "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.4.tgz", + "integrity": "sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.3" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.4.tgz", + "integrity": "sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.3" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.3.tgz", + "integrity": "sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.3.tgz", + "integrity": "sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.3.tgz", + "integrity": "sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.3.tgz", + "integrity": "sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.3.tgz", + "integrity": "sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.3.tgz", + "integrity": "sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.3.tgz", + "integrity": "sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.3.tgz", + "integrity": "sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.3.tgz", + "integrity": "sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.4.tgz", + "integrity": "sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.3" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.4.tgz", + "integrity": "sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.3" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.4.tgz", + "integrity": "sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.3" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.4.tgz", + "integrity": "sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.3" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.4.tgz", + "integrity": "sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.3" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.4.tgz", + "integrity": "sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.3" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.4.tgz", + "integrity": "sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.3" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.4.tgz", + "integrity": "sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.5.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.4.tgz", + "integrity": "sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.4.tgz", + "integrity": "sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.4.tgz", + "integrity": "sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.4.tgz", + "integrity": "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.0", + "semver": "^7.7.2" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.4", + "@img/sharp-darwin-x64": "0.34.4", + "@img/sharp-libvips-darwin-arm64": "1.2.3", + "@img/sharp-libvips-darwin-x64": "1.2.3", + "@img/sharp-libvips-linux-arm": "1.2.3", + "@img/sharp-libvips-linux-arm64": "1.2.3", + "@img/sharp-libvips-linux-ppc64": "1.2.3", + "@img/sharp-libvips-linux-s390x": "1.2.3", + "@img/sharp-libvips-linux-x64": "1.2.3", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", + "@img/sharp-libvips-linuxmusl-x64": "1.2.3", + "@img/sharp-linux-arm": "0.34.4", + "@img/sharp-linux-arm64": "0.34.4", + "@img/sharp-linux-ppc64": "0.34.4", + "@img/sharp-linux-s390x": "0.34.4", + "@img/sharp-linux-x64": "0.34.4", + "@img/sharp-linuxmusl-arm64": "0.34.4", + "@img/sharp-linuxmusl-x64": "0.34.4", + "@img/sharp-wasm32": "0.34.4", + "@img/sharp-win32-arm64": "0.34.4", + "@img/sharp-win32-ia32": "0.34.4", + "@img/sharp-win32-x64": "0.34.4" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/terser": { + "version": "5.44.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz", + "integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..ec04e34 --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "workspace", + "version": "1.0.0", + "description": "", + "main": "stereoh5.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/urix/HTML5-Stereo-Viewer.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/urix/HTML5-Stereo-Viewer/issues" + }, + "homepage": "https://github.com/urix/HTML5-Stereo-Viewer#readme", + "devDependencies": { + "sharp": "^0.34.4", + "terser": "^5.44.0" + } +} diff --git a/s-a.webp b/s-a.webp new file mode 100644 index 0000000..9245ea6 Binary files /dev/null and b/s-a.webp differ diff --git a/s-f.webp b/s-f.webp new file mode 100644 index 0000000..b0c3f6e Binary files /dev/null and b/s-f.webp differ diff --git a/s-f2.webp b/s-f2.webp new file mode 100644 index 0000000..4ff8a3f Binary files /dev/null and b/s-f2.webp differ diff --git a/s-f3.webp b/s-f3.webp new file mode 100644 index 0000000..63b8730 Binary files /dev/null and b/s-f3.webp differ diff --git a/s-lr.webp b/s-lr.webp new file mode 100644 index 0000000..f4d21fe Binary files /dev/null and b/s-lr.webp differ diff --git a/s-rl.webp b/s-rl.webp new file mode 100644 index 0000000..e889b77 Binary files /dev/null and b/s-rl.webp differ diff --git a/s-rl2.webp b/s-rl2.webp new file mode 100644 index 0000000..0b6033d Binary files /dev/null and b/s-rl2.webp differ diff --git a/s-rl3.webp b/s-rl3.webp new file mode 100644 index 0000000..404869e Binary files /dev/null and b/s-rl3.webp differ diff --git a/s-rl4.webp b/s-rl4.webp new file mode 100644 index 0000000..39d379f Binary files /dev/null and b/s-rl4.webp differ diff --git a/s-rl5.webp b/s-rl5.webp new file mode 100644 index 0000000..04449e5 Binary files /dev/null and b/s-rl5.webp differ diff --git a/s-rl6.webp b/s-rl6.webp new file mode 100644 index 0000000..965aa80 Binary files /dev/null and b/s-rl6.webp differ diff --git a/s-rl7.webp b/s-rl7.webp new file mode 100644 index 0000000..1ae3c13 Binary files /dev/null and b/s-rl7.webp differ diff --git a/s.htm b/s.htm index 20b66f8..08687b5 100644 --- a/s.htm +++ b/s.htm @@ -1 +1,113 @@ - HTML5 Stereo viewer

HTML5 Stereo viewer

Source images

Left-Right stereo pair source, Toys anaglyph source, Toys flat source, Toys Right-Left stereo pair source, Toys Right-Left stereo pair source source, St. Basil's Cathedral, Moscow, Russia Right-Left stereo pair source source, St. Basil's Cathedral, Moscow, Russia Right-Left stereo pair source source, Yauza river, Moscow, Russia Right-Left stereo pair source source, Moscow, Russia Right-Left stereo pair source source, forrest at Arkhangelsk region, Russia Right-Left stereo pair source source, at concert
\ No newline at end of file + + + + + + HTML5 Stereo viewer + + + + + +

HTML5 Stereo viewer

+
+ + + +
+

Source images

+ + + Left-Right stereo pair source, Toys + + + + anaglyph source, Toys + + + + flat source, Toys + + + + Right-Left stereo pair source, Toys + + + + Right-Left stereo pair source source, St. Basil's Cathedral, Moscow, Russia + + + + Right-Left stereo pair source source, St. Basil's Cathedral, Moscow, Russia + + + + Right-Left stereo pair source source, Yauza river, Moscow, Russia + + + + Right-Left stereo pair source source, Moscow, Russia + + + + Right-Left stereo pair source source, forrest at Arkhangelsk region, Russia + + + + Right-Left stereo pair source source, at concert + + + + +
+
+ + + + \ No newline at end of file diff --git a/stereoh5.js b/stereoh5.js index 0e76f64..d0e7253 100644 --- a/stereoh5.js +++ b/stereoh5.js @@ -1044,7 +1044,9 @@ function stereoCountImages() { for (j = 0; j < document.images.length; j++) { var cn = getClassName(document.images[j], new Array("anaglyph", "flat", "stereo", "stereoLR", "stereoRL")); if (cn != "") { - images[n] = document.images[j].src; + var imgElement = document.images[j]; + var resolvedSrc = (imgElement.currentSrc && imgElement.currentSrc.length > 0) ? imgElement.currentSrc : imgElement.src; + images[n] = resolvedSrc; imagesC[n] = document.images[j].getAttribute(stereoCaptionSrc); imagesT[n] = cn; if (imagesT[n] == "stereo") diff --git a/stereoh5.min.js b/stereoh5.min.js new file mode 100644 index 0000000..b1e134c --- /dev/null +++ b/stereoh5.min.js @@ -0,0 +1 @@ +var stereover="1.6",images=new Array,imagesT=new Array,imagesC=new Array,imageN=0,stereoMode=5,stereoBGcolor=0,stereoMouse=-1,stereoNavDef=0,stereoNav=stereoNavDef,stereoOptVis=!1,stereoSwap=!1,stereoCaption=!0,stereoCaptionSrc="alt",stereoDefType="stereoRL",stereoiOS=!1,stereoiOS_iPad=!1,stereoiOS_iPhone=!1,stereoIE=!1,stereourl="http://urixblog.com/html5-stereo-viewer",stereourlvis="http://urixblog.com/...",stereoCPRGHT="(C) 2011-2014 Yury Golubinsky",stereoModes=11,stereoGlasses=0,sGlassesRedCyan=0,sGlassesGreenMagenta=1,stereoFirstTimeHelpDisplayed=!0;function stereoViewerOpen(e,t,a,o,i,r){null!=o&&(stereoCaption=o),""!=i&&(stereoCaptionSrc=i),""!=r&&(stereoDefType=r),null!=e&e>=0&e<=stereoModes&&(stereoMode=e),null!=t&&(stereoSwap=t),stereoiOS_iPhone=-1!=navigator.appVersion.indexOf("iPhone")|-1!=navigator.appVersion.indexOf("iPod"),stereoiOS_iPad=-1!=navigator.appVersion.indexOf("iPad"),(stereoiOS=stereoiOS_iPad|stereoiOS_iPhone)&&(stereoNav=0),stereoIE=/MSIE (\d+\.\d+);/.test(navigator.userAgent),document.getElementById("stereoViewer")&&(document.body.insertBefore(document.getElementById("stereoViewer"),document.body.firstChild),document.body.removeChild(document.getElementById("stereoViewer")));var s=document.createElement("div");s.id="stereoViewer",s.style.position="fixed",s.style.zIndex=999990,s.style.top=0,s.style.left=0,s.style.backgroundColor="#000",s.style.visibility="visible",s.style.fontFamily="arial,verdana,helvetica",s.innerHTML='\t\t\t
\t\t\t\t\t\t\t
\t\t\t\t\t\t\t\t\t',document.body.insertBefore(s,document.body.firstChild),stereoiOS&!stereoiOS_iPad&&(document.getElementById("stereoControls").innerHTML='\t\t\t
\t\t\t
\t\t\t
\t\t\tMode:
\t\t\t
\t\t\t
\t\t\t\t\t\t Swap
\t\t\t\t\t\t
\t\t\tBackground color:
\t\t\t\t\t\t\t\t\t
\t\t\t
\t\t\t Show captions
\t\t\t
\t\t\t\t
HTML5 Stereo Viewer '+stereover+"
"+stereoCPRGHT+'
\t\t\t\t'+stereourlvis+'\t\t\t\t

\t\t\t\tCreative Commons License\t\t\t'),document.body.onkeyup=function(e){stereoKeyPress(e)},document.body.onmousewheel=function(e){stereoViewerClose(e)},document.body.onscroll=function(e){stereoViewerClose(e)},document.body.onorientationchange=function(e){stereoDrawImage()},document.getElementById("stereoControls").style.zIndex=999991,document.getElementById("stereoHelp").style.zIndex=999992,document.getElementById("stereoAbout").style.zIndex=999992,document.getElementById("stereoCanvas").width=document.documentElement.clientWidth,document.getElementById("stereoCanvas").height=document.documentElement.clientHeight,document.getElementById("stereoViewer").style.bottom=0,document.getElementById("stereoViewer").style.right=0,document.getElementById("stereoNav").checked=0!=stereoNav,stereoCheckCookie();var n=stereoGetCookie();n>=0&&n<=stereoModes&&(stereoMode=n,stereoSwap=stereoGetCookieSwap()>0,stereoGlasses=stereoGetCookieGlasses());for(var d=0;d<=stereoModes;d++)document.getElementById("modeselect").options[d].selected=stereoMode==d;for(d=0;d=2*o.width/3&&(stereoNextImage(),a=!0),a||stereoViewerOptionsOpen(!stereoOptVis)}function stereoViewerOptionsOpen(e){if(null!=document.getElementById("stereoControls")){if(e)var t="visible";else t="hidden";document.getElementById("stereoControls").style.visibility=t,e||(document.getElementById("stereoHelp").style.visibility=t,document.getElementById("stereoAbout").style.visibility=t),stereoOptVis=e}}function stereoHelpOpen(e){if("hidden"==document.getElementById("stereoHelp").style.visibility)var t="visible";else t="hidden";document.getElementById("stereoHelp").style.visibility=t,document.getElementById("stereoAbout").style.visibility="hidden"}function stereoAboutOpen(e){if("hidden"==document.getElementById("stereoAbout").style.visibility)var t="visible";else t="hidden";document.getElementById("stereoAbout").style.visibility=t,document.getElementById("stereoHelp").style.visibility="hidden"}function stereoDrawControls(e){var t=0,a=0;if(!e)e=window.event;function o(e,t,a,o){r.fillStyle=e,r.fillRect(0,0,stereoNav,i.height),r.fillStyle=a,r.beginPath(),r.moveTo(stereoNav/3,i.height/2),r.lineTo(2*stereoNav/3,i.height/2+stereoNav/3),r.lineTo(2*stereoNav/3,i.height/2-stereoNav/3),r.lineTo(stereoNav/3,i.height/2),r.fill(),r.fillStyle=t,r.fillRect(i.width-stereoNav,0,i.width,i.height),r.fillStyle=o,r.beginPath(),r.moveTo(i.width-stereoNav/3,i.height/2),r.lineTo(i.width-2*stereoNav/3,i.height/2+stereoNav/3),r.lineTo(i.width-2*stereoNav/3,i.height/2-stereoNav/3),r.lineTo(i.width-stereoNav/3,i.height/2),r.fill()}if(e.pageX||e.pageY?(t=e.pageX,a=e.pageY):(e.clientX||e.clientY)&&(t=e.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,a=e.clientY+document.body.scrollTop+document.documentElement.scrollTop),stereoNav>0){var i=document.getElementById("stereoCanvas"),r=i.getContext("2d");switch(stereoBGcolor){case 0:var s="rgba(60, 60, 60, 1.0)",n="rgba(30, 30, 30, 1.0)",d="rgba(30, 30, 30, 1.0)",l="rgba(0, 0, 0, 1.0)";break;case 1:s="rgba(190, 190, 190, 1.0)",n="rgba(160, 160, 160, 1.0)",d="rgba(160, 160, 160, 1.0)",l="rgba(130, 130, 130, 1.0)";break;case 2:s="rgba(240, 240, 240, 1.0)",n="rgba(220, 220, 220, 1.0)",d="rgba(255, 255, 255, 1.0)",l="rgba(240, 240, 240, 1.0)"}t>=0&&t=0&&a=i.width-stereoNav&&t=0&&a=img.width/img.height/2?t=(a=n-e)*(img.width/img.height)/2:a=(t=d-2*stereoNav)*(img.height/img.width)*2,t=Math.round(t),a=Math.round(a)}var s=document.getElementById("stereoCanvas").getContext("2d"),n=document.getElementById("stereoViewer").clientHeight,d=document.getElementById("stereoViewer").clientWidth,l=document.getElementById("stereoCanvasdiv");switch(l.height=n,l.width=d,(l=document.getElementById("stereoCanvas")).height=n,l.width=d,img=new Image,img.src=images[imageN],stereoBGcolor){case 0:s.fillStyle="rgba(0, 0, 0, 1)";break;case 1:s.fillStyle="rgba(128, 128, 128, 1)";break;case 2:s.fillStyle="rgba(255, 255, 255, 1)"}if(s.fillRect(stereoNav,0,d-2*stereoNav,n),document.getElementById("stereoViewer").style.backgroundColor=s.fillStyle,images.length>0){var m,c,g,p,h,u,b,f=new Number,v=new Number,w=new Number,I=0,k=0,C=0,D=0,M=0,S=0;function E(r){(m=document.createElement("canvas")).width=2*t,m.height=a,(c=m.getContext("2d")).drawImage(img,0,0,2*t,a),imageData=r?10==o?s.createImageData(t,2*a):s.createImageData(2*t,a):s.createImageData(t,a),"stereoLR"==imagesT[imageN]&&(i=!i);var l=i;if(r)switch(o){case 10:(n-e-2*a)/2%2==0&&(l=!l);break;case 11:(d-2*t)/2%2==0&&(l=!l)}l?(p=c.getImageData(0,0,t,a),g=c.getImageData(t,0,t,a)):(g=c.getImageData(0,0,t,a),p=c.getImageData(t,0,t,a))}function B(e,t){var a=[];if(null!=e)for(var o=e.split(" "),i="",r=t,n=0;n=img.width/img.height?t=(a=n-e)*(img.width/img.height):a=(t=d-2*stereoNav)*(img.height/img.width),t=Math.round(t),a=Math.round(a),"stereoLR"==imagesT[imageN]&&(i=!i),i?(s.drawImage(img,0,0,img.width/2,img.height,(d-t)/2+t/2,(n-e-a)/2,t/2,a),s.drawImage(img,img.width/2,0,img.width/2,img.height,(d-t)/2,(n-e-a)/2,t/2,a)):s.drawImage(img,(d-t)/2,(n-e-a)/2,t,a),"flat"==imagesT[imageN]|"anaglyph"==imagesT[imageN]?T(1):T(2);break;case 3:r(),"stereoLR"==imagesT[imageN]&&(i=!i),i?s.drawImage(img,img.width/2,0,img.width/2,img.height,(d-t)/2,(n-e-a)/2,t,t*(img.height/img.width*2)):s.drawImage(img,0,0,img.width/2,img.height,(d-t)/2,(n-e-a)/2,t,t*(img.height/img.width*2)),T(1);break;case 2:r(),"stereoLR"==imagesT[imageN]&&(i=!i),i?s.drawImage(img,0,0,img.width/2,img.height,(d-t)/2,(n-e-a)/2,t,t*(img.height/img.width*2)):s.drawImage(img,img.width/2,0,img.width/2,img.height,(d-t)/2,(n-e-a)/2,t,t*(img.height/img.width*2)),T(1);break;case 4:for(r(),E(!1),h=p,u=g,b=g,stereoGlasses==sGlassesGreenMagenta&&(h=g,u=p,b=g),y=t*a,x=0;x++=img.width/img.height/2?(a=(n-e)/2,t=(n-e)*(img.width/img.height)/2):a=(t=d-2*stereoNav)*(img.height/img.width),t=Math.round(t),a=Math.round(a),E(!0),M=S=4*t,y=0;y++=img.width/img.height/2?t=(a=n-e)*(img.width/img.height)/2:a=(t=d-2*stereoNav)*(img.height/img.width)*2,t=Math.round(t/2),a=Math.round(a),E(!0),y=t*a,x=0;x++0?imageN--:imageN=images.length-1,imageN<0&&(imageN=0),stereoDrawImage()}function stereoNextImage(){imageN=0&&e<=stereoModes?"Forget Defaults":"Save as Default",document.getElementById("stereoSwap").checked=stereoGetCookieSwap()>0}function stereoSetCookie(e,t,a){document.cookie="HTML5_STEREO_VIEWER="+escape(e.toString())+"; path=/",document.cookie="HTML5_STEREO_VIEWER_SWAP="+escape(t.toString())+"; path=/",document.cookie="HTML5_STEREO_VIEWER_GLASSES="+escape(a.toString())+"; path=/"}function stereoSetCookieForFirstTimeHelpDisplayed(){document.cookie="HTML5_STEREO_VIEWER_FIRST_TIME_HELP_DISPLAYED=YES; path=/"}function stereoGetCookieForFirstTimeHelpDisplayed(){stereoFirstTimeHelpDisplayed=!0;for(var e=document.cookie.split(";"),t=0;t=4?"inherit":"hidden"} \ No newline at end of file