diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:34:42 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:34:42 +0000 |
commit | da4c7e7ed675c3bf405668739c3012d140856109 (patch) | |
tree | cdd868dba063fecba609a1d819de271f0d51b23e /tools | |
parent | Adding upstream version 125.0.3. (diff) | |
download | firefox-da4c7e7ed675c3bf405668739c3012d140856109.tar.xz firefox-da4c7e7ed675c3bf405668739c3012d140856109.zip |
Adding upstream version 126.0.upstream/126.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tools')
76 files changed, 1888 insertions, 3396 deletions
diff --git a/tools/@types/index.d.ts b/tools/@types/index.d.ts new file mode 100644 index 0000000000..eb81de37f2 --- /dev/null +++ b/tools/@types/index.d.ts @@ -0,0 +1,9 @@ +/**
+ * NOTE: Do not modify this file by hand.
+ * Run `mach ts update` to reference typelibs generated in <objdir>.
+ */
+
+/// <reference types="./lib.gecko.dom.d.ts" />
+/// <reference types="./lib.gecko.nsresult.d.ts" />
+/// <reference types="./lib.gecko.services.d.ts" />
+/// <reference types="./lib.gecko.xpcom.d.ts" />
diff --git a/tools/@types/lib.gecko.dom.d.ts b/tools/@types/lib.gecko.dom.d.ts index 2f6028d43b..656ffabf90 100644 --- a/tools/@types/lib.gecko.dom.d.ts +++ b/tools/@types/lib.gecko.dom.d.ts @@ -1,6 +1,10 @@ -///////////////////////////// -/// Window APIs -///////////////////////////// +/** + * NOTE: This file is a work in progress. + * Content was generated using a heavily patched TypeScript-DOM-lib-generator. + * + * Until this whole process is automated, when changing a WebIDL interface, + * manually updating this file is *not* required (but doesn't hurt either). + */ /// <reference no-default-lib="true" /> /// <reference types="gecko" /> diff --git a/tools/browsertime/mach_commands.py b/tools/browsertime/mach_commands.py index 8386dd2c54..f0e90445e9 100644 --- a/tools/browsertime/mach_commands.py +++ b/tools/browsertime/mach_commands.py @@ -152,7 +152,7 @@ def browsertime_path(): def visualmetrics_path(): """The path to the `visualmetrics.py` script.""" - return mozpath.join(package_path(), "browsertime", "visualmetrics-portable.py") + return mozpath.join(package_path(), "visualmetrics", "visualmetrics-portable.py") def host_platform(): diff --git a/tools/browsertime/package-lock.json b/tools/browsertime/package-lock.json index b50278c6dc..8c31d08b23 100644 --- a/tools/browsertime/package-lock.json +++ b/tools/browsertime/package-lock.json @@ -1,6 +1,6 @@ { "name": "mozilla-central-tools-browsertime", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -10,7 +10,7 @@ "package.json": "^2.0.1" }, "devDependencies": { - "browsertime": "https://github.com/sitespeedio/browsertime/tarball/62de4fc9abc8067fb58378999b1bc4a4c42f9eb5" + "browsertime": "https://github.com/sitespeedio/browsertime/tarball/de9cbe379e64562cb5ccdcb4e4c5a9b6390547b6" } }, "node_modules/@cypress/xvfb": { @@ -24,9 +24,9 @@ } }, "node_modules/@devicefarmer/adbkit": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit/-/adbkit-3.2.5.tgz", - "integrity": "sha512-+J479WWZW3GU3t40flicDfiDrFz6vpiy2RcBQPEhFcs/3La9pOtr4Bgz2Q02E4luUG2RAL068rqIkKNUTy3tZw==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit/-/adbkit-3.2.6.tgz", + "integrity": "sha512-8lO1hSeTgtxcOHhp4tTWq/JaOysp5KNbbyFoxNEBnwkCDZu/Bji3ZfOaG++Riv9jN6c9bgdLBOZqJTC5VJPRKQ==", "dev": true, "dependencies": { "@devicefarmer/adbkit-logcat": "^2.1.2", @@ -86,13 +86,13 @@ "dev": true }, "node_modules/@jimp/bmp": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.22.10.tgz", - "integrity": "sha512-1UXRl1Nw1KptZ1r0ANqtXOst9vGH51dq7keVKQzyyTO2lz4dOaezS9StuSTNh+RmiHg/SVPaFRpPfB0S/ln4Kg==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.22.12.tgz", + "integrity": "sha512-aeI64HD0npropd+AR76MCcvvRaa+Qck6loCOS03CkkxGHN5/r336qTM5HPUdHKMDOGzqknuVPA8+kK1t03z12g==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10", + "@jimp/utils": "^0.22.12", "bmp-js": "^0.1.0" }, "peerDependencies": { @@ -100,13 +100,13 @@ } }, "node_modules/@jimp/core": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.22.10.tgz", - "integrity": "sha512-ZKyrehVy6wu1PnBXIUpn/fXmyMRQiVSbvHDubgXz4bfTOao3GiOurKHjByutQIgozuAN6ZHWiSge1dKA+dex3w==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.22.12.tgz", + "integrity": "sha512-l0RR0dOPyzMKfjUW1uebzueFEDtCOj9fN6pyTYWWOM/VS4BciXQ1VVrJs8pO3kycGYZxncRKhCoygbNr8eEZQA==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10", + "@jimp/utils": "^0.22.12", "any-base": "^1.1.0", "buffer": "^5.2.0", "exif-parser": "^0.1.12", @@ -117,23 +117,23 @@ } }, "node_modules/@jimp/custom": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.22.10.tgz", - "integrity": "sha512-sPZkUYe1hu0iIgNisjizxPJqq2vaaKvkCkPoXq2U6UV3ZA1si/WVdrg25da3IcGIEV+83AoHgM8TvqlLgrCJsg==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.22.12.tgz", + "integrity": "sha512-xcmww1O/JFP2MrlGUMd3Q78S3Qu6W3mYTXYuIqFq33EorgYHV/HqymHfXy9GjiCJ7OI+7lWx6nYFOzU7M4rd1Q==", "dev": true, "optional": true, "dependencies": { - "@jimp/core": "^0.22.10" + "@jimp/core": "^0.22.12" } }, "node_modules/@jimp/gif": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.22.10.tgz", - "integrity": "sha512-yEX2dSpamvkSx1PPDWGnKeWDrBz0vrCKjVG/cn4Zr68MRRT75tbZIeOrBa+RiUpY3ho5ix7d36LkYvt3qfUIhQ==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.22.12.tgz", + "integrity": "sha512-y6BFTJgch9mbor2H234VSjd9iwAhaNf/t3US5qpYIs0TSbAvM02Fbc28IaDETj9+4YB4676sz4RcN/zwhfu1pg==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10", + "@jimp/utils": "^0.22.12", "gifwrap": "^0.10.1", "omggif": "^1.0.9" }, @@ -142,13 +142,13 @@ } }, "node_modules/@jimp/jpeg": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.22.10.tgz", - "integrity": "sha512-6bu98pAcVN4DY2oiDLC4TOgieX/lZrLd1tombWZOFCN5PBmqaHQxm7IUmT+Wj4faEvh8QSHgVLSA+2JQQRJWVA==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.22.12.tgz", + "integrity": "sha512-Rq26XC/uQWaQKyb/5lksCTCxXhtY01NJeBN+dQv5yNYedN0i7iYu+fXEoRsfaJ8xZzjoANH8sns7rVP4GE7d/Q==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10", + "@jimp/utils": "^0.22.12", "jpeg-js": "^0.4.4" }, "peerDependencies": { @@ -156,52 +156,52 @@ } }, "node_modules/@jimp/plugin-blit": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.22.10.tgz", - "integrity": "sha512-6EI8Sl+mxYHEIy6Yteh6eknD+EZguKpNdr3sCKxNezmLR0+vK99vHcllo6uGSjXXiwtwS67Xqxn8SsoatL+UJQ==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.22.12.tgz", + "integrity": "sha512-xslz2ZoFZOPLY8EZ4dC29m168BtDx95D6K80TzgUi8gqT7LY6CsajWO0FAxDwHz6h0eomHMfyGX0stspBrTKnQ==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "node_modules/@jimp/plugin-blur": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.22.10.tgz", - "integrity": "sha512-4XRTWuPVdMXJeclJMisXPGizeHtTryVaVV5HnuQXpKqIZtzXReCCpNGH8q/i0kBQOQMXhGWS3mpqOEwtpPePKw==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.22.12.tgz", + "integrity": "sha512-S0vJADTuh1Q9F+cXAwFPlrKWzDj2F9t/9JAbUvaaDuivpyWuImEKXVz5PUZw2NbpuSHjwssbTpOZ8F13iJX4uw==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "node_modules/@jimp/plugin-circle": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.22.10.tgz", - "integrity": "sha512-mhcwTO1ywRxiCgtLGge6tDDIDPlX6qkI3CY+BjgGG/XhVHccCddXgOGLdlf+5OuKIEF2Nqs0V01LQEQIJFTmEw==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.22.12.tgz", + "integrity": "sha512-SWVXx1yiuj5jZtMijqUfvVOJBwOifFn0918ou4ftoHgegc5aHWW5dZbYPjvC9fLpvz7oSlptNl2Sxr1zwofjTg==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "node_modules/@jimp/plugin-color": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.22.10.tgz", - "integrity": "sha512-e4t3L7Kedd96E0x1XjsTM6NcgulKUU66HdFTao7Tc9FYJRFSlttARZ/C6LEryGDm/i69R6bJEpo7BkNz0YL55Q==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.22.12.tgz", + "integrity": "sha512-xImhTE5BpS8xa+mAN6j4sMRWaUgUDLoaGHhJhpC+r7SKKErYDR0WQV4yCE4gP+N0gozD0F3Ka1LUSaMXrn7ZIA==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10", + "@jimp/utils": "^0.22.12", "tinycolor2": "^1.6.0" }, "peerDependencies": { @@ -209,13 +209,13 @@ } }, "node_modules/@jimp/plugin-contain": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.22.10.tgz", - "integrity": "sha512-eP8KrzctuEoqibQAxi9WhbnoRosydhiwg+IYya3dKuKDBTrD9UHt+ERlPQ/lTNWHzV/l4S1ntV3r9s9saJgsXA==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.22.12.tgz", + "integrity": "sha512-Eo3DmfixJw3N79lWk8q/0SDYbqmKt1xSTJ69yy8XLYQj9svoBbyRpSnHR+n9hOw5pKXytHwUW6nU4u1wegHNoQ==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5", @@ -225,13 +225,13 @@ } }, "node_modules/@jimp/plugin-cover": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.22.10.tgz", - "integrity": "sha512-kJCwL5T1igfa0InCfkE7bBeqg26m46aoRt10ug+rvm11P6RrvRMGrgINFyIKB+mnB7CiyBN/MOula1CvLhSInQ==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.22.12.tgz", + "integrity": "sha512-z0w/1xH/v/knZkpTNx+E8a7fnasQ2wHG5ze6y5oL2dhH1UufNua8gLQXlv8/W56+4nJ1brhSd233HBJCo01BXA==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5", @@ -241,65 +241,65 @@ } }, "node_modules/@jimp/plugin-crop": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.22.10.tgz", - "integrity": "sha512-BOZ+YGaZlhU7c5ye65RxikicXH0Ki0It6/XHISvipR5WZrfjLjL2Ke20G+AGnwBQc76gKenVcMXVUCnEjtZV+Q==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.22.12.tgz", + "integrity": "sha512-FNuUN0OVzRCozx8XSgP9MyLGMxNHHJMFt+LJuFjn1mu3k0VQxrzqbN06yIl46TVejhyAhcq5gLzqmSCHvlcBVw==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "node_modules/@jimp/plugin-displace": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.22.10.tgz", - "integrity": "sha512-llNiWWMTKISDXt5+cXI0GaFmZWAjlT+4fFLYf4eXquuL/9wZoQsEBhv2GdGd48mkiS8jZq1Nnb2Q4ehEPTvrzw==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.22.12.tgz", + "integrity": "sha512-qpRM8JRicxfK6aPPqKZA6+GzBwUIitiHaZw0QrJ64Ygd3+AsTc7BXr+37k2x7QcyCvmKXY4haUrSIsBug4S3CA==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "node_modules/@jimp/plugin-dither": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.22.10.tgz", - "integrity": "sha512-05WLmeV5M+P/0FS+bWf13hMew2X0oa8w9AtmevL2UyA/5GqiyvP2Xm5WfGQ8oFiiMvpnL6RFomJQOZtWca0C2w==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.22.12.tgz", + "integrity": "sha512-jYgGdSdSKl1UUEanX8A85v4+QUm+PE8vHFwlamaKk89s+PXQe7eVE3eNeSZX4inCq63EHL7cX580dMqkoC3ZLw==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "node_modules/@jimp/plugin-fisheye": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.22.10.tgz", - "integrity": "sha512-InjiXvc7Gkzrx8VWtU97kDqV7ENnhHGPULymJWeZaF2aicud9Fpk4iCtd/DcZIrk7Cbe60A8RwNXN00HXIbSCg==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.22.12.tgz", + "integrity": "sha512-LGuUTsFg+fOp6KBKrmLkX4LfyCy8IIsROwoUvsUPKzutSqMJnsm3JGDW2eOmWIS/jJpPaeaishjlxvczjgII+Q==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "node_modules/@jimp/plugin-flip": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.22.10.tgz", - "integrity": "sha512-42GkGtTHWnhnwTMPVK/kXObZbkYIpQWfuIfy5EMEMk6zRj05zpv4vsjkKWfuemweZINwfvD7wDJF7FVFNNcZZg==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.22.12.tgz", + "integrity": "sha512-m251Rop7GN8W0Yo/rF9LWk6kNclngyjIJs/VXHToGQ6EGveOSTSQaX2Isi9f9lCDLxt+inBIb7nlaLLxnvHX8Q==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5", @@ -307,65 +307,65 @@ } }, "node_modules/@jimp/plugin-gaussian": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.22.10.tgz", - "integrity": "sha512-ykrG/6lTp9Q5YA8jS5XzwMHtRxb9HOFMgtmnrUZ8kU+BK8REecfy9Ic5BUEOjCYvS1a/xLsnrZQU07iiYxBxFg==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.22.12.tgz", + "integrity": "sha512-sBfbzoOmJ6FczfG2PquiK84NtVGeScw97JsCC3rpQv1PHVWyW+uqWFF53+n3c8Y0P2HWlUjflEla2h/vWShvhg==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "node_modules/@jimp/plugin-invert": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.22.10.tgz", - "integrity": "sha512-d8j9BlUJYs/c994t4azUWSWmQq4LLPG4ecm8m6SSNqap+S/HlVQGqjYhJEBbY9EXkOTYB9vBL9bqwSM1Rr6paA==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.22.12.tgz", + "integrity": "sha512-N+6rwxdB+7OCR6PYijaA/iizXXodpxOGvT/smd/lxeXsZ/empHmFFFJ/FaXcYh19Tm04dGDaXcNF/dN5nm6+xQ==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "node_modules/@jimp/plugin-mask": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.22.10.tgz", - "integrity": "sha512-yRBs1230XZkz24uFTdTcSlZ0HXZpIWzM3iFQN56MzZ7USgdVZjPPDCQ8I9RpqfZ36nDflQkUO0wV7ucsi4ogow==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.22.12.tgz", + "integrity": "sha512-4AWZg+DomtpUA099jRV8IEZUfn1wLv6+nem4NRJC7L/82vxzLCgXKTxvNvBcNmJjT9yS1LAAmiJGdWKXG63/NA==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "node_modules/@jimp/plugin-normalize": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.22.10.tgz", - "integrity": "sha512-Wk9GX6eJMchX/ZAazVa70Fagu+OXMvHiPY+HrcEwcclL+p1wo8xAHEsf9iKno7Ja4EU9lLhbBRY5hYJyiKMEkg==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.22.12.tgz", + "integrity": "sha512-0So0rexQivnWgnhacX4cfkM2223YdExnJTTy6d06WbkfZk5alHUx8MM3yEzwoCN0ErO7oyqEWRnEkGC+As1FtA==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "node_modules/@jimp/plugin-print": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.22.10.tgz", - "integrity": "sha512-1U3VloIR+beE1kWPdGEJMiE2h1Do29iv3w8sBbvPyRP4qXxRFcDpmCGtctsrKmb1krlBFlj8ubyAY90xL+5n9w==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.22.12.tgz", + "integrity": "sha512-c7TnhHlxm87DJeSnwr/XOLjJU/whoiKYY7r21SbuJ5nuH+7a78EW1teOaj5gEr2wYEd7QtkFqGlmyGXY/YclyQ==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10", + "@jimp/utils": "^0.22.12", "load-bmfont": "^1.4.1" }, "peerDependencies": { @@ -374,26 +374,26 @@ } }, "node_modules/@jimp/plugin-resize": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.22.10.tgz", - "integrity": "sha512-ixomxVcnAONXDgaq0opvAx4UAOiEhOA/tipuhFFOvPKFd4yf1BAnEviB5maB0SBHHkJXPUSzDp/73xVTMGSe7g==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.22.12.tgz", + "integrity": "sha512-3NyTPlPbTnGKDIbaBgQ3HbE6wXbAlFfxHVERmrbqAi8R3r6fQPxpCauA8UVDnieg5eo04D0T8nnnNIX//i/sXg==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5" } }, "node_modules/@jimp/plugin-rotate": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.22.10.tgz", - "integrity": "sha512-eeFX8dnRyf3LAdsdXWKWuN18hLRg8zy1cP0cP9rHzQVWRK7ck/QsLxK1vHq7MADGwQalNaNTJ9SQxH6c8mz6jw==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.22.12.tgz", + "integrity": "sha512-9YNEt7BPAFfTls2FGfKBVgwwLUuKqy+E8bDGGEsOqHtbuhbshVGxN2WMZaD4gh5IDWvR+emmmPPWGgaYNYt1gA==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5", @@ -403,13 +403,13 @@ } }, "node_modules/@jimp/plugin-scale": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.22.10.tgz", - "integrity": "sha512-TG/H0oUN69C9ArBCZg4PmuoixFVKIiru8282KzSB/Tp1I0xwX0XLTv3dJ5pobPlIgPcB+TmD4xAIdkCT4rtWxg==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.22.12.tgz", + "integrity": "sha512-dghs92qM6MhHj0HrV2qAwKPMklQtjNpoYgAB94ysYpsXslhRTiPisueSIELRwZGEr0J0VUxpUY7HgJwlSIgGZw==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5", @@ -417,13 +417,13 @@ } }, "node_modules/@jimp/plugin-shadow": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.22.10.tgz", - "integrity": "sha512-TN9xm6fI7XfxbMUQqFPZjv59Xdpf0tSiAQdINB4g6pJMWiVANR/74OtDONoy3KKpenu5Y38s+FkrtID/KcQAhw==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.22.12.tgz", + "integrity": "sha512-FX8mTJuCt7/3zXVoeD/qHlm4YH2bVqBuWQHXSuBK054e7wFRnRnbSLPUqAwSeYP3lWqpuQzJtgiiBxV3+WWwTg==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5", @@ -432,13 +432,13 @@ } }, "node_modules/@jimp/plugin-threshold": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.22.10.tgz", - "integrity": "sha512-DA2lSnU0TgIRbAgmXaxroYw3Ad6J2DOFEoJp0NleSm2h3GWbZEE5yW9U2B6hD3iqn4AenG4E2b2WzHXZyzSutw==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.22.12.tgz", + "integrity": "sha512-4x5GrQr1a/9L0paBC/MZZJjjgjxLYrqSmWd+e+QfAEPvmRxdRoQ5uKEuNgXnm9/weHQBTnQBQsOY2iFja+XGAw==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10" + "@jimp/utils": "^0.22.12" }, "peerDependencies": { "@jimp/custom": ">=0.3.5", @@ -447,33 +447,33 @@ } }, "node_modules/@jimp/plugins": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.22.10.tgz", - "integrity": "sha512-KDMZyM6pmvS8freB+UBLko1TO/k4D7URS/nphCozuH+P7i3UMe7NdckXKJ8u+WD6sqN0YFYvBehpkpnUiw/91w==", - "dev": true, - "optional": true, - "dependencies": { - "@jimp/plugin-blit": "^0.22.10", - "@jimp/plugin-blur": "^0.22.10", - "@jimp/plugin-circle": "^0.22.10", - "@jimp/plugin-color": "^0.22.10", - "@jimp/plugin-contain": "^0.22.10", - "@jimp/plugin-cover": "^0.22.10", - "@jimp/plugin-crop": "^0.22.10", - "@jimp/plugin-displace": "^0.22.10", - "@jimp/plugin-dither": "^0.22.10", - "@jimp/plugin-fisheye": "^0.22.10", - "@jimp/plugin-flip": "^0.22.10", - "@jimp/plugin-gaussian": "^0.22.10", - "@jimp/plugin-invert": "^0.22.10", - "@jimp/plugin-mask": "^0.22.10", - "@jimp/plugin-normalize": "^0.22.10", - "@jimp/plugin-print": "^0.22.10", - "@jimp/plugin-resize": "^0.22.10", - "@jimp/plugin-rotate": "^0.22.10", - "@jimp/plugin-scale": "^0.22.10", - "@jimp/plugin-shadow": "^0.22.10", - "@jimp/plugin-threshold": "^0.22.10", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.22.12.tgz", + "integrity": "sha512-yBJ8vQrDkBbTgQZLty9k4+KtUQdRjsIDJSPjuI21YdVeqZxYywifHl4/XWILoTZsjTUASQcGoH0TuC0N7xm3ww==", + "dev": true, + "optional": true, + "dependencies": { + "@jimp/plugin-blit": "^0.22.12", + "@jimp/plugin-blur": "^0.22.12", + "@jimp/plugin-circle": "^0.22.12", + "@jimp/plugin-color": "^0.22.12", + "@jimp/plugin-contain": "^0.22.12", + "@jimp/plugin-cover": "^0.22.12", + "@jimp/plugin-crop": "^0.22.12", + "@jimp/plugin-displace": "^0.22.12", + "@jimp/plugin-dither": "^0.22.12", + "@jimp/plugin-fisheye": "^0.22.12", + "@jimp/plugin-flip": "^0.22.12", + "@jimp/plugin-gaussian": "^0.22.12", + "@jimp/plugin-invert": "^0.22.12", + "@jimp/plugin-mask": "^0.22.12", + "@jimp/plugin-normalize": "^0.22.12", + "@jimp/plugin-print": "^0.22.12", + "@jimp/plugin-resize": "^0.22.12", + "@jimp/plugin-rotate": "^0.22.12", + "@jimp/plugin-scale": "^0.22.12", + "@jimp/plugin-shadow": "^0.22.12", + "@jimp/plugin-threshold": "^0.22.12", "timm": "^1.6.1" }, "peerDependencies": { @@ -481,13 +481,13 @@ } }, "node_modules/@jimp/png": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.22.10.tgz", - "integrity": "sha512-RYinU7tZToeeR2g2qAMn42AU+8OUHjXPKZZ9RkmoL4bguA1xyZWaSdr22/FBkmnHhOERRlr02KPDN1OTOYHLDQ==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.22.12.tgz", + "integrity": "sha512-Mrp6dr3UTn+aLK8ty/dSKELz+Otdz1v4aAXzV5q53UDD2rbB5joKVJ/ChY310B+eRzNxIovbUF1KVrUsYdE8Hg==", "dev": true, "optional": true, "dependencies": { - "@jimp/utils": "^0.22.10", + "@jimp/utils": "^0.22.12", "pngjs": "^6.0.0" }, "peerDependencies": { @@ -495,9 +495,9 @@ } }, "node_modules/@jimp/tiff": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.22.10.tgz", - "integrity": "sha512-OaivlSYzpNTHyH/h7pEtl3A7F7TbsgytZs52GLX/xITW92ffgDgT6PkldIrMrET6ERh/hdijNQiew7IoEEr2og==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.22.12.tgz", + "integrity": "sha512-E1LtMh4RyJsoCAfAkBRVSYyZDTtLq9p9LUiiYP0vPtXyxX4BiYBUYihTLSBlCQg5nF2e4OpQg7SPrLdJ66u7jg==", "dev": true, "optional": true, "dependencies": { @@ -508,17 +508,17 @@ } }, "node_modules/@jimp/types": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.22.10.tgz", - "integrity": "sha512-u/r+XYzbCx4zZukDmxx8S0er3Yq3iDPI6+31WKX0N18i2qPPJYcn8qwIFurfupRumGvJ8SlGLCgt/T+Y8zzUIw==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.22.12.tgz", + "integrity": "sha512-wwKYzRdElE1MBXFREvCto5s699izFHNVvALUv79GXNbsOVqlwlOxlWJ8DuyOGIXoLP4JW/m30YyuTtfUJgMRMA==", "dev": true, "optional": true, "dependencies": { - "@jimp/bmp": "^0.22.10", - "@jimp/gif": "^0.22.10", - "@jimp/jpeg": "^0.22.10", - "@jimp/png": "^0.22.10", - "@jimp/tiff": "^0.22.10", + "@jimp/bmp": "^0.22.12", + "@jimp/gif": "^0.22.12", + "@jimp/jpeg": "^0.22.12", + "@jimp/png": "^0.22.12", + "@jimp/tiff": "^0.22.12", "timm": "^1.6.1" }, "peerDependencies": { @@ -526,9 +526,9 @@ } }, "node_modules/@jimp/utils": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.22.10.tgz", - "integrity": "sha512-ztlOK9Mm2iLG2AMoabzM4i3WZ/FtshcgsJCbZCRUs/DKoeS2tySRJTnQZ1b7Roq0M4Ce+FUAxnCAcBV0q7PH9w==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.22.12.tgz", + "integrity": "sha512-yJ5cWUknGnilBq97ZXOyOS0HhsHOyAyjHwYfHxGbSyMTohgQI6sVyE8KPgDwH8HHW/nMKXk8TrSwAE71zt716Q==", "dev": true, "optional": true, "dependencies": { @@ -536,9 +536,9 @@ } }, "node_modules/@sitespeed.io/chromedriver": { - "version": "119.0.6045-105", - "resolved": "https://registry.npmjs.org/@sitespeed.io/chromedriver/-/chromedriver-119.0.6045-105.tgz", - "integrity": "sha512-DfQQaqTB28e05kG3CWjC9OWKeNTWiqgu5cl6CvYQsd2MTDDDRUQ0a+VZ8KTSrRx6xZCsTBgzZK2kNBNiMvNH8w==", + "version": "123.0.6312-58", + "resolved": "https://registry.npmjs.org/@sitespeed.io/chromedriver/-/chromedriver-123.0.6312-58.tgz", + "integrity": "sha512-1v24uZmt9bAc80td0YfPA0M6uA9zYpFrBBM12Wkir7GqtpX7DCsNMuqGqVzBfsYp8UiU+wG/FtIb6+3PMr4P6Q==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -547,9 +547,9 @@ } }, "node_modules/@sitespeed.io/edgedriver": { - "version": "119.0.2151-42", - "resolved": "https://registry.npmjs.org/@sitespeed.io/edgedriver/-/edgedriver-119.0.2151-42.tgz", - "integrity": "sha512-+jGP9BmWgh/yoNcJKyiYP0anF0m2H6+cjk1MaHvzgkIdrFMVfJQIN9+tmwCBiN4Ave52IHjDdHhEjK7B+SWvrA==", + "version": "122.0.2365-92", + "resolved": "https://registry.npmjs.org/@sitespeed.io/edgedriver/-/edgedriver-122.0.2365-92.tgz", + "integrity": "sha512-7A31VWQl9XjHEmmZur4nSlr+8xIweWNpuEyc151FS9ScQskRjJMS0iMJgSvLcIVwacm56ni2W6+IqdPLisRrwA==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -570,9 +570,9 @@ } }, "node_modules/@sitespeed.io/geckodriver": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/@sitespeed.io/geckodriver/-/geckodriver-0.33.0.tgz", - "integrity": "sha512-w6w+x9/Q44JekTPi8NlRsfh5Uz4TfquJcUEs0tA/oEcxLVxRS7VtaiaJEE0GzzN6cUmFS6Twas7E4bCA4k/Yxg==", + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/@sitespeed.io/geckodriver/-/geckodriver-0.34.0.tgz", + "integrity": "sha512-/AT910tNizgPVey9sSeYpJWt85GwkllGwGGCbnaB6VId/BJNeHfjst1mIIUr628UfUVQDOPJ1z6x0lcCjh6unw==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -696,12 +696,6 @@ "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", "dev": true }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -736,28 +730,18 @@ "dev": true, "optional": true }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/browsertime": { - "version": "18.0.0", - "resolved": "https://github.com/sitespeedio/browsertime/tarball/62de4fc9abc8067fb58378999b1bc4a4c42f9eb5", - "integrity": "sha512-dtX8pNd4HLQIBBphbTs4Ok0FTt/+zgikbjxI0B2YEjzOEtbSI//ofn4woOYdIC7JOiTtKhYB79eqXaIbVXORqw==", + "version": "21.6.1", + "resolved": "https://github.com/sitespeedio/browsertime/tarball/de9cbe379e64562cb5ccdcb4e4c5a9b6390547b6", + "integrity": "sha512-dk0EwuMFFgSv4Q/BsC6hUvX5j+8wxshFfm+ZfJQRWdp/weKLOkrB9ws1/l6QchlFXWWihRMgG1MEadJxZ4NdCA==", "dev": true, "license": "MIT", "dependencies": { "@cypress/xvfb": "1.2.4", - "@devicefarmer/adbkit": "3.2.5", - "@sitespeed.io/chromedriver": "119.0.6045-105", - "@sitespeed.io/edgedriver": "119.0.2151-42", - "@sitespeed.io/geckodriver": "0.33.0", + "@devicefarmer/adbkit": "3.2.6", + "@sitespeed.io/chromedriver": "123.0.6312-58", + "@sitespeed.io/edgedriver": "122.0.2365-92", + "@sitespeed.io/geckodriver": "0.34.0", "@sitespeed.io/throttle": "5.0.0", "@sitespeed.io/tracium": "0.3.3", "btoa": "1.2.1", @@ -767,7 +751,7 @@ "execa": "8.0.1", "fast-stats": "0.0.6", "ff-test-bidi-har-export": "0.0.12", - "find-up": "6.3.0", + "find-up": "7.0.0", "get-port": "7.0.0", "hasbin": "1.2.3", "intel": "1.2.0", @@ -777,17 +761,17 @@ "lodash.merge": "4.6.2", "lodash.pick": "4.4.0", "lodash.set": "4.3.2", - "selenium-webdriver": "4.15.0", + "selenium-webdriver": "4.18.1", "yargs": "17.7.2" }, "bin": { "browsertime": "bin/browsertime.js" }, "engines": { - "node": ">=14.19.1" + "node": ">=18.0.0" }, "optionalDependencies": { - "jimp": "0.22.10" + "jimp": "0.22.12" } }, "node_modules/btoa": { @@ -998,12 +982,6 @@ "node": "^12.20.0 || >=14" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -1109,9 +1087,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, "engines": { "node": ">=6" @@ -1199,16 +1177,17 @@ } }, "node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", + "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", "dev": true, "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -1238,12 +1217,6 @@ "node": ">=8" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -1345,26 +1318,6 @@ "git-up": "^1.0.0" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/global": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", @@ -1446,9 +1399,9 @@ } }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dependencies": { "function-bind": "^1.1.2" }, @@ -1507,16 +1460,6 @@ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", "dev": true }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -1648,15 +1591,15 @@ "integrity": "sha512-4dG1D1x/7g8PwHS9aK6QV5V94+ZvyP4+d19qDv43EzImmrndysIl4prmJ1hWWIGCqrZHyaHBm6BSEWHOLnpoNw==" }, "node_modules/jimp": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.22.10.tgz", - "integrity": "sha512-lCaHIJAgTOsplyJzC1w/laxSxrbSsEBw4byKwXgUdMmh+ayPsnidTblenQm+IvhIs44Gcuvlb6pd2LQ0wcKaKg==", + "version": "0.22.12", + "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.22.12.tgz", + "integrity": "sha512-R5jZaYDnfkxKJy1dwLpj/7cvyjxiclxU3F4TrI/J4j2rS0niq6YDUMoPn5hs8GDpO+OZGo7Ky057CRtWesyhfg==", "dev": true, "optional": true, "dependencies": { - "@jimp/custom": "^0.22.10", - "@jimp/plugins": "^0.22.10", - "@jimp/types": "^0.22.10", + "@jimp/custom": "^0.22.12", + "@jimp/plugins": "^0.22.12", + "@jimp/types": "^0.22.12", "regenerator-runtime": "^0.13.3" } }, @@ -1819,18 +1762,6 @@ "dom-walk": "^0.1.0" } }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/minimist": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", @@ -1968,9 +1899,9 @@ } }, "node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "dependencies": { "path-key": "^4.0.0" @@ -2026,15 +1957,6 @@ "dev": true, "optional": true }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, "node_modules/one-by-one": { "version": "3.2.8", "resolved": "https://registry.npmjs.org/one-by-one/-/one-by-one-3.2.8.tgz", @@ -2151,14 +2073,14 @@ "optional": true }, "node_modules/parse-bmfont-xml": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz", - "integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.6.tgz", + "integrity": "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA==", "dev": true, "optional": true, "dependencies": { "xml-parse-from-string": "^1.0.0", - "xml2js": "^0.4.5" + "xml2js": "^0.5.0" } }, "node_modules/parse-headers": { @@ -2202,15 +2124,6 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -2243,6 +2156,7 @@ "version": "2.9.3", "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", "dev": true, "optional": true }, @@ -2348,9 +2262,12 @@ "dev": true }, "node_modules/r-json": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/r-json/-/r-json-1.2.10.tgz", - "integrity": "sha512-hu9vyLjSlHXT62NAS7DjI9WazDlvjN0lgp3n431dCVnirVcLkZIpzSwA3orhZEKzdDD2jqNYI+w0yG0aFf4kpA==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/r-json/-/r-json-1.3.0.tgz", + "integrity": "sha512-xesd+RHCpymPCYd9DvDvUr1w1IieSChkqYF1EpuAYrvCfLXji9NP36DvyYZJZZB5soVDvZ0WUtBoZaU1g5Yt9A==", + "dependencies": { + "w-json": "1.3.10" + } }, "node_modules/r-package-json": { "version": "1.0.9", @@ -2491,21 +2408,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -2519,9 +2421,9 @@ "optional": true }, "node_modules/selenium-webdriver": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.15.0.tgz", - "integrity": "sha512-BNG1bq+KWiBGHcJ/wULi0eKY0yaDqFIbEmtbsYJmfaEghdCkXBsx1akgOorhNwjBipOr0uwpvNXqT6/nzl+zjg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.18.1.tgz", + "integrity": "sha512-uP4OJ5wR4+VjdTi5oi/k8oieV2fIhVdVuaOPrklKghgS59w7Zz3nGa5gcG73VcU9EBRv5IZEBRhPr7qFJAj5mQ==", "dev": true, "dependencies": { "jszip": "^3.10.1", @@ -2533,21 +2435,18 @@ } }, "node_modules/selenium-webdriver/node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, "engines": { - "node": ">=8.17.0" + "node": ">=14.14" } }, "node_modules/selenium-webdriver/node_modules/ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", "dev": true, "engines": { "node": ">=10.0.0" @@ -2627,9 +2526,9 @@ } }, "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==" }, "node_modules/spdx-expression-parse": { "version": "3.0.1", @@ -2641,9 +2540,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", - "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==" + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz", + "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==" }, "node_modules/split": { "version": "1.0.1", @@ -2907,6 +2806,18 @@ "typpy": "^2.3.4" } }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", @@ -2984,6 +2895,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/w-json": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/w-json/-/w-json-1.3.10.tgz", + "integrity": "sha512-XadVyw0xE+oZ5FGApXsdswv96rOhStzKqL53uSe5UaTadABGkWIg1+DTx8kiZ/VqTZTBneoL0l65RcPe4W3ecw==" + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -2992,9 +2908,9 @@ "optional": true }, "node_modules/whatwg-fetch": { - "version": "3.6.19", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.19.tgz", - "integrity": "sha512-d67JP4dHSbm2TrpFj8AbO8DnL1JXL5J9u0Kq2xW6d0TFDbCA3Muhdt8orXC22utleTVj7Prqt82baN6RBvnEgw==", + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", "dev": true, "optional": true }, @@ -3077,12 +2993,6 @@ "node": ">=8" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, "node_modules/ws": { "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", @@ -3125,9 +3035,9 @@ "optional": true }, "node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", "dev": true, "optional": true, "dependencies": { @@ -3212,2512 +3122,5 @@ "url": "https://github.com/sponsors/sindresorhus" } } - }, - "dependencies": { - "@cypress/xvfb": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", - "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", - "dev": true, - "requires": { - "debug": "^3.1.0", - "lodash.once": "^4.1.1" - } - }, - "@devicefarmer/adbkit": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit/-/adbkit-3.2.5.tgz", - "integrity": "sha512-+J479WWZW3GU3t40flicDfiDrFz6vpiy2RcBQPEhFcs/3La9pOtr4Bgz2Q02E4luUG2RAL068rqIkKNUTy3tZw==", - "dev": true, - "requires": { - "@devicefarmer/adbkit-logcat": "^2.1.2", - "@devicefarmer/adbkit-monkey": "~1.2.1", - "bluebird": "~3.7", - "commander": "^9.1.0", - "debug": "~4.3.1", - "node-forge": "^1.3.1", - "split": "~1.0.1" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "@devicefarmer/adbkit-logcat": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit-logcat/-/adbkit-logcat-2.1.3.tgz", - "integrity": "sha512-yeaGFjNBc/6+svbDeul1tNHtNChw6h8pSHAt5D+JsedUrMTN7tla7B15WLDyekxsuS2XlZHRxpuC6m92wiwCNw==", - "dev": true - }, - "@devicefarmer/adbkit-monkey": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@devicefarmer/adbkit-monkey/-/adbkit-monkey-1.2.1.tgz", - "integrity": "sha512-ZzZY/b66W2Jd6NHbAhLyDWOEIBWC11VizGFk7Wx7M61JZRz7HR9Cq5P+65RKWUU7u6wgsE8Lmh9nE4Mz+U2eTg==", - "dev": true - }, - "@jimp/bmp": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.22.10.tgz", - "integrity": "sha512-1UXRl1Nw1KptZ1r0ANqtXOst9vGH51dq7keVKQzyyTO2lz4dOaezS9StuSTNh+RmiHg/SVPaFRpPfB0S/ln4Kg==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10", - "bmp-js": "^0.1.0" - } - }, - "@jimp/core": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.22.10.tgz", - "integrity": "sha512-ZKyrehVy6wu1PnBXIUpn/fXmyMRQiVSbvHDubgXz4bfTOao3GiOurKHjByutQIgozuAN6ZHWiSge1dKA+dex3w==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10", - "any-base": "^1.1.0", - "buffer": "^5.2.0", - "exif-parser": "^0.1.12", - "file-type": "^16.5.4", - "isomorphic-fetch": "^3.0.0", - "pixelmatch": "^4.0.2", - "tinycolor2": "^1.6.0" - } - }, - "@jimp/custom": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.22.10.tgz", - "integrity": "sha512-sPZkUYe1hu0iIgNisjizxPJqq2vaaKvkCkPoXq2U6UV3ZA1si/WVdrg25da3IcGIEV+83AoHgM8TvqlLgrCJsg==", - "dev": true, - "optional": true, - "requires": { - "@jimp/core": "^0.22.10" - } - }, - "@jimp/gif": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.22.10.tgz", - "integrity": "sha512-yEX2dSpamvkSx1PPDWGnKeWDrBz0vrCKjVG/cn4Zr68MRRT75tbZIeOrBa+RiUpY3ho5ix7d36LkYvt3qfUIhQ==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10", - "gifwrap": "^0.10.1", - "omggif": "^1.0.9" - } - }, - "@jimp/jpeg": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.22.10.tgz", - "integrity": "sha512-6bu98pAcVN4DY2oiDLC4TOgieX/lZrLd1tombWZOFCN5PBmqaHQxm7IUmT+Wj4faEvh8QSHgVLSA+2JQQRJWVA==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10", - "jpeg-js": "^0.4.4" - } - }, - "@jimp/plugin-blit": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.22.10.tgz", - "integrity": "sha512-6EI8Sl+mxYHEIy6Yteh6eknD+EZguKpNdr3sCKxNezmLR0+vK99vHcllo6uGSjXXiwtwS67Xqxn8SsoatL+UJQ==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-blur": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.22.10.tgz", - "integrity": "sha512-4XRTWuPVdMXJeclJMisXPGizeHtTryVaVV5HnuQXpKqIZtzXReCCpNGH8q/i0kBQOQMXhGWS3mpqOEwtpPePKw==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-circle": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.22.10.tgz", - "integrity": "sha512-mhcwTO1ywRxiCgtLGge6tDDIDPlX6qkI3CY+BjgGG/XhVHccCddXgOGLdlf+5OuKIEF2Nqs0V01LQEQIJFTmEw==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-color": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.22.10.tgz", - "integrity": "sha512-e4t3L7Kedd96E0x1XjsTM6NcgulKUU66HdFTao7Tc9FYJRFSlttARZ/C6LEryGDm/i69R6bJEpo7BkNz0YL55Q==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10", - "tinycolor2": "^1.6.0" - } - }, - "@jimp/plugin-contain": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.22.10.tgz", - "integrity": "sha512-eP8KrzctuEoqibQAxi9WhbnoRosydhiwg+IYya3dKuKDBTrD9UHt+ERlPQ/lTNWHzV/l4S1ntV3r9s9saJgsXA==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-cover": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.22.10.tgz", - "integrity": "sha512-kJCwL5T1igfa0InCfkE7bBeqg26m46aoRt10ug+rvm11P6RrvRMGrgINFyIKB+mnB7CiyBN/MOula1CvLhSInQ==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-crop": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.22.10.tgz", - "integrity": "sha512-BOZ+YGaZlhU7c5ye65RxikicXH0Ki0It6/XHISvipR5WZrfjLjL2Ke20G+AGnwBQc76gKenVcMXVUCnEjtZV+Q==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-displace": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.22.10.tgz", - "integrity": "sha512-llNiWWMTKISDXt5+cXI0GaFmZWAjlT+4fFLYf4eXquuL/9wZoQsEBhv2GdGd48mkiS8jZq1Nnb2Q4ehEPTvrzw==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-dither": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.22.10.tgz", - "integrity": "sha512-05WLmeV5M+P/0FS+bWf13hMew2X0oa8w9AtmevL2UyA/5GqiyvP2Xm5WfGQ8oFiiMvpnL6RFomJQOZtWca0C2w==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-fisheye": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.22.10.tgz", - "integrity": "sha512-InjiXvc7Gkzrx8VWtU97kDqV7ENnhHGPULymJWeZaF2aicud9Fpk4iCtd/DcZIrk7Cbe60A8RwNXN00HXIbSCg==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-flip": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.22.10.tgz", - "integrity": "sha512-42GkGtTHWnhnwTMPVK/kXObZbkYIpQWfuIfy5EMEMk6zRj05zpv4vsjkKWfuemweZINwfvD7wDJF7FVFNNcZZg==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-gaussian": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.22.10.tgz", - "integrity": "sha512-ykrG/6lTp9Q5YA8jS5XzwMHtRxb9HOFMgtmnrUZ8kU+BK8REecfy9Ic5BUEOjCYvS1a/xLsnrZQU07iiYxBxFg==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-invert": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.22.10.tgz", - "integrity": "sha512-d8j9BlUJYs/c994t4azUWSWmQq4LLPG4ecm8m6SSNqap+S/HlVQGqjYhJEBbY9EXkOTYB9vBL9bqwSM1Rr6paA==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-mask": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.22.10.tgz", - "integrity": "sha512-yRBs1230XZkz24uFTdTcSlZ0HXZpIWzM3iFQN56MzZ7USgdVZjPPDCQ8I9RpqfZ36nDflQkUO0wV7ucsi4ogow==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-normalize": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.22.10.tgz", - "integrity": "sha512-Wk9GX6eJMchX/ZAazVa70Fagu+OXMvHiPY+HrcEwcclL+p1wo8xAHEsf9iKno7Ja4EU9lLhbBRY5hYJyiKMEkg==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-print": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.22.10.tgz", - "integrity": "sha512-1U3VloIR+beE1kWPdGEJMiE2h1Do29iv3w8sBbvPyRP4qXxRFcDpmCGtctsrKmb1krlBFlj8ubyAY90xL+5n9w==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10", - "load-bmfont": "^1.4.1" - } - }, - "@jimp/plugin-resize": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.22.10.tgz", - "integrity": "sha512-ixomxVcnAONXDgaq0opvAx4UAOiEhOA/tipuhFFOvPKFd4yf1BAnEviB5maB0SBHHkJXPUSzDp/73xVTMGSe7g==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-rotate": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.22.10.tgz", - "integrity": "sha512-eeFX8dnRyf3LAdsdXWKWuN18hLRg8zy1cP0cP9rHzQVWRK7ck/QsLxK1vHq7MADGwQalNaNTJ9SQxH6c8mz6jw==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-scale": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.22.10.tgz", - "integrity": "sha512-TG/H0oUN69C9ArBCZg4PmuoixFVKIiru8282KzSB/Tp1I0xwX0XLTv3dJ5pobPlIgPcB+TmD4xAIdkCT4rtWxg==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-shadow": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.22.10.tgz", - "integrity": "sha512-TN9xm6fI7XfxbMUQqFPZjv59Xdpf0tSiAQdINB4g6pJMWiVANR/74OtDONoy3KKpenu5Y38s+FkrtID/KcQAhw==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugin-threshold": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.22.10.tgz", - "integrity": "sha512-DA2lSnU0TgIRbAgmXaxroYw3Ad6J2DOFEoJp0NleSm2h3GWbZEE5yW9U2B6hD3iqn4AenG4E2b2WzHXZyzSutw==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10" - } - }, - "@jimp/plugins": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.22.10.tgz", - "integrity": "sha512-KDMZyM6pmvS8freB+UBLko1TO/k4D7URS/nphCozuH+P7i3UMe7NdckXKJ8u+WD6sqN0YFYvBehpkpnUiw/91w==", - "dev": true, - "optional": true, - "requires": { - "@jimp/plugin-blit": "^0.22.10", - "@jimp/plugin-blur": "^0.22.10", - "@jimp/plugin-circle": "^0.22.10", - "@jimp/plugin-color": "^0.22.10", - "@jimp/plugin-contain": "^0.22.10", - "@jimp/plugin-cover": "^0.22.10", - "@jimp/plugin-crop": "^0.22.10", - "@jimp/plugin-displace": "^0.22.10", - "@jimp/plugin-dither": "^0.22.10", - "@jimp/plugin-fisheye": "^0.22.10", - "@jimp/plugin-flip": "^0.22.10", - "@jimp/plugin-gaussian": "^0.22.10", - "@jimp/plugin-invert": "^0.22.10", - "@jimp/plugin-mask": "^0.22.10", - "@jimp/plugin-normalize": "^0.22.10", - "@jimp/plugin-print": "^0.22.10", - "@jimp/plugin-resize": "^0.22.10", - "@jimp/plugin-rotate": "^0.22.10", - "@jimp/plugin-scale": "^0.22.10", - "@jimp/plugin-shadow": "^0.22.10", - "@jimp/plugin-threshold": "^0.22.10", - "timm": "^1.6.1" - } - }, - "@jimp/png": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.22.10.tgz", - "integrity": "sha512-RYinU7tZToeeR2g2qAMn42AU+8OUHjXPKZZ9RkmoL4bguA1xyZWaSdr22/FBkmnHhOERRlr02KPDN1OTOYHLDQ==", - "dev": true, - "optional": true, - "requires": { - "@jimp/utils": "^0.22.10", - "pngjs": "^6.0.0" - } - }, - "@jimp/tiff": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.22.10.tgz", - "integrity": "sha512-OaivlSYzpNTHyH/h7pEtl3A7F7TbsgytZs52GLX/xITW92ffgDgT6PkldIrMrET6ERh/hdijNQiew7IoEEr2og==", - "dev": true, - "optional": true, - "requires": { - "utif2": "^4.0.1" - } - }, - "@jimp/types": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.22.10.tgz", - "integrity": "sha512-u/r+XYzbCx4zZukDmxx8S0er3Yq3iDPI6+31WKX0N18i2qPPJYcn8qwIFurfupRumGvJ8SlGLCgt/T+Y8zzUIw==", - "dev": true, - "optional": true, - "requires": { - "@jimp/bmp": "^0.22.10", - "@jimp/gif": "^0.22.10", - "@jimp/jpeg": "^0.22.10", - "@jimp/png": "^0.22.10", - "@jimp/tiff": "^0.22.10", - "timm": "^1.6.1" - } - }, - "@jimp/utils": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.22.10.tgz", - "integrity": "sha512-ztlOK9Mm2iLG2AMoabzM4i3WZ/FtshcgsJCbZCRUs/DKoeS2tySRJTnQZ1b7Roq0M4Ce+FUAxnCAcBV0q7PH9w==", - "dev": true, - "optional": true, - "requires": { - "regenerator-runtime": "^0.13.3" - } - }, - "@sitespeed.io/chromedriver": { - "version": "119.0.6045-105", - "resolved": "https://registry.npmjs.org/@sitespeed.io/chromedriver/-/chromedriver-119.0.6045-105.tgz", - "integrity": "sha512-DfQQaqTB28e05kG3CWjC9OWKeNTWiqgu5cl6CvYQsd2MTDDDRUQ0a+VZ8KTSrRx6xZCsTBgzZK2kNBNiMvNH8w==", - "dev": true, - "requires": { - "node-downloader-helper": "2.1.9", - "node-stream-zip": "1.15.0" - } - }, - "@sitespeed.io/edgedriver": { - "version": "119.0.2151-42", - "resolved": "https://registry.npmjs.org/@sitespeed.io/edgedriver/-/edgedriver-119.0.2151-42.tgz", - "integrity": "sha512-+jGP9BmWgh/yoNcJKyiYP0anF0m2H6+cjk1MaHvzgkIdrFMVfJQIN9+tmwCBiN4Ave52IHjDdHhEjK7B+SWvrA==", - "dev": true, - "requires": { - "node-downloader-helper": "2.1.7", - "node-stream-zip": "1.15.0" - }, - "dependencies": { - "node-downloader-helper": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/node-downloader-helper/-/node-downloader-helper-2.1.7.tgz", - "integrity": "sha512-3dBuMF/XPy5WFi3XiiXaglafzoycRH5GjmRz1nAt2uI9D+TcBrc+n/AzH8bzLHR85Wsf6vZSZblzw+MiUS/WNQ==", - "dev": true - } - } - }, - "@sitespeed.io/geckodriver": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/@sitespeed.io/geckodriver/-/geckodriver-0.33.0.tgz", - "integrity": "sha512-w6w+x9/Q44JekTPi8NlRsfh5Uz4TfquJcUEs0tA/oEcxLVxRS7VtaiaJEE0GzzN6cUmFS6Twas7E4bCA4k/Yxg==", - "dev": true, - "requires": { - "node-downloader-helper": "2.1.5", - "node-stream-zip": "1.15.0", - "tar": "6.1.13" - }, - "dependencies": { - "node-downloader-helper": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/node-downloader-helper/-/node-downloader-helper-2.1.5.tgz", - "integrity": "sha512-sLedzfv8C4VMAvTdDQcjLFAl3gydNeBXh2bLcCzvZRmd4EK0rkoTxJ8tkxnriUSJO/n13skJzH7l6CzCdBwYGg==", - "dev": true - } - } - }, - "@sitespeed.io/throttle": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@sitespeed.io/throttle/-/throttle-5.0.0.tgz", - "integrity": "sha512-eul4I7IllA6l3+GGX1aW/D75XYux0ODuZDzstKD0kAuvIkpQ4BVLkFBoLXQN50gLMFGqZ3QWMobhQ5L2/6sFgg==", - "dev": true, - "requires": { - "minimist": "1.2.6" - } - }, - "@sitespeed.io/tracium": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@sitespeed.io/tracium/-/tracium-0.3.3.tgz", - "integrity": "sha512-dNZafjM93Y+F+sfwTO5gTpsGXlnc/0Q+c2+62ViqP3gkMWvHEMSKkaEHgVJLcLg3i/g19GSIPziiKpgyne07Bw==", - "dev": true, - "requires": { - "debug": "^4.1.1" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", - "dev": true, - "optional": true - }, - "@types/node": { - "version": "16.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz", - "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==", - "dev": true, - "optional": true - }, - "abs": { - "version": "1.3.14", - "resolved": "https://registry.npmjs.org/abs/-/abs-1.3.14.tgz", - "integrity": "sha512-PrS26IzwKLWwuURpiKl8wRmJ2KdR/azaVrLEBWG/TALwT20Y7qjtYp1qcMLHA4206hBHY5phv3w4pjf9NPv4Vw==", - "requires": { - "ul": "^5.0.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true - }, - "any-base": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", - "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==", - "dev": true, - "optional": true - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "optional": true - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bmp-js": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", - "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==", - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "browsertime": { - "version": "https://github.com/sitespeedio/browsertime/tarball/62de4fc9abc8067fb58378999b1bc4a4c42f9eb5", - "integrity": "sha512-dtX8pNd4HLQIBBphbTs4Ok0FTt/+zgikbjxI0B2YEjzOEtbSI//ofn4woOYdIC7JOiTtKhYB79eqXaIbVXORqw==", - "dev": true, - "requires": { - "@cypress/xvfb": "1.2.4", - "@devicefarmer/adbkit": "3.2.5", - "@sitespeed.io/chromedriver": "119.0.6045-105", - "@sitespeed.io/edgedriver": "119.0.2151-42", - "@sitespeed.io/geckodriver": "0.33.0", - "@sitespeed.io/throttle": "5.0.0", - "@sitespeed.io/tracium": "0.3.3", - "btoa": "1.2.1", - "chrome-har": "0.13.2", - "chrome-remote-interface": "0.33.0", - "dayjs": "1.11.10", - "execa": "8.0.1", - "fast-stats": "0.0.6", - "ff-test-bidi-har-export": "0.0.12", - "find-up": "6.3.0", - "get-port": "7.0.0", - "hasbin": "1.2.3", - "intel": "1.2.0", - "jimp": "0.22.10", - "lodash.get": "4.4.2", - "lodash.groupby": "4.6.0", - "lodash.isempty": "4.4.0", - "lodash.merge": "4.6.2", - "lodash.pick": "4.4.0", - "lodash.set": "4.3.2", - "selenium-webdriver": "4.15.0", - "yargs": "17.7.2" - } - }, - "btoa": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", - "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==", - "dev": true - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "optional": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-equal": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", - "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==", - "dev": true, - "optional": true - }, - "capture-stack-trace": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.2.tgz", - "integrity": "sha512-X/WM2UQs6VMHUtjUDnZTRI+i1crWteJySFzr9UpGoQa4WQffXVTTXuekjl7TjZRlcF2XfjgITT0HxZ9RnxeT0w==" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "chrome-har": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/chrome-har/-/chrome-har-0.13.2.tgz", - "integrity": "sha512-QiwyoilXiGVLG9Y0UMzWOyuao/PctTU9AAOTMqH7BuuulY1e0foDZ/O9qmLfdBAe6MbwIl9aDYvrlbyna3uRZw==", - "dev": true, - "requires": { - "dayjs": "1.11.7", - "debug": "4.3.4", - "tough-cookie": "4.1.3", - "uuid": "9.0.0" - }, - "dependencies": { - "dayjs": { - "version": "1.11.7", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", - "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==", - "dev": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "chrome-remote-interface": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/chrome-remote-interface/-/chrome-remote-interface-0.33.0.tgz", - "integrity": "sha512-tv/SgeBfShXk43fwFpQ9wnS7mOCPzETnzDXTNxCb6TqKOiOeIfbrJz+2NAp8GmzwizpKa058wnU1Te7apONaYg==", - "dev": true, - "requires": { - "commander": "2.11.x", - "ws": "^7.2.0" - }, - "dependencies": { - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - } - } - }, - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha512-gYTKKexFO3kh200H1Nit76sRwRtOY32vQd3jpAQKpLtZqyNsSQNfI4N7o3eP2wUjV35pTWKRYqFUDBvUha/Pkw==", - "requires": { - "capture-stack-trace": "^1.0.0" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "dayjs": { - "version": "1.11.10", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", - "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==", - "dev": true - }, - "dbug": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/dbug/-/dbug-0.4.2.tgz", - "integrity": "sha512-nrmsMK1msY0WXwfA2czrKVDgpIYJR2JJaq5cX4DwW7Rxm11nXHqouh9wmubEs44bHYxk8CqeP/Jx4URqSB961w==", - "dev": true - }, - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" - }, - "deffy": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/deffy/-/deffy-2.2.4.tgz", - "integrity": "sha512-pLc9lsbsWjr6RxmJ2OLyvm+9l4j1yK69h+TML/gUit/t3vTijpkNGh8LioaJYTGO7F25m6HZndADcUOo2PsiUg==", - "requires": { - "typpy": "^2.0.0" - } - }, - "dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", - "dev": true, - "optional": true - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "requires": { - "readable-stream": "^2.0.2" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "err": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/err/-/err-1.1.1.tgz", - "integrity": "sha512-N97Ybd2jJHVQ+Ft3Q5+C2gM3kgygkdeQmEqbN2z15UTVyyEsIwLA1VK39O1DHEJhXbwIFcJLqm6iARNhFANcQA==", - "requires": { - "typpy": "^2.2.0" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "exec-limiter": { - "version": "3.2.13", - "resolved": "https://registry.npmjs.org/exec-limiter/-/exec-limiter-3.2.13.tgz", - "integrity": "sha512-86Ri699bwiHZVBzTzNj8gspqAhCPchg70zPVWIh3qzUOA1pUMcb272Em3LPk8AE0mS95B9yMJhtqF8vFJAn0dA==", - "requires": { - "limit-it": "^3.0.0", - "typpy": "^2.1.0" - } - }, - "execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - } - }, - "exif-parser": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", - "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==", - "dev": true, - "optional": true - }, - "fast-stats": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/fast-stats/-/fast-stats-0.0.6.tgz", - "integrity": "sha512-m0zkwa7Z07Wc4xm1YtcrCHmhzNxiYRrrfUyhkdhSZPzaAH/Ewbocdaq7EPVBFz19GWfIyyPcLfRHjHJYe83jlg==", - "dev": true - }, - "ff-test-bidi-har-export": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/ff-test-bidi-har-export/-/ff-test-bidi-har-export-0.0.12.tgz", - "integrity": "sha512-ccJZc14x/1ymgcLpUBz52Rci/UsbboqJ5wgiPrcHQMyh8YOwNJLGt3yGygIHNhiShZ8aA8H4jOmQU980Ngot9Q==", - "dev": true - }, - "file-type": { - "version": "16.5.4", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", - "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", - "dev": true, - "optional": true, - "requires": { - "readable-web-to-node-stream": "^3.0.0", - "strtok3": "^6.2.4", - "token-types": "^4.1.1" - } - }, - "find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "dev": true, - "requires": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - } - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" - }, - "function.name": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/function.name/-/function.name-1.0.13.tgz", - "integrity": "sha512-mVrqdoy5npWZyoXl4DxCeuVF6delDcQjVS9aPdvLYlBxtMTZDR2B5GVEQEoM1jJyspCqg3C0v4ABkLE7tp9xFA==", - "requires": { - "noop6": "^1.0.1" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-port": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.0.0.tgz", - "integrity": "sha512-mDHFgApoQd+azgMdwylJrv2DX47ywGq1i5VFJE7fZ0dttNq3iQMfsU4IvEgBHojA3KqEudyu7Vq+oN8kNaNkWw==", - "dev": true - }, - "get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true - }, - "gifwrap": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.10.1.tgz", - "integrity": "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw==", - "dev": true, - "optional": true, - "requires": { - "image-q": "^4.0.0", - "omggif": "^1.0.10" - } - }, - "git-package-json": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/git-package-json/-/git-package-json-1.4.10.tgz", - "integrity": "sha512-DRAcvbzd2SxGK7w8OgYfvKqhFliT5keX0lmSmVdgScgf1kkl5tbbo7Pam6uYoCa1liOiipKxQZG8quCtGWl/fA==", - "requires": { - "deffy": "^2.2.1", - "err": "^1.1.1", - "gry": "^5.0.0", - "normalize-package-data": "^2.3.5", - "oargv": "^3.4.1", - "one-by-one": "^3.1.0", - "r-json": "^1.2.1", - "r-package-json": "^1.0.0", - "tmp": "0.0.28" - } - }, - "git-source": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/git-source/-/git-source-1.1.10.tgz", - "integrity": "sha512-XZZ7ZgnLL35oLgM/xjnLYgtlKlxJG0FohC1kWDvGkU7s1VKGXK0pFF/g1itQEwQ3D+uTQzBnzPi8XbqOv7Wc1Q==", - "requires": { - "git-url-parse": "^5.0.1" - } - }, - "git-up": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/git-up/-/git-up-1.2.1.tgz", - "integrity": "sha512-SRVN3rOLACva8imc7BFrB6ts5iISWKH1/h/1Z+JZYoUI7UVQM7gQqk4M2yxUENbq2jUUT09NEND5xwP1i7Ktlw==", - "requires": { - "is-ssh": "^1.0.0", - "parse-url": "^1.0.0" - } - }, - "git-url-parse": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-5.0.1.tgz", - "integrity": "sha512-4uSiOgrryNEMBX+gTWogenYRUh2j1D+95STTSEF2RCTgLkfJikl8c7BGr0Bn274hwuxTsbS2/FQ5pVS9FoXegQ==", - "requires": { - "git-up": "^1.0.0" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dev": true, - "optional": true, - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "got": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-5.6.0.tgz", - "integrity": "sha512-MnypzkaW8dldA8AbJFjMs7y14+ykd2V8JCLKSvX1Gmzx1alH3Y+3LArywHDoAF2wS3pnZp4gacoYtvqBeF6drQ==", - "requires": { - "create-error-class": "^3.0.1", - "duplexer2": "^0.1.4", - "is-plain-obj": "^1.0.0", - "is-redirect": "^1.0.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "node-status-codes": "^1.0.0", - "object-assign": "^4.0.1", - "parse-json": "^2.1.0", - "pinkie-promise": "^2.0.0", - "read-all-stream": "^3.0.0", - "readable-stream": "^2.0.5", - "timed-out": "^2.0.0", - "unzip-response": "^1.0.0", - "url-parse-lax": "^1.0.0" - }, - "dependencies": { - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==" - } - } - }, - "gry": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/gry/-/gry-5.0.8.tgz", - "integrity": "sha512-meq9ZjYVpLzZh3ojhTg7IMad9grGsx6rUUKHLqPnhLXzJkRQvEL2U3tQpS5/WentYTtHtxkT3Ew/mb10D6F6/g==", - "requires": { - "abs": "^1.2.1", - "exec-limiter": "^3.0.0", - "one-by-one": "^3.0.0", - "ul": "^5.0.0" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "hasbin": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/hasbin/-/hasbin-1.2.3.tgz", - "integrity": "sha512-CCd8e/w2w28G8DyZvKgiHnQJ/5XXDz6qiUHnthvtag/6T5acUeN5lqq+HMoBqcmgWueWDhiCplrw0Kb1zDACRg==", - "dev": true, - "requires": { - "async": "~1.5" - } - }, - "hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "requires": { - "function-bind": "^1.1.2" - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" - }, - "human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "optional": true - }, - "image-q": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/image-q/-/image-q-4.0.0.tgz", - "integrity": "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==", - "dev": true, - "optional": true, - "requires": { - "@types/node": "16.9.1" - } - }, - "immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "intel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/intel/-/intel-1.2.0.tgz", - "integrity": "sha512-CUDyAtEeEeDo5YtwANOuDhxuFEOgInHvbMrBbhXCD4tAaHuzHM2llevtTeq2bmP8Jf7NkpN305pwDncRmhc1Wg==", - "dev": true, - "requires": { - "chalk": "^1.1.0", - "dbug": "~0.4.2", - "stack-trace": "~0.0.9", - "strftime": "~0.10.0", - "symbol": "~0.3.1", - "utcstring": "~0.1.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, - "is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "requires": { - "hasown": "^2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", - "dev": true, - "optional": true - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==" - }, - "is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==" - }, - "is-retry-allowed": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", - "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==" - }, - "is-ssh": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz", - "integrity": "sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==", - "requires": { - "protocols": "^2.0.1" - } - }, - "is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", - "dev": true, - "optional": true, - "requires": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, - "iterate-object": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/iterate-object/-/iterate-object-1.3.4.tgz", - "integrity": "sha512-4dG1D1x/7g8PwHS9aK6QV5V94+ZvyP4+d19qDv43EzImmrndysIl4prmJ1hWWIGCqrZHyaHBm6BSEWHOLnpoNw==" - }, - "jimp": { - "version": "0.22.10", - "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.22.10.tgz", - "integrity": "sha512-lCaHIJAgTOsplyJzC1w/laxSxrbSsEBw4byKwXgUdMmh+ayPsnidTblenQm+IvhIs44Gcuvlb6pd2LQ0wcKaKg==", - "dev": true, - "optional": true, - "requires": { - "@jimp/custom": "^0.22.10", - "@jimp/plugins": "^0.22.10", - "@jimp/types": "^0.22.10", - "regenerator-runtime": "^0.13.3" - } - }, - "jpeg-js": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", - "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", - "dev": true, - "optional": true - }, - "jszip": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", - "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", - "dev": true, - "requires": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "setimmediate": "^1.0.5" - } - }, - "lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dev": true, - "requires": { - "immediate": "~3.0.5" - } - }, - "limit-it": { - "version": "3.2.10", - "resolved": "https://registry.npmjs.org/limit-it/-/limit-it-3.2.10.tgz", - "integrity": "sha512-T0NK99pHnkimldr1WUqvbGV1oWDku/xC9J/OqzJFsV1jeOS6Bwl8W7vkeQIBqwiON9dTALws+rX/XPMQqWerDQ==", - "requires": { - "typpy": "^2.0.0" - } - }, - "load-bmfont": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.1.tgz", - "integrity": "sha512-8UyQoYmdRDy81Brz6aLAUhfZLwr5zV0L3taTQ4hju7m6biuwiWiJXjPhBJxbUQJA8PrkvJ/7Enqmwk2sM14soA==", - "dev": true, - "optional": true, - "requires": { - "buffer-equal": "0.0.1", - "mime": "^1.3.4", - "parse-bmfont-ascii": "^1.0.3", - "parse-bmfont-binary": "^1.0.5", - "parse-bmfont-xml": "^1.1.4", - "phin": "^2.9.1", - "xhr": "^2.0.1", - "xtend": "^4.0.0" - } - }, - "locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dev": true, - "requires": { - "p-locate": "^6.0.0" - } - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, - "lodash.groupby": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", - "integrity": "sha512-5dcWxm23+VAoz+awKmBaiBvzox8+RqMgFhi7UvX9DHZr2HdxHXM/Wrf8cfKpsW37RNrvtPn6hSwNqurSILbmJw==", - "dev": true - }, - "lodash.isempty": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", - "integrity": "sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", - "dev": true - }, - "lodash.pick": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==", - "dev": true - }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==", - "dev": true - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "optional": true - }, - "mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true - }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "dev": true, - "optional": true, - "requires": { - "dom-walk": "^0.1.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" - }, - "minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", - "dev": true - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node-downloader-helper": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/node-downloader-helper/-/node-downloader-helper-2.1.9.tgz", - "integrity": "sha512-FSvAol2Z8UP191sZtsUZwHIN0eGoGue3uEXGdWIH5228e9KH1YHXT7fN8Oa33UGf+FbqGTQg3sJfrRGzmVCaJA==", - "dev": true - }, - "node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "optional": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "dev": true - }, - "node-status-codes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", - "integrity": "sha512-1cBMgRxdMWE8KeWCqk2RIOrvUb0XCwYfEsY5/y2NlXyq4Y/RumnOZvTj4Nbr77+Vb2C+kyBoRTdkNOS8L3d/aQ==" - }, - "node-stream-zip": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz", - "integrity": "sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw==", - "dev": true - }, - "noop6": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/noop6/-/noop6-1.0.9.tgz", - "integrity": "sha512-DB3Hwyd89dPr5HqEPg3YHjzvwh/mCqizC1zZ8vyofqc+TQRyPDnT4wgXXbLGF4z9YAzwwTLi8pNLhGqcbSjgkA==" - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dev": true, - "requires": { - "path-key": "^4.0.0" - }, - "dependencies": { - "path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true - } - } - }, - "oargv": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/oargv/-/oargv-3.4.10.tgz", - "integrity": "sha512-SXaMANv9sr7S/dP0vj0+Ybipa47UE1ntTWQ2rpPRhC6Bsvfl+Jg03Xif7jfL0sWKOYWK8oPjcZ5eJ82t8AP/8g==", - "requires": { - "iterate-object": "^1.1.0", - "ul": "^5.0.0" - } - }, - "obj-def": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/obj-def/-/obj-def-1.0.9.tgz", - "integrity": "sha512-bQ4ya3VYD6FAA1+s6mEhaURRHSmw4+sKaXE6UyXZ1XDYc5D+c7look25dFdydmLd18epUegh398gdDkMUZI9xg==", - "requires": { - "deffy": "^2.2.2" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, - "omggif": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", - "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==", - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "one-by-one": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/one-by-one/-/one-by-one-3.2.8.tgz", - "integrity": "sha512-HR/pSzZdm46Xqj58K+Bu64kMbSTw8/u77AwWvV+rprO/OsuR++pPlkUJn+SmwqBGRgHKwSKQ974V3uls7crIeQ==", - "requires": { - "obj-def": "^1.0.0", - "sliced": "^1.0.1" - } - }, - "onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "requires": { - "mimic-fn": "^4.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" - }, - "p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "requires": { - "yocto-queue": "^1.0.0" - } - }, - "p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dev": true, - "requires": { - "p-limit": "^4.0.0" - } - }, - "package-json": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz", - "integrity": "sha512-PRg65iXMTt/uK8Rfh5zvzkUbfAPitF17YaCY+IbHsYgksiLvtzWWTUildHth3mVaZ7871OJ7gtP4LBRBlmAdXg==", - "requires": { - "got": "^5.0.0", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" - } - }, - "package-json-path": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/package-json-path/-/package-json-path-1.0.9.tgz", - "integrity": "sha512-uNu7f6Ef7tQHZRnkyVnCtzdSYVN9uBtge/sG7wzcUaawFWkPYUq67iXxRGrQSg/q0tzxIB8jSyIYUKjG2Jn//A==", - "requires": { - "abs": "^1.2.1" - } - }, - "package.json": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/package.json/-/package.json-2.0.1.tgz", - "integrity": "sha512-pSxZ6XR5yEawRN2ekxx9IKgPN5uNAYco7MCPxtBEWMKO3UKWa1X2CtQMzMgloeGj2g2o6cue3Sb5iPkByIJqlw==", - "requires": { - "git-package-json": "^1.4.0", - "git-source": "^1.1.0", - "package-json": "^2.3.1" - } - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "parse-bmfont-ascii": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", - "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==", - "dev": true, - "optional": true - }, - "parse-bmfont-binary": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", - "integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==", - "dev": true, - "optional": true - }, - "parse-bmfont-xml": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz", - "integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==", - "dev": true, - "optional": true, - "requires": { - "xml-parse-from-string": "^1.0.0", - "xml2js": "^0.4.5" - } - }, - "parse-headers": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", - "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==", - "dev": true, - "optional": true - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "requires": { - "error-ex": "^1.2.0" - } - }, - "parse-url": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-1.3.11.tgz", - "integrity": "sha512-1wj9nkgH/5EboDxLwaTMGJh3oH3f+Gue+aGdh631oCqoSBpokzmMmOldvOeBPtB8GJBYJbaF93KPzlkU+Y1ksg==", - "requires": { - "is-ssh": "^1.3.0", - "protocols": "^1.4.0" - }, - "dependencies": { - "protocols": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.8.tgz", - "integrity": "sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg==" - } - } - }, - "path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "peek-readable": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", - "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", - "dev": true, - "optional": true - }, - "phin": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", - "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==", - "dev": true, - "optional": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "requires": { - "pinkie": "^2.0.0" - } - }, - "pixelmatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", - "integrity": "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==", - "dev": true, - "optional": true, - "requires": { - "pngjs": "^3.0.0" - }, - "dependencies": { - "pngjs": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", - "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", - "dev": true, - "optional": true - } - } - }, - "pngjs": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", - "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", - "dev": true, - "optional": true - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==" - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "protocols": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz", - "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==" - }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true - }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "r-json": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/r-json/-/r-json-1.2.10.tgz", - "integrity": "sha512-hu9vyLjSlHXT62NAS7DjI9WazDlvjN0lgp3n431dCVnirVcLkZIpzSwA3orhZEKzdDD2jqNYI+w0yG0aFf4kpA==" - }, - "r-package-json": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/r-package-json/-/r-package-json-1.0.9.tgz", - "integrity": "sha512-G4Vpf1KImWmmPFGdtWQTU0L9zk0SjqEC4qs/jE7AQ+Ylmr5kizMzGeC4wnHp5+ijPqNN+2ZPpvyjVNdN1CDVcg==", - "requires": { - "package-json-path": "^1.0.0", - "r-json": "^1.2.1" - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "read-all-stream": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz", - "integrity": "sha512-DI1drPHbmBcUDWrJ7ull/F2Qb8HkwBncVx8/RpKYFSIACYaVRQReISYPdZz/mt1y1+qMCOrfReTopERmaxtP6w==", - "requires": { - "pinkie-promise": "^2.0.0", - "readable-stream": "^2.0.0" - } - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readable-web-to-node-stream": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", - "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", - "dev": true, - "optional": true, - "requires": { - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "optional": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true, - "optional": true - }, - "registry-auth-token": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", - "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", - "requires": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" - } - }, - "registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==", - "requires": { - "rc": "^1.0.1" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "sax": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", - "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==", - "dev": true, - "optional": true - }, - "selenium-webdriver": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.15.0.tgz", - "integrity": "sha512-BNG1bq+KWiBGHcJ/wULi0eKY0yaDqFIbEmtbsYJmfaEghdCkXBsx1akgOorhNwjBipOr0uwpvNXqT6/nzl+zjg==", - "dev": true, - "requires": { - "jszip": "^3.10.1", - "tmp": "^0.2.1", - "ws": ">=8.14.2" - }, - "dependencies": { - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } - }, - "ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", - "dev": true, - "requires": {} - } - } - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==" - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - }, - "sliced": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", - "integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==" - }, - "spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", - "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==" - }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dev": true, - "requires": { - "through": "2" - } - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "dev": true - }, - "strftime": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/strftime/-/strftime-0.10.2.tgz", - "integrity": "sha512-Y6IZaTVM80chcMe7j65Gl/0nmlNdtt+KWPle5YeCAjmsBfw+id2qdaJ5MDrxUq+OmHKab+jHe7mUjU/aNMSZZg==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" - }, - "strtok3": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", - "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", - "dev": true, - "optional": true, - "requires": { - "@tokenizer/token": "^0.3.0", - "peek-readable": "^4.1.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" - }, - "symbol": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/symbol/-/symbol-0.3.1.tgz", - "integrity": "sha512-SxMrE6uv9zhnBmTCpZna1u0TcZix1k2QASZ/DpF13rAo+0Ts40faFYsMTuAirgvbbjHw1byhJ949/fP20XzVZA==", - "dev": true - }, - "tar": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", - "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^4.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "timed-out": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz", - "integrity": "sha512-pqqJOi1rF5zNs/ps4vmbE4SFCrM4iR7LW+GHAsHqO/EumqbIWceioevYLM5xZRgQSH6gFgL9J/uB7EcJhQ9niQ==" - }, - "timm": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz", - "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==", - "dev": true, - "optional": true - }, - "tinycolor2": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", - "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", - "dev": true, - "optional": true - }, - "tmp": { - "version": "0.0.28", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz", - "integrity": "sha512-c2mmfiBmND6SOVxzogm1oda0OJ1HZVIk/5n26N59dDTh80MUeavpiCls4PGAdkX1PFkKokLpcf7prSjCeXLsJg==", - "requires": { - "os-tmpdir": "~1.0.1" - } - }, - "token-types": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", - "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", - "dev": true, - "optional": true, - "requires": { - "@tokenizer/token": "^0.3.0", - "ieee754": "^1.2.1" - } - }, - "tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", - "dev": true, - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true, - "optional": true - }, - "typpy": { - "version": "2.3.13", - "resolved": "https://registry.npmjs.org/typpy/-/typpy-2.3.13.tgz", - "integrity": "sha512-vOxIcQz9sxHi+rT09SJ5aDgVgrPppQjwnnayTrMye1ODaU8gIZTDM19t9TxmEElbMihx2Nq/0/b/MtyKfayRqA==", - "requires": { - "function.name": "^1.0.3" - } - }, - "ul": { - "version": "5.2.15", - "resolved": "https://registry.npmjs.org/ul/-/ul-5.2.15.tgz", - "integrity": "sha512-svLEUy8xSCip5IWnsRa0UOg+2zP0Wsj4qlbjTmX6GJSmvKMHADBuHOm1dpNkWqWPIGuVSqzUkV3Cris5JrlTRQ==", - "requires": { - "deffy": "^2.2.2", - "typpy": "^2.3.4" - } - }, - "universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true - }, - "unzip-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", - "integrity": "sha512-pwCcjjhEcpW45JZIySExBHYv5Y9EeL2OIGEfrSKp2dMUFGFv4CpvZkwJbVge8OvGH2BNNtJBx67DuKuJhf+N5Q==" - }, - "url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==", - "requires": { - "prepend-http": "^1.0.1" - } - }, - "utcstring": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/utcstring/-/utcstring-0.1.0.tgz", - "integrity": "sha512-1EpWQ6CECkoys7aX3LImrFo4nYIigY2RQHJTvgzZQCB4/oA6jJvTLTcgilTxX57GrSHDIVMtGwYd+SujGJvvyw==", - "dev": true - }, - "utif2": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/utif2/-/utif2-4.1.0.tgz", - "integrity": "sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w==", - "dev": true, - "optional": true, - "requires": { - "pako": "^1.0.11" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true, - "optional": true - }, - "whatwg-fetch": { - "version": "3.6.19", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.19.tgz", - "integrity": "sha512-d67JP4dHSbm2TrpFj8AbO8DnL1JXL5J9u0Kq2xW6d0TFDbCA3Muhdt8orXC22utleTVj7Prqt82baN6RBvnEgw==", - "dev": true, - "optional": true - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "optional": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, - "requires": {} - }, - "xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dev": true, - "optional": true, - "requires": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "xml-parse-from-string": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", - "integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==", - "dev": true, - "optional": true - }, - "xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dev": true, - "optional": true, - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - }, - "xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true, - "optional": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "optional": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - }, - "yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true - } } } diff --git a/tools/browsertime/package.json b/tools/browsertime/package.json index 48a87e2390..75d5e1428a 100644 --- a/tools/browsertime/package.json +++ b/tools/browsertime/package.json @@ -7,7 +7,7 @@ "package.json": "^2.0.1" }, "devDependencies": { - "browsertime": "https://github.com/sitespeedio/browsertime/tarball/62de4fc9abc8067fb58378999b1bc4a4c42f9eb5" + "browsertime": "https://github.com/sitespeedio/browsertime/tarball/de9cbe379e64562cb5ccdcb4e4c5a9b6390547b6" }, "notes(private)": "We don't want to publish to npm, so this is marked as private", "private": true diff --git a/tools/esmify/map.json b/tools/esmify/map.json index 04a790d406..0185ae5401 100644 --- a/tools/esmify/map.json +++ b/tools/esmify/map.json @@ -263,8 +263,6 @@ "resource:///modules/policies/ProxyPolicies.jsm": "browser/components/enterprisepolicies/helpers/ProxyPolicies.jsm", "resource:///modules/policies/WebsiteFilter.jsm": "browser/components/enterprisepolicies/helpers/WebsiteFilter.jsm", "resource:///modules/policies/schema.jsm": "browser/components/enterprisepolicies/schemas/schema.jsm", - "resource:///modules/sessionstore/ContentRestore.jsm": "browser/components/sessionstore/ContentRestore.jsm", - "resource:///modules/sessionstore/ContentSessionStore.jsm": "browser/components/sessionstore/ContentSessionStore.jsm", "resource:///modules/sessionstore/GlobalState.jsm": "browser/components/sessionstore/GlobalState.jsm", "resource:///modules/sessionstore/RecentlyClosedTabsAndWindowsMenuUtils.jsm": "browser/components/sessionstore/RecentlyClosedTabsAndWindowsMenuUtils.jsm", "resource:///modules/sessionstore/RunState.jsm": "browser/components/sessionstore/RunState.jsm", @@ -497,7 +495,6 @@ "resource://gre/modules/ContentPrefStore.jsm": "toolkit/components/contentprefs/ContentPrefStore.jsm", "resource://gre/modules/ContentPrefUtils.jsm": "toolkit/components/contentprefs/ContentPrefUtils.jsm", "resource://gre/modules/ContextualIdentityService.jsm": "toolkit/components/contextualidentity/ContextualIdentityService.jsm", - "resource://gre/modules/Corroborate.jsm": "toolkit/components/corroborator/Corroborate.jsm", "resource://gre/modules/CoveragePing.jsm": "toolkit/components/telemetry/pings/CoveragePing.jsm", "resource://gre/modules/CrashManager.jsm": "toolkit/components/crashes/CrashManager.in.jsm", "resource://gre/modules/CrashMonitor.jsm": "toolkit/components/crashmonitor/CrashMonitor.jsm", @@ -566,8 +563,8 @@ "resource://gre/modules/FirefoxRelay.jsm": "toolkit/components/passwordmgr/FirefoxRelay.jsm", "resource://gre/modules/FirstStartup.jsm": "toolkit/modules/FirstStartup.jsm", "resource://gre/modules/ForgetAboutSite.jsm": "toolkit/components/forgetaboutsite/ForgetAboutSite.jsm", - "resource://gre/modules/FormAutoComplete.jsm": "toolkit/components/satchel/FormAutoComplete.jsm", "resource://gre/modules/FormHistory.jsm": "toolkit/components/satchel/FormHistory.jsm", + "resource://gre/modules/FormAutoComplete.jsm": "toolkit/components/satchel/FormHistoryAutoComplete.jsm", "resource://gre/modules/FormHistoryStartup.jsm": "toolkit/components/satchel/FormHistoryStartup.jsm", "resource://gre/modules/FormLikeFactory.jsm": "toolkit/modules/FormLikeFactory.jsm", "resource://gre/modules/FxAccounts.jsm": "services/fxaccounts/FxAccounts.jsm", @@ -764,7 +761,6 @@ "resource://gre/modules/TelemetryStorage.jsm": "toolkit/components/telemetry/app/TelemetryStorage.jsm", "resource://gre/modules/TelemetryTimestamps.jsm": "toolkit/components/telemetry/app/TelemetryTimestamps.jsm", "resource://gre/modules/TelemetryUtils.jsm": "toolkit/components/telemetry/app/TelemetryUtils.jsm", - "resource://gre/modules/TerminatorTelemetry.jsm": "toolkit/components/terminator/TerminatorTelemetry.jsm", "resource://gre/modules/Timer.jsm": "toolkit/modules/Timer.jsm", "resource://gre/modules/TooltipTextProvider.jsm": "toolkit/components/tooltiptext/TooltipTextProvider.jsm", "resource://gre/modules/TrackingDBService.jsm": "toolkit/components/antitracking/TrackingDBService.jsm", @@ -929,7 +925,6 @@ "resource://reftest/globals.jsm": "layout/tools/reftest/globals.jsm", "resource://reftest/manifest.jsm": "layout/tools/reftest/manifest.jsm", "resource://reftest/reftest.jsm": "layout/tools/reftest/reftest.jsm", - "resource://report-site-issue/tabExtrasActor.jsm": "browser/extensions/report-site-issue/experimentalAPIs/actors/tabExtrasActor.jsm", "resource://services-automation/ServicesAutomation.jsm": "services/automation/ServicesAutomation.jsm", "resource://services-common/async.js": "services/common/async.js", "resource://services-common/hawkclient.js": "services/common/hawkclient.js", diff --git a/tools/esmify/use-import-export-declarations.js b/tools/esmify/use-import-export-declarations.js index fe8c4dd286..60e017645b 100644 --- a/tools/esmify/use-import-export-declarations.js +++ b/tools/esmify/use-import-export-declarations.js @@ -111,7 +111,7 @@ function isTopLevel(path) { return path.parent.node.type === "Program"; } -function convertToExport(jscodeshift, path, name) { +function convertToExport(jscodeshift, path) { const e = jscodeshift.exportNamedDeclaration(path.node); e.comments = []; e.comments = path.node.comments; diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js index c4d28594b5..036ed1bda3 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/recommended.js @@ -55,6 +55,7 @@ module.exports = { files: ["**/*.sys.mjs", "**/*.jsm"], rules: { "mozilla/lazy-getter-object-name": "error", + "mozilla/reject-chromeutils-import": "error", "mozilla/reject-eager-module-in-lazy-getter": "error", "mozilla/reject-global-this": "error", "mozilla/reject-globalThis-modification": "error", @@ -76,7 +77,7 @@ module.exports = { "no-unused-vars": [ "error", { - args: "none", + argsIgnorePattern: "^_", vars: "all", }, ], @@ -142,7 +143,7 @@ module.exports = { }, // When adding items to this file please check for effects on sub-directories. - plugins: ["fetch-options", "html", "json", "no-unsanitized"], + plugins: ["html", "json", "no-unsanitized"], // When adding items to this file please check for effects on all of toolkit // and browser @@ -163,10 +164,6 @@ module.exports = { // Encourage the use of dot notation whenever possible. "dot-notation": "error", - // XXX This rule should be enabled, see Bug 1557040 - // No credentials submitted with fetch calls - "fetch-options/no-fetch-credentials": "off", - // Maximum depth callbacks can be nested. "max-nested-callbacks": ["error", 10], @@ -317,7 +314,7 @@ module.exports = { "no-unused-vars": [ "error", { - args: "none", + argsIgnorePattern: "^_", vars: "local", }, ], diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/xpcshell-test.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/xpcshell-test.js index d3c983999a..7701a0b2ca 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/xpcshell-test.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/configs/xpcshell-test.js @@ -29,7 +29,7 @@ module.exports = { "no-unused-vars": [ "error", { - args: "none", + argsIgnorePattern: "^_", vars: "local", }, ], @@ -42,7 +42,7 @@ module.exports = { "no-unused-vars": [ "error", { - args: "none", + argsIgnorePattern: "^_", vars: "all", }, ], diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/browser-window.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/browser-window.js index 241299e2d3..83fa01935e 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/browser-window.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/environments/browser-window.js @@ -57,6 +57,7 @@ const MAPPINGS = { "browser/components/places/content/places-menupopup.js", "shopping-sidebar.js": "browser/components/shopping/content/shopping-sidebar.js", + "browser-sidebar.js": "browser/components/sidebar/browser-sidebar.js", }; const globalScriptsRegExp = diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/globals.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/globals.js index bbc1f9bed8..4d894b58cf 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/globals.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/globals.js @@ -634,8 +634,8 @@ module.exports = { let globalScope; let parser = { - Program() { - globalScope = context.getScope(); + Program(node) { + globalScope = helpers.getScope(context, node); }, }; let filename = context.getFilename(); @@ -651,10 +651,14 @@ module.exports = { for (let type of Object.keys(GlobalsForNode.prototype)) { parser[type] = function (node) { if (type === "Program") { - globalScope = context.getScope(); + globalScope = helpers.getScope(context, node); helpers.addGlobals(extraHTMLGlobals, globalScope); } - let globals = handler[type](node, context.getAncestors(), globalScope); + let globals = handler[type]( + node, + helpers.getAncestors(context, node), + globalScope + ); helpers.addGlobals( globals, globalScope, diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/helpers.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/helpers.js index 9ab51df37e..7d44b4b1b3 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/helpers.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/helpers.js @@ -794,4 +794,38 @@ module.exports = { } return null; }, + + /** + * Gets the scope for a node taking account of where the scope function + * is available (supports node versions earlier than 8.37.0). + * + * @param {object} context + * The context passed from ESLint. + * @param {object} node + * The node to get the scope for. + * returns {function} + * The getScope function object. + */ + getScope(context, node) { + return context.sourceCode?.getScope + ? context.sourceCode.getScope(node) + : context.getScope(); + }, + + /** + * Gets the ancestors for a node taking account of where the ancestors function + * is available (supports node versions earlier than 8.38.0). + * + * @param {object} context + * The context passed from ESLint. + * @param {object} node + * The node to get the scope for. + * returns {function} + * The getScope function object. + */ + getAncestors(context, node) { + return context.sourceCode?.getAncestors + ? context.sourceCode.getAncestors(node) + : context.getAncestors(); + }, }; diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/mark-exported-symbols-as-used.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/mark-exported-symbols-as-used.js index 3664374053..b632e3b632 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/mark-exported-symbols-as-used.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/mark-exported-symbols-as-used.js @@ -19,16 +19,26 @@ function markArrayElementsAsUsed(context, node, expression) { } for (let element of expression.elements) { - context.markVariableAsUsed(element.value); + context.markVariableAsUsed + ? context.markVariableAsUsed(element.value) + : context.sourceCode.markVariableAsUsed(element.value); } // Also mark EXPORTED_SYMBOLS as used. - context.markVariableAsUsed("EXPORTED_SYMBOLS"); + context.markVariableAsUsed + ? context.markVariableAsUsed("EXPORTED_SYMBOLS") + : context.sourceCode.markVariableAsUsed("EXPORTED_SYMBOLS"); } // Ignore assignments not in the global scope, e.g. where special module // definitions are required due to having different ways of importing files, // e.g. osfile. -function isGlobalScope(context) { +function isGlobalScope(context, node) { + if (context.sourceCode?.getScope) { + let upper = context.sourceCode.getScope(node).upper; + // ESLint v9 uses a global scope object with type = "global". Earlier + // versions use a null upper scope. + return !upper || upper.type == "global"; + } return !context.getScope().upper; } @@ -55,14 +65,14 @@ module.exports = { node.left.type === "MemberExpression" && node.left.object.type === "ThisExpression" && node.left.property.name === "EXPORTED_SYMBOLS" && - isGlobalScope(context) + isGlobalScope(context, node) ) { markArrayElementsAsUsed(context, node, node.right); } }, VariableDeclaration(node) { - if (!isGlobalScope(context)) { + if (!isGlobalScope(context, node)) { return; } diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-global-this.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-global-this.js index ec4b5fd43d..1067a4befa 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-global-this.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-global-this.js @@ -29,7 +29,7 @@ module.exports = { create(context) { return { ThisExpression(node) { - if (!helpers.getIsGlobalThis(context.getAncestors())) { + if (!helpers.getIsGlobalThis(helpers.getAncestors(context, node))) { return; } diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-mixing-eager-and-lazy.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-mixing-eager-and-lazy.js index 5779a90afd..41ddc998a3 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-mixing-eager-and-lazy.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-mixing-eager-and-lazy.js @@ -71,7 +71,7 @@ module.exports = { (callerSource === "ChromeUtils.import" || callerSource === "ChromeUtils.importESModule") && helpers.getIsTopLevelAndUnconditionallyExecuted( - context.getAncestors() + helpers.getAncestors(context, node) ) ) { if (node.arguments.length < 1) { diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-multiple-getters-calls.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-multiple-getters-calls.js index e6e37ad035..0e0f6e2e17 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-multiple-getters-calls.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-multiple-getters-calls.js @@ -56,6 +56,24 @@ module.exports = { return; } + if (node.arguments.length >= 3) { + const options = node.arguments[2]; + let globalOption = null; + if (options.type == "ObjectExpression") { + for (const prop of options.properties) { + if ( + prop.type == "Property" && + isIdentifier(prop.key, "global") + ) { + globalOption = helpers.getASTSource(prop.value); + } + } + } + if (globalOption) { + target += "+" + globalOption; + } + } + const parent = stmt.parent; let targets; if (parentToTargets.has(parent)) { diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-top-level-await.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-top-level-await.js index dff7db0f9a..7356fe10bf 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-top-level-await.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/reject-top-level-await.js @@ -26,7 +26,7 @@ module.exports = { create(context) { return { AwaitExpression(node) { - if (!helpers.getIsTopLevelScript(context.getAncestors())) { + if (!helpers.getIsTopLevelScript(helpers.getAncestors(context, node))) { return; } context.report({ node, messageId: "rejectTopLevelAwait" }); @@ -34,7 +34,7 @@ module.exports = { ForOfStatement(node) { if ( !node.await || - !helpers.getIsTopLevelScript(context.getAncestors()) + !helpers.getIsTopLevelScript(helpers.getAncestors(context, node)) ) { return; } diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/use-isInstance.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/use-isInstance.js index ffd9bc9566..f6d6f5e5d3 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/use-isInstance.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/use-isInstance.js @@ -11,6 +11,7 @@ const fs = require("fs"); const { maybeGetMemberPropertyName } = require("../helpers"); +const helpers = require("../helpers"); const privilegedGlobals = Object.keys( require("../environments/privileged.js").globals @@ -133,7 +134,7 @@ module.exports = { const { operator, right } = node; if ( operator === "instanceof" && - pointsToDOMInterface(context.getScope(), right) + pointsToDOMInterface(helpers.getScope(context, node), right) ) { context.report({ node, diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/use-static-import.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/use-static-import.js index 100b5682de..0a768e25d4 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/use-static-import.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/use-static-import.js @@ -35,7 +35,7 @@ module.exports = { node.init?.type != "CallExpression" || node.init?.callee?.type != "MemberExpression" || !context.getFilename().endsWith(".sys.mjs") || - !helpers.isTopLevel(context.getAncestors()) + !helpers.isTopLevel(helpers.getAncestors(context, node)) ) { return; } diff --git a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/valid-lazy.js b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/valid-lazy.js index 048ed17e3e..2be8840bf7 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/valid-lazy.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/valid-lazy.js @@ -225,7 +225,7 @@ module.exports = { } if ( helpers.getIsTopLevelAndUnconditionallyExecuted( - context.getAncestors() + helpers.getAncestors(context, node) ) ) { context.report({ diff --git a/tools/lint/eslint/eslint-plugin-mozilla/manifest.tt b/tools/lint/eslint/eslint-plugin-mozilla/manifest.tt index c33cc36e38..a804c1392a 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/manifest.tt +++ b/tools/lint/eslint/eslint-plugin-mozilla/manifest.tt @@ -1,9 +1,9 @@ [ { "filename": "eslint-plugin-mozilla.tar.gz", - "size": 5593447, + "size": 5695135, "algorithm": "sha512", - "digest": "ba1f9719d64200e0488003d76f75a189bf4103aa7e653b0aaa0b1053543c5349e3d272eaac006b98f1a3a6530cc0fcfd3aaedc62ce1df6050f737c4865f49d69", + "digest": "84122ccc750528b67632207208c6f53b0bafee52d1ef1ce42a07319008cb49edabaada0931058aafa1c6af66ed49b3a120d9bd40e4b120e4e4cb63ec6cc40e6b", "unpack": true, "visibility": "public" } diff --git a/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json b/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json index c4c36118d2..1b4f8f9b48 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json +++ b/tools/lint/eslint/eslint-plugin-mozilla/package-lock.json @@ -1,12 +1,12 @@ { "name": "eslint-plugin-mozilla", - "version": "3.7.1", + "version": "3.7.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "eslint-plugin-mozilla", - "version": "3.7.1", + "version": "3.7.3", "license": "MPL-2.0", "dependencies": { "eslint-scope": "^7.2.2", @@ -27,7 +27,6 @@ "@microsoft/eslint-plugin-sdl": "^0.2.2", "eslint": "^7.23.0 || ^8.0.0", "eslint-config-prettier": "^8.0.0 || ^9.0.0", - "eslint-plugin-fetch-options": "^0.0.5", "eslint-plugin-html": "^7.0.0 || ^8.0.0", "eslint-plugin-json": "^3.1.0", "eslint-plugin-no-unsanitized": "^4.0.0" @@ -119,9 +118,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==" }, "node_modules/@microsoft/eslint-plugin-sdl": { "version": "0.2.2", @@ -277,15 +276,16 @@ } }, "node_modules/array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" }, "engines": { @@ -387,12 +387,15 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/brace-expansion": { @@ -560,6 +563,57 @@ "node": ">= 8" } }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -716,17 +770,21 @@ } }, "node_modules/es-abstract": { - "version": "1.22.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz", - "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", "peer": true, "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", "es-define-property": "^1.0.0", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", "function.prototype.name": "^1.1.6", @@ -737,10 +795,11 @@ "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "hasown": "^2.0.1", + "hasown": "^2.0.2", "internal-slot": "^1.0.7", "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.3", @@ -751,17 +810,17 @@ "object-keys": "^1.1.1", "object.assign": "^4.1.5", "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.0", + "safe-array-concat": "^1.1.2", "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", - "string.prototype.trimstart": "^1.0.7", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.2", "typed-array-byte-length": "^1.0.1", "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.5", + "typed-array-length": "^1.0.6", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -791,6 +850,18 @@ "node": ">= 0.4" } }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-set-tostringtag": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", @@ -936,15 +1007,6 @@ "eslint": ">=4.19.1" } }, - "node_modules/eslint-plugin-fetch-options": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-fetch-options/-/eslint-plugin-fetch-options-0.0.5.tgz", - "integrity": "sha512-ZMxrccsOAZ7uMQ4nMvPJLqLg6oyLF96YOEwTKWAIbDHpwWUp1raXALZom8ikKucaEnhqWSRuBWI8jBXveFwkJg==", - "peer": true, - "engines": { - "node": ">=0.9.0" - } - }, "node_modules/eslint-plugin-html": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-8.0.0.tgz", @@ -1512,9 +1574,9 @@ } }, "node_modules/hasown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", - "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "peer": true, "dependencies": { "function-bind": "^1.1.2" @@ -1689,6 +1751,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "peer": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", @@ -2192,28 +2269,29 @@ } }, "node_modules/object.entries": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", - "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -2223,27 +2301,31 @@ } }, "node_modules/object.hasown": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", - "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", + "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", "peer": true, "dependencies": { - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -2558,13 +2640,13 @@ } }, "node_modules/safe-array-concat": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", - "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "peer": true, "dependencies": { - "call-bind": "^1.0.5", - "get-intrinsic": "^1.2.2", + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", "has-symbols": "^1.0.3", "isarray": "^2.0.5" }, @@ -2640,17 +2722,17 @@ } }, "node_modules/set-function-length": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", - "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "peer": true, "dependencies": { - "define-data-property": "^1.1.2", + "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.3", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -2723,34 +2805,41 @@ } }, "node_modules/string.prototype.matchall": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", - "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "regexp.prototype.flags": "^1.5.0", - "set-function-name": "^2.0.0", - "side-channel": "^1.0.4" + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -2760,28 +2849,31 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2939,9 +3031,9 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", - "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "peer": true, "dependencies": { "call-bind": "^1.0.7", @@ -3049,16 +3141,16 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", - "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "peer": true, "dependencies": { - "available-typed-arrays": "^1.0.6", - "call-bind": "^1.0.5", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.1" + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" diff --git a/tools/lint/eslint/eslint-plugin-mozilla/package.json b/tools/lint/eslint/eslint-plugin-mozilla/package.json index 5d54e8b387..7384f41401 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/package.json +++ b/tools/lint/eslint/eslint-plugin-mozilla/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-mozilla", - "version": "3.7.1", + "version": "3.7.3", "description": "A collection of rules that help enforce JavaScript coding standard in the Mozilla project.", "keywords": [ "eslint", @@ -35,7 +35,6 @@ "@microsoft/eslint-plugin-sdl": "^0.2.2", "eslint": "^7.23.0 || ^8.0.0", "eslint-config-prettier": "^8.0.0 || ^9.0.0", - "eslint-plugin-fetch-options": "^0.0.5", "eslint-plugin-html": "^7.0.0 || ^8.0.0", "eslint-plugin-json": "^3.1.0", "eslint-plugin-no-unsanitized": "^4.0.0" diff --git a/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-multiple-getters-calls.js b/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-multiple-getters-calls.js index a2b88a8652..d9450ad24e 100644 --- a/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-multiple-getters-calls.js +++ b/tools/lint/eslint/eslint-plugin-mozilla/tests/reject-multiple-getters-calls.js @@ -46,6 +46,14 @@ ruleTester.run("reject-multiple-getters-calls", rule, { }); } `, + ` + ChromeUtils.defineESModuleGetters(lazy, { + AppConstants: "resource://gre/modules/AppConstants.sys.mjs", + }, { global: "current" }); + ChromeUtils.defineESModuleGetters(lazy, { + PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs", + }, { global: "shared" }); + `, ], invalid: [ invalidCode(` @@ -56,5 +64,13 @@ ruleTester.run("reject-multiple-getters-calls", rule, { PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs", }); `), + invalidCode(` + ChromeUtils.defineESModuleGetters(lazy, { + AppConstants: "resource://gre/modules/AppConstants.sys.mjs", + }, { global: "current" }); + ChromeUtils.defineESModuleGetters(lazy, { + PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs", + }, { global: "current" }); + `), ], }); diff --git a/tools/lint/eslint/eslint-plugin-spidermonkey-js/lib/environments/self-hosted.js b/tools/lint/eslint/eslint-plugin-spidermonkey-js/lib/environments/self-hosted.js index 37ae42bfa3..bf7069510c 100644 --- a/tools/lint/eslint/eslint-plugin-spidermonkey-js/lib/environments/self-hosted.js +++ b/tools/lint/eslint/eslint-plugin-spidermonkey-js/lib/environments/self-hosted.js @@ -149,7 +149,8 @@ function selfHostingFunctions() { let content = tryReadFile("js/src/vm/SelfHosting.cpp").replace(/\s+/g, ""); let globals = Object.create(null); - for (let m of content.matchAll(/(?:JS_FN|JS_INLINABLE_FN)\("(\w+)"/g)) { + let re = /(?:JS_FN|JS_INLINABLE_FN|JS_TRAMPOLINE_FN)\("(\w+)"/g; + for (let m of content.matchAll(re)) { globals[m[1]] = "readonly"; } return globals; diff --git a/tools/lint/eslint/manifest.tt b/tools/lint/eslint/manifest.tt index bee00211ab..540b2da8e8 100644 --- a/tools/lint/eslint/manifest.tt +++ b/tools/lint/eslint/manifest.tt @@ -1,9 +1,9 @@ [ { "filename": "eslint.tar.gz", - "size": 22159369, + "size": 22290302, "algorithm": "sha512", - "digest": "683b12e0c7463c4e5ba0ec47d680744d7eb870438822963557526d490c36a6a7929d9d0471fbac9dd6f549953285ac734f25a9e0cb1b3651c38350e5582cce5e", + "digest": "e1db81761e5eb2761af1d8117b1b336ad1979ccc0cfcaca0b72a4772aee9e9b98b532c71b4e125fbef574b75100b8e9102465638fbd90996784c2d4e5b90b98c", "unpack": true, "visibility": "public" } diff --git a/tools/lint/file-whitespace.yml b/tools/lint/file-whitespace.yml index 91a8ed2103..748c1a329b 100644 --- a/tools/lint/file-whitespace.yml +++ b/tools/lint/file-whitespace.yml @@ -146,6 +146,7 @@ file-whitespace: - python/mozperftest/perfdocs/running.rst - python/mozperftest/perfdocs/vision.rst - python/mozperftest/perfdocs/writing.rst + extensions: - .c - .cc diff --git a/tools/lint/license.yml b/tools/lint/license.yml index c1cf7e628e..34e1eb817c 100644 --- a/tools/lint/license.yml +++ b/tools/lint/license.yml @@ -30,6 +30,9 @@ license: - gradle.properties # might not work with license - gradle/wrapper/gradle-wrapper.properties + - mobile/android/android-components/gradle/wrapper/gradle-wrapper.properties + - mobile/android/fenix/gradle/wrapper/gradle-wrapper.properties + - mobile/android/focus-android/gradle/wrapper/gradle-wrapper.properties # ICU4X data - intl/icu_segmenter_data # Imported code that is dual Apache2 / MIT licensed @@ -41,6 +44,48 @@ license: - mobile/android/geckoview_example/src/main - testing/webcompat/interventions/ - testing/webcompat/shims/ + # TODO - Bug 1881094: temporarily ignored for firefox-android migration + - mobile/android/android-components/components/browser/engine-system/src/main/res/ + - mobile/android/android-components/components/browser/errorpages/src/main/res/ + - mobile/android/android-components/components/browser/menu/src/main/res/ + - mobile/android/android-components/components/browser/menu2/src/main/res/ + - mobile/android/android-components/components/browser/toolbar/src/main/res/ + - mobile/android/android-components/components/compose/awesomebar/src/main/res/ + - mobile/android/android-components/components/compose/browser-toolbar/src/main/res/ + - mobile/android/android-components/components/compose/cfr/src/main/res/ + - mobile/android/android-components/components/compose/tabstray/src/main/res/ + - mobile/android/android-components/components/feature/addons/src/main/res/ + - mobile/android/android-components/components/feature/app-links/src/main/res/ + - mobile/android/android-components/components/feature/autofill/src/main/res/ + - mobile/android/android-components/components/feature/awesomebar/src/main/res/ + - mobile/android/android-components/components/feature/contextmenu/src/main/res/ + - mobile/android/android-components/components/feature/customtabs/src/main/res/ + - mobile/android/android-components/components/feature/downloads/src/main/res/ + - mobile/android/android-components/components/feature/findinpage/src/main/res/ + - mobile/android/android-components/components/feature/fxsuggest/src/main/res/ + - mobile/android/android-components/components/feature/media/src/main/res/ + - mobile/android/android-components/components/feature/privatemode/src/main/res/ + - mobile/android/android-components/components/feature/prompts/src/main/res/ + - mobile/android/android-components/components/feature/pwa/src/main/res/ + - mobile/android/android-components/components/feature/qr/src/main/res/ + - mobile/android/android-components/components/feature/readerview/src/main/res/ + - mobile/android/android-components/components/feature/search/src/main/res/ + - mobile/android/android-components/components/feature/sitepermissions/ + - mobile/android/android-components/components/feature/tabs/src/main/res/ + - mobile/android/android-components/components/feature/webcompat/src/main/assets/extensions/webcompat/injections/ + - mobile/android/android-components/components/feature/webnotifications/src/main/res/ + - mobile/android/android-components/components/lib/crash/src/main/res/ + - mobile/android/android-components/components/service/nimbus/src/main/res/ + - mobile/android/android-components/components/support/base/src/main/res/ + - mobile/android/android-components/components/support/ktx/src/main/res/ + - mobile/android/android-components/components/support/utils/src/main/res/ + - mobile/android/android-components/components/ui/tabcounter/src/main/res/ + - mobile/android/android-components/components/ui/widgets/src/main/res/ + - mobile/android/android-components/docs/ + - mobile/android/fenix/app/src/main/res/ + - mobile/android/fenix/benchmark/src/main/AndroidManifest.xml + - mobile/android/focus-android/app/lint-baseline.xml + - mobile/android/focus-android/app/src/main/res/ # might not work with license - mobile/android/gradle/dotgradle-offline/gradle.properties # might not work with license @@ -51,8 +96,6 @@ license: - python/mozlint/test/files/ # By design - python/mozrelease/mozrelease - - security/mac/hardenedruntime/v1/production/browser.xml - - security/mac/hardenedruntime/v1/developer/browser.xml - security/mac/hardenedruntime/v2/developer/browser.xml - security/mac/hardenedruntime/v2/developer/media-plugin-helper.xml - security/mac/hardenedruntime/v2/developer/plugin-container.xml diff --git a/tools/lint/perfdocs/framework_gatherers.py b/tools/lint/perfdocs/framework_gatherers.py index 75a6371731..3c0a4026d9 100644 --- a/tools/lint/perfdocs/framework_gatherers.py +++ b/tools/lint/perfdocs/framework_gatherers.py @@ -167,7 +167,7 @@ class RaptorGatherer(FrameworkGatherer): :return list: the list of the tests """ desc_exclusion = ["here", "manifest_relpath", "path", "relpath"] - test_manifest = TestManifest([str(manifest_path)], strict=False) + test_manifest = TestManifest([str(manifest_path)], strict=False, document=True) test_list = test_manifest.active_tests(exists=False, disabled=False) subtests = {} for subtest in test_list: @@ -178,6 +178,20 @@ class RaptorGatherer(FrameworkGatherer): if key not in desc_exclusion: description[key] = value + # Add searchfox link + key = list(test_manifest.source_documents.keys())[0] + + if ( + test_manifest.source_documents[key] + and subtest["name"] in test_manifest.source_documents[key].keys() + ): + description["link searchfox"] = ( + "https://searchfox.org/mozilla-central/source/" + + manifest_path + + "#" + + test_manifest.source_documents[key][subtest["name"]]["lineno"] + ) + # Prepare alerting metrics for verification description["metrics"] = [ metric.strip() @@ -226,7 +240,6 @@ class RaptorGatherer(FrameworkGatherer): browsers = [ "firefox", "chrome", - "chromium", "refbrow", "fennec68", "geckoview", @@ -272,6 +285,8 @@ class RaptorGatherer(FrameworkGatherer): result += f" * **{sub_title}**: `<{description[key]}>`__\n" elif key == "secondary_url": result += f" * **{sub_title}**: `<{description[key]}>`__\n" + elif key == "link searchfox": + result += f" * **{sub_title}**: `<{description[key]}>`__\n" elif key in ["playback_pageset_manifest"]: result += ( f" * **{sub_title}**: " diff --git a/tools/lint/rejected-words.yml b/tools/lint/rejected-words.yml index d45bcf5d08..ed9e8c9d60 100644 --- a/tools/lint/rejected-words.yml +++ b/tools/lint/rejected-words.yml @@ -154,7 +154,16 @@ avoid-blacklist-and-whitelist: - layout/tools/reftest/reftestcommandline.py - layout/tools/reftest/runreftest.py - layout/tools/reftest/selftest/conftest.py + - mobile/android/android-components/components/feature/webcompat/src/main/assets/extensions/webcompat/shims/nielsen.js + - mobile/android/android-components/docs/changelog.md - mobile/android/app/geckoview-prefs.js + - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/ext/Bitmap.kt + - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt + - mobile/android/fenix/app/src/main/java/org/mozilla/fenix/translations/preferences/downloadlanguages/DownloadLanguagesFeature.kt + - mobile/android/fenix/app/src/test/java/org/mozilla/fenix/translations/preferences/downloadlanguages/DownloadLanguagesFeatureTest.kt + - mobile/android/focus-android/app/src/main/res/values-ar/strings.xml + - mobile/android/focus-android/app/src/main/res/values-et/strings.xml + - mobile/android/focus-android/app/src/main/res/values-lt/strings.xml - mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/HardwareCodecCapabilityUtils.java - mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentBlocking.java - mobile/android/geckoview/src/main/java/org/mozilla/geckoview/CrashReporter.java diff --git a/tools/lint/rst/requirements.in b/tools/lint/rst/requirements.in index e6b6022a47..21ff1eeb41 100644 --- a/tools/lint/rst/requirements.in +++ b/tools/lint/rst/requirements.in @@ -1,6 +1,6 @@ alabaster==0.7.13 charset-normalizer==2.0.12 -docutils==0.17.1 +docutils==0.18.1 idna==2.10 imagesize==1.4.1 importlib-metadata==6.0.0 @@ -8,13 +8,13 @@ markupsafe==2.0.1 packaging==21.0 requests==2.27.1 snowballstemmer==2.2.0 -sphinxcontrib-applehelp==1.0.2 -sphinxcontrib-htmlhelp==2.0.0 -sphinxcontrib-mermaid==0.8.1 +sphinxcontrib-applehelp==1.0.4 +sphinxcontrib-htmlhelp==2.0.1 +sphinxcontrib-mermaid==0.9.2 rstcheck==3.5.0 Pygments==2.14.0 pytz==2022.7.1 urllib3==1.26.9 # We need sphinx to avoid some rstcheck errors and warnings -Sphinx==5.3.0 +Sphinx==7.1.2 pkgutil-resolve-name==1.3.10 ; python_version < '3.9' diff --git a/tools/lint/rst/requirements.txt b/tools/lint/rst/requirements.txt index ded13595c3..ac8de0bba7 100644 --- a/tools/lint/rst/requirements.txt +++ b/tools/lint/rst/requirements.txt @@ -1,8 +1,8 @@ # -# This file is autogenerated by pip-compile with Python 3.7 +# This file is autogenerated by pip-compile with Python 3.8 # by the following command: # -# pip-compile --config=pyproject.toml --generate-hashes --output-file=tools/lint/rst/requirements.txt ./tools/lint/rst/requirements.in +# pip-compile --generate-hashes --output-file=tools/lint/rst/requirements.txt ./tools/lint/rst/requirements.in # alabaster==0.7.13 \ --hash=sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3 \ @@ -24,9 +24,9 @@ charset-normalizer==2.0.12 \ # via # -r ./tools/lint/rst/requirements.in # requests -docutils==0.17.1 \ - --hash=sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125 \ - --hash=sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61 +docutils==0.18.1 \ + --hash=sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c \ + --hash=sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06 # via # -r ./tools/lint/rst/requirements.in # rstcheck @@ -168,13 +168,13 @@ snowballstemmer==2.2.0 \ # via # -r ./tools/lint/rst/requirements.in # sphinx -sphinx==5.3.0 \ - --hash=sha256:060ca5c9f7ba57a08a1219e547b269fadf125ae25b06b9fa7f66768efb652d6d \ - --hash=sha256:51026de0a9ff9fc13c05d74913ad66047e104f56a129ff73e174eb5c3ee794b5 +sphinx==7.1.2 \ + --hash=sha256:780f4d32f1d7d1126576e0e5ecc19dc32ab76cd24e950228dcf7b1f6d3d9e22f \ + --hash=sha256:d170a81825b2fcacb6dfd5a0d7f578a053e45d3f2b153fecc948c37344eb4cbe # via -r ./tools/lint/rst/requirements.in -sphinxcontrib-applehelp==1.0.2 \ - --hash=sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a \ - --hash=sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58 +sphinxcontrib-applehelp==1.0.4 \ + --hash=sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228 \ + --hash=sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e # via # -r ./tools/lint/rst/requirements.in # sphinx @@ -182,9 +182,9 @@ sphinxcontrib-devhelp==1.0.2 \ --hash=sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e \ --hash=sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4 # via sphinx -sphinxcontrib-htmlhelp==2.0.0 \ - --hash=sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07 \ - --hash=sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2 +sphinxcontrib-htmlhelp==2.0.1 \ + --hash=sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff \ + --hash=sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903 # via # -r ./tools/lint/rst/requirements.in # sphinx @@ -192,9 +192,9 @@ sphinxcontrib-jsmath==1.0.1 \ --hash=sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 \ --hash=sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8 # via sphinx -sphinxcontrib-mermaid==0.8.1 \ - --hash=sha256:15491c24ec78cf1626b1e79e797a9ce87cb7959cf38f955eb72dd5512aeb6ce9 \ - --hash=sha256:fa3e5325d4ba395336e6137d113f55026b1a03ccd115dc54113d1d871a580466 +sphinxcontrib-mermaid==0.9.2 \ + --hash=sha256:252ef13dd23164b28f16d8b0205cf184b9d8e2b714a302274d9f59eb708e77af \ + --hash=sha256:6795a72037ca55e65663d2a2c1a043d636dc3d30d418e56dd6087d1459d98a5d # via -r ./tools/lint/rst/requirements.in sphinxcontrib-qthelp==1.0.3 \ --hash=sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72 \ @@ -204,10 +204,6 @@ sphinxcontrib-serializinghtml==1.1.5 \ --hash=sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd \ --hash=sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952 # via sphinx -typing-extensions==4.7.1 \ - --hash=sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36 \ - --hash=sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2 - # via importlib-metadata urllib3==1.26.9 \ --hash=sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14 \ --hash=sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e diff --git a/tools/lint/shellcheck.yml b/tools/lint/shellcheck.yml index 0100e3d5cc..b97422ee80 100644 --- a/tools/lint/shellcheck.yml +++ b/tools/lint/shellcheck.yml @@ -4,6 +4,8 @@ shellcheck: include: - extensions/spellcheck/locales/en-US/hunspell/dictionary-sources/ - taskcluster/docker/ + - tools/update-verify/release/common + - tools/update-verify/release/updates exclude: [] # 1090: https://github.com/koalaman/shellcheck/wiki/SC1090 # 'Can't follow a non-constant source' diff --git a/tools/lint/trojan-source.yml b/tools/lint/trojan-source.yml index 611ab660f5..a273626b58 100644 --- a/tools/lint/trojan-source.yml +++ b/tools/lint/trojan-source.yml @@ -14,6 +14,7 @@ trojan-source: - third_party/python/arrow/arrow/locales.py - third_party/rust/chardetng/src/data.rs - third_party/rust/clap_builder/src/output/textwrap/core.rs + - third_party/rust/textwrap/src/core.rs - third_party/rust/icu_provider/src/hello_world.rs - third_party/rust/uniffi-example-rondpoint/tests/bindings/test_rondpoint.py - third_party/rust/error-chain/tests/tests.rs diff --git a/tools/moztreedocs/__init__.py b/tools/moztreedocs/__init__.py index 7b8aed6059..45c0674db3 100644 --- a/tools/moztreedocs/__init__.py +++ b/tools/moztreedocs/__init__.py @@ -125,7 +125,7 @@ class _SphinxManager(object): args.append(full) args.extend(excludes) - sphinx.ext.apidoc.main(argv=args) + sphinx.ext.apidoc.main(args) def _synchronize_docs(self, app): m = InstallManifest() diff --git a/tools/profiler/core/MicroGeckoProfiler.cpp b/tools/profiler/core/MicroGeckoProfiler.cpp index bedb755742..6c384aeb41 100644 --- a/tools/profiler/core/MicroGeckoProfiler.cpp +++ b/tools/profiler/core/MicroGeckoProfiler.cpp @@ -133,10 +133,10 @@ struct ProfileBufferEntryReader::Deserializer<TraceOption> { } // namespace mozilla #endif // MOZ_GECKO_PROFILER -void uprofiler_simple_event_marker(const char* name, char phase, int num_args, - const char** arg_names, - const unsigned char* arg_types, - const unsigned long long* arg_values) { +void uprofiler_simple_event_marker_internal( + const char* name, char phase, int num_args, const char** arg_names, + const unsigned char* arg_types, const unsigned long long* arg_values, + bool full_stack) { #ifdef MOZ_GECKO_PROFILER if (!profiler_thread_is_being_profiled_for_markers()) { return; @@ -196,8 +196,27 @@ void uprofiler_simple_event_marker(const char* name, char phase, int num_args, break; } } - profiler_add_marker(ProfilerString8View::WrapNullTerminatedString(name), - geckoprofiler::category::MEDIA_RT, {timing.extract()}, - TraceMarker{}, tuple); + profiler_add_marker( + ProfilerString8View::WrapNullTerminatedString(name), + geckoprofiler::category::MEDIA_RT, + {timing.extract(), + full_stack ? MarkerStack::Capture(StackCaptureOptions::Full) + : MarkerStack::Capture(StackCaptureOptions::NoStack)}, + TraceMarker{}, tuple); #endif // MOZ_GECKO_PROFILER } + +void uprofiler_simple_event_marker_with_stack( + const char* name, char phase, int num_args, const char** arg_names, + const unsigned char* arg_types, const unsigned long long* arg_values) { + uprofiler_simple_event_marker_internal(name, phase, num_args, arg_names, + arg_types, arg_values, true); +} + +void uprofiler_simple_event_marker(const char* name, char phase, int num_args, + const char** arg_names, + const unsigned char* arg_types, + const unsigned long long* arg_values) { + uprofiler_simple_event_marker_internal(name, phase, num_args, arg_names, + arg_types, arg_values, false); +} diff --git a/tools/profiler/core/PowerCounters-android.cpp b/tools/profiler/core/PowerCounters-android.cpp new file mode 100644 index 0000000000..5e784952b5 --- /dev/null +++ b/tools/profiler/core/PowerCounters-android.cpp @@ -0,0 +1,178 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "PowerCounters.h" +#include "nsXULAppAPI.h" // for XRE_IsParentProcess +#include <dlfcn.h> + +#define ALOG(args...) \ + __android_log_print(ANDROID_LOG_INFO, "GeckoProfiler", ##args) + +/* + * The following declarations come from the dlext.h header (not in the ndk). + * https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/include/android/dlext.h;drc=655e430b28d7404f763e7ebefe84fba5a387666d + */ +struct android_namespace_t; +typedef struct { + /** A bitmask of `ANDROID_DLEXT_` enum values. */ + uint64_t flags; + + /** Used by `ANDROID_DLEXT_RESERVED_ADDRESS` and + * `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`. */ + void* _Nullable reserved_addr; + /** Used by `ANDROID_DLEXT_RESERVED_ADDRESS` and + * `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`. */ + size_t reserved_size; + + /** Used by `ANDROID_DLEXT_WRITE_RELRO` and `ANDROID_DLEXT_USE_RELRO`. */ + int relro_fd; + + /** Used by `ANDROID_DLEXT_USE_LIBRARY_FD`. */ + int library_fd; + /** Used by `ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET` */ + off64_t library_fd_offset; + + /** Used by `ANDROID_DLEXT_USE_NAMESPACE`. */ + struct android_namespace_t* _Nullable library_namespace; +} android_dlextinfo; +enum { ANDROID_DLEXT_USE_NAMESPACE = 0x200 }; +extern "C" + __attribute__((visibility("default"))) void* _Nullable android_dlopen_ext( + const char* _Nullable __filename, int __flags, + const android_dlextinfo* _Nullable __info); + +// See also documentation at +// https://developer.android.com/studio/profile/power-profiler#power-rails +bool GetAvailableRails(RailDescriptor*, size_t* size_of_arr); + +class RailEnergy final : public BaseProfilerCount { + public: + explicit RailEnergy(RailEnergyData* data, const char* aRailName, + const char* aSubsystemName) + : BaseProfilerCount(aSubsystemName, nullptr, nullptr, "power", aRailName), + mDataPtr(data), + mLastTimestamp(0) {} + + ~RailEnergy() {} + + RailEnergy(const RailEnergy&) = delete; + RailEnergy& operator=(const RailEnergy&) = delete; + + CountSample Sample() override { + CountSample result = { + // RailEnergyData.energy is in microwatt-seconds (uWs) + // we need to return values in picowatt-hour. + .count = static_cast<int64_t>(mDataPtr->energy * 1e3 / 3.6), + .number = 0, + .isSampleNew = mDataPtr->timestamp != mLastTimestamp, + }; + mLastTimestamp = mDataPtr->timestamp; + return result; + } + + private: + RailEnergyData* mDataPtr; + uint64_t mLastTimestamp; +}; + +PowerCounters::PowerCounters() { + if (!XRE_IsParentProcess()) { + // Energy meters are global, so only sample them on the parent. + return; + } + + // A direct dlopen call on libperfetto_android_internal.so fails with a + // namespace error because libperfetto_android_internal.so is missing in + // /etc/public.libraries.txt + // Instead, use android_dlopen_ext with the "default" namespace. + void* libcHandle = dlopen("libc.so", RTLD_LAZY); + if (!libcHandle) { + ALOG("failed to dlopen libc: %s", dlerror()); + return; + } + + struct android_namespace_t* (*android_get_exported_namespace)(const char*) = + reinterpret_cast<struct android_namespace_t* (*)(const char*)>( + dlsym(libcHandle, "__loader_android_get_exported_namespace")); + if (!android_get_exported_namespace) { + ALOG("failed to get __loader_android_get_exported_namespace: %s", + dlerror()); + return; + } + + struct android_namespace_t* ns = android_get_exported_namespace("default"); + const android_dlextinfo dlextinfo = { + .flags = ANDROID_DLEXT_USE_NAMESPACE, + .library_namespace = ns, + }; + + mLibperfettoModule = android_dlopen_ext("libperfetto_android_internal.so", + RTLD_LOCAL | RTLD_LAZY, &dlextinfo); + MOZ_ASSERT(mLibperfettoModule); + if (!mLibperfettoModule) { + ALOG("failed to get libperfetto handle: %s", dlerror()); + return; + } + + decltype(&GetAvailableRails) getAvailableRails = + reinterpret_cast<decltype(&GetAvailableRails)>( + dlsym(mLibperfettoModule, "GetAvailableRails")); + if (!getAvailableRails) { + ALOG("failed to get GetAvailableRails pointer: %s", dlerror()); + return; + } + + constexpr size_t kMaxNumRails = 32; + if (!mRailDescriptors.resize(kMaxNumRails)) { + ALOG("failed to grow mRailDescriptors"); + return; + } + size_t numRails = mRailDescriptors.length(); + getAvailableRails(&mRailDescriptors[0], &numRails); + mRailDescriptors.shrinkTo(numRails); + ALOG("found %zu rails", numRails); + if (numRails == 0) { + // We will see 0 rails either if the device has no support for power + // profiling or if the SELinux policy blocks access (ie. on a non-rooted + // device). + return; + } + + if (!mRailEnergyData.resize(numRails)) { + ALOG("failed to grow mRailEnergyData"); + return; + } + for (size_t i = 0; i < numRails; ++i) { + RailDescriptor& rail = mRailDescriptors[i]; + ALOG("rail %zu, name: %s, subsystem: %s", i, rail.rail_name, + rail.subsys_name); + RailEnergy* railEnergy = + new RailEnergy(&mRailEnergyData[i], rail.rail_name, rail.subsys_name); + if (!mCounters.emplaceBack(railEnergy)) { + delete railEnergy; + } + } + + mGetRailEnergyData = reinterpret_cast<decltype(&GetRailEnergyData)>( + dlsym(mLibperfettoModule, "GetRailEnergyData")); + if (!mGetRailEnergyData) { + ALOG("failed to get GetRailEnergyData pointer"); + return; + } +} +PowerCounters::~PowerCounters() { + if (mLibperfettoModule) { + dlclose(mLibperfettoModule); + } +} +void PowerCounters::Sample() { + // Energy meters are global, so only sample them on the parent. + // Also return early if we failed to access the GetRailEnergyData symbol. + if (!XRE_IsParentProcess() || !mGetRailEnergyData) { + return; + } + + size_t length = mRailEnergyData.length(); + mGetRailEnergyData(&mRailEnergyData[0], &length); +} diff --git a/tools/profiler/core/PowerCounters-linux.cpp b/tools/profiler/core/PowerCounters-linux.cpp index 006cea4867..a28171a6e2 100644 --- a/tools/profiler/core/PowerCounters-linux.cpp +++ b/tools/profiler/core/PowerCounters-linux.cpp @@ -276,12 +276,3 @@ PowerCounters::PowerCounters() { } } } - -PowerCounters::~PowerCounters() { - for (auto* raplEvent : mCounters) { - delete raplEvent; - } - mCounters.clear(); -} - -void PowerCounters::Sample() {} diff --git a/tools/profiler/core/PowerCounters-mac-amd64.cpp b/tools/profiler/core/PowerCounters-mac-amd64.cpp index 540cee155d..c5a82694cd 100644 --- a/tools/profiler/core/PowerCounters-mac-amd64.cpp +++ b/tools/profiler/core/PowerCounters-mac-amd64.cpp @@ -350,13 +350,7 @@ class RAPL { } } - ~RAPL() { - free(mPkes); - delete mPkg; - delete mCores; - delete mGpu; - delete mRam; - } + ~RAPL() { free(mPkes); } void Sample() { constexpr uint64_t kSupportedVersion = 1; @@ -403,14 +397,14 @@ class RAPL { PowerCounters::PowerCounters() { // RAPL values are global, so only sample them on the parent. - mRapl = XRE_IsParentProcess() ? new RAPL(mCounters) : nullptr; + if (XRE_IsParentProcess()) { + mRapl = mozilla::MakeUnique<RAPL>(mCounters); + } } -PowerCounters::~PowerCounters() { - mCounters.clear(); - delete mRapl; - mRapl = nullptr; -} +// This default destructor can not be defined in the header file as it depends +// on the full definition of RAPL which lives in this file. +PowerCounters::~PowerCounters() {} void PowerCounters::Sample() { if (mRapl) { diff --git a/tools/profiler/core/PowerCounters-mac-arm64.cpp b/tools/profiler/core/PowerCounters-mac-arm64.cpp index 3a84a479ef..76fceeca8d 100644 --- a/tools/profiler/core/PowerCounters-mac-arm64.cpp +++ b/tools/profiler/core/PowerCounters-mac-arm64.cpp @@ -36,12 +36,4 @@ class ProcessPower final : public BaseProfilerCount { } }; -PowerCounters::PowerCounters() : mProcessPower(new ProcessPower()) { - if (mProcessPower) { - (void)mCounters.append(mProcessPower.get()); - } -} - -PowerCounters::~PowerCounters() { mCounters.clear(); } - -void PowerCounters::Sample() {} +PowerCounters::PowerCounters() { (void)mCounters.append(new ProcessPower()); } diff --git a/tools/profiler/core/PowerCounters-win.cpp b/tools/profiler/core/PowerCounters-win.cpp index 6e8f492d6d..535a553867 100644 --- a/tools/profiler/core/PowerCounters-win.cpp +++ b/tools/profiler/core/PowerCounters-win.cpp @@ -212,13 +212,13 @@ class PowerMeterDevice { void AppendCountersTo(PowerCounters::CountVector& aCounters) { if (aCounters.reserve(aCounters.length() + mChannels.length())) { for (auto& channel : mChannels) { - aCounters.infallibleAppend(channel.get()); + aCounters.infallibleAppend(channel); } } } private: - Vector<UniquePtr<PowerMeterChannel>, 4> mChannels; + Vector<PowerMeterChannel*, 4> mChannels; HANDLE mHandle = INVALID_HANDLE_VALUE; UniquePtr<EMI_CHANNEL_MEASUREMENT_DATA[]> mDataBuffer; }; @@ -301,7 +301,9 @@ PowerCounters::PowerCounters() { } } -PowerCounters::~PowerCounters() { mCounters.clear(); } +// This default destructor can not be defined in the header file as it depends +// on the full definition of PowerMeterDevice which lives in this file. +PowerCounters::~PowerCounters() {} void PowerCounters::Sample() { for (auto& device : mPowerMeterDevices) { diff --git a/tools/profiler/core/PowerCounters.h b/tools/profiler/core/PowerCounters.h index 2fd8d5892c..df511e87ec 100644 --- a/tools/profiler/core/PowerCounters.h +++ b/tools/profiler/core/PowerCounters.h @@ -19,20 +19,57 @@ class ProcessPower; #if defined(GP_PLAT_amd64_darwin) class RAPL; #endif +#if defined(GP_PLAT_arm64_android) + +/* + * These declarations come from: + * https://cs.android.com/android/platform/superproject/main/+/main:external/perfetto/src/android_internal/power_stats.h;l=34-52;drc=1777bdef274bcfbccd4e6f8b6d00a1bac48a8645 + */ + +struct RailDescriptor { + // Index corresponding to the rail + uint32_t index; + // Name of the rail + char rail_name[64]; + // Name of the subsystem to which this rail belongs + char subsys_name[64]; + // Hardware sampling rate + uint32_t sampling_rate; +}; + +struct RailEnergyData { + // Index corresponding to RailDescriptor.index + uint32_t index; + // Time since device boot(CLOCK_BOOTTIME) in milli-seconds + uint64_t timestamp; + // Accumulated energy since device boot in microwatt-seconds (uWs) + uint64_t energy; +}; +bool GetRailEnergyData(RailEnergyData*, size_t* size_of_arr); +#endif class PowerCounters { public: -#if defined(_MSC_VER) || defined(GP_OS_darwin) || defined(GP_PLAT_amd64_linux) +#if defined(_MSC_VER) || defined(GP_OS_darwin) || \ + defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_arm64_android) explicit PowerCounters(); +#else + explicit PowerCounters(){}; +#endif +#if defined(_MSC_VER) || defined(GP_PLAT_amd64_darwin) || \ + defined(GP_PLAT_arm64_android) ~PowerCounters(); +#else + ~PowerCounters() = default; +#endif +#if defined(_MSC_VER) || defined(GP_PLAT_amd64_darwin) || \ + defined(GP_PLAT_arm64_android) void Sample(); #else - explicit PowerCounters(){}; - ~PowerCounters(){}; void Sample(){}; #endif - using CountVector = mozilla::Vector<BaseProfilerCount*, 4>; + using CountVector = mozilla::Vector<mozilla::UniquePtr<BaseProfilerCount>, 4>; const CountVector& GetCounters() { return mCounters; } private: @@ -41,11 +78,14 @@ class PowerCounters { #if defined(_MSC_VER) mozilla::Vector<mozilla::UniquePtr<PowerMeterDevice>> mPowerMeterDevices; #endif -#if defined(GP_PLAT_arm64_darwin) - mozilla::UniquePtr<ProcessPower> mProcessPower; -#endif #if defined(GP_PLAT_amd64_darwin) - RAPL* mRapl; + mozilla::UniquePtr<RAPL> mRapl; +#endif +#if defined(GP_PLAT_arm64_android) + void* mLibperfettoModule = nullptr; + decltype(&GetRailEnergyData) mGetRailEnergyData = nullptr; + mozilla::Vector<RailDescriptor> mRailDescriptors; + mozilla::Vector<RailEnergyData> mRailEnergyData; #endif }; diff --git a/tools/profiler/core/platform-linux-android.cpp b/tools/profiler/core/platform-linux-android.cpp index 11af93456c..8e93ca4e91 100644 --- a/tools/profiler/core/platform-linux-android.cpp +++ b/tools/profiler/core/platform-linux-android.cpp @@ -551,7 +551,11 @@ SamplerThread::SamplerThread(PSLockRef aLock, uint32_t aActivityGeneration, } SamplerThread::~SamplerThread() { - pthread_join(mThread, nullptr); + if (pthread_equal(mThread, pthread_self())) { + pthread_detach(mThread); + } else { + pthread_join(mThread, nullptr); + } // Just in the unlikely case some callbacks were added between the end of the // thread and now. InvokePostSamplingCallbacks(std::move(mPostSamplingCallbackList), diff --git a/tools/profiler/core/platform-macos.cpp b/tools/profiler/core/platform-macos.cpp index 78f000c470..ad0b0699f3 100644 --- a/tools/profiler/core/platform-macos.cpp +++ b/tools/profiler/core/platform-macos.cpp @@ -256,7 +256,11 @@ SamplerThread::SamplerThread(PSLockRef aLock, uint32_t aActivityGeneration, } SamplerThread::~SamplerThread() { - pthread_join(mThread, nullptr); + if (pthread_equal(mThread, pthread_self())) { + pthread_detach(mThread); + } else { + pthread_join(mThread, nullptr); + } // Just in the unlikely case some callbacks were added between the end of the // thread and now. InvokePostSamplingCallbacks(std::move(mPostSamplingCallbackList), diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp index 8ce029402b..6b7e318f80 100644 --- a/tools/profiler/core/platform.cpp +++ b/tools/profiler/core/platform.cpp @@ -42,7 +42,12 @@ #include "ProfilerIOInterposeObserver.h" #include "ProfilerParent.h" #include "ProfilerRustBindings.h" +#include "mozilla/Assertions.h" +#include "mozilla/Maybe.h" #include "mozilla/MozPromise.h" +#include "nsCOMPtr.h" +#include "nsDebug.h" +#include "nsXPCOM.h" #include "shared-libraries.h" #include "VTuneProfiler.h" #include "ETWTools.h" @@ -95,6 +100,7 @@ #include "nsSystemInfo.h" #include "nsThreadUtils.h" #include "nsXULAppAPI.h" +#include "nsDirectoryServiceUtils.h" #include "Tracing.h" #include "prdtoa.h" #include "prtime.h" @@ -108,6 +114,18 @@ #include <string_view> #include <type_traits> +// The signals that we use to control the profiler conflict with the signals +// used to control the code coverage tool. Therefore, if coverage is enabled, we +// need to disable our own signal handling mechanisms. +#ifndef MOZ_CODE_COVERAGE +# ifdef XP_WIN +// TODO: Add support for windows "signal"-like behaviour. See Bug 1867328. +# else +# include <signal.h> +# include <unistd.h> +# endif +#endif + #if defined(GP_OS_android) # include "JavaExceptions.h" # include "mozilla/java/GeckoJavaSamplerNatives.h" @@ -234,6 +252,10 @@ ProfileChunkedBuffer& profiler_get_core_buffer() { mozilla::Atomic<int, mozilla::MemoryOrdering::Relaxed> gSkipSampling; +// Atomic flag to stop the profiler from within the sampling loop +mozilla::Atomic<bool, mozilla::MemoryOrdering::Relaxed> gStopAndDumpFromSignal( + false); + #if defined(GP_OS_android) class GeckoJavaSampler : public java::GeckoJavaSampler::Natives<GeckoJavaSampler> { @@ -647,6 +669,9 @@ class CorePS { PS_GET_AND_SET(const nsACString&, ProcessName) PS_GET_AND_SET(const nsACString&, ETLDplus1) +#if !defined(XP_WIN) + PS_GET_AND_SET(const Maybe<nsCOMPtr<nsIFile>>&, DownloadDirectory) +#endif static void SetBandwidthCounter(ProfilerBandwidthCounter* aBandwidthCounter) { MOZ_ASSERT(sInstance); @@ -695,6 +720,11 @@ class CorePS { // lock, so it is safe to have only one instance allocated for all of the // threads. JsFrameBuffer mJsFrames; + + // Cached download directory for when we need to dump profiles to disk. +#if !defined(XP_WIN) + Maybe<nsCOMPtr<nsIFile>> mDownloadDirectory; +#endif }; CorePS* CorePS::sInstance = nullptr; @@ -839,7 +869,7 @@ class ActivePS { if (ProfilerFeature::HasPower(aFeatures)) { mMaybePowerCounters = new PowerCounters(); for (const auto& powerCounter : mMaybePowerCounters->GetCounters()) { - locked_profiler_add_sampled_counter(aLock, powerCounter); + locked_profiler_add_sampled_counter(aLock, powerCounter.get()); } } @@ -935,7 +965,7 @@ class ActivePS { if (sInstance->mMaybePowerCounters) { for (const auto& powerCounter : sInstance->mMaybePowerCounters->GetCounters()) { - locked_profiler_remove_sampled_counter(aLock, powerCounter); + locked_profiler_remove_sampled_counter(aLock, powerCounter.get()); } delete sInstance->mMaybePowerCounters; sInstance->mMaybePowerCounters = nullptr; @@ -1918,11 +1948,10 @@ static uint32_t ExtractJsFrames( // Merges the profiling stack, native stack, and JS stack, outputting the // details to aCollector. static void MergeStacks( - uint32_t aFeatures, bool aIsSynchronous, + bool aIsSynchronous, const ThreadRegistration::UnlockedReaderAndAtomicRWOnThread& aThreadData, - const Registers& aRegs, const NativeStack& aNativeStack, - ProfilerStackCollector& aCollector, JsFrame* aJsFrames, - uint32_t aJsFramesCount) { + const NativeStack& aNativeStack, ProfilerStackCollector& aCollector, + JsFrame* aJsFrames, uint32_t aJsFramesCount) { // WARNING: this function runs within the profiler's "critical section". // WARNING: this function might be called while the profiler is inactive, and // cannot rely on ActivePS. @@ -2571,13 +2600,13 @@ static inline void DoSharedSample( DoNativeBacktrace(aThreadData, aRegs, nativeStack, stackWalkControlIfSupported); - MergeStacks(aFeatures, aIsSynchronous, aThreadData, aRegs, nativeStack, - collector, aJsFrames, jsFramesCount); + MergeStacks(aIsSynchronous, aThreadData, nativeStack, collector, aJsFrames, + jsFramesCount); } else #endif { - MergeStacks(aFeatures, aIsSynchronous, aThreadData, aRegs, nativeStack, - collector, aJsFrames, jsFramesCount); + MergeStacks(aIsSynchronous, aThreadData, nativeStack, collector, aJsFrames, + jsFramesCount); // We can't walk the whole native stack, but we can record the top frame. if (aCaptureOptions == StackCaptureOptions::Full) { @@ -2933,16 +2962,6 @@ static void StreamMetaJSCustomObject( ActivePS::WriteActiveConfiguration(aLock, aWriter, MakeStringSpan("configuration")); - if (!NS_IsMainThread()) { - // Leave the rest of the properties out if we're not on the main thread. - // At the moment, the only case in which this function is called on a - // background thread is if we're in a content process and are going to - // send this profile to the parent process. In that case, the parent - // process profile's "meta" object already has the rest of the properties, - // and the parent process profile is dumped on that process's main thread. - return; - } - aWriter.DoubleProperty("interval", ActivePS::Interval(aLock)); aWriter.IntProperty("stackwalk", ActivePS::FeatureStackWalk(aLock)); @@ -3019,6 +3038,16 @@ static void StreamMetaJSCustomObject( } aWriter.EndObject(); + if (!NS_IsMainThread()) { + // Leave the rest of the properties out if we're not on the main thread. + // At the moment, the only case in which this function is called on a + // background thread is if we're in a content process and are going to + // send this profile to the parent process. In that case, the parent + // process profile's "meta" object already has the rest of the properties, + // and the parent process profile is dumped on that process's main thread. + return; + } + // We should avoid collecting extension metadata for profiler when there is no // observer service, since a ExtensionPolicyService could not be created then. if (nsCOMPtr<nsIObserverService> os = services::GetObserverService()) { @@ -4077,6 +4106,10 @@ static SamplerThread* NewSamplerThread(PSLockRef aLock, uint32_t aGeneration, return new SamplerThread(aLock, aGeneration, aInterval, aFeatures); } +// Forward declare the function to call when we need to dump + stop from within +// the sampler thread +void profiler_dump_and_stop(); + // This function is the sampler thread. This implementation is used for all // targets. void SamplerThread::Run() { @@ -4732,6 +4765,27 @@ void SamplerThread::Run() { scheduledSampleStart = beforeSleep + sampleInterval; SleepMicro(static_cast<uint32_t>(sampleInterval.ToMicroseconds())); } + + // Check to see if the hard-reset flag has been set to stop the profiler. + // This should only be used on the worst occasions when we need to stop the + // profiler from within the sampling thread (e.g. if the main thread is + // stuck) We need to do this here as it is outside of the scope of the lock. + // Otherwise we'll encounter a race condition where `profiler_stop` tries to + // get the lock that we already hold. We also need to wait until after we + // have carried out post sampling callbacks, as otherwise we may reach a + // situation where another part of the program is waiting for us to finish + // sampling, but we have ended early! + if (gStopAndDumpFromSignal) { + // Reset the flag in case we restart the profiler at a later point + gStopAndDumpFromSignal = false; + // dump the profile, and stop the profiler + profiler_dump_and_stop(); + // profiler_stop will try to destroy the active sampling thread. This will + // also destroy some data structures that are used further down this + // function, leading to invalid accesses. We therefore exit the function + // directly, rather than breaking from the loop. + return; + } } // End of `while` loop. We can only be here from a `break` inside the loop. @@ -4840,10 +4894,10 @@ void SamplerThread::SpyOnUnregisteredThreads() { /* aWindowInfo = */ nsTArray<WindowInfo>{}, /* aUtilityInfo = */ nsTArray<UtilityInfo>{}, /* aChild = */ 0 -#ifdef XP_MACOSX +#ifdef XP_DARWIN , /* aChildTask = */ MACH_PORT_NULL -#endif // XP_MACOSX +#endif // XP_DARWIN ); const ProcInfoPromise::ResolveOrRejectValue procInfoOrError = @@ -5240,6 +5294,104 @@ static const char* get_size_suffix(const char* str) { return ptr; } +#if !defined(XP_WIN) && !defined(MOZ_CODE_COVERAGE) +static void profiler_stop_signal_handler(int signal, siginfo_t* info, + void* context) { + // We cannot really do any logging here, as this is a signal handler. + // Signal handlers are limited in what functions they can call, for more + // details see: https://man7.org/linux/man-pages/man7/signal-safety.7.html + // Writing to a file is allowed, but as signal handlers are also limited in + // how long they can run, we instead set an atomic variable to true to trigger + // the sampling thread to stop and dump the data in the profiler. + gStopAndDumpFromSignal = true; +} +#endif + +// This may fail if we have previously had an issue finding the download +// directory, or if the directory has moved since we cached the path. +// This is non-ideal, but captured by Bug 1885000 +Maybe<nsAutoCString> profiler_find_dump_path() { +// Note, this is currently a posix-only implementation, as we currently have +// issues with fetching the download directory on Windows. See Bug 1890154. +#if defined(XP_WIN) + return Nothing(); +#else + Maybe<nsCOMPtr<nsIFile>> directory = Nothing(); + nsAutoCString path; + + { + // Acquire the lock so that we can get things from CorePS + PSAutoLock lock; + Maybe<nsCOMPtr<nsIFile>> downloadDir = Nothing(); + downloadDir = CorePS::DownloadDirectory(lock); + + // This needs to be done within the context of the lock, as otherwise + // another thread might modify CorePS::mDownloadDirectory while we're + // cloning the pointer. + if (downloadDir) { + nsCOMPtr<nsIFile> d; + downloadDir.value()->Clone(getter_AddRefs(d)); + directory = Some(d); + } else { + return Nothing(); + } + } + + // Now, we can check to see if we have a directory, and use it to construct + // the output file + if (directory) { + // Set up the name of our profile file + path.AppendPrintf("profile_%i_%i.json", XRE_GetProcessType(), getpid()); + + // Append it to the directory we found + nsresult rv = directory.value()->AppendNative(path); + if (NS_FAILED(rv)) { + LOG("Failed to append path to profile file"); + return Nothing(); + } + + // Write the result *back* to the original path + rv = directory.value()->GetNativePath(path); + if (NS_FAILED(rv)) { + LOG("Failed to get native path for temp path"); + return Nothing(); + } + + return Some(path); + } + + return Nothing(); +#endif +} + +void profiler_dump_and_stop() { + // pause the profiler until we are done dumping + profiler_pause(); + + // Try to save the profile to a file + if (auto path = profiler_find_dump_path()) { + profiler_save_profile_to_file(path.value().get()); + } else { + LOG("Failed to dump profile to disk"); + } + + // Stop the profiler + profiler_stop(); +} + +void profiler_init_signal_handlers() { +#if !defined(XP_WIN) && !defined(MOZ_CODE_COVERAGE) + // Set a handler to stop the profiler + struct sigaction prof_stop_sa {}; + memset(&prof_stop_sa, 0, sizeof(struct sigaction)); + prof_stop_sa.sa_sigaction = profiler_stop_signal_handler; + prof_stop_sa.sa_flags = SA_RESTART | SA_SIGINFO; + sigemptyset(&prof_stop_sa.sa_mask); + DebugOnly<int> rstop = sigaction(SIGUSR2, &prof_stop_sa, nullptr); + MOZ_ASSERT(rstop == 0, "Failed to install Profiler SIGUSR2 handler"); +#endif +} + void profiler_init(void* aStackTop) { LOG("profiler_init"); @@ -5289,10 +5441,12 @@ void profiler_init(void* aStackTop) { locked_register_thread(lock, offThreadRef); } } - // Platform-specific initialization. PlatformInit(lock); + // Initialise the signal handlers needed to start/stop the profiler + profiler_init_signal_handlers(); + #if defined(GP_OS_android) if (jni::IsAvailable()) { GeckoJavaSampler::Init(); @@ -6309,6 +6463,37 @@ bool profiler_is_paused() { return ActivePS::AppendPostSamplingCallback(lock, std::move(aCallback)); } +// See `ProfilerControl.h` for more details. +void profiler_lookup_download_directory() { +// This implementation is causing issues on Windows (see Bug 1890154) but as it +// only exists to support the posix signal handling (on non-windows platforms) +// we can remove it for now. +#if !defined(XP_WIN) + LOG("profiler_lookup_download_directory"); + + MOZ_ASSERT( + NS_IsMainThread(), + "We can only get access to the directory service from the main thread"); + + // Make sure the profiler is actually running~ + MOZ_RELEASE_ASSERT(CorePS::Exists()); + + // take the lock so that we can write to CorePS + PSAutoLock lock; + + nsCOMPtr<nsIFile> tDownloadDir; + nsresult rv = NS_GetSpecialDirectory(NS_OS_DEFAULT_DOWNLOAD_DIR, + getter_AddRefs(tDownloadDir)); + if (NS_FAILED(rv)) { + LOG("Failed to find download directory. Profiler signal handling will not " + "be able to save to disk. Error: %s", + GetStaticErrorName(rv)); + } else { + CorePS::SetDownloadDirectory(lock, Some(tDownloadDir)); + } +#endif +} + RefPtr<GenericPromise> profiler_pause() { LOG("profiler_pause"); @@ -7157,13 +7342,13 @@ static void profiler_suspend_and_sample_thread( # error "Invalid configuration" # endif - MergeStacks(aFeatures, !aLockIfAsynchronousSampling, aThreadData, aRegs, - nativeStack, aCollector, aJsFrames, jsFramesCount); + MergeStacks(!aLockIfAsynchronousSampling, aThreadData, nativeStack, + aCollector, aJsFrames, jsFramesCount); } else #endif { - MergeStacks(aFeatures, !aLockIfAsynchronousSampling, aThreadData, aRegs, - nativeStack, aCollector, aJsFrames, jsFramesCount); + MergeStacks(!aLockIfAsynchronousSampling, aThreadData, nativeStack, + aCollector, aJsFrames, jsFramesCount); aCollector.CollectNativeLeafAddr((void*)aRegs.mPC); } diff --git a/tools/profiler/moz.build b/tools/profiler/moz.build index ddb2ce5fff..4d2bf3628f 100644 --- a/tools/profiler/moz.build +++ b/tools/profiler/moz.build @@ -85,6 +85,10 @@ if CONFIG["MOZ_GECKO_PROFILER"]: UNIFIED_SOURCES += [ "core/PowerCounters-linux.cpp", ] + elif CONFIG["TARGET_CPU"] == "aarch64" and CONFIG["OS_TARGET"] == "Android": + SOURCES += [ + "core/PowerCounters-android.cpp", + ] if CONFIG["TARGET_CPU"] == "arm" and CONFIG["OS_TARGET"] != "FreeBSD": SOURCES += [ "core/EHABIStackWalk.cpp", diff --git a/tools/profiler/public/MicroGeckoProfiler.h b/tools/profiler/public/MicroGeckoProfiler.h index 7b735e1eec..c23142f07f 100644 --- a/tools/profiler/public/MicroGeckoProfiler.h +++ b/tools/profiler/public/MicroGeckoProfiler.h @@ -34,6 +34,10 @@ extern MOZ_EXPORT void uprofiler_unregister_thread(); extern MOZ_EXPORT void uprofiler_simple_event_marker( const char* name, char phase, int num_args, const char** arg_names, const unsigned char* arg_types, const unsigned long long* arg_values); + +extern MOZ_EXPORT void uprofiler_simple_event_marker_with_stack( + const char* name, char phase, int num_args, const char** arg_names, + const unsigned char* arg_types, const unsigned long long* arg_values); #ifdef __cplusplus } @@ -60,6 +64,10 @@ struct UprofilerFuncPtrs { const char** arg_names, const unsigned char* arg_types, const unsigned long long* arg_values); + void (*simple_event_marker_with_stack)(const char* name, char phase, + int num_args, const char** arg_names, + const unsigned char* arg_types, + const unsigned long long* arg_values); }; #pragma GCC diagnostic push @@ -77,6 +85,12 @@ static void simple_event_marker_noop(const char* name, char phase, int num_args, /* no-op */ } +static void simple_event_marker_with_stack_noop( + const char* name, char phase, int num_args, const char** arg_names, + const unsigned char* arg_types, const unsigned long long* arg_values) { + /* no-op */ +} + #pragma GCC diagnostic pop #if defined(_WIN32) @@ -88,7 +102,7 @@ static void simple_event_marker_noop(const char* name, char phase, int num_args, #if defined(_WIN32) # define UPROFILER_GET_SYM(handle, sym) GetProcAddress(handle, sym) #else -# define UPROFILER_GET_SYM(handle, sym) dlsym(handle, sym) +# define UPROFILER_GET_SYM(handle, sym) (typeof(sym)*)(dlsym(handle, #sym)) #endif #if defined(_WIN32) @@ -98,33 +112,30 @@ static void simple_event_marker_noop(const char* name, char phase, int num_args, fprintf(stderr, "%s error: %s\n", #func, dlerror()); #endif +#define FETCH(func) \ + uprofiler.func = UPROFILER_GET_SYM(handle, uprofiler_##func); \ + if (!uprofiler.func) { \ + UPROFILER_PRINT_ERROR(uprofiler_##func); \ + uprofiler.func = func##_noop; \ + } + +#define UPROFILER_VISIT() \ + FETCH(register_thread) \ + FETCH(unregister_thread) \ + FETCH(simple_event_marker) \ + FETCH(simple_event_marker_with_stack) + // Assumes that a variable of type UprofilerFuncPtrs, named uprofiler // is accessible in the scope -#define UPROFILER_GET_FUNCTIONS() \ - void* handle = UPROFILER_OPENLIB(); \ - if (!handle) { \ - UPROFILER_PRINT_ERROR(UPROFILER_OPENLIB); \ - uprofiler.register_thread = register_thread_noop; \ - uprofiler.unregister_thread = unregister_thread_noop; \ - uprofiler.simple_event_marker = simple_event_marker_noop; \ - } \ - uprofiler.register_thread = \ - UPROFILER_GET_SYM(handle, "uprofiler_register_thread"); \ - if (!uprofiler.register_thread) { \ - UPROFILER_PRINT_ERROR(uprofiler_unregister_thread); \ - uprofiler.register_thread = register_thread_noop; \ - } \ - uprofiler.unregister_thread = \ - UPROFILER_GET_SYM(handle, "uprofiler_unregister_thread"); \ - if (!uprofiler.unregister_thread) { \ - UPROFILER_PRINT_ERROR(uprofiler_unregister_thread); \ - uprofiler.unregister_thread = unregister_thread_noop; \ - } \ - uprofiler.simple_event_marker = \ - UPROFILER_GET_SYM(handle, "uprofiler_simple_event_marker"); \ - if (!uprofiler.simple_event_marker) { \ - UPROFILER_PRINT_ERROR(uprofiler_simple_event_marker); \ - uprofiler.simple_event_marker = simple_event_marker_noop; \ - } +#define UPROFILER_GET_FUNCTIONS() \ + void* handle = UPROFILER_OPENLIB(); \ + if (!handle) { \ + UPROFILER_PRINT_ERROR(UPROFILER_OPENLIB); \ + uprofiler.register_thread = register_thread_noop; \ + uprofiler.unregister_thread = unregister_thread_noop; \ + uprofiler.simple_event_marker = simple_event_marker_noop; \ + uprofiler.simple_event_marker_with_stack = simple_event_with_stack_noop; \ + } \ + UPROFILER_VISIT() #endif // MICRO_GECKO_PROFILER diff --git a/tools/profiler/public/ProfilerControl.h b/tools/profiler/public/ProfilerControl.h index 466d15eb69..ac145fac00 100644 --- a/tools/profiler/public/ProfilerControl.h +++ b/tools/profiler/public/ProfilerControl.h @@ -40,6 +40,8 @@ static inline void profiler_init(void* stackTop) {} static inline void profiler_shutdown( IsFastShutdown aIsFastShutdown = IsFastShutdown::No) {} +static inline void profiler_lookup_download_directory() {} + #else // !MOZ_GECKO_PROFILER # include "BaseProfiler.h" @@ -123,6 +125,18 @@ void profiler_ensure_started( const char** aFilters, uint32_t aFilterCount, uint64_t aActiveTabID, const mozilla::Maybe<double>& aDuration = mozilla::Nothing()); +// Tell the profiler to look up the download directory for writing profiles. +// With some features, such as signal control, we need to know the location of +// a directory where we can save profiles to disk. Because we start the +// profiler before we start the directory service, we can't access the +// download directory at profiler startup. Similarly, when we need to get the +// directory, we often can't, as we're running in non-main-thread contexts +// that don't have access to the directory service. This function gives us a +// third option, by giving us a hook to look for the download directory when +// the time is right. This might be triggered internally (e.g. when we start +// profiling), or externally, e.g. after the directory service is initialised. +void profiler_lookup_download_directory(); + //--------------------------------------------------------------------------- // Control the profiler //--------------------------------------------------------------------------- diff --git a/tools/profiler/tests/xpcshell/test_feature_posix_signals.js b/tools/profiler/tests/xpcshell/test_feature_posix_signals.js new file mode 100644 index 0000000000..28fbf890e8 --- /dev/null +++ b/tools/profiler/tests/xpcshell/test_feature_posix_signals.js @@ -0,0 +1,194 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +ChromeUtils.defineESModuleGetters(this, { + Downloads: "resource://gre/modules/Downloads.sys.mjs", + FileUtils: "resource://gre/modules/FileUtils.sys.mjs", + BrowserTestUtils: "resource://testing-common/BrowserTestUtils.sys.mjs", +}); + +const { ctypes } = ChromeUtils.importESModule( + "resource://gre/modules/ctypes.sys.mjs" +); + +// Derived from functionality in js/src/devtools/rootAnalysis/utility.js +function openLibrary(names) { + for (const name of names) { + try { + return ctypes.open(name); + } catch (e) {} + } + return undefined; +} + +// Derived heavily from equivalent sandbox testing code. +// For more details see: +// https://searchfox.org/mozilla-central/rev/1aaacaeb4fa3aca6837ecc157e43e947229ba8ce/security/sandbox/test/browser_content_sandbox_utils.js#89 +function raiseSignal(pid, sig) { + try { + const libc = openLibrary([ + "libc.so.6", + "libc.so", + "libc.dylib", + "libSystem.B.dylib", + ]); + if (!libc) { + info("Failed to open any libc shared object"); + return { ok: false }; + } + + // c.f. https://man7.org/linux/man-pages/man2/kill.2.html + // This choice of typing for `pid` is complex, and brittle, as it's + // platform dependent. Getting it wrong can result in incoreect + // generation/calling of the `kill` function. Unfortunately, as it's + // defined as `pid_t` in a header, we can't easily get access to it. + // For now, we just use an integer, and hope that the system int size + // aligns with the `pid_t` size. + const kill = libc.declare( + "kill", + ctypes.default_abi, + ctypes.int, // return value + ctypes.int32_t, // pid + ctypes.int // sig + ); + + let kres = kill(pid, sig); + if (kres != 0) { + info(`Kill returned a non-zero result ${kres}.`); + return { ok: false }; + } + + libc.close(); + } catch (e) { + info(`Exception ${e} thrown while trying to call kill`); + return { ok: false }; + } + + return { ok: true }; +} + +// We would like to use the following to wait for a stop signal to actually be +// handled: +// await Services.profiler.waitOnePeriodicSampling(); +// However, as we are trying to shut down the profiler using the sampler +// thread, this can cause complications between the callback waiting for the +// sampling to be over, and the sampler thread actually finishing. +// Instead, we use the BrowserTestUtils.waitForCondition to wait until the +// profiler is no longer active. +async function waitUntilProfilerStopped(interval = 1000, maxTries = 100) { + await BrowserTestUtils.waitForCondition( + () => !Services.profiler.IsActive(), + "the profiler should be inactive", + interval, + maxTries + ); +} + +async function cleanupAfterTest() { + // We need to cleanup written profiles after a test + // Get the system downloads directory, and use it to build a profile file + let profile = FileUtils.File(await Downloads.getSystemDownloadsDirectory()); + + // Get the process ID + let pid = Services.appinfo.processID; + + // write it to the profile file name + profile.append(`profile_0_${pid}.json`); + + // remove the file! + await IOUtils.remove(profile.path, { ignoreAbsent: true }); + + // Make sure the profiler is fully stopped, even if the test failed + await Services.profiler.StopProfiler(); +} + +// Hardcode the constants SIGUSR1 and SIGUSR2. +// This is an absolutely terrible idea, as they are implementation defined! +// However, it turns out that for 99% of the platforms we care about, and for +// 99.999% of the platforms we test, these constants are, well, constant. +// Additionally, these constants are only for _testing_ the signal handling +// feature - the actual feature relies on platform specific definitions. This +// may cause a mismatch if we test on on, say, a gnu hurd kernel, or on a +// linux kernel running on sparc, but the feature will not break - only +// the testing. +// const SIGUSR1 = Services.appinfo.OS === "Darwin" ? 30 : 10; +const SIGUSR2 = Services.appinfo.OS === "Darwin" ? 31 : 12; + +add_task(async () => { + info("Test that stopping the profiler with a posix signal works."); + registerCleanupFunction(cleanupAfterTest); + + Assert.ok( + !Services.profiler.IsActive(), + "The profiler should not begin the test active." + ); + + const entries = 100; + const interval = 1; + const threads = []; + const features = []; + + // Start the profiler, and ensure that it's active + await Services.profiler.StartProfiler(entries, interval, threads, features); + Assert.ok(Services.profiler.IsActive(), "The profiler should now be active."); + + // Get the process ID + let pid = Services.appinfo.processID; + + // Try and stop the profiler using a signal. + let result = raiseSignal(pid, SIGUSR2); + Assert.ok(result, "Raising a SIGUSR2 signal should succeed."); + + await waitUntilProfilerStopped(); + + do_test_finished(); +}); + +add_task(async () => { + info( + "Test that stopping the profiler with a posix signal writes a profile file to the system download directory." + ); + registerCleanupFunction(cleanupAfterTest); + + Assert.ok( + !Services.profiler.IsActive(), + "The profiler should not begin the test active." + ); + + const entries = 100; + const interval = 1; + const threads = []; + const features = []; + + // Get the system downloads directory, and use it to build a profile file + let profile = FileUtils.File(await Downloads.getSystemDownloadsDirectory()); + + // Get the process ID + let pid = Services.appinfo.processID; + + // use the pid to construct the name of the profile, and resulting file + profile.append(`profile_0_${pid}.json`); + + // Start the profiler, and ensure that it's active + await Services.profiler.StartProfiler(entries, interval, threads, features); + Assert.ok(Services.profiler.IsActive(), "The profiler should now be active."); + + // Try and stop the profiler using a signal. + let result = raiseSignal(pid, SIGUSR2); + Assert.ok(result, "Raising a SIGUSR2 signal should succeed."); + + // Wait for the file to exist + await BrowserTestUtils.waitForCondition( + async () => await IOUtils.exists(profile.path), + "Waiting for a profile file to be written to disk." + ); + + await waitUntilProfilerStopped(); + Assert.ok( + !Services.profiler.IsActive(), + "The profiler should now be inactive." + ); + + do_test_finished(); +}); diff --git a/tools/profiler/tests/xpcshell/xpcshell.toml b/tools/profiler/tests/xpcshell/xpcshell.toml index 5c094899a4..2cde39d09f 100644 --- a/tools/profiler/tests/xpcshell/xpcshell.toml +++ b/tools/profiler/tests/xpcshell/xpcshell.toml @@ -24,9 +24,6 @@ skip-if = ["!debug"] ["test_feature_fileioall.js"] skip-if = ["release_or_beta"] -# The sanitizer checks appears to overwrite our own memory hooks in xpcshell tests, -# and no allocation markers are gathered. Skip this test in that configuration. - ["test_feature_java.js"] skip-if = ["os != 'android'"] @@ -50,6 +47,12 @@ skip-if = [ "socketprocess_networking", ] +["test_feature_posix_signals.js"] +skip-if = [ + "ccov", + "os == 'win'", +] + # Native stackwalking is somewhat unreliable depending on the platform. # # We don't have frame pointers on macOS release and beta, so stack walking does not @@ -61,6 +64,9 @@ skip-if = [ # For sanitizer builds, there were many intermittents, and we're not getting much # additional coverage there, so it's better to be a bit more reliable. +# The sanitizer checks appears to overwrite our own memory hooks in xpcshell tests, +# and no allocation markers are gathered. Skip this test in that configuration. + ["test_feature_stackwalking.js"] skip-if = [ "os == 'mac' && release_or_beta", diff --git a/tools/rewriting/Generated.txt b/tools/rewriting/Generated.txt index b921cf71d0..f8aa8f24c6 100644 --- a/tools/rewriting/Generated.txt +++ b/tools/rewriting/Generated.txt @@ -1,5 +1,4 @@ .gradle/ -build/vs/vs2019.yaml build/vs/vs2022.yaml browser/components/aboutwelcome/content/aboutwelcome.bundle.js browser/components/aboutwelcome/logs/ @@ -9,6 +8,8 @@ browser/components/asrouter/content/asrouter-admin.bundle.js browser/components/asrouter/logs/ browser/components/asrouter/content-src/schemas/BackgroundTaskMessagingExperiment.schema.json browser/components/asrouter/content-src/schemas/MessagingExperiment.schema.json +browser/components/asrouter/tests/InflightAssetsMessageProvider.sys.mjs +browser/components/asrouter/tests/NimbusRolloutMessageProvider.sys.mjs browser/components/newtab/logs/ browser/components/newtab/node_modules/ browser/components/storybook/storybook-static/ @@ -24,6 +25,13 @@ intl/unicharutil/util/nsSpecialCasingData.cpp intl/unicharutil/util/nsUnicodePropertyData.cpp mobile/locales/l10n-changesets.json mobile/locales/l10n-onchange-changesets.json +mobile/android/**/.build-cache +mobile/android/**/.gradle +mobile/android/**/build +mobile/android/**/bin +mobile/android/**/generated +mobile/android/**\/local.properties +mobile/android/**\/manifest.json node_modules/ python/mozperftest/mozperftest/tests/data/ security/manager/tools/KnownRootHashes.json diff --git a/tools/tryselect/push.py b/tools/tryselect/push.py index cf5e646c8c..a4811682bc 100644 --- a/tools/tryselect/push.py +++ b/tools/tryselect/push.py @@ -121,7 +121,7 @@ def task_labels_from_try_config(try_task_config): if try_task_config["version"] == 2: parameters = try_task_config.get("parameters", {}) if "try_task_config" in parameters: - return parameters["try_task_config"]["tasks"] + return parameters["try_task_config"].get("tasks") else: return None elif try_task_config["version"] == 1: @@ -183,6 +183,21 @@ def display_push_estimates(try_task_config): ) +# improves on `" ".join(sys.argv[:])` by requoting argv items containing spaces or single quotes +def get_sys_argv(injected_argv=None): + argv_to_use = injected_argv or sys.argv[:] + + formatted_argv = [] + for item in argv_to_use: + if " " in item or "'" in item: + formatted_item = f'"{item}"' + else: + formatted_item = item + formatted_argv.append(formatted_item) + + return " ".join(formatted_argv) + + def push_to_try( method, msg, @@ -206,9 +221,12 @@ def push_to_try( # Format the commit message closed_tree_string = " ON A CLOSED TREE" if closed_tree else "" - commit_message = "{}{}\n\nPushed via `mach try {}`".format( + the_cmdline = get_sys_argv() + full_commandline_entry = f"mach try command: `{the_cmdline}`" + commit_message = "{}{}\n\n{}\n\nPushed via `mach try {}`".format( msg, closed_tree_string, + full_commandline_entry, method, ) diff --git a/tools/tryselect/selectors/chooser/app.py b/tools/tryselect/selectors/chooser/app.py index 99d63cd37f..2e9e2d5ab0 100644 --- a/tools/tryselect/selectors/chooser/app.py +++ b/tools/tryselect/selectors/chooser/app.py @@ -107,6 +107,23 @@ class Test(Section): @register_section +class Android(Section): + name = "android" + kind = ( + "build-apk,build-bundle,build-components,test-apk,test-components,ui-test-apk" + ) + title = "Firefox for Android" + attrs = ["kind", "build-type", "component", "shipping-product"] + + def labelfn(self, task): + if task["kind"] in ("build-components", "test-components"): + label = "{}-{}".format(task["kind"], task.get("component")) + else: + label = "{}-{}".format(task["kind"], task.get("build-type")) + return label + + +@register_section class Perf(Section): name = "perf" kind = "test" diff --git a/tools/tryselect/selectors/chooser/static/filter.js b/tools/tryselect/selectors/chooser/static/filter.js index 2d8731e61f..683ced8953 100644 --- a/tools/tryselect/selectors/chooser/static/filter.js +++ b/tools/tryselect/selectors/chooser/static/filter.js @@ -10,7 +10,7 @@ const pluralize = (count, noun, suffix = "s") => var selected = []; var updateLabels = () => { - $(".tab-pane.active > .filter-label").each(function (index) { + $(".tab-pane.active > .filter-label").each(function () { let box = $("#" + this.htmlFor)[0]; let method = box.checked ? "add" : "remove"; $(this)[method + "Class"]("is-checked"); @@ -21,7 +21,7 @@ var apply = () => { let filters = {}; let kinds = []; - $(".filter:checked").each(function (index) { + $(".filter:checked").each(function () { for (let kind of this.name.split(",")) { if (!kinds.includes(kind)) { kinds.push(kind); @@ -76,7 +76,7 @@ var apply = () => { var applyChunks = () => { // For tasks that have a chunk filter applied, we handle that here. let filters = {}; - $(".filter:text").each(function (index) { + $(".filter:text").each(function () { let value = $(this).val(); if (value === "") { return; diff --git a/tools/tryselect/selectors/chooser/static/select.js b/tools/tryselect/selectors/chooser/static/select.js index 8a315c0a52..e90744a09a 100644 --- a/tools/tryselect/selectors/chooser/static/select.js +++ b/tools/tryselect/selectors/chooser/static/select.js @@ -39,7 +39,7 @@ labels.click(function (e) { function selectAll(btn) { let checked = !!btn.value; - $("div.active label.filter-label").each(function (index) { + $("div.active label.filter-label").each(function () { $(this).find("input:checkbox")[0].checked = checked; }); apply(); diff --git a/tools/tryselect/selectors/perf.py b/tools/tryselect/selectors/perf.py index 261905d5a3..e8a6e6f9cc 100644 --- a/tools/tryselect/selectors/perf.py +++ b/tools/tryselect/selectors/perf.py @@ -127,19 +127,6 @@ class PerfParser(CompareParser): }, ], [ - # Bug 1866047 - Remove once monorepo changes are complete - ["--fenix"], - { - "action": "store_true", - "default": False, - "help": "Include Fenix in tasks to run (disabled by default). Must " - "be used in conjunction with --android. Fenix isn't built on mozilla-central " - "so we pull the APK being tested from the firefox-android project. This " - "means that the fenix APK being tested in the two pushes is the same, and " - "any local changes made won't impact it.", - }, - ], - [ ["--chrome"], { "action": "store_true", diff --git a/tools/tryselect/selectors/perfselector/classification.py b/tools/tryselect/selectors/perfselector/classification.py index cabf2a323e..a8e2adc034 100644 --- a/tools/tryselect/selectors/perfselector/classification.py +++ b/tools/tryselect/selectors/perfselector/classification.py @@ -31,13 +31,12 @@ class Platforms(ClassificationEnum): class Apps(ClassificationEnum): FIREFOX = {"value": "firefox", "index": 0} CHROME = {"value": "chrome", "index": 1} - CHROMIUM = {"value": "chromium", "index": 2} - GECKOVIEW = {"value": "geckoview", "index": 3} - FENIX = {"value": "fenix", "index": 4} - CHROME_M = {"value": "chrome-m", "index": 5} - SAFARI = {"value": "safari", "index": 6} - CHROMIUM_RELEASE = {"value": "custom-car", "index": 7} - CHROMIUM_RELEASE_M = {"value": "cstm-car-m", "index": 8} + GECKOVIEW = {"value": "geckoview", "index": 2} + FENIX = {"value": "fenix", "index": 3} + CHROME_M = {"value": "chrome-m", "index": 4} + SAFARI = {"value": "safari", "index": 5} + CHROMIUM_RELEASE = {"value": "custom-car", "index": 6} + CHROMIUM_RELEASE_M = {"value": "cstm-car-m", "index": 7} class Suites(ClassificationEnum): @@ -66,10 +65,6 @@ def check_for_android(android=False, **kwargs): return android -def check_for_fenix(fenix=False, **kwargs): - return fenix or ("fenix" in kwargs.get("requested_apps", [])) - - def check_for_chrome(chrome=False, **kwargs): return chrome @@ -137,12 +132,6 @@ class ClassificationProvider: "restriction": check_for_chrome, "platforms": [Platforms.DESKTOP.value], }, - Apps.CHROMIUM.value: { - "query": "'chromium", - "negation": "!chrom", - "restriction": check_for_chrome, - "platforms": [Platforms.DESKTOP.value], - }, Apps.GECKOVIEW.value: { "query": "'geckoview", "negation": "!geckoview", @@ -151,7 +140,6 @@ class ClassificationProvider: Apps.FENIX.value: { "query": "'fenix", "negation": "!fenix", - "restriction": check_for_fenix, "platforms": [Platforms.ANDROID.value], }, Apps.CHROME_M.value: { @@ -207,7 +195,6 @@ class ClassificationProvider: "apps": [ # XXX No live CaR tests Apps.FIREFOX.value, Apps.CHROME.value, - Apps.CHROMIUM.value, Apps.FENIX.value, Apps.GECKOVIEW.value, Apps.SAFARI.value, @@ -304,7 +291,6 @@ class ClassificationProvider: Suites.RAPTOR.value: [ Apps.FIREFOX.value, Apps.CHROME.value, - Apps.CHROMIUM.value, Apps.FENIX.value, Apps.GECKOVIEW.value, ], @@ -376,7 +362,6 @@ class ClassificationProvider: Suites.RAPTOR.value: [ Apps.FIREFOX.value, Apps.CHROME.value, - Apps.CHROMIUM.value, Apps.FENIX.value, Apps.GECKOVIEW.value, ], @@ -384,4 +369,25 @@ class ClassificationProvider: "tasks": [], "description": "A group of tests that monitor key graphics and media metrics to keep the browser fast", }, + "Pageload Lite": { + "query": { + Suites.RAPTOR.value: ["'browsertime 'tp6-bench"], + }, + "suites": [Suites.RAPTOR.value], + "platform-restrictions": [ + Platforms.DESKTOP.value, + Platforms.LINUX.value, + Platforms.MACOSX.value, + Platforms.WINDOWS.value, + ], + "variant-restrictions": {Suites.RAPTOR.value: [Variants.FISSION.value]}, + "app-restrictions": { + Suites.RAPTOR.value: [Apps.FIREFOX.value], + }, + "tasks": [], + "description": ( + "Similar to the Pageload category, but it provides a minimum set " + "of pageload tests to run for performance testing." + ), + }, } diff --git a/tools/tryselect/selectors/release.py b/tools/tryselect/selectors/release.py index 994bbe644d..fae85469ba 100644 --- a/tools/tryselect/selectors/release.py +++ b/tools/tryselect/selectors/release.py @@ -94,6 +94,7 @@ def run( "browser/config/version.txt": "{}\n".format(app_version), "browser/config/version_display.txt": "{}\n".format(version), "config/milestone.txt": "{}\n".format(app_version), + "mobile/android/version.txt": "{}\n".format(version), } with open("browser/config/version.txt") as f: current_version = FirefoxVersion.parse(f.read()) diff --git a/tools/tryselect/test/test_auto.t b/tools/tryselect/test/test_auto.t index c3fe797949..398eb1a431 100644 --- a/tools/tryselect/test/test_auto.t +++ b/tools/tryselect/test/test_auto.t @@ -8,6 +8,8 @@ Test auto selector Commit message: Tasks automatically selected. + mach try command: `./mach try auto --no-push --no-artifact` + Pushed via `mach try auto` Calculated try_task_config.json: { @@ -27,6 +29,8 @@ Test auto selector Commit message: Tasks automatically selected. ON A CLOSED TREE + mach try command: `./mach try auto --no-push --no-artifact --closed-tree` + Pushed via `mach try auto` Calculated try_task_config.json: { @@ -45,6 +49,8 @@ Test auto selector Commit message: foo Tasks automatically selected. bar ON A CLOSED TREE + mach try command: `./mach try auto --no-push --no-artifact --closed-tree -m "foo {msg} bar"` + Pushed via `mach try auto` Calculated try_task_config.json: { diff --git a/tools/tryselect/test/test_empty.t b/tools/tryselect/test/test_empty.t index d7e9c22618..9e330f8dab 100644 --- a/tools/tryselect/test/test_empty.t +++ b/tools/tryselect/test/test_empty.t @@ -7,6 +7,8 @@ Test empty selector Commit message: No try selector specified, use "Add New Jobs" to select tasks. + mach try command: `./mach try empty --no-push` + Pushed via `mach try empty` Calculated try_task_config.json: { @@ -26,6 +28,8 @@ Test empty selector Commit message: No try selector specified, use "Add New Jobs" to select tasks. ON A CLOSED TREE + mach try command: `./mach try empty --no-push --closed-tree` + Pushed via `mach try empty` Calculated try_task_config.json: { @@ -45,6 +49,8 @@ Test empty selector Commit message: foo No try selector specified, use "Add New Jobs" to select tasks. bar ON A CLOSED TREE + mach try command: `./mach try empty --no-push --closed-tree -m "foo {msg} bar"` + Pushed via `mach try empty` Calculated try_task_config.json: { diff --git a/tools/tryselect/test/test_fuzzy.t b/tools/tryselect/test/test_fuzzy.t index 843b053e08..347e49ce72 100644 --- a/tools/tryselect/test/test_fuzzy.t +++ b/tools/tryselect/test/test_fuzzy.t @@ -7,6 +7,8 @@ Test fuzzy selector Commit message: Fuzzy query='foo + mach try command: `./mach try fuzzy --no-push --no-artifact -q "'foo"` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { @@ -33,6 +35,8 @@ Test fuzzy selector Commit message: Fuzzy query='bar + mach try command: `./mach try fuzzy --no-push --no-artifact --full -q "'bar"` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { @@ -58,6 +62,8 @@ Test multiple selectors Commit message: Fuzzy query='foo&query='bar + mach try command: `./mach try fuzzy --no-push --no-artifact --full -q "'foo" -q "'bar"` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { @@ -85,6 +91,8 @@ Test query intersection Commit message: Fuzzy query='foo&query='opt + mach try command: `./mach try fuzzy --no-push --no-artifact --and -q "'foo" -q "'opt"` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { @@ -112,6 +120,8 @@ Test intersection with preset containing multiple queries Commit message: Fuzzy query='test&query='opt&query='test + mach try command: `./mach try fuzzy --no-push --no-artifact --preset foo -xq "'test"` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { @@ -134,6 +144,8 @@ Test intersection with preset containing multiple queries Commit message: Fuzzy query='test&query='opt&query='test + mach try command: `./mach try --no-push --no-artifact --preset foo -xq "'test"` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { @@ -159,6 +171,8 @@ Test exact match Commit message: Fuzzy query=testfoo | 'testbar + mach try command: `./mach try fuzzy --no-push --no-artifact --full -q "testfoo | 'testbar"` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { @@ -181,6 +195,8 @@ Test exact match Commit message: Fuzzy query=testfoo | 'testbar + mach try command: `./mach try fuzzy --no-push --no-artifact --full --exact -q "testfoo | 'testbar"` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { @@ -206,6 +222,8 @@ Test task config Commit message: Fuzzy query='foo + mach try command: `./mach try fuzzy --no-push --artifact -q "'foo"` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { @@ -230,6 +248,8 @@ Test task config Commit message: Fuzzy query='foo + mach try command: `./mach try fuzzy --no-push --no-artifact --env FOO=1 --env BAR=baz -q "'foo"` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { diff --git a/tools/tryselect/test/test_message.t b/tools/tryselect/test/test_message.t index a707e410fb..45adc2dc5a 100644 --- a/tools/tryselect/test/test_message.t +++ b/tools/tryselect/test/test_message.t @@ -9,6 +9,8 @@ Test custom commit messages with fuzzy selector Fuzzy query=foo + mach try command: `./mach try fuzzy --no-push --no-artifact -q foo --message Foobar` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { @@ -31,6 +33,8 @@ Test custom commit messages with fuzzy selector Commit message: Foobar: Fuzzy query=foo + mach try command: `./mach try fuzzy --no-push --no-artifact -q foo -m "Foobar: {msg}"` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { @@ -62,11 +66,15 @@ Test custom commit messages with syntax selector try: -b do -p linux -u mochitests + mach try command: `./mach try syntax --no-push --no-artifact -p linux -u mochitests --message Foobar` + Pushed via `mach try syntax` $ ./mach try syntax $testargs -p linux -u mochitests -m "Foobar: {msg}" Commit message: Foobar: try: -b do -p linux -u mochitests + mach try command: `./mach try syntax --no-push --no-artifact -p linux -u mochitests -m "Foobar: {msg}"` + Pushed via `mach try syntax` $ unset EDITOR $ ./mach try syntax $testargs -p linux -u mochitests -m > /dev/null 2>&1 diff --git a/tools/tryselect/test/test_perf.py b/tools/tryselect/test/test_perf.py index c4e3b6b5fa..73aa3c4d71 100644 --- a/tools/tryselect/test/test_perf.py +++ b/tools/tryselect/test/test_perf.py @@ -193,7 +193,6 @@ TEST_CATEGORIES = { "!live", "!profil", "!chrom", - "!fenix", "!safari", "!m-car", ] @@ -206,7 +205,6 @@ TEST_CATEGORIES = { "!live", "!profil", "!chrom", - "!fenix", "!safari", "!m-car", ] @@ -220,7 +218,6 @@ TEST_CATEGORIES = { "!live", "!profil", "!chrom", - "!fenix", "!safari", "!m-car", ], @@ -234,7 +231,6 @@ TEST_CATEGORIES = { }, [ "Responsiveness android-p2 geckoview", - "Benchmarks desktop chromium", ], ), # Default settings ( @@ -248,7 +244,6 @@ TEST_CATEGORIES = { "!bytecode", "!profil", "!chrom", - "!fenix", "!safari", "!m-car", ] @@ -260,7 +255,6 @@ TEST_CATEGORIES = { "!bytecode", "!profil", "!chrom", - "!fenix", "!safari", "!m-car", ] @@ -273,7 +267,6 @@ TEST_CATEGORIES = { "!bytecode", "!profil", "!chrom", - "!fenix", "!safari", "!m-car", ], @@ -281,7 +274,6 @@ TEST_CATEGORIES = { }, [ "Responsiveness android-p2 geckoview", - "Benchmarks desktop chromium", "Benchmarks desktop firefox profiling", "Talos desktop live-sites", "Talos desktop profiling+swr", @@ -300,7 +292,6 @@ TEST_CATEGORIES = { "!bytecode", "!profil", "!chrom", - "!fenix", "!m-car", ] }, @@ -331,7 +322,7 @@ TEST_CATEGORIES = { ), ( {"live_sites": True, "chrome": True}, - 114, + 90, { "Benchmarks desktop": { "raptor": [ @@ -339,7 +330,6 @@ TEST_CATEGORIES = { "!android 'shippable !-32 !clang", "!bytecode", "!profil", - "!fenix", "!safari", "!m-car", ] @@ -351,20 +341,10 @@ TEST_CATEGORIES = { "'live", "!bytecode", "!profil", - "!fenix", "!safari", "!m-car", ], }, - "Benchmarks desktop chromium": { - "raptor": [ - "'browsertime 'benchmark", - "!android 'shippable !-32 !clang", - "'chromium", - "!bytecode", - "!profil", - ], - }, }, [ "Responsiveness android-p2 geckoview", @@ -374,7 +354,7 @@ TEST_CATEGORIES = { ), ( {"android": True}, - 78, + 88, { "Benchmarks desktop": { "raptor": [ @@ -384,7 +364,6 @@ TEST_CATEGORIES = { "!live", "!profil", "!chrom", - "!fenix", "!safari", "!m-car", ], @@ -403,12 +382,11 @@ TEST_CATEGORIES = { [ "Responsiveness android-a51 chrome-m", "Firefox Pageload android", - "Pageload android-a51 fenix", ], ), ( {"android": True, "chrome": True}, - 128, + 118, { "Benchmarks desktop": { "raptor": [ @@ -417,7 +395,6 @@ TEST_CATEGORIES = { "!bytecode", "!live", "!profil", - "!fenix", "!safari", "!m-car", ], @@ -437,7 +414,7 @@ TEST_CATEGORIES = { ), ( {"android": True, "chrome": True, "profile": True}, - 164, + 156, { "Benchmarks desktop": { "raptor": [ @@ -445,7 +422,6 @@ TEST_CATEGORIES = { "!android 'shippable !-32 !clang", "!bytecode", "!live", - "!fenix", "!safari", "!m-car", ] @@ -463,7 +439,6 @@ TEST_CATEGORIES = { "Resource Usage desktop profiling", "DAMP (Devtools) desktop chrome", "Resource Usage android", - "Resource Usage windows chromium", ], ), ( @@ -497,7 +472,6 @@ TEST_CATEGORIES = { "Resource Usage desktop profiling", "DAMP (Devtools) desktop chrome", "Resource Usage android", - "Resource Usage windows chromium", ], ), # Show all available windows tests, no other platform should exist @@ -755,7 +729,6 @@ TEST_CATEGORIES = { "!bytecode", "!profil", "!chrom", - "!fenix", "!safari", "!m-car", ], @@ -767,7 +740,6 @@ TEST_CATEGORIES = { "!bytecode", "!profil", "!chrom", - "!fenix", "!safari", "!m-car", ], @@ -847,7 +819,7 @@ def test_category_expansion_with_non_pgo_flag(category_options, call_counts): [ ( {}, - [10, 2, 2, 10, 2, 1], + [9, 2, 2, 10, 2, 1], 2, ( "\n!!!NOTE!!!\n You'll be able to find a performance comparison " @@ -858,7 +830,7 @@ def test_category_expansion_with_non_pgo_flag(category_options, call_counts): ), ( {"query": "'Pageload 'linux 'firefox"}, - [10, 2, 2, 10, 2, 1], + [9, 2, 2, 10, 2, 1], 2, ( "\n!!!NOTE!!!\n You'll be able to find a performance comparison " @@ -869,7 +841,7 @@ def test_category_expansion_with_non_pgo_flag(category_options, call_counts): ), ( {"cached_revision": "cached_base_revision"}, - [10, 1, 1, 10, 2, 0], + [9, 1, 1, 10, 2, 0], 2, ( "\n!!!NOTE!!!\n You'll be able to find a performance comparison " @@ -880,7 +852,7 @@ def test_category_expansion_with_non_pgo_flag(category_options, call_counts): ), ( {"dry_run": True}, - [10, 1, 1, 10, 2, 0], + [9, 1, 1, 10, 2, 0], 2, ( "\n!!!NOTE!!!\n You'll be able to find a performance comparison " @@ -913,7 +885,7 @@ def test_category_expansion_with_non_pgo_flag(category_options, call_counts): ), ( {"single_run": True}, - [10, 1, 1, 4, 2, 0], + [9, 1, 1, 4, 2, 0], 2, ( "If you need any help, you can find us in the #perf-help Matrix channel:\n" @@ -922,7 +894,7 @@ def test_category_expansion_with_non_pgo_flag(category_options, call_counts): ), ( {"detect_changes": True}, - [11, 2, 2, 10, 2, 1], + [10, 2, 2, 10, 2, 1], 2, ( "\n!!!NOTE!!!\n You'll be able to find a performance comparison " @@ -933,7 +905,7 @@ def test_category_expansion_with_non_pgo_flag(category_options, call_counts): ), ( {"perfcompare_beta": True}, - [10, 2, 2, 10, 2, 1], + [9, 2, 2, 10, 2, 1], 2, ( "\n!!!NOTE!!!\n You'll be able to find a performance comparison " @@ -971,7 +943,6 @@ def test_full_run(options, call_counts, log_ind, expected_log_message): ["", TASKS], ["", TASKS], ["", TASKS], - ["", TASKS], ["", ["Perftest Change Detector"]], ] # Number of side effects for fzf should always be greater than @@ -997,11 +968,11 @@ def test_full_run(options, call_counts, log_ind, expected_log_message): [ ( {"detect_changes": True}, - [11, 0, 0, 2, 1], + [10, 0, 0, 2, 1], 1, ( "Executing raptor queries: 'browsertime 'benchmark, !clang 'linux " - "'shippable, !bytecode, !live, !profil, !chrom, !fenix, !safari, !m-car" + "'shippable, !bytecode, !live, !profil, !chrom, !safari, !m-car" ), InvalidRegressionDetectorQuery, ), diff --git a/tools/tryselect/test/test_preset.t b/tools/tryselect/test/test_preset.t index 13e6946d32..07b4fb1bf4 100644 --- a/tools/tryselect/test/test_preset.t +++ b/tools/tryselect/test/test_preset.t @@ -10,12 +10,16 @@ Test preset with no subcommand Commit message: try: -b do -p linux -u mochitests -t none --tag foo + mach try command: `./mach try --no-push --no-artifact --preset foo` + Pushed via `mach try syntax` $ ./mach try syntax $testargs --preset foo Commit message: try: -b do -p linux -u mochitests -t none --tag foo + mach try command: `./mach try syntax --no-push --no-artifact --preset foo` + Pushed via `mach try syntax` $ ./mach try $testargs --list-presets @@ -59,12 +63,16 @@ Test preset with syntax subcommand Commit message: try: -b do -p win32 -u none -t all --tag bar + mach try command: `./mach try syntax --no-push --no-artifact --preset bar` + Pushed via `mach try syntax` $ ./mach try $testargs --preset bar Commit message: try: -b do -p win32 -u none -t all --tag bar + mach try command: `./mach try --no-push --no-artifact --preset bar` + Pushed via `mach try syntax` $ ./mach try syntax $testargs --list-presets @@ -128,6 +136,8 @@ Test preset with fuzzy subcommand Commit message: Fuzzy query='foo + mach try command: `./mach try fuzzy --no-push --no-artifact --preset baz` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { @@ -152,6 +162,8 @@ Test preset with fuzzy subcommand Commit message: Fuzzy query='foo + mach try command: `./mach try --no-push --no-artifact --preset baz` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { @@ -178,6 +190,8 @@ Queries can be appended to presets Commit message: Fuzzy query='foo&query='build + mach try command: `./mach try fuzzy --no-push --no-artifact --preset baz -q "'build"` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { @@ -203,6 +217,8 @@ Queries can be appended to presets Commit message: Fuzzy query='foo&query='opt + mach try command: `./mach try --no-push --no-artifact --preset baz -xq "'opt"` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { @@ -294,6 +310,8 @@ Test gecko-profile argument handling. Add in profiling to a preset. Commit message: Fuzzy query='foo + mach try command: `./mach try fuzzy --no-push --no-artifact --preset baz --gecko-profile-features=nostacksampling,cpu` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { @@ -326,6 +344,8 @@ settings; everything else uses dashes.) Commit message: Fuzzy query='foo + mach try command: `./mach try fuzzy --no-push --no-artifact --preset profile` + Pushed via `mach try fuzzy` Calculated try_task_config.json: { diff --git a/tools/tryselect/test/test_push.py b/tools/tryselect/test/test_push.py index 97f2e047d7..c8dbbe4184 100644 --- a/tools/tryselect/test/test_push.py +++ b/tools/tryselect/test/test_push.py @@ -50,5 +50,35 @@ def test_generate_try_task_config(method, labels, params, routes, expected): ) +def test_get_sys_argv(): + input_argv = [ + "./mach", + "try", + "fuzzy", + "--full", + "--artifact", + "--push-to-lando", + "--query", + "'android-hw !shippable !nofis", + "--no-push", + ] + expected_string = './mach try fuzzy --full --artifact --push-to-lando --query "\'android-hw !shippable !nofis" --no-push' + assert push.get_sys_argv(input_argv) == expected_string + + +def test_get_sys_argv_2(): + input_argv = [ + "./mach", + "try", + "fuzzy", + "--query", + "'test-linux1804-64-qr/opt-mochitest-plain-", + "--worker-override=t-linux-large=gecko-t/t-linux-2204-wayland-experimental", + "--no-push", + ] + expected_string = './mach try fuzzy --query "\'test-linux1804-64-qr/opt-mochitest-plain-" --worker-override=t-linux-large=gecko-t/t-linux-2204-wayland-experimental --no-push' + assert push.get_sys_argv(input_argv) == expected_string + + if __name__ == "__main__": mozunit.main() diff --git a/tools/tryselect/test/test_release.py b/tools/tryselect/test/test_release.py index a1a0d348b2..00eeb0c6c6 100644 --- a/tools/tryselect/test/test_release.py +++ b/tools/tryselect/test/test_release.py @@ -18,11 +18,18 @@ def test_release(run_mach, capfd): output = capfd.readouterr().out print(output) - expected = dedent( + expected_part1 = dedent( """ Commit message: staging release: 97.0 + """ + ).lstrip() + # The output now features a display of the `mach try` command run here + # that will vary based on the user and invocation, so ignore that part. + + expected_part2 = dedent( + """ Pushed via `mach try release` Calculated try_task_config.json: { @@ -36,7 +43,8 @@ def test_release(run_mach, capfd): """ ).lstrip() - assert expected in output + assert expected_part1 in output + assert expected_part2 in output if __name__ == "__main__": diff --git a/tools/tryselect/try_presets.yml b/tools/tryselect/try_presets.yml index 680d318dc6..b0d258bb0d 100644 --- a/tools/tryselect/try_presets.yml +++ b/tools/tryselect/try_presets.yml @@ -17,12 +17,31 @@ android-components: - "'build-components" - "'test-components" +android-geckoview: + selector: fuzzy + # Show chunk numbers so we can query with -1$ / -2$ etc. + show_chunk_numbers: true + # disable_target_task_filter: true + # Run taskgraph full so all tasks are available + full: true + description: >- + Run android-geckoview builds and tests. + query: + # Lint + - "^source-test-mozlint android-lints$ | eslint$ | rejected-words$ | file-perm$ | file-whitespace$" + # Tests + - "^test-android-em-7.0-x86_64-qr/debug-isolated-process-geckoview- 'test-verify | cppunittest-1proc$ | gtest-1proc$ | junit$ | junit-fis$ | junit-nofis$ | junit-nofis-ship$ | xpcshell-1$ | xpcshell-2$" + - "^test-android-em-7.0-x86_64-qr/debug-isolated-process-geckoview-mochitest- media-1$ | media-2$ | plain-1$ | plain-2$ | plain-3$ | plain-4$ | plain-5$ | plain-gpu$" + - "^test-android-em-7.0-x86_64-qr/opt-geckoview- xpcshell-1$ | xpcshell-2$ | cppunittest-1proc$ | gtest-1proc$ | junit-fis$ | junit-nofis-ship$ | junit-nofis$ | junit$ | mochitest-media$" + - "^test-android-em-7.0-x86_64-qr/opt-geckoview-mochitest- media$ | plain-1$ | plain-2$ | plain-3$ | plain-4$ | plain-5$ | plain-gpu$" + - "^test-android-em-7.0-x86_64-qr/opt-geckoview-test-verify" + builds: selector: fuzzy description: >- Run builds without any of the extras. query: - - "^build- !fuzzing !notarization !reproduced !rusttests !signing !upload-symbols" + - "^build- !fuzzing !notarization !reproduced !rusttests !signing !upload-symbols !components !apk !bundle" builds-debug: selector: fuzzy @@ -30,7 +49,7 @@ builds-debug: Run the bare minimum of debug build jobs to ensure builds work on all tier-1 platforms. query: - - "^build- 'debug !fuzzing !rusttests !signing !plain !asan !tsan !noopt !toolchain !upload-symbols" + - "^build- 'debug !fuzzing !rusttests !signing !plain !asan !tsan !noopt !toolchain !upload-symbols !apk !bundle" builds-debugopt: selector: fuzzy @@ -38,7 +57,7 @@ builds-debugopt: Run the bare minimum of debug and opt build jobs to ensure builds work on all tier-1 platforms. query: - - "^build- !fuzzing !rusttests !signing !plain !asan !tsan !noopt !toolchain !upload-symbols" + - "^build- !fuzzing !rusttests !signing !plain !asan !tsan !noopt !toolchain !upload-symbols !components !apk !bundle" desktop-frontend: description: >- @@ -150,7 +169,7 @@ fpush-linux-android: query: - "'test-linux1804 'debug- !-shippable !-asan" - "'test-android-em 'debug" - - "^build !-shippable !-signing !-asan !-fuzzing !-rusttests !-base-toolchain !-aar-" + - "^build !-shippable !-signing !-asan !-fuzzing !-rusttests !-base-toolchain !-aar- !components !apk !bundle" geckodriver: selector: fuzzy @@ -254,7 +273,7 @@ sample-suites: query: - ^test- -1$ # Only run a single talos + raptor suite per platform - - ^test- !1$ !2$ !3$ !4$ !5$ !6$ !7$ !8$ !9$ !0$ !raptor !talos + - ^test- !1$ !2$ !3$ !4$ !5$ !6$ !7$ !8$ !9$ !0$ !raptor !talos !components !apk - ^test- 'raptor-speedometer | 'talos-g1 sm-shell-all: @@ -320,7 +339,7 @@ webrender: description: >- Runs the conformance tests relevant to WebRender. query: - - "!talos !raptor !shippable !asan '-qr" + - "!talos !raptor !shippable !asan '-qr !components" - "^webrender-" webrender-reftests: diff --git a/tools/update-packaging/common.sh b/tools/update-packaging/common.sh index 397ed21e25..e055b1c24e 100755 --- a/tools/update-packaging/common.sh +++ b/tools/update-packaging/common.sh @@ -92,12 +92,14 @@ make_add_instruction() { check_for_add_if_not_update() { add_if_not_file_chk="$1" - if [ "$(basename "$add_if_not_file_chk")" = "channel-prefs.js" -o \ - "$(basename "$add_if_not_file_chk")" = "update-settings.ini" ]; then - ## "true" *giggle* + if [[ "$(basename "$add_if_not_file_chk")" = "channel-prefs.js" || \ + "$add_if_not_file_chk" =~ (^|/)ChannelPrefs\.framework/ || \ + "$(basename "$add_if_not_file_chk")" = "update-settings.ini" || \ + "$add_if_not_file_chk" =~ (^|/)UpdateSettings\.framework/ ]]; then + ## "true" return 0; fi - ## 'false'... because this is bash. Oh yay! + ## "false" return 1; } diff --git a/tools/update-verify/release/common/cached_download.sh b/tools/update-verify/release/common/cached_download.sh index 7cb3c42f8d..4522b5504d 100644 --- a/tools/update-verify/release/common/cached_download.sh +++ b/tools/update-verify/release/common/cached_download.sh @@ -1,10 +1,12 @@ +#!/bin/bash # this library works like a wrapper around wget, to allow downloads to be cached # so that if later the same url is retrieved, the entry from the cache will be # returned. -pushd `dirname $0` &>/dev/null +pushd "$(dirname "$0")" &>/dev/null || exit cache_dir="$(pwd)/cache" -popd &>/dev/null +popd &>/dev/null || exit +retry="$MY_DIR/../../../../mach python -m redo.cmd -s 1 -a 3" # Deletes all files in the cache directory # We don't support folders or .dot(hidden) files @@ -12,7 +14,7 @@ popd &>/dev/null # which are the only workaround to poor mount r/w performance on MacOS # Reference: https://forums.docker.com/t/file-access-in-mounted-volumes-extremely-slow-cpu-bound/8076/288 clear_cache () { - rm -rf "${cache_dir}/*" + rm -rf "${cache_dir:?}/*" } # download method - you pass a filename to save the file under, and the url to call @@ -20,9 +22,10 @@ cached_download () { local output_file="${1}" local url="${2}" - if fgrep -x "${url}" "${cache_dir}/urls.list" >/dev/null; then + if grep -Fx "${url}" "${cache_dir}/urls.list" >/dev/null; then echo "Retrieving '${url}' from cache..." - local line_number="$(fgrep -nx "${url}" "${cache_dir}/urls.list" | sed 's/:.*//')" + local line_number + line_number="$(grep -Fnx "${url}" "${cache_dir}/urls.list" | sed 's/:.*//')" cp "${cache_dir}/obj_$(printf "%05d\n" "${line_number}").cache" "${output_file}" else echo "Downloading '${url}' and placing in cache..." @@ -31,7 +34,8 @@ cached_download () { local exit_code=$? if [ "${exit_code}" == 0 ]; then echo "${url}" >> "${cache_dir}/urls.list" - local line_number="$(fgrep -nx "${url}" "${cache_dir}/urls.list" | sed 's/:.*//')" + local line_number + line_number="$(grep -Fnx "${url}" "${cache_dir}/urls.list" | sed 's/:.*//')" cp "${output_file}" "${cache_dir}/obj_$(printf "%05d\n" "${line_number}").cache" else return "${exit_code}" diff --git a/tools/update-verify/release/common/check_updates.sh b/tools/update-verify/release/common/check_updates.sh index acf06d8b4e..f03d8a069d 100644 --- a/tools/update-verify/release/common/check_updates.sh +++ b/tools/update-verify/release/common/check_updates.sh @@ -1,3 +1,5 @@ +#!/bin/bash + check_updates () { # called with 10 args - platform, source package, target package, update package, old updater boolean, # a path to the updater binary to use for the tests, a file to write diffs to, the update channel, @@ -6,24 +8,34 @@ check_updates () { source_package=$2 target_package=$3 locale=$4 - use_old_updater=$5 - updater=$6 - diff_file=$7 - channel=$8 - mar_channel_IDs=$9 - update_to_dep=${10} + updater=$5 + diff_file=$6 + channel=$7 + mar_channel_IDs=$8 + update_to_dep=$9 + local mac_update_settings_dir_override + mac_update_settings_dir_override=${10} + local product + product=${11} # cleanup rm -rf source/* rm -rf target/* - unpack_build $update_platform source "$source_package" $locale '' $mar_channel_IDs - if [ "$?" != "0" ]; then + # $mac_update_settings_dir_override allows unpack_build to find a host platform appropriate + # `update-settings.ini` file, which is needed to successfully run the updater later in this + # function. + if ! unpack_build "$update_platform" source "$source_package" "$locale" '' "$mar_channel_IDs" "$mac_update_settings_dir_override" "$product"; then echo "FAILED: cannot unpack_build $update_platform source $source_package" return 1 fi - unpack_build $update_platform target "$target_package" $locale - if [ "$?" != "0" ]; then + # Unlike unpacking the `source` build, we don't actually _need_ $mac_update_settings_dir_override + # here to succesfully apply the update, but its usage in `source` causes an `update-settings.ini` + # file to be present in the directory we diff, which means we either also need it present in the + # `target` directory, or to remove it after the update is applied. The latter was chosen + # because it keeps the workaround close together (as opposed to just above this, and then much + # further down). + if ! unpack_build "$update_platform" target "$target_package" "$locale" '' '' "$mac_update_settings_dir_override" "$product"; then echo "FAILED: cannot unpack_build $update_platform target $target_package" return 1 fi @@ -36,30 +48,35 @@ check_updates () { platform_dirname="bin" ;; Linux_x86-gcc | Linux_x86-gcc3 | Linux_x86_64-gcc3) - platform_dirname=`echo $product | tr '[A-Z]' '[a-z]'` + platform_dirname=$(echo "$product" | tr '[:upper:]' '[:lower:]') ;; esac if [ -f update/update.status ]; then rm update/update.status; fi if [ -f update/update.log ]; then rm update/update.log; fi + # This check is disabled because we rely on glob expansion here + # shellcheck disable=SC2086 if [ -d source/$platform_dirname ]; then - if [ `uname | cut -c-5` == "MINGW" ]; then + if [ "$(uname | cut -c-5)" == "MINGW" ]; then # windows # change /c/path/to/pwd to c:\\path\\to\\pwd - four_backslash_pwd=$(echo $PWD | sed -e 's,^/\([a-zA-Z]\)/,\1:/,' | sed -e 's,/,\\\\,g') - two_backslash_pwd=$(echo $PWD | sed -e 's,^/\([a-zA-Z]\)/,\1:/,' | sed -e 's,/,\\,g') + two_backslash_pwd=$(echo "$PWD" | sed -e 's,^/\([a-zA-Z]\)/,\1:/,' | sed -e 's,/,\\,g') cwd="$two_backslash_pwd\\source\\$platform_dirname" update_abspath="$two_backslash_pwd\\update" else # not windows # use ls here, because mac uses *.app, and we need to expand it + # This check is disabled because we rely on glob expansion here + # shellcheck disable=SC2086 cwd=$(ls -d $PWD/source/$platform_dirname) update_abspath="$PWD/update" fi + # This check is disabled because we rely on glob expansion here + # shellcheck disable=SC2086 cd_dir=$(ls -d ${PWD}/source/${platform_dirname}) - cd "${cd_dir}" + cd "${cd_dir}" || (echo "TEST-UNEXPECTED-FAIL: couldn't cd to ${cd_dir}" && return 1) set -x "$updater" "$update_abspath" "$cwd" "$cwd" 0 set +x @@ -70,7 +87,7 @@ check_updates () { fi cat update/update.log - update_status=`cat update/update.status` + update_status=$(cat update/update.status) if [ "$update_status" != "succeeded" ] then @@ -87,13 +104,17 @@ check_updates () { # positive from failing the tests, we simply remove it before diffing. # The precomplete file in Contents/Resources is still diffed, so we # don't lose any coverage by doing this. - cd `echo "source/$platform_dirname"` + # This check is disabled because we rely on glob expansion here + # shellcheck disable=SC2086 + cd source/$platform_dirname || (echo "TEST-UNEXPECTED-FAIL: couldn't cd to source/${platform_dirname}" && exit 1) if [[ -f "Contents/Resources/precomplete" && -f "precomplete" ]] then rm "precomplete" fi cd ../.. - cd `echo "target/$platform_dirname"` + # This check is disabled because we rely on glob expansion here + # shellcheck disable=SC2086 + cd target/$platform_dirname || (echo "TEST-UNEXPECTED-FAIL: couldn't cd to target/${platform_dirname}" && exit 1) if [[ -f "Contents/Resources/precomplete" && -f "precomplete" ]] then rm "precomplete" @@ -110,7 +131,28 @@ check_updates () { ignore_coderesources= fi - ../compare-directories.py source/${platform_dirname} target/${platform_dirname} ${channel} ${ignore_coderesources} > "${diff_file}" + # On Mac, there are two Frameworks that are not included with updates, and + # which change with every build. Because of this, we ignore differences in + # them in `compare-directories.py`. The best verification we can do for them + # is that they still exist. + if [[ $update_platform == Darwin_* ]]; then + # This check is disabled because we rely on glob expansion here + # shellcheck disable=SC2086 + if ! compgen -G source/${platform_dirname}/Contents/MacOS/updater.app/Contents/Frameworks/UpdateSettings.framework >/dev/null; then + echo "TEST-UNEXPECTED-FAIL: UpdateSettings.framework doesn't exist after update" + return 4 + fi + # This check is disabled because we rely on glob expansion here + # shellcheck disable=SC2086 + if ! compgen -G source/${platform_dirname}/Contents/Frameworks/ChannelPrefs.framework >/dev/null; then + echo "TEST-UNEXPECTED-FAIL: ChannelPrefs.framework doesn't exist after update" + return 5 + fi + fi + + # This check is disabled because we rely on glob expansion here + # shellcheck disable=SC2086 + ../compare-directories.py source/${platform_dirname} target/${platform_dirname} "${channel}" ${ignore_coderesources} > "${diff_file}" diffErr=$? cat "${diff_file}" if [ $diffErr == 2 ] diff --git a/tools/update-verify/release/common/download_builds.sh b/tools/update-verify/release/common/download_builds.sh index e279c808db..0374ecaffc 100644 --- a/tools/update-verify/release/common/download_builds.sh +++ b/tools/update-verify/release/common/download_builds.sh @@ -1,7 +1,4 @@ -pushd `dirname $0` &>/dev/null -MY_DIR=$(pwd) -popd &>/dev/null -retry="$MY_DIR/../../../../mach python -m redo.cmd -s 1 -a 3" +#!/bin/bash download_builds() { # cleanup @@ -13,15 +10,15 @@ download_builds() { if [ -z "$source_url" ] || [ -z "$target_url" ] then - "download_builds usage: <source_url> <target_url>" + echo "download_builds usage: <source_url> <target_url>" exit 1 fi for url in "$source_url" "$target_url" do - source_file=`basename "$url"` + source_file=$(basename "$url") if [ -f "$source_file" ]; then rm "$source_file"; fi - cd downloads + cd downloads || exit if [ -f "$source_file" ]; then rm "$source_file"; fi cached_download "${source_file}" "${url}" status=$? diff --git a/tools/update-verify/release/common/download_mars.sh b/tools/update-verify/release/common/download_mars.sh index d2dab107d2..84cbfe2ccc 100644 --- a/tools/update-verify/release/common/download_mars.sh +++ b/tools/update-verify/release/common/download_mars.sh @@ -1,3 +1,5 @@ +#!/bin/bash + download_mars () { update_url="$1" only="$2" @@ -23,42 +25,49 @@ download_mars () { fi echo "Empty response, sleeping" sleep 5 - try=$(($try+1)) + try=$((try+1)) done echo; echo; # padding - update_line=`fgrep "<update " update.xml` + update_line=$(grep -F "<update " update.xml) grep_rv=$? if [ 0 -ne $grep_rv ]; then echo "TEST-UNEXPECTED-FAIL: no <update/> found for $update_url" return 1 fi - command=`echo $update_line | sed -e 's/^.*<update //' -e 's:>.*$::' -e 's:\&:\&:g'` + command=$(echo "$update_line" | sed -e 's/^.*<update //' -e 's:>.*$::' -e 's:\&:\&:g') eval "export $command" - if [ ! -z "$to_build_id" -a "$buildID" != "$to_build_id" ]; then + # buildID and some other variables further down are gathered by eval'ing + # the massaged `update.xml` file a bit further up. Because of this, shellcheck + # cannot verify their existence, and gets grumpy. Ideally we would do this + # differently, but it's not worth the trouble at the time of writing. + # shellcheck disable=SC2154 + if [ -n "$to_build_id" ] && [ "$buildID" != "$to_build_id" ]; then echo "TEST-UNEXPECTED-FAIL: expected buildID $to_build_id does not match actual $buildID" return 1 fi - if [ ! -z "$to_display_version" -a "$displayVersion" != "$to_display_version" ]; then + # shellcheck disable=SC2154 + if [ -n "$to_display_version" ] && [ "$displayVersion" != "$to_display_version" ]; then echo "TEST-UNEXPECTED-FAIL: expected displayVersion $to_display_version does not match actual $displayVersion" return 1 fi - if [ ! -z "$to_app_version" -a "$appVersion" != "$to_app_version" ]; then + # shellcheck disable=SC2154 + if [ -n "$to_app_version" ] && [ "$appVersion" != "$to_app_version" ]; then echo "TEST-UNEXPECTED-FAIL: expected appVersion $to_app_version does not match actual $appVersion" return 1 fi mkdir -p update/ - if [ -z $only ]; then + if [ -z "$only" ]; then only="partial complete" fi for patch_type in $only do - line=`fgrep "patch type=\"$patch_type" update.xml` + line=$(grep -F "patch type=\"$patch_type" update.xml) grep_rv=$? if [ 0 -ne $grep_rv ]; then @@ -66,40 +75,44 @@ download_mars () { return 1 fi - command=`echo $line | sed -e 's/^.*<patch //' -e 's:/>.*$::' -e 's:\&:\&:g'` + command=$(echo "$line" | sed -e 's/^.*<patch //' -e 's:/>.*$::' -e 's:\&:\&:g') eval "export $command" if [ "$test_only" == "1" ] then echo "Testing $URL" - curl -s -I -L $URL + curl -s -I -L "$URL" return else - cached_download "update/${patch_type}.mar" "${URL}" - fi - if [ "$?" != 0 ]; then - echo "Could not download $patch_type!" - echo "from: $URL" + if ! cached_download "update/${patch_type}.mar" "${URL}"; then + echo "Could not download $patch_type!" + echo "from: $URL" + fi fi - actual_size=`perl -e "printf \"%d\n\", (stat(\"update/$patch_type.mar\"))[7]"` - actual_hash=`openssl dgst -$hashFunction update/$patch_type.mar | sed -e 's/^.*= //'` + actual_size=$(perl -e "printf \"%d\n\", (stat(\"update/$patch_type.mar\"))[7]") + # shellcheck disable=SC2154 + actual_hash=$(openssl dgst -"$hashFunction" update/"$patch_type".mar | sed -e 's/^.*= //') - if [ $actual_size != $size ]; then + # shellcheck disable=SC2154 + if [ "$actual_size" != "$size" ]; then echo "TEST-UNEXPECTED-FAIL: $patch_type from $update_url wrong size" + # shellcheck disable=SC2154 echo "TEST-UNEXPECTED-FAIL: update.xml size: $size" echo "TEST-UNEXPECTED-FAIL: actual size: $actual_size" return 1 fi - if [ $actual_hash != $hashValue ]; then + # shellcheck disable=SC2154 + if [ "$actual_hash" != "$hashValue" ]; then echo "TEST-UNEXPECTED-FAIL: $patch_type from $update_url wrong hash" + # shellcheck disable=SC2154 echo "TEST-UNEXPECTED-FAIL: update.xml hash: $hashValue" echo "TEST-UNEXPECTED-FAIL: actual hash: $actual_hash" return 1 fi - cp update/$patch_type.mar update/update.mar - echo $actual_size > update/$patch_type.size + cp update/"$patch_type".mar update/update.mar + echo "$actual_size" > update/"$patch_type".size done } diff --git a/tools/update-verify/release/common/unpack-diskimage.sh b/tools/update-verify/release/common/unpack-diskimage.sh index b647a69c4d..760fe0bd33 100755 --- a/tools/update-verify/release/common/unpack-diskimage.sh +++ b/tools/update-verify/release/common/unpack-diskimage.sh @@ -53,43 +53,43 @@ TIMEOUT=90 # If the mount point already exists, then the previous run may not have cleaned # up properly. We should try to umount and remove the its directory. -if [ -d $MOUNTPOINT ]; then +if [ -d "$MOUNTPOINT" ]; then echo "$MOUNTPOINT already exists, trying to clean up" - hdiutil detach $MOUNTPOINT -force - rm -rdfv $MOUNTPOINT + hdiutil detach "$MOUNTPOINT" -force + rm -rdfv "$MOUNTPOINT" fi # Install an on-exit handler that will unmount and remove the '$MOUNTPOINT' directory -trap "{ if [ -d $MOUNTPOINT ]; then hdiutil detach $MOUNTPOINT -force; rm -rdfv $MOUNTPOINT; fi; }" EXIT +trap '{ if [ -d $MOUNTPOINT ]; then hdiutil detach $MOUNTPOINT -force; rm -rdfv $MOUNTPOINT; fi; }' EXIT -mkdir -p $MOUNTPOINT +mkdir -p "$MOUNTPOINT" -hdiutil attach -verbose -noautoopen -mountpoint $MOUNTPOINT "$DMG_PATH" &> $LOGFILE +hdiutil attach -verbose -noautoopen -mountpoint "$MOUNTPOINT" "$DMG_PATH" &> $LOGFILE # Wait for files to show up # hdiutil uses a helper process, diskimages-helper, which isn't always done its # work by the time hdiutil exits. So we wait until something shows up in the # mount point directory. i=0 -while [ "$(echo $MOUNTPOINT/*)" == "$MOUNTPOINT/*" ]; do - if [ $i -gt $TIMEOUT ]; then +while [ "$(echo "$MOUNTPOINT"/*)" == "$MOUNTPOINT/*" ]; do + if [ "$i" -gt $TIMEOUT ]; then echo "No files found, exiting" exit 1 fi sleep 1 - i=$(expr $i + 1) + i=$((i+1)) done # Now we can copy everything out of the $MOUNTPOINT directory into the target directory -rsync -av $MOUNTPOINT/* $MOUNTPOINT/.DS_Store $MOUNTPOINT/.background $MOUNTPOINT/.VolumeIcon.icns $TARGETPATH/ > $LOGFILE +rsync -av "$MOUNTPOINT"/* "$MOUNTPOINT"/.DS_Store "$MOUNTPOINT"/.background "$MOUNTPOINT"/.VolumeIcon.icns "$TARGETPATH"/ > $LOGFILE # sometimes hdiutil fails with "Resource busy" -hdiutil detach $MOUNTPOINT || { sleep 10; \ - if [ -d $MOUNTPOINT ]; then hdiutil detach $MOUNTPOINT -force; fi; } +hdiutil detach "$MOUNTPOINT" || { sleep 10; \ + if [ -d "$MOUNTPOINT" ]; then hdiutil detach "$MOUNTPOINT" -force; fi; } i=0 -while [ "$(echo $MOUNTPOINT/*)" != "$MOUNTPOINT/*" ]; do - if [ $i -gt $TIMEOUT ]; then +while [ "$(echo "$MOUNTPOINT"/*)" != "$MOUNTPOINT/*" ]; do + if [ "$i" -gt $TIMEOUT ]; then echo "Cannot umount, exiting" exit 1 fi sleep 1 - i=$(expr $i + 1) + i=$((i+1)) done -rm -rdf $MOUNTPOINT +rm -rdf "$MOUNTPOINT" diff --git a/tools/update-verify/release/common/unpack.sh b/tools/update-verify/release/common/unpack.sh index 3249936493..a0e1204487 100755 --- a/tools/update-verify/release/common/unpack.sh +++ b/tools/update-verify/release/common/unpack.sh @@ -1,11 +1,5 @@ #!/bin/bash -function cleanup() { - hdiutil detach ${DEV_NAME} || - { sleep 5 && hdiutil detach ${DEV_NAME} -force; }; - return $1 && $?; -}; - unpack_build () { unpack_platform="$1" dir_name="$2" @@ -13,27 +7,35 @@ unpack_build () { locale=$4 unpack_jars=$5 update_settings_string=$6 + # If provided, must be a directory containing `update-settings.ini` which + # will be used instead of attempting to find this file in the unpacked + # build. `update_settings_string` modifications will still be performed on + # the file. + local mac_update_settings_dir_override + mac_update_settings_dir_override=$7 + local product + product=$8 if [ ! -f "$pkg_file" ]; then return 1 fi - mkdir -p $dir_name - pushd $dir_name > /dev/null + mkdir -p "$dir_name" + pushd "$dir_name" > /dev/null || exit case $unpack_platform in # $unpack_platform is either # - a balrog platform name (from testing/mozharness/scripts/release/update-verify-config-creator.py) # - a simple platform name (from tools/update-verify/release/updates/verify.sh) mac|Darwin_*) - os=`uname` + os=$(uname) # How we unpack a dmg differs depending on which platform we're on. if [[ "$os" == "Darwin" ]] then cd ../ echo "installing $pkg_file" - ../common/unpack-diskimage.sh "$pkg_file" mnt $dir_name + ../common/unpack-diskimage.sh "$pkg_file" mnt "$dir_name" else 7z x ../"$pkg_file" > /dev/null - if [ `ls -1 | wc -l` -ne 1 ] + if [ "$(find . -mindepth 1 -maxdepth 1 | wc -l)" -ne 1 ] then echo "Couldn't find .app package" return 1 @@ -43,14 +45,18 @@ unpack_build () { mv "${unpack_dir}"/*.app . rm -rf "${unpack_dir}" appdir=$(ls -1) - appdir=$(ls -d *.app) - # The updater guesses the location of these files based on - # its own target architecture, not the mar. If we're not - # unpacking mac-on-mac, we need to copy them so it can find - # them. It's important to copy (and not move), because when - # we diff the installer vs updated build afterwards, the - # installer version will have them in their original place. - cp "${appdir}/Contents/Resources/update-settings.ini" "${appdir}/update-settings.ini" + appdir=$(ls -d ./*.app) + if [ -d "${mac_update_settings_dir_override}" ]; then + cp "${mac_update_settings_dir_override}/update-settings.ini" "${appdir}/update-settings.ini" + else + # The updater guesses the location of these files based on + # its own target architecture, not the mar. If we're not + # unpacking mac-on-mac, we need to copy them so it can find + # them. It's important to copy (and not move), because when + # we diff the installer vs updated build afterwards, the + # installer version will have them in their original place. + cp "${appdir}/Contents/Resources/update-settings.ini" "${appdir}/update-settings.ini" + fi cp "${appdir}/Contents/Resources/precomplete" "${appdir}/precomplete" fi update_settings_file="${appdir}/update-settings.ini" @@ -64,7 +70,7 @@ unpack_build () { cp -rp localized/* bin/ rm -rf nonlocalized rm -rf localized - if [ $(find optional/ | wc -l) -gt 1 ] + if [ "$(find optional/ | wc -l)" -gt 1 ] then cp -rp optional/* bin/ rm -rf optional @@ -77,45 +83,43 @@ unpack_build () { else for file in *.xpi do - unzip -o $file > /dev/null + unzip -o "$file" > /dev/null done - unzip -o ${locale}.xpi > /dev/null + unzip -o "${locale}".xpi > /dev/null fi update_settings_file='bin/update-settings.ini' ;; linux|Linux_*) - if `echo $pkg_file | grep -q "tar.gz"` + if echo "$pkg_file" | grep -q "tar.gz" then tar xfz ../"$pkg_file" > /dev/null - elif `echo $pkg_file | grep -q "tar.bz2"` + elif echo "$pkg_file" | grep -q "tar.bz2" then tar xfj ../"$pkg_file" > /dev/null else echo "Unknown package type for file: $pkg_file" exit 1 fi - update_settings_file=`echo $product | tr '[A-Z]' '[a-z]'`'/update-settings.ini' + update_settings_file=$(echo "$product" | tr '[:upper:]' '[:lower:]')'/update-settings.ini' ;; *) echo "Unknown platform to unpack: $unpack_platform" exit 1 esac - if [ ! -z $unpack_jars ]; then - for f in `find . -name '*.jar' -o -name '*.ja'`; do - unzip -o "$f" -d "$f.dir" > /dev/null - done + if [ -n "$unpack_jars" ]; then + find . \( -name '*.jar' -o -name '*.ja' \) -exec unzip -o {} -d {}.dir \; >/dev/null fi - if [ ! -z $update_settings_string ]; then + if [ -n "$update_settings_string" ]; then echo "Modifying update-settings.ini" - cat "${update_settings_file}" | sed -e "s/^ACCEPTED_MAR_CHANNEL_IDS.*/ACCEPTED_MAR_CHANNEL_IDS=${update_settings_string}/" > "${update_settings_file}.new" + sed -e "s/^ACCEPTED_MAR_CHANNEL_IDS.*/ACCEPTED_MAR_CHANNEL_IDS=${update_settings_string}/" < "${update_settings_file}" > "${update_settings_file}.new" diff -u "${update_settings_file}" "${update_settings_file}.new" echo " " rm "${update_settings_file}" mv "${update_settings_file}.new" "${update_settings_file}" fi - popd > /dev/null + popd > /dev/null || exit } diff --git a/tools/update-verify/release/compare-directories.py b/tools/update-verify/release/compare-directories.py index ea70d79b31..714f02a66d 100755 --- a/tools/update-verify/release/compare-directories.py +++ b/tools/update-verify/release/compare-directories.py @@ -29,7 +29,6 @@ TRANSFORMS = [ # this can be removed once each channel has a watershed above 59.0b2 (from bug 1431342) "files": [ "defaults/pref/channel-prefs.js", - "Contents/Resources/defaults/pref/channel-prefs.js", ], "channel_prefix": ["aurora", "beta", "release", "esr"], "side": "source", @@ -39,7 +38,6 @@ TRANSFORMS = [ # updates from a beta to an RC build, the latter specifies the release channel "files": [ "defaults/pref/channel-prefs.js", - "Contents/Resources/defaults/pref/channel-prefs.js", ], "channel_prefix": ["beta"], "side": "target", @@ -52,7 +50,6 @@ TRANSFORMS = [ # updates from an RC to a beta build "files": [ "defaults/pref/channel-prefs.js", - "Contents/Resources/defaults/pref/channel-prefs.js", ], "channel_prefix": ["beta"], "side": "source", @@ -69,7 +66,6 @@ TRANSFORMS = [ # to break before applying this transform. "files": [ "defaults/pref/channel-prefs.js", - "Contents/Resources/defaults/pref/channel-prefs.js", ], "channel_prefix": ["aurora", "beta", "release", "esr"], "side": "target", @@ -80,7 +76,7 @@ TRANSFORMS = [ # updates from a beta to an RC build, the latter specifies the release channel # on mac, we actually have both files. The second location is the real # one but we copy to the first to run the linux64 updater - "files": ["update-settings.ini", "Contents/Resources/update-settings.ini"], + "files": ["update-settings.ini"], "channel_prefix": ["beta"], "side": "target", "substitution": [ @@ -88,20 +84,20 @@ TRANSFORMS = [ "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-beta,firefox-mozilla-release\n", ], }, - { - # updates from an RC to a beta build - # on mac, we only need to modify the legit file this time. unpack_build - # handles the copy for the updater in both source and target - "files": ["Contents/Resources/update-settings.ini"], - "channel_prefix": ["beta"], - "side": "source", - "substitution": [ - "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-release\n", - "ACCEPTED_MAR_CHANNEL_IDS=firefox-mozilla-beta,firefox-mozilla-release\n", - ], - }, ] +# Files that are expected to be different, but cannot be transformed to get a useful diff. +# This should generally only be used for files that have unpredictable contents, eg: +# things that are signed but not updated. +IGNORE_FILES = ( + "Contents/MacOS/updater.app/Contents/Frameworks/UpdateSettings.framework/Resources/Info.plist", + "Contents/MacOS/updater.app/Contents/Frameworks/UpdateSettings.framework/_CodeSignature/CodeResources", + "Contents/MacOS/updater.app/Contents/Frameworks/UpdateSettings.framework/UpdateSettings", + "Contents/Frameworks/ChannelPrefs.framework/Resources/Info.plist", + "Contents/Frameworks/ChannelPrefs.framework/_CodeSignature/CodeResources", + "Contents/Frameworks/ChannelPrefs.framework/ChannelPrefs", +) + def walk_dir(path): all_files = [] @@ -170,6 +166,14 @@ def compare_common_files(files, channel, source_dir, target_dir): source_file ) != hash_file(target_file): logging.info("Difference found in {}".format(filename)) + if filename in IGNORE_FILES: + logging.info( + "Ignoring difference in {} because it is listed in IGNORE_FILES".format( + filename + ) + ) + continue + file_contents = { "source": open(source_file).readlines(), "target": open(target_file).readlines(), diff --git a/tools/update-verify/release/updates/verify.sh b/tools/update-verify/release/updates/verify.sh index 3f8556b424..4f7201c048 100755 --- a/tools/update-verify/release/updates/verify.sh +++ b/tools/update-verify/release/updates/verify.sh @@ -20,14 +20,14 @@ to_app_version="" to_display_version="" override_certs="" diff_summary_log=${DIFF_SUMMARY_LOG:-"$PWD/diff-summary.log"} -if [ -e ${diff_summary_log} ]; then - rm ${diff_summary_log} +if [ -e "${diff_summary_log}" ]; then + rm "${diff_summary_log}" fi -touch ${diff_summary_log} +touch "${diff_summary_log}" -pushd `dirname $0` &>/dev/null +pushd "$(dirname "$0")" &>/dev/null || exit MY_DIR=$(pwd) -popd &>/dev/null +popd &>/dev/null || exit retry="$MY_DIR/../../../../mach python -m redo.cmd -s 1 -a 3" cert_replacer="$MY_DIR/../replace-updater-certs.py" @@ -82,7 +82,7 @@ do arg="$1" shift set -- "$@" "$arg" - pass_arg_count=`expr $pass_arg_count + 1` + pass_arg_count=$((pass_arg_count + 1)) esac done @@ -100,7 +100,7 @@ then exit 0 fi -while read entry +while read -r entry do # initialize all config variables release="" @@ -111,21 +111,10 @@ do channel="" from="" patch_types="complete" - use_old_updater=0 mar_channel_IDs="" updater_package="" - eval $entry - - # the arguments for updater changed in Gecko 34/SeaMonkey 2.31 - major_version=`echo $release | cut -f1 -d.` - if [[ "$product" == "seamonkey" ]]; then - minor_version=`echo $release | cut -f2 -d.` - if [[ $major_version -le 2 && $minor_version -lt 31 ]]; then - use_old_updater=1 - fi - elif [[ $major_version -lt 34 ]]; then - use_old_updater=1 - fi + mac_update_settings_dir_override="" + eval "$entry" # Note: cross platform tests seem to work for everything except Mac-on-Windows. # We probably don't care about this use case. @@ -144,11 +133,11 @@ do then if [ "$runmode" == "$TEST_ONLY" ] then - download_mars "${aus_server}/update/3/${update_path}/default/update.xml?force=1" ${patch_type} 1 \ + download_mars "${aus_server}/update/3/${update_path}/default/update.xml?force=1" "${patch_type}" 1 \ "${to_build_id}" "${to_app_version}" "${to_display_version}" err=$? else - download_mars "${aus_server}/update/3/${update_path}/update.xml?force=1" ${patch_type} 0 \ + download_mars "${aus_server}/update/3/${update_path}/update.xml?force=1" "${patch_type}" 0 \ "${to_build_id}" "${to_app_version}" "${to_display_version}" err=$? fi @@ -157,9 +146,9 @@ do continue fi else - mkdir -p updates/${update_path}/complete - mkdir -p updates/${update_path}/partial - $retry wget -q -O ${patch_type} updates/${update_path}/${patch_type}/update.xml "${aus_server}/update/3/${update_path}/update.xml?force=1" + mkdir -p updates/"${update_path}"/complete + mkdir -p updates/"${update_path}"/partial + $retry wget -q -O "${patch_type}" updates/"${update_path}"/"${patch_type}"/update.xml "${aus_server}/update/3/${update_path}/update.xml?force=1" fi if [ "$runmode" == "$COMPLETE" ] @@ -170,25 +159,42 @@ do fi updater_platform="" - updater_package_url=`echo "${ftp_server_from}${updater_package}" | sed "s/%locale%/${locale}/"` - updater_package_filename=`basename "$updater_package_url"` + updater_package_url=$(echo "${ftp_server_from}${updater_package}" | sed "s/%locale%/${locale}/") + updater_package_filename=$(basename "$updater_package_url") case $updater_package_filename in *dmg) platform_dirname="*.app" updater_bins="Contents/MacOS/updater.app/Contents/MacOS/updater Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater" updater_platform="mac" + mac_update_settings_dir_override="" ;; *exe) - updater_package_url=`echo "${updater_package_url}" | sed "s/ja-JP-mac/ja/"` + updater_package_url=${updater_package_url/ja-JP-mac/ja} platform_dirname="bin" updater_bins="updater.exe" updater_platform="win32" + case $platform in + Darwin_*) + mac_update_settings_dir_override="${PWD}/updater/${platform_dirname}" + ;; + *) + mac_update_settings_dir_override="" + ;; + esac ;; *bz2) - updater_package_url=`echo "${updater_package_url}" | sed "s/ja-JP-mac/ja/"` - platform_dirname=`echo $product | tr '[A-Z]' '[a-z]'` + updater_package_url=${updater_package_url/ja-JP-mac/ja} + platform_dirname=$(echo "$product" | tr '[:upper:]' '[:lower:]') updater_bins="updater" updater_platform="linux" + case $platform in + Darwin_*) + mac_update_settings_dir_override="${PWD}/updater/${platform_dirname}" + ;; + *) + mac_update_settings_dir_override="" + ;; + esac ;; *) echo "Couldn't detect updater platform" @@ -198,10 +204,10 @@ do rm -rf updater/* cached_download "${updater_package_filename}" "${updater_package_url}" - unpack_build "$updater_platform" updater "$updater_package_filename" "$locale" + unpack_build "$updater_platform" updater "$updater_package_filename" "$locale" "$product" # Even on Windows, we want Unix-style paths for the updater, because of MSYS. - cwd=$(\ls -d $PWD/updater/$platform_dirname) + cwd=$(\ls -d "$PWD"/updater/"$platform_dirname") # Bug 1209376. Linux updater linked against other libraries in the installation directory export LD_LIBRARY_PATH=$cwd updater="null" @@ -214,7 +220,7 @@ do done update_to_dep=false - if [ ! -z "$override_certs" ]; then + if [ -n "$override_certs" ]; then echo "Replacing certs in updater binary" cp "${updater}" "${updater}.orig" case ${override_certs} in @@ -232,6 +238,8 @@ do echo "Unknown override cert - skipping" ;; esac + # because we actually rely on $overrides being split up into separate args 🤦 + # shellcheck disable=SC2086 python3 "${cert_replacer}" "${MY_DIR}/../mar_certs" "${updater}.orig" "${updater}" ${overrides} else echo "override_certs is '${override_certs}', not replacing any certificates" @@ -242,21 +250,23 @@ do continue fi - from_path=`echo $from | sed "s/%locale%/${locale}/"` - to_path=`echo $to | sed "s/%locale%/${locale}/"` + # Quotes around %locale% needed to prevent bash from interpreting the + # "%" characters as special characters. + from_path=${from/"%locale%"/${locale}} + to_path=${to/"%locale%"/${locale}} download_builds "${ftp_server_from}${from_path}" "${ftp_server_to}${to_path}" err=$? if [ "$err" != "0" ]; then echo "TEST-UNEXPECTED-FAIL: [$release $locale $patch_type] download_builds returned non-zero exit code: $err" continue fi - source_file=`basename "$from_path"` - target_file=`basename "$to_path"` + source_file=$(basename "$from_path") + target_file=$(basename "$to_path") diff_file="results.diff" if [ -e ${diff_file} ]; then rm ${diff_file} fi - check_updates "${platform}" "downloads/${source_file}" "downloads/${target_file}" ${locale} ${use_old_updater} ${updater} ${diff_file} ${channel} "${mar_channel_IDs}" ${update_to_dep} + check_updates "${platform}" "downloads/${source_file}" "downloads/${target_file}" "${locale}" "${updater}" ${diff_file} "${channel}" "${mar_channel_IDs}" ${update_to_dep} "${mac_update_settings_dir_override}" "${product}" err=$? if [ "$err" == "0" ]; then continue @@ -268,25 +278,27 @@ do echo "TEST-UNEXPECTED-FAIL: [$release $locale $patch_type] check_updates returned unknown error for $platform downloads/$source_file vs. downloads/$target_file: $err" fi - if [ -s ${diff_file} ]; then - echo "Found diffs for ${patch_type} update from ${aus_server}/update/3/${update_path}/update.xml?force=1" >> ${diff_summary_log} - cat ${diff_file} >> ${diff_summary_log} - echo "" >> ${diff_summary_log} + if [ -s "${diff_file}" ]; then + { + echo "Found diffs for ${patch_type} update from ${aus_server}/update/3/${update_path}/update.xml?force=1" + cat "${diff_file}" + echo "" + } >> "${diff_summary_log}" fi fi done if [ -f update/partial.size ] && [ -f update/complete.size ]; then - partial_size=`cat update/partial.size` - complete_size=`cat update/complete.size` - if [ $partial_size -gt $complete_size ]; then + partial_size=$(cat update/partial.size) + complete_size=$(cat update/complete.size) + if [ "$partial_size" -gt "$complete_size" ]; then echo "TEST-UNEXPECTED-FAIL: [$release $locale $patch_type] partial updates are larger than complete updates" - elif [ $partial_size -eq $complete_size ]; then + elif [ "$partial_size" -eq "$complete_size" ]; then echo "WARN: [$release $locale $patch_type] partial updates are the same size as complete updates, this should only happen for major updates" else echo "SUCCESS: [$release $locale $patch_type] partial updates are smaller than complete updates, all is well in the universe" fi fi done -done < $config_file +done < "$config_file" clear_cache |