From cdca3eeb83ee0fe15daa351a54573f1bae430e37 Mon Sep 17 00:00:00 2001 From: Kala Severe Date: Tue, 17 Mar 2026 16:54:07 -0700 Subject: [PATCH 01/11] Bug: 2020622 Updated column title from Total Runs to Total Trials (#1012) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * updated column title from Total Runs to Total Trials * change key from runs to trials * Update all npm dependencies (2026-03-13) (#1010) * ⬆️ Update all npm dependencies (2026-03-13) * updated snapshots --------- Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> Co-authored-by: Carla Severe * updated column title from Total Runs to Total Trials * change key from runs to trials --------- Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> --- .../OverTimeResultsView.test.tsx.snap | 4 ++-- .../__snapshots__/ResultsTable.test.tsx.snap | 8 ++++---- .../__snapshots__/ResultsView.test.tsx.snap | 4 ++-- .../SubtestsResultsView.test.tsx.snap | 20 +++++++++---------- src/common/testVersions/mannWhitney.tsx | 4 ++-- src/common/testVersions/studentT.tsx | 4 ++-- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap index da6222eb3..029e425c6 100644 --- a/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap +++ b/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap @@ -536,7 +536,7 @@ exports[`Results View The table should match snapshot and other elements should
- Total Runs + Total Trials
- Total Runs + Total Trials
- Total Runs + Total Trials
- Total Runs + Total Trials
- Total Runs + Total Trials
- Total Runs + Total Trials
- Total Runs + Total Trials
- Total Runs + Total Trials
- Total Runs + Total Trials
Date: Wed, 25 Mar 2026 21:48:16 +0530 Subject: [PATCH 02/11] Bug-2020964: Update Contributing section in README (#1009) * docs: Update Contributing section in README Updated the section in the README where it asks to link PR to issue. We use Bugzilla for filing issues. This PR adds the correct steps to link the PR to the issues. The old steps were relevant if we were using GitHub for filing issues. * Bug-2020964: Implemented review comments Removed the additional instruction on bugzilla attachment as per review comment. --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 196a48901..bf0ca0caf 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,18 @@ If you do not receive a response within 2-3 days, you can follow up in the #Perf After addressing the issue, ensure both tests and linting pass before submitting a pull request. -When submitting a pull request, please mention the issue number to link the pull request and issue to one another. You can do this by typing # following immediately by the issue number, i.e., `#123` +When submitting a pull request, please mention the bugzilla issue number in the PR title and description . For example, if you are creating a PR for issue XXX, create a PR as below + +``` +Bug-XXX: Short description of the issue being fixed + +Description of the issue being fixed and how the PR addresses it. + +Fixes [Bug-XXX](https://bugzilla.mozilla.org/show_bug.cgi?id=XXX) +``` + +Once the PR is created, please link the PR to the corresponding bugzilla issue by pasting the PR link as an +attachment in the bugzilla issue. --- From 66147c3cd32d13ec1c0d241e73834e02a1bc1c98 Mon Sep 17 00:00:00 2001 From: "depfu[bot]" <23717796+depfu[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 09:38:00 -0700 Subject: [PATCH 03/11] Update all npm dependencies (2026-03-25) (#1014) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⬆️ Update all npm dependencies (2026-03-25) Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> --- package-lock.json | 2031 +++++++++++++++++++++++---------------------- package.json | 22 +- 2 files changed, 1040 insertions(+), 1013 deletions(-) diff --git a/package-lock.json b/package-lock.json index 36548a7d1..9bb91c41e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "buffer": "^6.0.3", "chart.js": "^4.5.1", "crypto-browserify": "^3.12.1", - "dayjs": "^1.11.19", + "dayjs": "^1.11.20", "express": "^5.2.1", "fast-kde": "^0.2.2", "format": "^0.2.2", @@ -41,13 +41,13 @@ "devDependencies": { "@babel/core": "^7.29.0", "@babel/plugin-transform-runtime": "^7.29.0", - "@babel/preset-env": "^7.29.0", + "@babel/preset-env": "^7.29.2", "@babel/preset-react": "^7.28.5", "@babel/preset-typescript": "^7.28.5", - "@babel/runtime": "^7.28.6", + "@babel/runtime": "^7.29.2", "@eslint/js": "^9.39.4", "@fetch-mock/jest": "^0.2.20", - "@jest/types": "^30.2.0", + "@jest/types": "^30.3.0", "@swc/core": "^1.15.18", "@swc/jest": "^0.2.39", "@testing-library/dom": "^10.4.1", @@ -57,14 +57,14 @@ "@types/jest": "^30.0.0", "@types/jest-axe": "^3.5.9", "@types/material-ui": "^0.21.18", - "@types/node": "^25.2.3", + "@types/node": "^25.5.0", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", "babel-loader": "^10.1.1", - "babel-preset-jest": "^30.2.0", + "babel-preset-jest": "^30.3.0", "case-sensitive-paths-webpack-plugin": "^2.4.0", "copy-webpack-plugin": "^13.0.1", - "core-js": "^3.48.0", + "core-js": "^3.49.0", "css-loader": "^7.1.4", "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", @@ -77,10 +77,10 @@ "globals": "^17.4.0", "history": "^5.3.0", "html-webpack-plugin": "^5.6.6", - "jest": "^30.2.0", + "jest": "^30.3.0", "jest-axe": "^10.0.0", - "jest-environment-jsdom": "^30.2.0", - "jest-resolve": "^30.2.0", + "jest-environment-jsdom": "^30.3.0", + "jest-resolve": "^30.3.0", "npm-run-all2": "^8.0.4", "prettier": "3.7.4", "react-app-polyfill": "^3.0.0", @@ -91,7 +91,7 @@ "ts-loader": "^9.5.4", "ts-node": "^10.9.2", "typescript": "^5.9.3", - "typescript-eslint": "^8.56.0", + "typescript-eslint": "^8.57.2", "webpack": "^5.105.4", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.3", @@ -1803,9 +1803,9 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.0.tgz", - "integrity": "sha512-fNEdfc0yi16lt6IZo2Qxk3knHVdfMYX33czNb4v8yWhemoBhibCpQK/uYHtSKIiO+p/zd3+8fYVXhQdOVV608w==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.2.tgz", + "integrity": "sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw==", "dev": true, "dependencies": { "@babel/compat-data": "^7.29.0", @@ -1963,9 +1963,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", - "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", "engines": { "node": ">=6.9.0" } @@ -2680,12 +2680,12 @@ } }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" @@ -2739,16 +2739,16 @@ } }, "node_modules/@jest/console": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.2.0.tgz", - "integrity": "sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.3.0.tgz", + "integrity": "sha512-PAwCvFJ4696XP2qZj+LAn1BWjZaJ6RjG6c7/lkMaUJnkyMS34ucuIsfqYvfskVNvUI27R/u4P1HMYFnlVXG/Ww==", "dev": true, "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", + "jest-message-util": "30.3.0", + "jest-util": "30.3.0", "slash": "^3.0.0" }, "engines": { @@ -2756,38 +2756,37 @@ } }, "node_modules/@jest/core": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.2.0.tgz", - "integrity": "sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.3.0.tgz", + "integrity": "sha512-U5mVPsBxLSO6xYbf+tgkymLx+iAhvZX43/xI1+ej2ZOPnPdkdO1CzDmFKh2mZBn2s4XZixszHeQnzp1gm/DIxw==", "dev": true, "dependencies": { - "@jest/console": "30.2.0", + "@jest/console": "30.3.0", "@jest/pattern": "30.0.1", - "@jest/reporters": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", + "@jest/reporters": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "ci-info": "^4.2.0", "exit-x": "^0.2.2", "graceful-fs": "^4.2.11", - "jest-changed-files": "30.2.0", - "jest-config": "30.2.0", - "jest-haste-map": "30.2.0", - "jest-message-util": "30.2.0", + "jest-changed-files": "30.3.0", + "jest-config": "30.3.0", + "jest-haste-map": "30.3.0", + "jest-message-util": "30.3.0", "jest-regex-util": "30.0.1", - "jest-resolve": "30.2.0", - "jest-resolve-dependencies": "30.2.0", - "jest-runner": "30.2.0", - "jest-runtime": "30.2.0", - "jest-snapshot": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", - "jest-watcher": "30.2.0", - "micromatch": "^4.0.8", - "pretty-format": "30.2.0", + "jest-resolve": "30.3.0", + "jest-resolve-dependencies": "30.3.0", + "jest-runner": "30.3.0", + "jest-runtime": "30.3.0", + "jest-snapshot": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", + "jest-watcher": "30.3.0", + "pretty-format": "30.3.0", "slash": "^3.0.0" }, "engines": { @@ -2815,9 +2814,9 @@ } }, "node_modules/@jest/core/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "node_modules/@jest/core/node_modules/ansi-styles": { @@ -2833,9 +2832,9 @@ } }, "node_modules/@jest/core/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "dependencies": { "@jest/schemas": "30.0.5", @@ -2895,42 +2894,42 @@ "dev": true }, "node_modules/@jest/diff-sequences": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", - "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", + "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", "dev": true, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/environment": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz", - "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.3.0.tgz", + "integrity": "sha512-SlLSF4Be735yQXyh2+mctBOzNDx5s5uLv88/j8Qn1wH679PDcwy67+YdADn8NJnGjzlXtN62asGH/T4vWOkfaw==", "dev": true, "dependencies": { - "@jest/fake-timers": "30.2.0", - "@jest/types": "30.2.0", + "@jest/fake-timers": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", - "jest-mock": "30.2.0" + "jest-mock": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/environment-jsdom-abstract": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.2.0.tgz", - "integrity": "sha512-kazxw2L9IPuZpQ0mEt9lu9Z98SqR74xcagANmMBU16X0lS23yPc0+S6hGLUz8kVRlomZEs/5S/Zlpqwf5yu6OQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.3.0.tgz", + "integrity": "sha512-0hNFs5N6We3DMCwobzI0ydhkY10sT1tZSC0AAiy+0g2Dt/qEWgrcV5BrMxPczhe41cxW4qm6X+jqZaUdpZIajA==", "dev": true, "dependencies": { - "@jest/environment": "30.2.0", - "@jest/fake-timers": "30.2.0", - "@jest/types": "30.2.0", + "@jest/environment": "30.3.0", + "@jest/fake-timers": "30.3.0", + "@jest/types": "30.3.0", "@types/jsdom": "^21.1.7", "@types/node": "*", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" + "jest-mock": "30.3.0", + "jest-util": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -2946,22 +2945,22 @@ } }, "node_modules/@jest/expect": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz", - "integrity": "sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.3.0.tgz", + "integrity": "sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg==", "dev": true, "dependencies": { - "expect": "30.2.0", - "jest-snapshot": "30.2.0" + "expect": "30.3.0", + "jest-snapshot": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", - "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.3.0.tgz", + "integrity": "sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==", "dev": true, "dependencies": { "@jest/get-type": "30.1.0" @@ -2971,17 +2970,17 @@ } }, "node_modules/@jest/fake-timers": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz", - "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.3.0.tgz", + "integrity": "sha512-WUQDs8SOP9URStX1DzhD425CqbN/HxUYCTwVrT8sTVBfMvFqYt/s61EK5T05qnHu0po6RitXIvP9otZxYDzTGQ==", "dev": true, "dependencies": { - "@jest/types": "30.2.0", - "@sinonjs/fake-timers": "^13.0.0", + "@jest/types": "30.3.0", + "@sinonjs/fake-timers": "^15.0.0", "@types/node": "*", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", + "jest-util": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -2997,15 +2996,15 @@ } }, "node_modules/@jest/globals": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz", - "integrity": "sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.3.0.tgz", + "integrity": "sha512-+owLCBBdfpgL3HU+BD5etr1SvbXpSitJK0is1kiYjJxAAJggYMRQz5hSdd5pq1sSggfxPbw2ld71pt4x5wwViA==", "dev": true, "dependencies": { - "@jest/environment": "30.2.0", - "@jest/expect": "30.2.0", - "@jest/types": "30.2.0", - "jest-mock": "30.2.0" + "@jest/environment": "30.3.0", + "@jest/expect": "30.3.0", + "@jest/types": "30.3.0", + "jest-mock": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -3026,31 +3025,31 @@ } }, "node_modules/@jest/reporters": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz", - "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.3.0.tgz", + "integrity": "sha512-a09z89S+PkQnL055bVj8+pe2Caed2PBOaczHcXCykW5ngxX9EWx/1uAwncxc/HiU0oZqfwseMjyhxgRjS49qPw==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", + "@jest/console": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "@jridgewell/trace-mapping": "^0.3.25", "@types/node": "*", "chalk": "^4.1.2", "collect-v8-coverage": "^1.0.2", "exit-x": "^0.2.2", - "glob": "^10.3.10", + "glob": "^10.5.0", "graceful-fs": "^4.2.11", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^5.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", - "jest-worker": "30.2.0", + "jest-message-util": "30.3.0", + "jest-util": "30.3.0", + "jest-worker": "30.3.0", "slash": "^3.0.0", "string-length": "^4.0.2", "v8-to-istanbul": "^9.0.1" @@ -3077,9 +3076,10 @@ } }, "node_modules/@jest/reporters/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "dependencies": { "foreground-child": "^3.1.0", @@ -3097,12 +3097,12 @@ } }, "node_modules/@jest/reporters/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -3125,12 +3125,12 @@ } }, "node_modules/@jest/snapshot-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz", - "integrity": "sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.3.0.tgz", + "integrity": "sha512-ORbRN9sf5PP82v3FXNSwmO1OTDR2vzR2YTaR+E3VkSBZ8zadQE6IqYdYEeFH1NIkeB2HIGdF02dapb6K0Mj05g==", "dev": true, "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "natural-compare": "^1.4.0" @@ -3154,13 +3154,13 @@ } }, "node_modules/@jest/test-result": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.2.0.tgz", - "integrity": "sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.3.0.tgz", + "integrity": "sha512-e/52nJGuD74AKTSe0P4y5wFRlaXP0qmrS17rqOMHeSwm278VyNyXE3gFO/4DTGF9w+65ra3lo3VKj0LBrzmgdQ==", "dev": true, "dependencies": { - "@jest/console": "30.2.0", - "@jest/types": "30.2.0", + "@jest/console": "30.3.0", + "@jest/types": "30.3.0", "@types/istanbul-lib-coverage": "^2.0.6", "collect-v8-coverage": "^1.0.2" }, @@ -3169,14 +3169,14 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz", - "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.3.0.tgz", + "integrity": "sha512-dgbWy9b8QDlQeRZcv7LNF+/jFiiYHTKho1xirauZ7kVwY7avjFF6uTT0RqlgudB5OuIPagFdVtfFMosjVbk1eA==", "dev": true, "dependencies": { - "@jest/test-result": "30.2.0", + "@jest/test-result": "30.3.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", + "jest-haste-map": "30.3.0", "slash": "^3.0.0" }, "engines": { @@ -3184,23 +3184,22 @@ } }, "node_modules/@jest/transform": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", - "integrity": "sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.3.0.tgz", + "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==", "dev": true, "dependencies": { "@babel/core": "^7.27.4", - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@jridgewell/trace-mapping": "^0.3.25", "babel-plugin-istanbul": "^7.0.1", "chalk": "^4.1.2", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", + "jest-haste-map": "30.3.0", "jest-regex-util": "30.0.1", - "jest-util": "30.2.0", - "micromatch": "^4.0.8", + "jest-util": "30.3.0", "pirates": "^4.0.7", "slash": "^3.0.0", "write-file-atomic": "^5.0.1" @@ -3217,9 +3216,9 @@ "license": "MIT" }, "node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.3.0.tgz", + "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "dependencies": { "@jest/pattern": "30.0.1", @@ -3881,17 +3880,15 @@ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", - "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", + "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.1" } @@ -4621,12 +4618,12 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.2.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.3.tgz", - "integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", + "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", "dev": true, "dependencies": { - "undici-types": "~7.16.0" + "undici-types": "~7.18.0" } }, "node_modules/@types/parse-json": { @@ -4783,16 +4780,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz", - "integrity": "sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.2.tgz", + "integrity": "sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/type-utils": "8.56.0", - "@typescript-eslint/utils": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/type-utils": "8.57.2", + "@typescript-eslint/utils": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -4805,7 +4802,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.56.0", + "@typescript-eslint/parser": "^8.57.2", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } @@ -4821,15 +4818,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.0.tgz", - "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.2.tgz", + "integrity": "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3" }, "engines": { @@ -4845,13 +4842,13 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz", - "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.2.tgz", + "integrity": "sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==", "dev": true, "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.56.0", - "@typescript-eslint/types": "^8.56.0", + "@typescript-eslint/tsconfig-utils": "^8.57.2", + "@typescript-eslint/types": "^8.57.2", "debug": "^4.4.3" }, "engines": { @@ -4866,13 +4863,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", - "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.2.tgz", + "integrity": "sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0" + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4883,9 +4880,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz", - "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.2.tgz", + "integrity": "sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4899,14 +4896,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.0.tgz", - "integrity": "sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.2.tgz", + "integrity": "sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0", - "@typescript-eslint/utils": "8.56.0", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/utils": "8.57.2", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -4923,9 +4920,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", - "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.2.tgz", + "integrity": "sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4936,17 +4933,17 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", - "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.2.tgz", + "integrity": "sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==", "dev": true, "dependencies": { - "@typescript-eslint/project-service": "8.56.0", - "@typescript-eslint/tsconfig-utils": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/project-service": "8.57.2", + "@typescript-eslint/tsconfig-utils": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3", - "minimatch": "^9.0.5", + "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" @@ -4972,9 +4969,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "dependencies": { "balanced-match": "^4.0.2" @@ -4984,30 +4981,30 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.6.tgz", - "integrity": "sha512-kQAVowdR33euIqeA0+VZTDqU+qo1IeVY+hrKYtZMio3Pg0P0vuh/kwRylLUddJhB6pf3q/botcOvRtx4IN1wqQ==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, "dependencies": { "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", - "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.2.tgz", + "integrity": "sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0" + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5022,12 +5019,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", - "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.2.tgz", + "integrity": "sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/types": "8.57.2", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -5989,15 +5986,15 @@ } }, "node_modules/babel-jest": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz", - "integrity": "sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.3.0.tgz", + "integrity": "sha512-gRpauEU2KRrCox5Z296aeVHR4jQ98BCnu0IO332D/xpHNOsIH/bgSRk9k6GbKIbBw8vFeN6ctuu6tV8WOyVfYQ==", "dev": true, "dependencies": { - "@jest/transform": "30.2.0", + "@jest/transform": "30.3.0", "@types/babel__core": "^7.20.5", "babel-plugin-istanbul": "^7.0.1", - "babel-preset-jest": "30.2.0", + "babel-preset-jest": "30.3.0", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "slash": "^3.0.0" @@ -6100,9 +6097,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.2.0.tgz", - "integrity": "sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.3.0.tgz", + "integrity": "sha512-+TRkByhsws6sfPjVaitzadk1I0F5sPvOVUH5tyTSzhePpsGIVrdeunHSw/C36QeocS95OOk8lunc4rlu5Anwsg==", "dev": true, "dependencies": { "@types/babel__core": "^7.20.5" @@ -6200,12 +6197,12 @@ } }, "node_modules/babel-preset-jest": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.2.0.tgz", - "integrity": "sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.3.0.tgz", + "integrity": "sha512-6ZcUbWHC+dMz2vfzdNwi87Z1gQsLNK2uLuK1Q89R11xdvejcivlYYwDlEv0FHX3VwEXpbBQ9uufB/MUNpZGfhQ==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "30.2.0", + "babel-plugin-jest-hoist": "30.3.0", "babel-preset-current-node-syntax": "^1.2.0" }, "engines": { @@ -6805,9 +6802,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.1.0.tgz", - "integrity": "sha512-UX0OwmYRYQQetfrLEZeewIFFI+wSTofC+pMBLNuH3RUuu/xzG1oz84UCEDOSoQlN3fZ4+AzmV50ZYvGqkMh9yA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", + "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", "dev": true }, "node_modules/classnames": { @@ -6884,9 +6881,9 @@ } }, "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", "dev": true }, "node_modules/color-convert": { @@ -7099,9 +7096,9 @@ } }, "node_modules/core-js": { - "version": "3.48.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.48.0.tgz", - "integrity": "sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ==", + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz", + "integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==", "dev": true, "hasInstallScript": true, "funding": { @@ -7408,9 +7405,9 @@ } }, "node_modules/dayjs": { - "version": "1.11.19", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz", - "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==" + "version": "1.11.20", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", + "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==" }, "node_modules/debug": { "version": "4.4.3", @@ -7443,9 +7440,9 @@ } }, "node_modules/dedent": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", - "integrity": "sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", "dev": true, "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -8705,17 +8702,17 @@ } }, "node_modules/expect": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", - "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.3.0.tgz", + "integrity": "sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==", "dev": true, "dependencies": { - "@jest/expect-utils": "30.2.0", + "@jest/expect-utils": "30.3.0", "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", + "jest-util": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -9803,7 +9800,6 @@ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, - "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -10664,15 +10660,15 @@ } }, "node_modules/jest": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-30.2.0.tgz", - "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.3.0.tgz", + "integrity": "sha512-AkXIIFcaazymvey2i/+F94XRnM6TsVLZDhBMLsd1Sf/W0wzsvvpjeyUrCZD6HGG4SDYPgDJDBKeiJTBb10WzMg==", "dev": true, "dependencies": { - "@jest/core": "30.2.0", - "@jest/types": "30.2.0", + "@jest/core": "30.3.0", + "@jest/types": "30.3.0", "import-local": "^3.2.0", - "jest-cli": "30.2.0" + "jest-cli": "30.3.0" }, "bin": { "jest": "bin/jest.js" @@ -10732,13 +10728,13 @@ } }, "node_modules/jest-changed-files": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.2.0.tgz", - "integrity": "sha512-L8lR1ChrRnSdfeOvTrwZMlnWV8G/LLjQ0nG9MBclwWZidA2N5FviRki0Bvh20WRMOX31/JYvzdqTJrk5oBdydQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.3.0.tgz", + "integrity": "sha512-B/7Cny6cV5At6M25EWDgf9S617lHivamL8vl6KEpJqkStauzcG4e+WPfDgMMF+H4FVH4A2PLRyvgDJan4441QA==", "dev": true, "dependencies": { "execa": "^5.1.1", - "jest-util": "30.2.0", + "jest-util": "30.3.0", "p-limit": "^3.1.0" }, "engines": { @@ -10746,28 +10742,28 @@ } }, "node_modules/jest-circus": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.2.0.tgz", - "integrity": "sha512-Fh0096NC3ZkFx05EP2OXCxJAREVxj1BcW/i6EWqqymcgYKWjyyDpral3fMxVcHXg6oZM7iULer9wGRFvfpl+Tg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.3.0.tgz", + "integrity": "sha512-PyXq5szeSfR/4f1lYqCmmQjh0vqDkURUYi9N6whnHjlRz4IUQfMcXkGLeEoiJtxtyPqgUaUUfyQlApXWBSN1RA==", "dev": true, "dependencies": { - "@jest/environment": "30.2.0", - "@jest/expect": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/types": "30.2.0", + "@jest/environment": "30.3.0", + "@jest/expect": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", "co": "^4.6.0", "dedent": "^1.6.0", "is-generator-fn": "^2.1.0", - "jest-each": "30.2.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-runtime": "30.2.0", - "jest-snapshot": "30.2.0", - "jest-util": "30.2.0", + "jest-each": "30.3.0", + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-runtime": "30.3.0", + "jest-snapshot": "30.3.0", + "jest-util": "30.3.0", "p-limit": "^3.1.0", - "pretty-format": "30.2.0", + "pretty-format": "30.3.0", "pure-rand": "^7.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" @@ -10789,9 +10785,9 @@ } }, "node_modules/jest-circus/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "node_modules/jest-circus/node_modules/ansi-styles": { @@ -10807,9 +10803,9 @@ } }, "node_modules/jest-circus/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "dependencies": { "@jest/schemas": "30.0.5", @@ -10821,20 +10817,20 @@ } }, "node_modules/jest-cli": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.2.0.tgz", - "integrity": "sha512-Os9ukIvADX/A9sLt6Zse3+nmHtHaE6hqOsjQtNiugFTbKRHYIYtZXNGNK9NChseXy7djFPjndX1tL0sCTlfpAA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.3.0.tgz", + "integrity": "sha512-l6Tqx+j1fDXJEW5bqYykDQQ7mQg+9mhWXtnj+tQZrTWYHyHoi6Be8HPumDSA+UiX2/2buEgjA58iJzdj146uCw==", "dev": true, "dependencies": { - "@jest/core": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/types": "30.2.0", + "@jest/core": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/types": "30.3.0", "chalk": "^4.1.2", "exit-x": "^0.2.2", "import-local": "^3.2.0", - "jest-config": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", + "jest-config": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", "yargs": "^17.7.2" }, "bin": { @@ -10853,33 +10849,32 @@ } }, "node_modules/jest-config": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.2.0.tgz", - "integrity": "sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.3.0.tgz", + "integrity": "sha512-WPMAkMAtNDY9P/oKObtsRG/6KTrhtgPJoBTmk20uDn4Uy6/3EJnnaZJre/FMT1KVRx8cve1r7/FlMIOfRVWL4w==", "dev": true, "dependencies": { "@babel/core": "^7.27.4", "@jest/get-type": "30.1.0", "@jest/pattern": "30.0.1", - "@jest/test-sequencer": "30.2.0", - "@jest/types": "30.2.0", - "babel-jest": "30.2.0", + "@jest/test-sequencer": "30.3.0", + "@jest/types": "30.3.0", + "babel-jest": "30.3.0", "chalk": "^4.1.2", "ci-info": "^4.2.0", "deepmerge": "^4.3.1", - "glob": "^10.3.10", + "glob": "^10.5.0", "graceful-fs": "^4.2.11", - "jest-circus": "30.2.0", + "jest-circus": "30.3.0", "jest-docblock": "30.2.0", - "jest-environment-node": "30.2.0", + "jest-environment-node": "30.3.0", "jest-regex-util": "30.0.1", - "jest-resolve": "30.2.0", - "jest-runner": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", - "micromatch": "^4.0.8", + "jest-resolve": "30.3.0", + "jest-runner": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", "parse-json": "^5.2.0", - "pretty-format": "30.2.0", + "pretty-format": "30.3.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -10916,9 +10911,9 @@ } }, "node_modules/jest-config/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "node_modules/jest-config/node_modules/ansi-styles": { @@ -10943,9 +10938,10 @@ } }, "node_modules/jest-config/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "dependencies": { "foreground-child": "^3.1.0", @@ -10963,12 +10959,12 @@ } }, "node_modules/jest-config/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -10978,9 +10974,9 @@ } }, "node_modules/jest-config/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "dependencies": { "@jest/schemas": "30.0.5", @@ -11020,16 +11016,16 @@ } }, "node_modules/jest-each": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.2.0.tgz", - "integrity": "sha512-lpWlJlM7bCUf1mfmuqTA8+j2lNURW9eNafOy99knBM01i5CQeY5UH1vZjgT9071nDJac1M4XsbyI44oNOdhlDQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.3.0.tgz", + "integrity": "sha512-V8eMndg/aZ+3LnCJgSm13IxS5XSBM22QSZc9BtPK8Dek6pm+hfUNfwBdvsB3d342bo1q7wnSkC38zjX259qZNA==", "dev": true, "dependencies": { "@jest/get-type": "30.1.0", - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "chalk": "^4.1.2", - "jest-util": "30.2.0", - "pretty-format": "30.2.0" + "jest-util": "30.3.0", + "pretty-format": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -11048,9 +11044,9 @@ } }, "node_modules/jest-each/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "node_modules/jest-each/node_modules/ansi-styles": { @@ -11066,9 +11062,9 @@ } }, "node_modules/jest-each/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "dependencies": { "@jest/schemas": "30.0.5", @@ -11080,15 +11076,13 @@ } }, "node_modules/jest-environment-jsdom": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-30.2.0.tgz", - "integrity": "sha512-zbBTiqr2Vl78pKp/laGBREYzbZx9ZtqPjOK4++lL4BNDhxRnahg51HtoDrk9/VjIy9IthNEWdKVd7H5bqBhiWQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-30.3.0.tgz", + "integrity": "sha512-RLEOJy6ip1lpw0yqJ8tB3i88FC7VBz7i00Zvl2qF71IdxjS98gC9/0SPWYIBVXHm5hgCYK0PAlSlnHGGy9RoMg==", "dev": true, "dependencies": { - "@jest/environment": "30.2.0", - "@jest/environment-jsdom-abstract": "30.2.0", - "@types/jsdom": "^21.1.7", - "@types/node": "*", + "@jest/environment": "30.3.0", + "@jest/environment-jsdom-abstract": "30.3.0", "jsdom": "^26.1.0" }, "engines": { @@ -11104,18 +11098,18 @@ } }, "node_modules/jest-environment-node": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.2.0.tgz", - "integrity": "sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.3.0.tgz", + "integrity": "sha512-4i6HItw/JSiJVsC5q0hnKIe/hbYfZLVG9YJ/0pU9Hz2n/9qZe3Rhn5s5CUZA5ORZlcdT/vmAXRMyONXJwPrmYQ==", "dev": true, "dependencies": { - "@jest/environment": "30.2.0", - "@jest/fake-timers": "30.2.0", - "@jest/types": "30.2.0", + "@jest/environment": "30.3.0", + "@jest/fake-timers": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", - "jest-mock": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0" + "jest-mock": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -11132,20 +11126,20 @@ } }, "node_modules/jest-haste-map": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz", - "integrity": "sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.3.0.tgz", + "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", "dev": true, "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", "anymatch": "^3.1.3", "fb-watchman": "^2.0.2", "graceful-fs": "^4.2.11", "jest-regex-util": "30.0.1", - "jest-util": "30.2.0", - "jest-worker": "30.2.0", - "micromatch": "^4.0.8", + "jest-util": "30.3.0", + "jest-worker": "30.3.0", + "picomatch": "^4.0.3", "walker": "^1.0.8" }, "engines": { @@ -11155,14 +11149,26 @@ "fsevents": "^2.3.3" } }, + "node_modules/jest-haste-map/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/jest-leak-detector": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.2.0.tgz", - "integrity": "sha512-M6jKAjyzjHG0SrQgwhgZGy9hFazcudwCNovY/9HPIicmNSBuockPSedAP9vlPK6ONFJ1zfyH/M2/YYJxOz5cdQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.3.0.tgz", + "integrity": "sha512-cuKmUUGIjfXZAiGJ7TbEMx0bcqNdPPI6P1V+7aF+m/FUJqFDxkFR4JqkTu8ZOiU5AaX/x0hZ20KaaIPXQzbMGQ==", "dev": true, "dependencies": { "@jest/get-type": "30.1.0", - "pretty-format": "30.2.0" + "pretty-format": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -11181,9 +11187,9 @@ } }, "node_modules/jest-leak-detector/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "node_modules/jest-leak-detector/node_modules/ansi-styles": { @@ -11199,9 +11205,9 @@ } }, "node_modules/jest-leak-detector/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "dependencies": { "@jest/schemas": "30.0.5", @@ -11213,15 +11219,15 @@ } }, "node_modules/jest-matcher-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz", - "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.3.0.tgz", + "integrity": "sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==", "dev": true, "dependencies": { "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "jest-diff": "30.2.0", - "pretty-format": "30.2.0" + "jest-diff": "30.3.0", + "pretty-format": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -11240,9 +11246,9 @@ } }, "node_modules/jest-matcher-utils/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "node_modules/jest-matcher-utils/node_modules/ansi-styles": { @@ -11258,24 +11264,24 @@ } }, "node_modules/jest-matcher-utils/node_modules/jest-diff": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", - "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", + "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", "dev": true, "dependencies": { - "@jest/diff-sequences": "30.0.1", + "@jest/diff-sequences": "30.3.0", "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "pretty-format": "30.2.0" + "pretty-format": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-matcher-utils/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "dependencies": { "@jest/schemas": "30.0.5", @@ -11287,18 +11293,18 @@ } }, "node_modules/jest-message-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz", - "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.3.0.tgz", + "integrity": "sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==", "dev": true, "dependencies": { "@babel/code-frame": "^7.27.1", - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "micromatch": "^4.0.8", - "pretty-format": "30.2.0", + "picomatch": "^4.0.3", + "pretty-format": "30.3.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" }, @@ -11319,9 +11325,9 @@ } }, "node_modules/jest-message-util/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "node_modules/jest-message-util/node_modules/ansi-styles": { @@ -11336,10 +11342,22 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/jest-message-util/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/jest-message-util/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "dependencies": { "@jest/schemas": "30.0.5", @@ -11351,14 +11369,14 @@ } }, "node_modules/jest-mock": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz", - "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.3.0.tgz", + "integrity": "sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog==", "dev": true, "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", - "jest-util": "30.2.0" + "jest-util": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -11392,17 +11410,17 @@ } }, "node_modules/jest-resolve": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.2.0.tgz", - "integrity": "sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.3.0.tgz", + "integrity": "sha512-NRtTAHQlpd15F9rUR36jqwelbrDV/dY4vzNte3S2kxCKUJRYNd5/6nTSbYiak1VX5g8IoFF23Uj5TURkUW8O5g==", "dev": true, "dependencies": { "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", + "jest-haste-map": "30.3.0", "jest-pnp-resolver": "^1.2.3", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", "slash": "^3.0.0", "unrs-resolver": "^1.7.11" }, @@ -11411,44 +11429,44 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.2.0.tgz", - "integrity": "sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.3.0.tgz", + "integrity": "sha512-9ev8s3YN6Hsyz9LV75XUwkCVFlwPbaFn6Wp75qnI0wzAINYWY8Fb3+6y59Rwd3QaS3kKXffHXsZMziMavfz/nw==", "dev": true, "dependencies": { "jest-regex-util": "30.0.1", - "jest-snapshot": "30.2.0" + "jest-snapshot": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-runner": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.2.0.tgz", - "integrity": "sha512-PqvZ2B2XEyPEbclp+gV6KO/F1FIFSbIwewRgmROCMBo/aZ6J1w8Qypoj2pEOcg3G2HzLlaP6VUtvwCI8dM3oqQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.3.0.tgz", + "integrity": "sha512-gDv6C9LGKWDPLia9TSzZwf4h3kMQCqyTpq+95PODnTRDO0g9os48XIYYkS6D236vjpBir2fF63YmJFtqkS5Duw==", "dev": true, "dependencies": { - "@jest/console": "30.2.0", - "@jest/environment": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", + "@jest/console": "30.3.0", + "@jest/environment": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", "emittery": "^0.13.1", "exit-x": "^0.2.2", "graceful-fs": "^4.2.11", "jest-docblock": "30.2.0", - "jest-environment-node": "30.2.0", - "jest-haste-map": "30.2.0", - "jest-leak-detector": "30.2.0", - "jest-message-util": "30.2.0", - "jest-resolve": "30.2.0", - "jest-runtime": "30.2.0", - "jest-util": "30.2.0", - "jest-watcher": "30.2.0", - "jest-worker": "30.2.0", + "jest-environment-node": "30.3.0", + "jest-haste-map": "30.3.0", + "jest-leak-detector": "30.3.0", + "jest-message-util": "30.3.0", + "jest-resolve": "30.3.0", + "jest-runtime": "30.3.0", + "jest-util": "30.3.0", + "jest-watcher": "30.3.0", + "jest-worker": "30.3.0", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -11457,31 +11475,31 @@ } }, "node_modules/jest-runtime": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.2.0.tgz", - "integrity": "sha512-p1+GVX/PJqTucvsmERPMgCPvQJpFt4hFbM+VN3n8TMo47decMUcJbt+rgzwrEme0MQUA/R+1de2axftTHkKckg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.3.0.tgz", + "integrity": "sha512-CgC+hIBJbuh78HEffkhNKcbXAytQViplcl8xupqeIWyKQF50kCQA8J7GeJCkjisC6hpnC9Muf8jV5RdtdFbGng==", "dev": true, "dependencies": { - "@jest/environment": "30.2.0", - "@jest/fake-timers": "30.2.0", - "@jest/globals": "30.2.0", + "@jest/environment": "30.3.0", + "@jest/fake-timers": "30.3.0", + "@jest/globals": "30.3.0", "@jest/source-map": "30.0.1", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", "cjs-module-lexer": "^2.1.0", "collect-v8-coverage": "^1.0.2", - "glob": "^10.3.10", + "glob": "^10.5.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", + "jest-haste-map": "30.3.0", + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", "jest-regex-util": "30.0.1", - "jest-resolve": "30.2.0", - "jest-snapshot": "30.2.0", - "jest-util": "30.2.0", + "jest-resolve": "30.3.0", + "jest-snapshot": "30.3.0", + "jest-util": "30.3.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -11499,9 +11517,10 @@ } }, "node_modules/jest-runtime/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "dependencies": { "foreground-child": "^3.1.0", @@ -11519,12 +11538,12 @@ } }, "node_modules/jest-runtime/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -11534,9 +11553,9 @@ } }, "node_modules/jest-snapshot": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.2.0.tgz", - "integrity": "sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.3.0.tgz", + "integrity": "sha512-f14c7atpb4O2DeNhwcvS810Y63wEn8O1HqK/luJ4F6M4NjvxmAKQwBUWjbExUtMxWJQ0wVgmCKymeJK6NZMnfQ==", "dev": true, "dependencies": { "@babel/core": "^7.27.4", @@ -11544,20 +11563,20 @@ "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.2.0", + "@jest/expect-utils": "30.3.0", "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", + "@jest/snapshot-utils": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "babel-preset-current-node-syntax": "^1.2.0", "chalk": "^4.1.2", - "expect": "30.2.0", + "expect": "30.3.0", "graceful-fs": "^4.2.11", - "jest-diff": "30.2.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", - "pretty-format": "30.2.0", + "jest-diff": "30.3.0", + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-util": "30.3.0", + "pretty-format": "30.3.0", "semver": "^7.7.2", "synckit": "^0.11.8" }, @@ -11578,9 +11597,9 @@ } }, "node_modules/jest-snapshot/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "node_modules/jest-snapshot/node_modules/ansi-styles": { @@ -11596,24 +11615,24 @@ } }, "node_modules/jest-snapshot/node_modules/jest-diff": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", - "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", + "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", "dev": true, "dependencies": { - "@jest/diff-sequences": "30.0.1", + "@jest/diff-sequences": "30.3.0", "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "pretty-format": "30.2.0" + "pretty-format": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-snapshot/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "dependencies": { "@jest/schemas": "30.0.5", @@ -11625,28 +11644,27 @@ } }, "node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.3.0.tgz", + "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" + "picomatch": "^4.0.3" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-util/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -11655,17 +11673,17 @@ } }, "node_modules/jest-validate": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.2.0.tgz", - "integrity": "sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.3.0.tgz", + "integrity": "sha512-I/xzC8h5G+SHCb2P2gWkJYrNiTbeL47KvKeW5EzplkyxzBRBw1ssSHlI/jXec0ukH2q7x2zAWQm7015iusg62Q==", "dev": true, "dependencies": { "@jest/get-type": "30.1.0", - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "camelcase": "^6.3.0", "chalk": "^4.1.2", "leven": "^3.1.0", - "pretty-format": "30.2.0" + "pretty-format": "30.3.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" @@ -11684,9 +11702,9 @@ } }, "node_modules/jest-validate/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "node_modules/jest-validate/node_modules/ansi-styles": { @@ -11714,9 +11732,9 @@ } }, "node_modules/jest-validate/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "dependencies": { "@jest/schemas": "30.0.5", @@ -11728,18 +11746,18 @@ } }, "node_modules/jest-watcher": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.2.0.tgz", - "integrity": "sha512-PYxa28dxJ9g777pGm/7PrbnMeA0Jr7osHP9bS7eJy9DuAjMgdGtxgf0uKMyoIsTWAkIbUW5hSDdJ3urmgXBqxg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.3.0.tgz", + "integrity": "sha512-PJ1d9ThtTR8aMiBWUdcownq9mDdLXsQzJayTk4kmaBRHKvwNQn+ANveuhEBUyNI2hR1TVhvQ8D5kHubbzBHR/w==", "dev": true, "dependencies": { - "@jest/test-result": "30.2.0", - "@jest/types": "30.2.0", + "@jest/test-result": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "emittery": "^0.13.1", - "jest-util": "30.2.0", + "jest-util": "30.3.0", "string-length": "^4.0.2" }, "engines": { @@ -11747,14 +11765,14 @@ } }, "node_modules/jest-worker": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", - "integrity": "sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.3.0.tgz", + "integrity": "sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ==", "dev": true, "dependencies": { "@types/node": "*", "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.2.0", + "jest-util": "30.3.0", "merge-stream": "^2.0.0", "supports-color": "^8.1.1" }, @@ -12317,9 +12335,9 @@ } }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -12578,9 +12596,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.22", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.22.tgz", - "integrity": "sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==", + "version": "2.2.23", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", + "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==", "dev": true }, "node_modules/object-assign": { @@ -15720,7 +15738,6 @@ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } @@ -15863,15 +15880,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.56.0.tgz", - "integrity": "sha512-c7toRLrotJ9oixgdW7liukZpsnq5CZ7PuKztubGYlNppuTqhIoWfhgHo/7EU0v06gS2l/x0i2NEFK1qMIf0rIg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.57.2.tgz", + "integrity": "sha512-VEPQ0iPgWO/sBaZOU1xo4nuNdODVOajPnTIbog2GKYr31nIlZ0fWPoCQgGfF3ETyBl1vn63F/p50Um9Z4J8O8A==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "8.56.0", - "@typescript-eslint/parser": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0", - "@typescript-eslint/utils": "8.56.0" + "@typescript-eslint/eslint-plugin": "8.57.2", + "@typescript-eslint/parser": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/utils": "8.57.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -15932,9 +15949,9 @@ } }, "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "dev": true }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -16700,6 +16717,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", "dev": true, "dependencies": { "iconv-lite": "0.6.3" @@ -18155,9 +18173,9 @@ } }, "@babel/preset-env": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.0.tgz", - "integrity": "sha512-fNEdfc0yi16lt6IZo2Qxk3knHVdfMYX33czNb4v8yWhemoBhibCpQK/uYHtSKIiO+p/zd3+8fYVXhQdOVV608w==", + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.2.tgz", + "integrity": "sha512-DYD23veRYGvBFhcTY1iUvJnDNpuqNd/BzBwCvzOTKUnJjKg5kpUBh3/u9585Agdkgj+QuygG7jLfOPWMa2KVNw==", "dev": true, "requires": { "@babel/compat-data": "^7.29.0", @@ -18289,9 +18307,9 @@ } }, "@babel/runtime": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", - "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==" + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==" }, "@babel/template": { "version": "7.28.6", @@ -18773,12 +18791,12 @@ } }, "strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "requires": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^6.2.2" } }, "wrap-ansi": { @@ -18814,52 +18832,51 @@ "dev": true }, "@jest/console": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.2.0.tgz", - "integrity": "sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.3.0.tgz", + "integrity": "sha512-PAwCvFJ4696XP2qZj+LAn1BWjZaJ6RjG6c7/lkMaUJnkyMS34ucuIsfqYvfskVNvUI27R/u4P1HMYFnlVXG/Ww==", "dev": true, "requires": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", + "jest-message-util": "30.3.0", + "jest-util": "30.3.0", "slash": "^3.0.0" } }, "@jest/core": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.2.0.tgz", - "integrity": "sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.3.0.tgz", + "integrity": "sha512-U5mVPsBxLSO6xYbf+tgkymLx+iAhvZX43/xI1+ej2ZOPnPdkdO1CzDmFKh2mZBn2s4XZixszHeQnzp1gm/DIxw==", "dev": true, "requires": { - "@jest/console": "30.2.0", + "@jest/console": "30.3.0", "@jest/pattern": "30.0.1", - "@jest/reporters": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", + "@jest/reporters": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "ci-info": "^4.2.0", "exit-x": "^0.2.2", "graceful-fs": "^4.2.11", - "jest-changed-files": "30.2.0", - "jest-config": "30.2.0", - "jest-haste-map": "30.2.0", - "jest-message-util": "30.2.0", + "jest-changed-files": "30.3.0", + "jest-config": "30.3.0", + "jest-haste-map": "30.3.0", + "jest-message-util": "30.3.0", "jest-regex-util": "30.0.1", - "jest-resolve": "30.2.0", - "jest-resolve-dependencies": "30.2.0", - "jest-runner": "30.2.0", - "jest-runtime": "30.2.0", - "jest-snapshot": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", - "jest-watcher": "30.2.0", - "micromatch": "^4.0.8", - "pretty-format": "30.2.0", + "jest-resolve": "30.3.0", + "jest-resolve-dependencies": "30.3.0", + "jest-runner": "30.3.0", + "jest-runtime": "30.3.0", + "jest-snapshot": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", + "jest-watcher": "30.3.0", + "pretty-format": "30.3.0", "slash": "^3.0.0" }, "dependencies": { @@ -18873,9 +18890,9 @@ } }, "@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "ansi-styles": { @@ -18885,9 +18902,9 @@ "dev": true }, "pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "requires": { "@jest/schemas": "30.0.5", @@ -18939,69 +18956,69 @@ } }, "@jest/diff-sequences": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", - "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", + "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", "dev": true }, "@jest/environment": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz", - "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.3.0.tgz", + "integrity": "sha512-SlLSF4Be735yQXyh2+mctBOzNDx5s5uLv88/j8Qn1wH679PDcwy67+YdADn8NJnGjzlXtN62asGH/T4vWOkfaw==", "dev": true, "requires": { - "@jest/fake-timers": "30.2.0", - "@jest/types": "30.2.0", + "@jest/fake-timers": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", - "jest-mock": "30.2.0" + "jest-mock": "30.3.0" } }, "@jest/environment-jsdom-abstract": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.2.0.tgz", - "integrity": "sha512-kazxw2L9IPuZpQ0mEt9lu9Z98SqR74xcagANmMBU16X0lS23yPc0+S6hGLUz8kVRlomZEs/5S/Zlpqwf5yu6OQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.3.0.tgz", + "integrity": "sha512-0hNFs5N6We3DMCwobzI0ydhkY10sT1tZSC0AAiy+0g2Dt/qEWgrcV5BrMxPczhe41cxW4qm6X+jqZaUdpZIajA==", "dev": true, "requires": { - "@jest/environment": "30.2.0", - "@jest/fake-timers": "30.2.0", - "@jest/types": "30.2.0", + "@jest/environment": "30.3.0", + "@jest/fake-timers": "30.3.0", + "@jest/types": "30.3.0", "@types/jsdom": "^21.1.7", "@types/node": "*", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" + "jest-mock": "30.3.0", + "jest-util": "30.3.0" } }, "@jest/expect": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz", - "integrity": "sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.3.0.tgz", + "integrity": "sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg==", "dev": true, "requires": { - "expect": "30.2.0", - "jest-snapshot": "30.2.0" + "expect": "30.3.0", + "jest-snapshot": "30.3.0" } }, "@jest/expect-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", - "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.3.0.tgz", + "integrity": "sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==", "dev": true, "requires": { "@jest/get-type": "30.1.0" } }, "@jest/fake-timers": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz", - "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.3.0.tgz", + "integrity": "sha512-WUQDs8SOP9URStX1DzhD425CqbN/HxUYCTwVrT8sTVBfMvFqYt/s61EK5T05qnHu0po6RitXIvP9otZxYDzTGQ==", "dev": true, "requires": { - "@jest/types": "30.2.0", - "@sinonjs/fake-timers": "^13.0.0", + "@jest/types": "30.3.0", + "@sinonjs/fake-timers": "^15.0.0", "@types/node": "*", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", + "jest-util": "30.3.0" } }, "@jest/get-type": { @@ -19011,15 +19028,15 @@ "dev": true }, "@jest/globals": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz", - "integrity": "sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.3.0.tgz", + "integrity": "sha512-+owLCBBdfpgL3HU+BD5etr1SvbXpSitJK0is1kiYjJxAAJggYMRQz5hSdd5pq1sSggfxPbw2ld71pt4x5wwViA==", "dev": true, "requires": { - "@jest/environment": "30.2.0", - "@jest/expect": "30.2.0", - "@jest/types": "30.2.0", - "jest-mock": "30.2.0" + "@jest/environment": "30.3.0", + "@jest/expect": "30.3.0", + "@jest/types": "30.3.0", + "jest-mock": "30.3.0" } }, "@jest/pattern": { @@ -19033,31 +19050,31 @@ } }, "@jest/reporters": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz", - "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.3.0.tgz", + "integrity": "sha512-a09z89S+PkQnL055bVj8+pe2Caed2PBOaczHcXCykW5ngxX9EWx/1uAwncxc/HiU0oZqfwseMjyhxgRjS49qPw==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", + "@jest/console": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "@jridgewell/trace-mapping": "^0.3.25", "@types/node": "*", "chalk": "^4.1.2", "collect-v8-coverage": "^1.0.2", "exit-x": "^0.2.2", - "glob": "^10.3.10", + "glob": "^10.5.0", "graceful-fs": "^4.2.11", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^5.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", - "jest-worker": "30.2.0", + "jest-message-util": "30.3.0", + "jest-util": "30.3.0", + "jest-worker": "30.3.0", "slash": "^3.0.0", "string-length": "^4.0.2", "v8-to-istanbul": "^9.0.1" @@ -19073,9 +19090,9 @@ } }, "glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "requires": { "foreground-child": "^3.1.0", @@ -19087,12 +19104,12 @@ } }, "minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "requires": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" } } } @@ -19107,12 +19124,12 @@ } }, "@jest/snapshot-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz", - "integrity": "sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.3.0.tgz", + "integrity": "sha512-ORbRN9sf5PP82v3FXNSwmO1OTDR2vzR2YTaR+E3VkSBZ8zadQE6IqYdYEeFH1NIkeB2HIGdF02dapb6K0Mj05g==", "dev": true, "requires": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "natural-compare": "^1.4.0" @@ -19130,47 +19147,46 @@ } }, "@jest/test-result": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.2.0.tgz", - "integrity": "sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.3.0.tgz", + "integrity": "sha512-e/52nJGuD74AKTSe0P4y5wFRlaXP0qmrS17rqOMHeSwm278VyNyXE3gFO/4DTGF9w+65ra3lo3VKj0LBrzmgdQ==", "dev": true, "requires": { - "@jest/console": "30.2.0", - "@jest/types": "30.2.0", + "@jest/console": "30.3.0", + "@jest/types": "30.3.0", "@types/istanbul-lib-coverage": "^2.0.6", "collect-v8-coverage": "^1.0.2" } }, "@jest/test-sequencer": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz", - "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.3.0.tgz", + "integrity": "sha512-dgbWy9b8QDlQeRZcv7LNF+/jFiiYHTKho1xirauZ7kVwY7avjFF6uTT0RqlgudB5OuIPagFdVtfFMosjVbk1eA==", "dev": true, "requires": { - "@jest/test-result": "30.2.0", + "@jest/test-result": "30.3.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", + "jest-haste-map": "30.3.0", "slash": "^3.0.0" } }, "@jest/transform": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", - "integrity": "sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.3.0.tgz", + "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==", "dev": true, "requires": { "@babel/core": "^7.27.4", - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@jridgewell/trace-mapping": "^0.3.25", "babel-plugin-istanbul": "^7.0.1", "chalk": "^4.1.2", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", + "jest-haste-map": "30.3.0", "jest-regex-util": "30.0.1", - "jest-util": "30.2.0", - "micromatch": "^4.0.8", + "jest-util": "30.3.0", "pirates": "^4.0.7", "slash": "^3.0.0", "write-file-atomic": "^5.0.1" @@ -19185,9 +19201,9 @@ } }, "@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.3.0.tgz", + "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", "dev": true, "requires": { "@jest/pattern": "30.0.1", @@ -19639,9 +19655,9 @@ } }, "@sinonjs/fake-timers": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", - "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", + "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", "dev": true, "requires": { "@sinonjs/commons": "^3.0.1" @@ -20188,12 +20204,12 @@ "dev": true }, "@types/node": { - "version": "25.2.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.3.tgz", - "integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz", + "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", "dev": true, "requires": { - "undici-types": "~7.16.0" + "undici-types": "~7.18.0" } }, "@types/parse-json": { @@ -20335,16 +20351,16 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz", - "integrity": "sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.2.tgz", + "integrity": "sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/type-utils": "8.56.0", - "@typescript-eslint/utils": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/type-utils": "8.57.2", + "@typescript-eslint/utils": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -20359,77 +20375,77 @@ } }, "@typescript-eslint/parser": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.0.tgz", - "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.2.tgz", + "integrity": "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3" } }, "@typescript-eslint/project-service": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz", - "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.2.tgz", + "integrity": "sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==", "dev": true, "requires": { - "@typescript-eslint/tsconfig-utils": "^8.56.0", - "@typescript-eslint/types": "^8.56.0", + "@typescript-eslint/tsconfig-utils": "^8.57.2", + "@typescript-eslint/types": "^8.57.2", "debug": "^4.4.3" } }, "@typescript-eslint/scope-manager": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", - "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.2.tgz", + "integrity": "sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==", "dev": true, "requires": { - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0" + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2" } }, "@typescript-eslint/tsconfig-utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz", - "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.2.tgz", + "integrity": "sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==", "dev": true, "requires": {} }, "@typescript-eslint/type-utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.0.tgz", - "integrity": "sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.2.tgz", + "integrity": "sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==", "dev": true, "requires": { - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0", - "@typescript-eslint/utils": "8.56.0", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/utils": "8.57.2", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" } }, "@typescript-eslint/types": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", - "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.2.tgz", + "integrity": "sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", - "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.2.tgz", + "integrity": "sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==", "dev": true, "requires": { - "@typescript-eslint/project-service": "8.56.0", - "@typescript-eslint/tsconfig-utils": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/project-service": "8.57.2", + "@typescript-eslint/tsconfig-utils": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3", - "minimatch": "^9.0.5", + "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" @@ -20442,18 +20458,18 @@ "dev": true }, "brace-expansion": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "requires": { "balanced-match": "^4.0.2" } }, "minimatch": { - "version": "9.0.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.6.tgz", - "integrity": "sha512-kQAVowdR33euIqeA0+VZTDqU+qo1IeVY+hrKYtZMio3Pg0P0vuh/kwRylLUddJhB6pf3q/botcOvRtx4IN1wqQ==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, "requires": { "brace-expansion": "^5.0.2" @@ -20462,24 +20478,24 @@ } }, "@typescript-eslint/utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", - "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.2.tgz", + "integrity": "sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0" + "@typescript-eslint/scope-manager": "8.57.2", + "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2" } }, "@typescript-eslint/visitor-keys": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", - "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.2.tgz", + "integrity": "sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==", "dev": true, "requires": { - "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/types": "8.57.2", "eslint-visitor-keys": "^5.0.0" }, "dependencies": { @@ -21127,15 +21143,15 @@ "dev": true }, "babel-jest": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz", - "integrity": "sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.3.0.tgz", + "integrity": "sha512-gRpauEU2KRrCox5Z296aeVHR4jQ98BCnu0IO332D/xpHNOsIH/bgSRk9k6GbKIbBw8vFeN6ctuu6tV8WOyVfYQ==", "dev": true, "requires": { - "@jest/transform": "30.2.0", + "@jest/transform": "30.3.0", "@types/babel__core": "^7.20.5", "babel-plugin-istanbul": "^7.0.1", - "babel-preset-jest": "30.2.0", + "babel-preset-jest": "30.3.0", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "slash": "^3.0.0" @@ -21194,9 +21210,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.2.0.tgz", - "integrity": "sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.3.0.tgz", + "integrity": "sha512-+TRkByhsws6sfPjVaitzadk1I0F5sPvOVUH5tyTSzhePpsGIVrdeunHSw/C36QeocS95OOk8lunc4rlu5Anwsg==", "dev": true, "requires": { "@types/babel__core": "^7.20.5" @@ -21274,12 +21290,12 @@ } }, "babel-preset-jest": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.2.0.tgz", - "integrity": "sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.3.0.tgz", + "integrity": "sha512-6ZcUbWHC+dMz2vfzdNwi87Z1gQsLNK2uLuK1Q89R11xdvejcivlYYwDlEv0FHX3VwEXpbBQ9uufB/MUNpZGfhQ==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "30.2.0", + "babel-plugin-jest-hoist": "30.3.0", "babel-preset-current-node-syntax": "^1.2.0" } }, @@ -21692,9 +21708,9 @@ } }, "cjs-module-lexer": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.1.0.tgz", - "integrity": "sha512-UX0OwmYRYQQetfrLEZeewIFFI+wSTofC+pMBLNuH3RUuu/xzG1oz84UCEDOSoQlN3fZ4+AzmV50ZYvGqkMh9yA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", + "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", "dev": true }, "classnames": { @@ -21753,9 +21769,9 @@ "dev": true }, "collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", "dev": true }, "color-convert": { @@ -21902,9 +21918,9 @@ } }, "core-js": { - "version": "3.48.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.48.0.tgz", - "integrity": "sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ==", + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz", + "integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==", "dev": true }, "core-js-compat": { @@ -22126,9 +22142,9 @@ } }, "dayjs": { - "version": "1.11.19", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz", - "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==" + "version": "1.11.20", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", + "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==" }, "debug": { "version": "4.4.3", @@ -22150,9 +22166,9 @@ "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==" }, "dedent": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", - "integrity": "sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", "dev": true, "requires": {} }, @@ -23037,17 +23053,17 @@ "dev": true }, "expect": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", - "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.3.0.tgz", + "integrity": "sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==", "dev": true, "requires": { - "@jest/expect-utils": "30.2.0", + "@jest/expect-utils": "30.3.0", "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", + "jest-util": "30.3.0" } }, "express": { @@ -24344,15 +24360,15 @@ } }, "jest": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-30.2.0.tgz", - "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.3.0.tgz", + "integrity": "sha512-AkXIIFcaazymvey2i/+F94XRnM6TsVLZDhBMLsd1Sf/W0wzsvvpjeyUrCZD6HGG4SDYPgDJDBKeiJTBb10WzMg==", "dev": true, "requires": { - "@jest/core": "30.2.0", - "@jest/types": "30.2.0", + "@jest/core": "30.3.0", + "@jest/types": "30.3.0", "import-local": "^3.2.0", - "jest-cli": "30.2.0" + "jest-cli": "30.3.0" } }, "jest-axe": { @@ -24388,39 +24404,39 @@ } }, "jest-changed-files": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.2.0.tgz", - "integrity": "sha512-L8lR1ChrRnSdfeOvTrwZMlnWV8G/LLjQ0nG9MBclwWZidA2N5FviRki0Bvh20WRMOX31/JYvzdqTJrk5oBdydQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.3.0.tgz", + "integrity": "sha512-B/7Cny6cV5At6M25EWDgf9S617lHivamL8vl6KEpJqkStauzcG4e+WPfDgMMF+H4FVH4A2PLRyvgDJan4441QA==", "dev": true, "requires": { "execa": "^5.1.1", - "jest-util": "30.2.0", + "jest-util": "30.3.0", "p-limit": "^3.1.0" } }, "jest-circus": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.2.0.tgz", - "integrity": "sha512-Fh0096NC3ZkFx05EP2OXCxJAREVxj1BcW/i6EWqqymcgYKWjyyDpral3fMxVcHXg6oZM7iULer9wGRFvfpl+Tg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.3.0.tgz", + "integrity": "sha512-PyXq5szeSfR/4f1lYqCmmQjh0vqDkURUYi9N6whnHjlRz4IUQfMcXkGLeEoiJtxtyPqgUaUUfyQlApXWBSN1RA==", "dev": true, "requires": { - "@jest/environment": "30.2.0", - "@jest/expect": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/types": "30.2.0", + "@jest/environment": "30.3.0", + "@jest/expect": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", "co": "^4.6.0", "dedent": "^1.6.0", "is-generator-fn": "^2.1.0", - "jest-each": "30.2.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-runtime": "30.2.0", - "jest-snapshot": "30.2.0", - "jest-util": "30.2.0", + "jest-each": "30.3.0", + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-runtime": "30.3.0", + "jest-snapshot": "30.3.0", + "jest-util": "30.3.0", "p-limit": "^3.1.0", - "pretty-format": "30.2.0", + "pretty-format": "30.3.0", "pure-rand": "^7.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" @@ -24436,9 +24452,9 @@ } }, "@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "ansi-styles": { @@ -24448,9 +24464,9 @@ "dev": true }, "pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "requires": { "@jest/schemas": "30.0.5", @@ -24461,51 +24477,50 @@ } }, "jest-cli": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.2.0.tgz", - "integrity": "sha512-Os9ukIvADX/A9sLt6Zse3+nmHtHaE6hqOsjQtNiugFTbKRHYIYtZXNGNK9NChseXy7djFPjndX1tL0sCTlfpAA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.3.0.tgz", + "integrity": "sha512-l6Tqx+j1fDXJEW5bqYykDQQ7mQg+9mhWXtnj+tQZrTWYHyHoi6Be8HPumDSA+UiX2/2buEgjA58iJzdj146uCw==", "dev": true, "requires": { - "@jest/core": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/types": "30.2.0", + "@jest/core": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/types": "30.3.0", "chalk": "^4.1.2", "exit-x": "^0.2.2", "import-local": "^3.2.0", - "jest-config": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", + "jest-config": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", "yargs": "^17.7.2" } }, "jest-config": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.2.0.tgz", - "integrity": "sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.3.0.tgz", + "integrity": "sha512-WPMAkMAtNDY9P/oKObtsRG/6KTrhtgPJoBTmk20uDn4Uy6/3EJnnaZJre/FMT1KVRx8cve1r7/FlMIOfRVWL4w==", "dev": true, "requires": { "@babel/core": "^7.27.4", "@jest/get-type": "30.1.0", "@jest/pattern": "30.0.1", - "@jest/test-sequencer": "30.2.0", - "@jest/types": "30.2.0", - "babel-jest": "30.2.0", + "@jest/test-sequencer": "30.3.0", + "@jest/types": "30.3.0", + "babel-jest": "30.3.0", "chalk": "^4.1.2", "ci-info": "^4.2.0", "deepmerge": "^4.3.1", - "glob": "^10.3.10", + "glob": "^10.5.0", "graceful-fs": "^4.2.11", - "jest-circus": "30.2.0", + "jest-circus": "30.3.0", "jest-docblock": "30.2.0", - "jest-environment-node": "30.2.0", + "jest-environment-node": "30.3.0", "jest-regex-util": "30.0.1", - "jest-resolve": "30.2.0", - "jest-runner": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", - "micromatch": "^4.0.8", + "jest-resolve": "30.3.0", + "jest-runner": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", "parse-json": "^5.2.0", - "pretty-format": "30.2.0", + "pretty-format": "30.3.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -24520,9 +24535,9 @@ } }, "@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "ansi-styles": { @@ -24541,9 +24556,9 @@ } }, "glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "requires": { "foreground-child": "^3.1.0", @@ -24555,18 +24570,18 @@ } }, "minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "requires": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" } }, "pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "requires": { "@jest/schemas": "30.0.5", @@ -24598,16 +24613,16 @@ } }, "jest-each": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.2.0.tgz", - "integrity": "sha512-lpWlJlM7bCUf1mfmuqTA8+j2lNURW9eNafOy99knBM01i5CQeY5UH1vZjgT9071nDJac1M4XsbyI44oNOdhlDQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.3.0.tgz", + "integrity": "sha512-V8eMndg/aZ+3LnCJgSm13IxS5XSBM22QSZc9BtPK8Dek6pm+hfUNfwBdvsB3d342bo1q7wnSkC38zjX259qZNA==", "dev": true, "requires": { "@jest/get-type": "30.1.0", - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "chalk": "^4.1.2", - "jest-util": "30.2.0", - "pretty-format": "30.2.0" + "jest-util": "30.3.0", + "pretty-format": "30.3.0" }, "dependencies": { "@jest/schemas": { @@ -24620,9 +24635,9 @@ } }, "@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "ansi-styles": { @@ -24632,9 +24647,9 @@ "dev": true }, "pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "requires": { "@jest/schemas": "30.0.5", @@ -24645,31 +24660,29 @@ } }, "jest-environment-jsdom": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-30.2.0.tgz", - "integrity": "sha512-zbBTiqr2Vl78pKp/laGBREYzbZx9ZtqPjOK4++lL4BNDhxRnahg51HtoDrk9/VjIy9IthNEWdKVd7H5bqBhiWQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-30.3.0.tgz", + "integrity": "sha512-RLEOJy6ip1lpw0yqJ8tB3i88FC7VBz7i00Zvl2qF71IdxjS98gC9/0SPWYIBVXHm5hgCYK0PAlSlnHGGy9RoMg==", "dev": true, "requires": { - "@jest/environment": "30.2.0", - "@jest/environment-jsdom-abstract": "30.2.0", - "@types/jsdom": "^21.1.7", - "@types/node": "*", + "@jest/environment": "30.3.0", + "@jest/environment-jsdom-abstract": "30.3.0", "jsdom": "^26.1.0" } }, "jest-environment-node": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.2.0.tgz", - "integrity": "sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.3.0.tgz", + "integrity": "sha512-4i6HItw/JSiJVsC5q0hnKIe/hbYfZLVG9YJ/0pU9Hz2n/9qZe3Rhn5s5CUZA5ORZlcdT/vmAXRMyONXJwPrmYQ==", "dev": true, "requires": { - "@jest/environment": "30.2.0", - "@jest/fake-timers": "30.2.0", - "@jest/types": "30.2.0", + "@jest/environment": "30.3.0", + "@jest/fake-timers": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", - "jest-mock": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0" + "jest-mock": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0" } }, "jest-get-type": { @@ -24679,32 +24692,40 @@ "dev": true }, "jest-haste-map": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz", - "integrity": "sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.3.0.tgz", + "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", "dev": true, "requires": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", "anymatch": "^3.1.3", "fb-watchman": "^2.0.2", "fsevents": "^2.3.3", "graceful-fs": "^4.2.11", "jest-regex-util": "30.0.1", - "jest-util": "30.2.0", - "jest-worker": "30.2.0", - "micromatch": "^4.0.8", + "jest-util": "30.3.0", + "jest-worker": "30.3.0", + "picomatch": "^4.0.3", "walker": "^1.0.8" + }, + "dependencies": { + "picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true + } } }, "jest-leak-detector": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.2.0.tgz", - "integrity": "sha512-M6jKAjyzjHG0SrQgwhgZGy9hFazcudwCNovY/9HPIicmNSBuockPSedAP9vlPK6ONFJ1zfyH/M2/YYJxOz5cdQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.3.0.tgz", + "integrity": "sha512-cuKmUUGIjfXZAiGJ7TbEMx0bcqNdPPI6P1V+7aF+m/FUJqFDxkFR4JqkTu8ZOiU5AaX/x0hZ20KaaIPXQzbMGQ==", "dev": true, "requires": { "@jest/get-type": "30.1.0", - "pretty-format": "30.2.0" + "pretty-format": "30.3.0" }, "dependencies": { "@jest/schemas": { @@ -24717,9 +24738,9 @@ } }, "@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "ansi-styles": { @@ -24729,9 +24750,9 @@ "dev": true }, "pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "requires": { "@jest/schemas": "30.0.5", @@ -24742,15 +24763,15 @@ } }, "jest-matcher-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz", - "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.3.0.tgz", + "integrity": "sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==", "dev": true, "requires": { "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "jest-diff": "30.2.0", - "pretty-format": "30.2.0" + "jest-diff": "30.3.0", + "pretty-format": "30.3.0" }, "dependencies": { "@jest/schemas": { @@ -24763,9 +24784,9 @@ } }, "@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "ansi-styles": { @@ -24775,21 +24796,21 @@ "dev": true }, "jest-diff": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", - "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", + "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", "dev": true, "requires": { - "@jest/diff-sequences": "30.0.1", + "@jest/diff-sequences": "30.3.0", "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "pretty-format": "30.2.0" + "pretty-format": "30.3.0" } }, "pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "requires": { "@jest/schemas": "30.0.5", @@ -24800,18 +24821,18 @@ } }, "jest-message-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz", - "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.3.0.tgz", + "integrity": "sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==", "dev": true, "requires": { "@babel/code-frame": "^7.27.1", - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "micromatch": "^4.0.8", - "pretty-format": "30.2.0", + "picomatch": "^4.0.3", + "pretty-format": "30.3.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" }, @@ -24826,9 +24847,9 @@ } }, "@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "ansi-styles": { @@ -24837,10 +24858,16 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, + "picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true + }, "pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "requires": { "@jest/schemas": "30.0.5", @@ -24851,14 +24878,14 @@ } }, "jest-mock": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz", - "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.3.0.tgz", + "integrity": "sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog==", "dev": true, "requires": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", - "jest-util": "30.2.0" + "jest-util": "30.3.0" } }, "jest-pnp-resolver": { @@ -24875,87 +24902,87 @@ "dev": true }, "jest-resolve": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.2.0.tgz", - "integrity": "sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.3.0.tgz", + "integrity": "sha512-NRtTAHQlpd15F9rUR36jqwelbrDV/dY4vzNte3S2kxCKUJRYNd5/6nTSbYiak1VX5g8IoFF23Uj5TURkUW8O5g==", "dev": true, "requires": { "chalk": "^4.1.2", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", + "jest-haste-map": "30.3.0", "jest-pnp-resolver": "^1.2.3", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", "slash": "^3.0.0", "unrs-resolver": "^1.7.11" } }, "jest-resolve-dependencies": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.2.0.tgz", - "integrity": "sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.3.0.tgz", + "integrity": "sha512-9ev8s3YN6Hsyz9LV75XUwkCVFlwPbaFn6Wp75qnI0wzAINYWY8Fb3+6y59Rwd3QaS3kKXffHXsZMziMavfz/nw==", "dev": true, "requires": { "jest-regex-util": "30.0.1", - "jest-snapshot": "30.2.0" + "jest-snapshot": "30.3.0" } }, "jest-runner": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.2.0.tgz", - "integrity": "sha512-PqvZ2B2XEyPEbclp+gV6KO/F1FIFSbIwewRgmROCMBo/aZ6J1w8Qypoj2pEOcg3G2HzLlaP6VUtvwCI8dM3oqQ==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.3.0.tgz", + "integrity": "sha512-gDv6C9LGKWDPLia9TSzZwf4h3kMQCqyTpq+95PODnTRDO0g9os48XIYYkS6D236vjpBir2fF63YmJFtqkS5Duw==", "dev": true, "requires": { - "@jest/console": "30.2.0", - "@jest/environment": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", + "@jest/console": "30.3.0", + "@jest/environment": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", "emittery": "^0.13.1", "exit-x": "^0.2.2", "graceful-fs": "^4.2.11", "jest-docblock": "30.2.0", - "jest-environment-node": "30.2.0", - "jest-haste-map": "30.2.0", - "jest-leak-detector": "30.2.0", - "jest-message-util": "30.2.0", - "jest-resolve": "30.2.0", - "jest-runtime": "30.2.0", - "jest-util": "30.2.0", - "jest-watcher": "30.2.0", - "jest-worker": "30.2.0", + "jest-environment-node": "30.3.0", + "jest-haste-map": "30.3.0", + "jest-leak-detector": "30.3.0", + "jest-message-util": "30.3.0", + "jest-resolve": "30.3.0", + "jest-runtime": "30.3.0", + "jest-util": "30.3.0", + "jest-watcher": "30.3.0", + "jest-worker": "30.3.0", "p-limit": "^3.1.0", "source-map-support": "0.5.13" } }, "jest-runtime": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.2.0.tgz", - "integrity": "sha512-p1+GVX/PJqTucvsmERPMgCPvQJpFt4hFbM+VN3n8TMo47decMUcJbt+rgzwrEme0MQUA/R+1de2axftTHkKckg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.3.0.tgz", + "integrity": "sha512-CgC+hIBJbuh78HEffkhNKcbXAytQViplcl8xupqeIWyKQF50kCQA8J7GeJCkjisC6hpnC9Muf8jV5RdtdFbGng==", "dev": true, "requires": { - "@jest/environment": "30.2.0", - "@jest/fake-timers": "30.2.0", - "@jest/globals": "30.2.0", + "@jest/environment": "30.3.0", + "@jest/fake-timers": "30.3.0", + "@jest/globals": "30.3.0", "@jest/source-map": "30.0.1", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", "cjs-module-lexer": "^2.1.0", "collect-v8-coverage": "^1.0.2", - "glob": "^10.3.10", + "glob": "^10.5.0", "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", + "jest-haste-map": "30.3.0", + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", "jest-regex-util": "30.0.1", - "jest-resolve": "30.2.0", - "jest-snapshot": "30.2.0", - "jest-util": "30.2.0", + "jest-resolve": "30.3.0", + "jest-snapshot": "30.3.0", + "jest-util": "30.3.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -24970,9 +24997,9 @@ } }, "glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "requires": { "foreground-child": "^3.1.0", @@ -24984,20 +25011,20 @@ } }, "minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "requires": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" } } } }, "jest-snapshot": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.2.0.tgz", - "integrity": "sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.3.0.tgz", + "integrity": "sha512-f14c7atpb4O2DeNhwcvS810Y63wEn8O1HqK/luJ4F6M4NjvxmAKQwBUWjbExUtMxWJQ0wVgmCKymeJK6NZMnfQ==", "dev": true, "requires": { "@babel/core": "^7.27.4", @@ -25005,20 +25032,20 @@ "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.2.0", + "@jest/expect-utils": "30.3.0", "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", + "@jest/snapshot-utils": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", "babel-preset-current-node-syntax": "^1.2.0", "chalk": "^4.1.2", - "expect": "30.2.0", + "expect": "30.3.0", "graceful-fs": "^4.2.11", - "jest-diff": "30.2.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", - "pretty-format": "30.2.0", + "jest-diff": "30.3.0", + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-util": "30.3.0", + "pretty-format": "30.3.0", "semver": "^7.7.2", "synckit": "^0.11.8" }, @@ -25033,9 +25060,9 @@ } }, "@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "ansi-styles": { @@ -25045,21 +25072,21 @@ "dev": true }, "jest-diff": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", - "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", + "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", "dev": true, "requires": { - "@jest/diff-sequences": "30.0.1", + "@jest/diff-sequences": "30.3.0", "@jest/get-type": "30.1.0", "chalk": "^4.1.2", - "pretty-format": "30.2.0" + "pretty-format": "30.3.0" } }, "pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "requires": { "@jest/schemas": "30.0.5", @@ -25070,39 +25097,39 @@ } }, "jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.3.0.tgz", + "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", "dev": true, "requires": { - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" + "picomatch": "^4.0.3" }, "dependencies": { "picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true } } }, "jest-validate": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.2.0.tgz", - "integrity": "sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.3.0.tgz", + "integrity": "sha512-I/xzC8h5G+SHCb2P2gWkJYrNiTbeL47KvKeW5EzplkyxzBRBw1ssSHlI/jXec0ukH2q7x2zAWQm7015iusg62Q==", "dev": true, "requires": { "@jest/get-type": "30.1.0", - "@jest/types": "30.2.0", + "@jest/types": "30.3.0", "camelcase": "^6.3.0", "chalk": "^4.1.2", "leven": "^3.1.0", - "pretty-format": "30.2.0" + "pretty-format": "30.3.0" }, "dependencies": { "@jest/schemas": { @@ -25115,9 +25142,9 @@ } }, "@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true }, "ansi-styles": { @@ -25133,9 +25160,9 @@ "dev": true }, "pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", "dev": true, "requires": { "@jest/schemas": "30.0.5", @@ -25146,30 +25173,30 @@ } }, "jest-watcher": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.2.0.tgz", - "integrity": "sha512-PYxa28dxJ9g777pGm/7PrbnMeA0Jr7osHP9bS7eJy9DuAjMgdGtxgf0uKMyoIsTWAkIbUW5hSDdJ3urmgXBqxg==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.3.0.tgz", + "integrity": "sha512-PJ1d9ThtTR8aMiBWUdcownq9mDdLXsQzJayTk4kmaBRHKvwNQn+ANveuhEBUyNI2hR1TVhvQ8D5kHubbzBHR/w==", "dev": true, "requires": { - "@jest/test-result": "30.2.0", - "@jest/types": "30.2.0", + "@jest/test-result": "30.3.0", + "@jest/types": "30.3.0", "@types/node": "*", "ansi-escapes": "^4.3.2", "chalk": "^4.1.2", "emittery": "^0.13.1", - "jest-util": "30.2.0", + "jest-util": "30.3.0", "string-length": "^4.0.2" } }, "jest-worker": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", - "integrity": "sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==", + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.3.0.tgz", + "integrity": "sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ==", "dev": true, "requires": { "@types/node": "*", "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.2.0", + "jest-util": "30.3.0", "merge-stream": "^2.0.0", "supports-color": "^8.1.1" }, @@ -25582,9 +25609,9 @@ "dev": true }, "minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "dev": true }, "moize": { @@ -25748,9 +25775,9 @@ } }, "nwsapi": { - "version": "2.2.22", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.22.tgz", - "integrity": "sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==", + "version": "2.2.23", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", + "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==", "dev": true }, "object-assign": { @@ -28055,15 +28082,15 @@ "dev": true }, "typescript-eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.56.0.tgz", - "integrity": "sha512-c7toRLrotJ9oixgdW7liukZpsnq5CZ7PuKztubGYlNppuTqhIoWfhgHo/7EU0v06gS2l/x0i2NEFK1qMIf0rIg==", + "version": "8.57.2", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.57.2.tgz", + "integrity": "sha512-VEPQ0iPgWO/sBaZOU1xo4nuNdODVOajPnTIbog2GKYr31nIlZ0fWPoCQgGfF3ETyBl1vn63F/p50Um9Z4J8O8A==", "dev": true, "requires": { - "@typescript-eslint/eslint-plugin": "8.56.0", - "@typescript-eslint/parser": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0", - "@typescript-eslint/utils": "8.56.0" + "@typescript-eslint/eslint-plugin": "8.57.2", + "@typescript-eslint/parser": "8.57.2", + "@typescript-eslint/typescript-estree": "8.57.2", + "@typescript-eslint/utils": "8.57.2" } }, "typestyle": { @@ -28102,9 +28129,9 @@ } }, "undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "dev": true }, "unicode-canonical-property-names-ecmascript": { diff --git a/package.json b/package.json index 554f66565..9e6c0cc0c 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "buffer": "^6.0.3", "chart.js": "^4.5.1", "crypto-browserify": "^3.12.1", - "dayjs": "^1.11.19", + "dayjs": "^1.11.20", "express": "^5.2.1", "fast-kde": "^0.2.2", "format": "^0.2.2", @@ -83,13 +83,13 @@ "devDependencies": { "@babel/core": "^7.29.0", "@babel/plugin-transform-runtime": "^7.29.0", - "@babel/preset-env": "^7.29.0", + "@babel/preset-env": "^7.29.2", "@babel/preset-react": "^7.28.5", "@babel/preset-typescript": "^7.28.5", - "@babel/runtime": "^7.28.6", + "@babel/runtime": "^7.29.2", "@eslint/js": "^9.39.4", "@fetch-mock/jest": "^0.2.20", - "@jest/types": "^30.2.0", + "@jest/types": "^30.3.0", "@swc/core": "^1.15.18", "@swc/jest": "^0.2.39", "@testing-library/dom": "^10.4.1", @@ -99,14 +99,14 @@ "@types/jest": "^30.0.0", "@types/jest-axe": "^3.5.9", "@types/material-ui": "^0.21.18", - "@types/node": "^25.2.3", + "@types/node": "^25.5.0", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", "babel-loader": "^10.1.1", - "babel-preset-jest": "^30.2.0", + "babel-preset-jest": "^30.3.0", "case-sensitive-paths-webpack-plugin": "^2.4.0", "copy-webpack-plugin": "^13.0.1", - "core-js": "^3.48.0", + "core-js": "^3.49.0", "css-loader": "^7.1.4", "eslint": "^9.39.4", "eslint-config-prettier": "^10.1.8", @@ -119,10 +119,10 @@ "globals": "^17.4.0", "history": "^5.3.0", "html-webpack-plugin": "^5.6.6", - "jest": "^30.2.0", + "jest": "^30.3.0", "jest-axe": "^10.0.0", - "jest-environment-jsdom": "^30.2.0", - "jest-resolve": "^30.2.0", + "jest-environment-jsdom": "^30.3.0", + "jest-resolve": "^30.3.0", "npm-run-all2": "^8.0.4", "prettier": "3.7.4", "react-app-polyfill": "^3.0.0", @@ -133,7 +133,7 @@ "ts-loader": "^9.5.4", "ts-node": "^10.9.2", "typescript": "^5.9.3", - "typescript-eslint": "^8.56.0", + "typescript-eslint": "^8.57.2", "webpack": "^5.105.4", "webpack-cli": "^6.0.1", "webpack-dev-server": "^5.2.3", From 391a9a6e059b95a5769c5f6320cf957727927ff3 Mon Sep 17 00:00:00 2001 From: Kala Severe Date: Wed, 25 Mar 2026 12:36:24 -0700 Subject: [PATCH 04/11] Bug 2024075 Test Version Refactor: Moved subtest columns to test version strategy and test version files (#1017) moved subtest columns to test version strategy and test version files Updated tests to make mann-whitney-u the default. Added duplicated code to revisionRowHelpers. --- .../SubtestsRevisionRow.test.tsx | 9 +- src/common/testVersions/index.ts | 4 + src/common/testVersions/mannWhitney.tsx | 87 +++++++- src/common/testVersions/studentT.tsx | 71 ++++++- src/components/CompareResults/RevisionRow.tsx | 7 +- .../SubtestsResults/SubtestsRevisionRow.tsx | 201 +----------------- src/utils/revisionRowHelpers.ts | 6 + 7 files changed, 179 insertions(+), 206 deletions(-) diff --git a/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx b/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx index 6972fc89f..8dbe08dec 100644 --- a/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx +++ b/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx @@ -139,13 +139,13 @@ describe('SubtestsRevisionRow Component', () => { expect(await screen.findByText(/Normality Test/i)).toBeInTheDocument(); }); - it('renders subtests results defaulting to student-t with no testVersion', async () => { + it('renders subtests results defaulting to mann-whitney-u with no testVersion', async () => { const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); - const { subtestsResult } = getTestData(); + const { subtestsMannWhitneyResult } = getTestData(); const mockGridTemplateColumns = '1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr'; renderWithRoute( , @@ -153,7 +153,7 @@ describe('SubtestsRevisionRow Component', () => { const expandRowButton = await screen.findByTestId(/ExpandMoreIcon/); await user.click(expandRowButton); - expect(await screen.findByText(/Difference of means/i)).toBeInTheDocument(); + expect(await screen.findByText(/Normality Test/i)).toBeInTheDocument(); }); it('should display baseMean and newMean in subtests for student-t testVersion', async () => { @@ -164,6 +164,7 @@ describe('SubtestsRevisionRow Component', () => { result={subtestsResult[0]} gridTemplateColumns={mockGridTemplateColumns} replicates={false} + testVersion='student-t' />, ); diff --git a/src/common/testVersions/index.ts b/src/common/testVersions/index.ts index 8c61c882e..8339e66af 100644 --- a/src/common/testVersions/index.ts +++ b/src/common/testVersions/index.ts @@ -12,6 +12,10 @@ export interface TestVersionStrategy { newAvg: number | null; }; renderColumns(result: CombinedResultsItemType): ReactNode; + renderSubtestColumns( + result: CombinedResultsItemType, + expanded: boolean, + ): ReactNode; } // Registry mapping each TestVersion to its concrete strategy. diff --git a/src/common/testVersions/mannWhitney.tsx b/src/common/testVersions/mannWhitney.tsx index 034915734..c7bf53704 100644 --- a/src/common/testVersions/mannWhitney.tsx +++ b/src/common/testVersions/mannWhitney.tsx @@ -2,14 +2,19 @@ import ThumbDownIcon from '@mui/icons-material/ThumbDown'; import ThumbUpIcon from '@mui/icons-material/ThumbUp'; import Box from '@mui/material/Box'; +import { FontSize } from '../../styles'; import { CombinedResultsItemType, MannWhitneyResultsItem, } from '../../types/state'; import { TableConfig } from '../../types/types'; +import { formatNumber } from '../../utils/format'; import { capitalize } from '../../utils/helpers'; -import { getPlatformShortName } from '../../utils/platform'; -import { determineStatusHintClass } from '../../utils/revisionRowHelpers'; +import { getBrowserDisplay, getPlatformShortName } from '../../utils/platform'; +import { + determineSign, + determineStatusHintClass, +} from '../../utils/revisionRowHelpers'; import { defaultSortFunction } from '../../utils/sortFunctions'; import { tooltipBaseMean, @@ -202,6 +207,84 @@ export const mannWhitneyStrategy = { }; }, + renderSubtestColumns(result: CombinedResultsItemType, expanded: boolean) { + const { + test, + cliffs_delta, + mann_whitney_test, + cles, + direction_of_change, + base_measurement_unit: baseUnit, + new_measurement_unit: newUnit, + base_app: baseApp, + new_app: newApp, + } = result as MannWhitneyResultsItem; + const mann_whitney_interpretation = mann_whitney_test?.interpretation + ? capitalize(mann_whitney_test.interpretation) + : '-'; + const clesVal = ((cles?.cles ?? 0) * 100).toFixed(2); + const baseAvgValue = + (result as MannWhitneyResultsItem).base_standard_stats?.mean ?? 0; + const newAvgValue = + (result as MannWhitneyResultsItem).new_standard_stats?.mean ?? 0; + return ( + <> +
+ {test} +
+
+ {formatNumber(baseAvgValue)} {baseUnit} + {getBrowserDisplay(baseApp, newApp, expanded) && ( + ({baseApp}) + )} +
+
+ {determineSign(baseAvgValue, newAvgValue)} +
+
+ {formatNumber(newAvgValue)} {newUnit} + {getBrowserDisplay(baseApp, newApp, expanded) && ( + ({newApp}) + )} +
+
+ + {direction_of_change === 'improvement' ? ( + + ) : null} + {direction_of_change === 'regression' ? ( + + ) : null} + {capitalize(direction_of_change ?? '')} + +
+
+ {' '} + {cliffs_delta || '-'} +
+
+ {mann_whitney_interpretation} +
+
+ {clesVal ? `${clesVal}% ` : '-'} +
+ + ); + }, + renderColumns(result: CombinedResultsItemType) { const { cliffs_delta, direction_of_change, mann_whitney_test, cles } = result as MannWhitneyResultsItem; diff --git a/src/common/testVersions/studentT.tsx b/src/common/testVersions/studentT.tsx index cc6276301..584f40692 100644 --- a/src/common/testVersions/studentT.tsx +++ b/src/common/testVersions/studentT.tsx @@ -5,10 +5,13 @@ import ThumbDownIcon from '@mui/icons-material/ThumbDown'; import ThumbUpIcon from '@mui/icons-material/ThumbUp'; import Box from '@mui/material/Box'; +import { FontSize } from '../../styles'; import { CombinedResultsItemType, CompareResultsItem } from '../../types/state'; import { TableConfig } from '../../types/types'; -import { getPlatformShortName } from '../../utils/platform'; +import { formatNumber } from '../../utils/format'; +import { getBrowserDisplay, getPlatformShortName } from '../../utils/platform'; import { + determineSign, determineStatus, determineStatusHintClass, } from '../../utils/revisionRowHelpers'; @@ -154,6 +157,72 @@ export const studentTStrategy = { }; }, + renderSubtestColumns(result: CombinedResultsItemType, expanded: boolean) { + const { + test, + delta_percentage: deltaPercent, + confidence_text: confidenceText, + is_improvement: improvement, + is_regression: regression, + base_avg_value: baseAvgValue, + new_avg_value: newAvgValue, + base_app: baseApp, + new_app: newApp, + base_measurement_unit: baseUnit, + new_measurement_unit: newUnit, + } = result as CompareResultsItem; + + return ( + <> +
+ {test} +
+
+ {formatNumber(baseAvgValue)} {baseUnit} + {getBrowserDisplay(baseApp, newApp, expanded) && ( + ({baseApp}) + )} +
+
+ {determineSign(baseAvgValue, newAvgValue)} +
+
+ {formatNumber(newAvgValue)} {newUnit} + {getBrowserDisplay(baseApp, newApp, expanded) && ( + ({newApp}) + )} +
+
+ + {improvement ? : null} + {regression ? : null} + {determineStatus(!!improvement, !!regression)} + +
+
+ {' '} + {`${deltaPercent} % `} +
+
+ {confidenceText && confidenceIcons[confidenceText]} + {confidenceText || '-'} +
+ + ); + }, + renderColumns(result: CombinedResultsItemType) { const { is_improvement: improvement, diff --git a/src/components/CompareResults/RevisionRow.tsx b/src/components/CompareResults/RevisionRow.tsx index e0650be6a..f79497feb 100644 --- a/src/components/CompareResults/RevisionRow.tsx +++ b/src/components/CompareResults/RevisionRow.tsx @@ -26,6 +26,7 @@ import { getPlatformAndVersion, getBrowserDisplay, } from '../../utils/platform'; +import { determineSign } from '../../utils/revisionRowHelpers'; import AndroidIcon from '../Shared/Icons/AndroidIcon'; import LinuxIcon from '../Shared/Icons/LinuxIcon'; import SubtestsIcon from '../Shared/Icons/SubtestsIcon'; @@ -120,12 +121,6 @@ const revisionRow = style({ }, }); -function determineSign(baseMedianValue: number, newMedianValue: number) { - if (baseMedianValue > newMedianValue) return '>'; - if (baseMedianValue < newMedianValue) return '<'; - return ''; -} - const platformIcons: Record = { Linux: , macOS: , diff --git a/src/components/CompareResults/SubtestsResults/SubtestsRevisionRow.tsx b/src/components/CompareResults/SubtestsResults/SubtestsRevisionRow.tsx index fc4a7336b..0a882525e 100644 --- a/src/components/CompareResults/SubtestsResults/SubtestsRevisionRow.tsx +++ b/src/components/CompareResults/SubtestsResults/SubtestsRevisionRow.tsx @@ -1,29 +1,18 @@ import { useId, useState } from 'react'; -import DragHandleIcon from '@mui/icons-material/DragHandle'; import ExpandLessIcon from '@mui/icons-material/ExpandLess'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; -import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; -import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'; -import ThumbDownIcon from '@mui/icons-material/ThumbDown'; -import ThumbUpIcon from '@mui/icons-material/ThumbUp'; import TimelineIcon from '@mui/icons-material/Timeline'; import { IconButton, Box } from '@mui/material'; import { style } from 'typestyle'; import RevisionRowExpandable from '.././RevisionRowExpandable'; -import { MANN_WHITNEY_U, STUDENT_T } from '../../../common/constants'; +import { MANN_WHITNEY_U } from '../../../common/constants'; +import { getStrategy } from '../../../common/testVersions'; import { Strings } from '../../../resources/Strings'; -import { FontSize, Spacing } from '../../../styles'; -import type { - CombinedResultsItemType, - CompareResultsItem, - MannWhitneyResultsItem, -} from '../../../types/state'; +import { Spacing } from '../../../styles'; +import type { CombinedResultsItemType } from '../../../types/state'; import { TestVersion } from '../../../types/types'; -import { capitalize } from '../../../utils/helpers'; -import { getBrowserDisplay } from '../../../utils/platform'; -import { formatNumber } from './../../../utils/format'; const revisionRow = style({ borderRadius: '4px 0px 0px 4px', @@ -113,178 +102,6 @@ const typography = style({ lineHeight: '1.5', }); -const confidenceIcons = { - Low: , - Medium: , - High: , -}; - -function determineStatus(improvement: boolean, regression: boolean) { - if (improvement) return 'Improvement'; - if (regression) return 'Regression'; - return '-'; -} - -function determineStatusHintClass(improvement: boolean, regression: boolean) { - if (improvement) return 'status-hint-improvement'; - if (regression) return 'status-hint-regression'; - return ''; -} - -function determineSign(baseMedianValue: number, newMedianValue: number) { - if (baseMedianValue > newMedianValue) return '>'; - if (baseMedianValue < newMedianValue) return '<'; - return ''; -} - -export const renderSubtestColumnsBasedOnTestVersion = ( - testVersion: TestVersion, - result: CombinedResultsItemType, - expanded: boolean, -) => { - if (testVersion === MANN_WHITNEY_U) { - const { - test, - cliffs_delta, - mann_whitney_test, - cles, - direction_of_change, - base_measurement_unit: baseUnit, - new_measurement_unit: newUnit, - base_app: baseApp, - new_app: newApp, - } = result as MannWhitneyResultsItem; - const mann_whitney_interpretation = mann_whitney_test?.interpretation - ? capitalize(mann_whitney_test?.interpretation) - : '-'; - const clesVal = ((cles?.cles ?? 0) * 100).toFixed(2); - const baseAvgValue = - (result as MannWhitneyResultsItem).base_standard_stats?.mean ?? 0; - const newAvgValue = - (result as MannWhitneyResultsItem).new_standard_stats?.mean ?? 0; - return ( - <> -
- {test} -
-
- {formatNumber(baseAvgValue)} {baseUnit} - {getBrowserDisplay(baseApp, newApp, expanded) && ( - ({baseApp}) - )} -
-
- {determineSign(baseAvgValue, newAvgValue)} -
-
- {formatNumber(newAvgValue)} {newUnit} - {getBrowserDisplay(baseApp, newApp, expanded) && ( - ({newApp}) - )} -
-
- - {direction_of_change === 'improvement' ? ( - - ) : null} - {direction_of_change === 'regression' ? ( - - ) : null} - {capitalize(direction_of_change ?? '')} - -
-
- {' '} - {cliffs_delta || '-'} -
-
- {mann_whitney_interpretation} -
-
- {clesVal ? `${clesVal}% ` : '-'} -
- - ); - } else { - const { - test, - delta_percentage: deltaPercent, - confidence_text: confidenceText, - is_improvement: improvement, - is_regression: regression, - base_avg_value: baseAvgValue, - new_avg_value: newAvgValue, - base_app: baseApp, - new_app: newApp, - base_measurement_unit: baseUnit, - new_measurement_unit: newUnit, - } = result as CompareResultsItem; - - return ( - <> -
- {test} -
-
- {formatNumber(baseAvgValue)} {baseUnit} - {getBrowserDisplay(baseApp, newApp, expanded) && ( - ({baseApp}) - )} -
-
- {determineSign(baseAvgValue, newAvgValue)} -
-
- {formatNumber(newAvgValue)} {newUnit} - {getBrowserDisplay(baseApp, newApp, expanded) && ( - ({newApp}) - )} -
-
- - {improvement ? : null} - {regression ? : null} - {determineStatus(!!improvement, !!regression)} - -
-
- {' '} - {`${deltaPercent} % `} -
-
- {confidenceText && confidenceIcons[confidenceText]} - {confidenceText || '-'} -
- - ); - } -}; - function SubtestsRevisionRow(props: RevisionRowProps) { const id = useId(); const { result, gridTemplateColumns, replicates, testVersion } = props; @@ -307,6 +124,8 @@ function SubtestsRevisionRow(props: RevisionRowProps) { setExpanded(!expanded); }; + const strategy = getStrategy(testVersion ?? MANN_WHITNEY_U); + return ( <> - {renderSubtestColumnsBasedOnTestVersion( - testVersion ?? STUDENT_T, - result, - expanded, - )} + {strategy.renderSubtestColumns(result, expanded)}
)} diff --git a/src/utils/revisionRowHelpers.ts b/src/utils/revisionRowHelpers.ts index 39b1e9caa..e007a8ee1 100644 --- a/src/utils/revisionRowHelpers.ts +++ b/src/utils/revisionRowHelpers.ts @@ -1,3 +1,9 @@ +export function determineSign(baseValue: number, newValue: number) { + if (baseValue > newValue) return '>'; + if (baseValue < newValue) return '<'; + return ''; +} + export function determineStatus(improvement: boolean, regression: boolean) { if (improvement) return 'Improvement'; if (regression) return 'Regression'; From cbcb72a59eeda13f106655064714a31b65bf0fdd Mon Sep 17 00:00:00 2001 From: Kala Severe Date: Wed, 25 Mar 2026 13:30:58 -0700 Subject: [PATCH 05/11] Bug 2022720 Test Version Refactor: Refactor how the expanded row's components are rendered (#1016) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * moved test version specific components to the specific test version Added new methods to the strategy interface: expanded left, expanded right, expanded bottom, and getComparisonreResult * lint fix and snapshots updated * removed redundant test version prop from mwu comps * added test coverage for student median difference * Bug-2020964: Update Contributing section in README (#1009) * docs: Update Contributing section in README Updated the section in the README where it asks to link PR to issue. We use Bugzilla for filing issues. This PR adds the correct steps to link the PR to the issues. The old steps were relevant if we were using GitHub for filing issues. * Bug-2020964: Implemented review comments Removed the additional instruction on bugzilla attachment as per review comment. * Update all npm dependencies (2026-03-25) (#1014) ⬆️ Update all npm dependencies (2026-03-25) Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> * Bug 2024075 Test Version Refactor: Moved subtest columns to test version strategy and test version files (#1017) moved subtest columns to test version strategy and test version files Updated tests to make mann-whitney-u the default. Added duplicated code to revisionRowHelpers. * moved test version specific components to the specific test version Added new methods to the strategy interface: expanded left, expanded right, expanded bottom, and getComparisonreResult * lint fix and snapshots updated * added test coverage for student median difference * revert package.json --------- Co-authored-by: Alex Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> --- .../RevisionRowExpandable.test.tsx | 40 +++++ .../__snapshots__/ResultsView.test.tsx.snap | 6 +- .../SubtestsRevisionRow.test.tsx.snap | 6 +- src/common/testVersions/index.ts | 4 + src/common/testVersions/mannWhitney.tsx | 51 ++++++ src/common/testVersions/studentT.tsx | 81 +++++++++- .../MannWhitneyCompareMetrics.tsx | 6 +- .../CompareResults/ModeInterpretation.tsx | 6 +- .../CompareResults/RevisionRowExpandable.tsx | 152 ++---------------- .../CompareResults/StatisticsWarnings.tsx | 5 - 10 files changed, 193 insertions(+), 164 deletions(-) diff --git a/src/__tests__/CompareResults/RevisionRowExpandable.test.tsx b/src/__tests__/CompareResults/RevisionRowExpandable.test.tsx index bf3667388..53e061568 100644 --- a/src/__tests__/CompareResults/RevisionRowExpandable.test.tsx +++ b/src/__tests__/CompareResults/RevisionRowExpandable.test.tsx @@ -21,6 +21,46 @@ function renderWithRoute(component: ReactElement) { }); } +describe('RevisionRowExpandable for student-t testVersion', () => { + it('should display median difference and percentage when both median values are present', async () => { + const { testCompareData } = getTestData(); + // testCompareData[0]: base_median_value=704.84, new_median_value=712.44, unit='ms' + // expected difference: 7.6, percentage: 1.08 + renderWithRoute( + , + ); + + const header = await screen.findByText(/Difference of medians/); + const medianBox = header.closest('div'); + expect(medianBox).toHaveTextContent('1.08%'); + expect(medianBox).toHaveTextContent('7.6 ms'); + }); + + it('should not display median difference when median values are absent', async () => { + const { testCompareData } = getTestData(); + const noMedians = { + ...testCompareData[0], + base_median_value: 0, + new_median_value: 0, + }; + + renderWithRoute( + , + ); + + await screen.findByText(/Difference of means/); + expect(screen.queryByText(/Difference of medians/)).not.toBeInTheDocument(); + }); +}); + describe('RevisionRowExpandable for mann-whitney-u testVersion', () => { it('should display ModeInterpretation for mann-whitney-u', async () => { const { mockMannWhitneyResultData } = getTestData(); diff --git a/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap index b095553c6..2d0538e89 100644 --- a/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap +++ b/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap @@ -67,8 +67,7 @@ exports[`Results View Should display Base, New and Common graphs with replicates Comparison result - : - + : ( lower @@ -460,8 +459,7 @@ exports[`Results View Should display Base, New and Common graphs with tooltips 1 Comparison result - : - + : ( lower diff --git a/src/__tests__/CompareResults/__snapshots__/SubtestsRevisionRow.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/SubtestsRevisionRow.test.tsx.snap index 838dfa61a..c63f3aa33 100644 --- a/src/__tests__/CompareResults/__snapshots__/SubtestsRevisionRow.test.tsx.snap +++ b/src/__tests__/CompareResults/__snapshots__/SubtestsRevisionRow.test.tsx.snap @@ -36,7 +36,7 @@ exports[`SubtestsRevisionRow Component renders browser name when base and new ap <
984.16 @@ -208,7 +208,7 @@ exports[`SubtestsRevisionRow Component renders doesnt render browser name when b <
982.41 @@ -362,7 +362,7 @@ exports[`SubtestsRevisionRow Component renders the component with correct data 1 <
982.41 diff --git a/src/common/testVersions/index.ts b/src/common/testVersions/index.ts index 8339e66af..4fc8b3e47 100644 --- a/src/common/testVersions/index.ts +++ b/src/common/testVersions/index.ts @@ -16,6 +16,10 @@ export interface TestVersionStrategy { result: CombinedResultsItemType, expanded: boolean, ): ReactNode; + renderExpandedLeft(result: CombinedResultsItemType): ReactNode; + getComparisonResult(result: CombinedResultsItemType): string; + renderExpandedRight(result: CombinedResultsItemType): ReactNode; + renderExpandedBottom(result: CombinedResultsItemType): ReactNode; } // Registry mapping each TestVersion to its concrete strategy. diff --git a/src/common/testVersions/mannWhitney.tsx b/src/common/testVersions/mannWhitney.tsx index c7bf53704..37143e826 100644 --- a/src/common/testVersions/mannWhitney.tsx +++ b/src/common/testVersions/mannWhitney.tsx @@ -2,6 +2,10 @@ import ThumbDownIcon from '@mui/icons-material/ThumbDown'; import ThumbUpIcon from '@mui/icons-material/ThumbUp'; import Box from '@mui/material/Box'; +import { MannWhitneyCompareMetrics } from '../../components/CompareResults/MannWhitneyCompareMetrics'; +import { ModeInterpretation } from '../../components/CompareResults/ModeInterpretation'; +import PValCliffsDeltaComp from '../../components/CompareResults/PValCliffsDeltaComp'; +import { StatisticsWarnings } from '../../components/CompareResults/StatisticsWarnings'; import { FontSize } from '../../styles'; import { CombinedResultsItemType, @@ -285,6 +289,53 @@ export const mannWhitneyStrategy = { ); }, + renderExpandedLeft() { + return null; + }, + + getComparisonResult(result: CombinedResultsItemType) { + return capitalize( + (result as MannWhitneyResultsItem).direction_of_change ?? '', + ); + }, + + renderExpandedRight(result: CombinedResultsItemType) { + const mwResult = result as MannWhitneyResultsItem; + const { cles, cles_direction } = mwResult.cles ?? { + cles: '', + cles_direction: '', + }; + const { cliffs_delta, cliffs_interpretation } = mwResult; + const pValue = mwResult.mann_whitney_test?.pvalue; + const p_value_cles = mwResult.mann_whitney_test?.interpretation + ? capitalize(mwResult.mann_whitney_test.interpretation) + : ''; + + return ( + <> + + + + ); + }, + + renderExpandedBottom(result: CombinedResultsItemType) { + const mwResult = result as MannWhitneyResultsItem; + return ( +
+ + +
+ ); + }, + renderColumns(result: CombinedResultsItemType) { const { cliffs_delta, direction_of_change, mann_whitney_test, cles } = result as MannWhitneyResultsItem; diff --git a/src/common/testVersions/studentT.tsx b/src/common/testVersions/studentT.tsx index 584f40692..0b1292502 100644 --- a/src/common/testVersions/studentT.tsx +++ b/src/common/testVersions/studentT.tsx @@ -5,6 +5,8 @@ import ThumbDownIcon from '@mui/icons-material/ThumbDown'; import ThumbUpIcon from '@mui/icons-material/ThumbUp'; import Box from '@mui/material/Box'; +import Distribution from '../../components/CompareResults/Distribution'; +import { Strings } from '../../resources/Strings'; import { FontSize } from '../../styles'; import { CombinedResultsItemType, CompareResultsItem } from '../../types/state'; import { TableConfig } from '../../types/types'; @@ -171,7 +173,6 @@ export const studentTStrategy = { base_measurement_unit: baseUnit, new_measurement_unit: newUnit, } = result as CompareResultsItem; - return ( <>
@@ -186,7 +187,7 @@ export const studentTStrategy = {
{determineSign(baseAvgValue, newAvgValue)}
-
+
{formatNumber(newAvgValue)} {newUnit} {getBrowserDisplay(baseApp, newApp, expanded) && ( ({newApp}) @@ -223,6 +224,82 @@ export const studentTStrategy = { ); }, + renderExpandedLeft(result: CombinedResultsItemType) { + return ; + }, + + getComparisonResult(result: CombinedResultsItemType) { + return (result as CompareResultsItem).new_is_better ? 'better' : 'worse'; + }, + + renderExpandedRight(result: CombinedResultsItemType) { + const { + delta_percentage: deltaPercent, + delta_value: delta, + confidence_text: confidenceText, + confidence: confidenceValue, + base_median_value: baseMedian, + new_median_value: newMedian, + base_measurement_unit: baseUnit, + new_measurement_unit: newUnit, + } = result as CompareResultsItem; + + const deltaUnit = baseUnit || newUnit || ''; + const formatTwoDigits = new Intl.NumberFormat('en-US', { + maximumFractionDigits: 2, + }); + const medianDifference = + baseMedian && newMedian + ? formatTwoDigits.format(newMedian - baseMedian) + : ''; + const medianPercentage = + baseMedian && newMedian + ? formatTwoDigits.format(((newMedian - baseMedian) / baseMedian) * 100) + : ''; + + const { confidenceNote } = Strings.components.expandableRow; + + return ( + <> + + Difference of means: {deltaPercent}% ({formatNumber(delta)} + {deltaUnit ? ' ' + deltaUnit : null}) + + {newMedian && baseMedian ? ( + + Difference of medians: {medianPercentage}% ( + {medianDifference} + {deltaUnit ? ' ' + deltaUnit : null}) + + ) : null} + {confidenceText ? ( +
+ + Confidence: {confidenceText} + {confidenceValue ? ' ' + `(${confidenceValue})` : null} + + + **Note: {confidenceNote}{' '} + +
+ ) : ( + + Confidence: Not available{' '} + + )} + + ); + }, + + renderExpandedBottom() { + return null; + }, + renderColumns(result: CombinedResultsItemType) { const { is_improvement: improvement, diff --git a/src/components/CompareResults/MannWhitneyCompareMetrics.tsx b/src/components/CompareResults/MannWhitneyCompareMetrics.tsx index c89f4bc34..1cead497e 100644 --- a/src/components/CompareResults/MannWhitneyCompareMetrics.tsx +++ b/src/components/CompareResults/MannWhitneyCompareMetrics.tsx @@ -1,22 +1,18 @@ import { Box } from '@mui/material'; -import { MANN_WHITNEY_U } from '../../common/constants'; import { MannWhitneyResultsItem } from '../../types/state'; -import { TestVersion } from '../../types/types'; import { getModeInterpretation } from '../../utils/helpers'; const METRIC_HEADERS = ['Metric', 'Base', 'New', 'Interpretation']; interface MannWhitneyCompareMetricsProps { result: MannWhitneyResultsItem; - testVersion: TestVersion; } export const MannWhitneyCompareMetrics = ({ result, - testVersion, }: MannWhitneyCompareMetricsProps) => { - if (!result || testVersion !== MANN_WHITNEY_U) { + if (!result) { return null; } diff --git a/src/components/CompareResults/ModeInterpretation.tsx b/src/components/CompareResults/ModeInterpretation.tsx index dcb10f47e..59f08bf62 100644 --- a/src/components/CompareResults/ModeInterpretation.tsx +++ b/src/components/CompareResults/ModeInterpretation.tsx @@ -1,17 +1,13 @@ import { Box } from '@mui/material'; -import { MANN_WHITNEY_U } from '../../common/constants'; import { MannWhitneyResultsItem } from '../../types/state'; -import { TestVersion } from '../../types/types'; export const ModeInterpretation = ({ result, - testVersion, }: { result: MannWhitneyResultsItem; - testVersion: TestVersion; }) => { - if (!result || !result.silverman_kde || testVersion !== MANN_WHITNEY_U) { + if (!result || !result.silverman_kde) { return null; } diff --git a/src/components/CompareResults/RevisionRowExpandable.tsx b/src/components/CompareResults/RevisionRowExpandable.tsx index d31e4b27c..0a8697abd 100644 --- a/src/components/CompareResults/RevisionRowExpandable.tsx +++ b/src/components/CompareResults/RevisionRowExpandable.tsx @@ -4,31 +4,13 @@ import Grid from '@mui/material/Grid'; import Stack from '@mui/material/Stack'; import CommonGraph from './CommonGraph'; -import Distribution from './Distribution'; -import { ModeInterpretation } from './ModeInterpretation'; -import { MANN_WHITNEY_U, STUDENT_T } from '../../common/constants'; +import { getStrategy } from '../../common/testVersions'; import { Strings } from '../../resources/Strings'; import { Spacing } from '../../styles'; -import type { - CombinedResultsItemType, - CompareResultsItem, - MannWhitneyResultsItem, -} from '../../types/state'; +import type { CombinedResultsItemType } from '../../types/state'; import { TestVersion } from '../../types/types'; -import { formatNumber } from './../../utils/format'; -import { MannWhitneyCompareMetrics } from './MannWhitneyCompareMetrics'; -import PValCliffsDeltaComp from './PValCliffsDeltaComp'; -import { StatisticsWarnings } from './StatisticsWarnings'; -import { capitalize } from '../../utils/helpers'; -const strings = Strings.components.expandableRow; -const { singleRun, confidenceNote } = strings; - -const numberFormatterTwoDigits = new Intl.NumberFormat('en-US', { - maximumFractionDigits: 2, -}); -const formatNumberTwoDigits = (value: number) => - numberFormatterTwoDigits.format(value); +const { singleRun } = Strings.components.expandableRow; function RevisionRowExpandable(props: RevisionRowExpandableProps) { const { result, id, testVersion } = props; @@ -39,31 +21,15 @@ function RevisionRowExpandable(props: RevisionRowExpandableProps) { base_runs_replicates: baseRunsReplicates, new_runs_replicates: newRunsReplicates, platform, - delta_percentage: deltaPercent, - delta_value: delta, - confidence_text: confidenceText, - confidence: confidenceValue, - base_median_value: baseMedian, - new_median_value: newMedian, - base_measurement_unit: baseUnit, - new_measurement_unit: newUnit, - base_app: baseApplication, - new_app: newApplication, more_runs_are_needed: moreRunsAreNeeded, lower_is_better: lowerIsBetter, - new_is_better: newIsBetter, + base_app: baseApplication, + new_app: newApplication, + base_measurement_unit: baseUnit, + new_measurement_unit: newUnit, } = result; - const unit = baseUnit || newUnit; - const deltaUnit = unit ? `${unit}` : ''; - let medianDifference = ''; - let medianPercentage = ''; - if (baseMedian && newMedian) { - medianDifference = formatNumberTwoDigits(newMedian - baseMedian); - medianPercentage = formatNumberTwoDigits( - ((newMedian - baseMedian) / baseMedian) * 100, - ); - } + const strategy = getStrategy(testVersion); const baseValues = baseRunsReplicates && baseRunsReplicates.length @@ -73,31 +39,6 @@ function RevisionRowExpandable(props: RevisionRowExpandableProps) { const newValues = newRunsReplicates && newRunsReplicates.length ? newRunsReplicates : newRuns; - const renderPValCliffsDeltaComp = (result: MannWhitneyResultsItem) => { - if (testVersion === MANN_WHITNEY_U && result) { - const { cles, cles_direction } = result?.cles ?? { - cles: '', - cles_direction: '', - }; - const { cliffs_delta, cliffs_interpretation } = result; - const pValue = result?.mann_whitney_test?.pvalue; - const p_value_cles = result?.mann_whitney_test?.interpretation - ? capitalize(result.mann_whitney_test.interpretation) - : ''; - return ( - - ); - } - return; - }; - return ( - {/******* student t test rendering **************/} - {testVersion === STUDENT_T && ( - - )} + {strategy.renderExpandedLeft(result)} @@ -149,80 +87,14 @@ function RevisionRowExpandable(props: RevisionRowExpandableProps) {
)} - Comparison result:{' '} - {testVersion === MANN_WHITNEY_U - ? capitalize( - (result as MannWhitneyResultsItem).direction_of_change ?? - '', - ) - : newIsBetter - ? 'better' - : 'worse'}{' '} + Comparison result: {strategy.getComparisonResult(result)}{' '} ({lowerIsBetter ? 'lower' : 'higher'} is better) - {/******* student t test rendering **************/} - {testVersion === STUDENT_T && ( - <> - - Difference of means: {deltaPercent}% ( - {formatNumber(delta)} - {deltaUnit ? ' ' + deltaUnit : null}) - - {newMedian && baseMedian ? ( - - Difference of medians: {medianPercentage}% ( - {medianDifference} - {deltaUnit ? ' ' + deltaUnit : null}) - - ) : null} - {confidenceText ? ( -
- - Confidence: {confidenceText} - {confidenceValue ? ' ' + `(${confidenceValue})` : null} - - - **Note: {confidenceNote}{' '} - -
- ) : ( - - Confidence: Not available{' '} - - )} - - )} - {/******* mann-whitney rendering **************/} - {renderPValCliffsDeltaComp(result as MannWhitneyResultsItem)} - + {strategy.renderExpandedRight(result)}
- - {/******* mann-whitney rendering **************/} -
- - -
-
+ {strategy.renderExpandedBottom(result)} ); diff --git a/src/components/CompareResults/StatisticsWarnings.tsx b/src/components/CompareResults/StatisticsWarnings.tsx index bc43aad86..513de1b6b 100644 --- a/src/components/CompareResults/StatisticsWarnings.tsx +++ b/src/components/CompareResults/StatisticsWarnings.tsx @@ -1,19 +1,14 @@ import { Warning } from '@mui/icons-material'; import { Box } from '@mui/system'; -import { MANN_WHITNEY_U } from '../../common/constants'; import { Colors } from '../../styles'; import { MannWhitneyResultsItem } from '../../types/state'; -import { TestVersion } from '../../types/types'; export const StatisticsWarnings = ({ result, - testVersion, }: { result: MannWhitneyResultsItem; - testVersion: TestVersion; }) => { - if (testVersion !== MANN_WHITNEY_U) return null; const componentStyles = { backgroundColor: 'transparent', marginTop: 2, From bcf6843802d7d72426ead1a0f9bd507ce5b41066 Mon Sep 17 00:00:00 2001 From: Matthew Gaudet Date: Thu, 2 Apr 2026 11:51:15 -0600 Subject: [PATCH 06/11] Bug 2024042 - Add median diff column (#1015) * Bug 2024042 - Add median diff column resolve conflicts for oqz * Bug 2024042 - Adjust testing expectations * Bug 2024042 - Rename Effect Size column to save space, and tighten MD column name --- src/__tests__/App.test.tsx | 2 +- .../CompareResults/ResultsTable.test.tsx | 316 ++++++------ .../CompareResults/RevisionRow.test.tsx | 4 +- .../SubtestsResultsView.test.tsx | 104 ++-- .../SubtestsRevisionRow.test.tsx | 10 +- .../OverTimeResultsView.test.tsx.snap | 81 ++- .../__snapshots__/ResultsTable.test.tsx.snap | 352 +++++++++++-- .../__snapshots__/ResultsView.test.tsx.snap | 85 +++- .../SubtestsResultsView.test.tsx.snap | 471 +++++++++++++++--- .../CompareOverTime.test.tsx.snap | 2 +- .../CompareWithBase.test.tsx.snap | 4 +- src/common/constants.ts | 2 + src/common/testVersions/mannWhitney.tsx | 56 ++- 13 files changed, 1132 insertions(+), 357 deletions(-) diff --git a/src/__tests__/App.test.tsx b/src/__tests__/App.test.tsx index 926a89faa..8dfcdbdbc 100644 --- a/src/__tests__/App.test.tsx +++ b/src/__tests__/App.test.tsx @@ -400,7 +400,7 @@ describe('App', () => { // (this indicates the testVersion defaulted to mann-whitney-u) expect(screen.getByText("Cliff's Delta")).toBeInTheDocument(); expect(screen.getByText('Significance')).toBeInTheDocument(); - expect(screen.getByText('Effect Size (%)')).toBeInTheDocument(); + expect(screen.getByText('CLES(%)')).toBeInTheDocument(); // Verify the Stats Test Version dropdown shows Mann-Whitney-U as selected const testVersionDropdown = screen.getByRole('combobox', { diff --git a/src/__tests__/CompareResults/ResultsTable.test.tsx b/src/__tests__/CompareResults/ResultsTable.test.tsx index 2f917ef8f..12c1b39f1 100644 --- a/src/__tests__/CompareResults/ResultsTable.test.tsx +++ b/src/__tests__/CompareResults/ResultsTable.test.tsx @@ -79,6 +79,7 @@ function summarizeVisibleRows(testVersion?: TestVersion) { testVersion === 'mann-whitney-u' ? [ '.platform span', + '.median-diff', '.status', '.delta', '.significance', @@ -715,9 +716,9 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: spam', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ' rev: devilrabbit', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ]); expect(screen.getByRole('rowgroup')).toMatchSnapshot(); }); @@ -741,12 +742,12 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await screen.findByText('a11yr'); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, Improvement, 0.1, Not significant, 25.00 %', - ' - inexistant, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, , -, Significant, 100.00 %', - ' - Windows 10, , -, Significant, 50.00 %', + ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - inexistant, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); @@ -755,9 +756,9 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Platform', /Windows/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', + ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['osx', 'linux', 'android', 'ios'], @@ -768,12 +769,12 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Platform', /Windows/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, Improvement, 0.1, Not significant, 25.00 %', - ' - inexistant, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, , -, Significant, 100.00 %', - ' - Windows 10, , -, Significant, 50.00 %', + ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - inexistant, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); @@ -781,8 +782,8 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Platform', /Linux/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, Improvement, 0.1, Not significant, 25.00 %', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', + ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['osx', 'android', 'ios'], @@ -791,9 +792,9 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Platform', /Linux/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', + ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['osx', 'android', 'ios', 'linux'], @@ -802,22 +803,22 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Platform', 'Select all values'); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, Improvement, 0.1, Not significant, 25.00 %', - ' - inexistant, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, , -, Significant, 100.00 %', - ' - Windows 10, , -, Significant, 50.00 %', + ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - inexistant, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); await clickMenuItem(user, 'Platform', /macOS/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', - ' - Windows 10, , -, Significant, 100.00 %', - ' - Windows 10, , -, Significant, 50.00 %', + ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['windows', 'linux', 'android', 'ios'], @@ -826,9 +827,9 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Platform', /Android/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', - ' - Windows 10, , -, Significant, 100.00 %', - ' - Windows 10, , -, Significant, 50.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['windows', 'linux', 'ios'], @@ -837,7 +838,7 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Platform', /Select only.*Android/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, Improvement, 0.1, Not significant, 25.00 %', + ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['android'], @@ -874,10 +875,10 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await screen.findByText('a11yr'); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, , -, Significant, 100.00 %', - ' - Windows 10, , -, Significant, 50.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); @@ -885,8 +886,8 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Status', /No changes/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ status: ['improvement', 'regression'], @@ -895,7 +896,7 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Status', /Improvement/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ status: ['regression'], @@ -905,9 +906,9 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Status', /Regression/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, , -, Significant, 100.00 %', - ' - Windows 10, , -, Significant, 50.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ status: ['none', 'improvement'], @@ -916,17 +917,17 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Status', /Regression/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, , -, Significant, 100.00 %', - ' - Windows 10, , -, Significant, 50.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); await clickMenuItem(user, 'Status', /Select only.*Regression/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ status: ['regression'], @@ -935,7 +936,7 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Status', /Select only.*Improvement/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ status: ['improvement'], @@ -952,7 +953,7 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ]); const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); expect(await summarizeTableFiltersFromCheckboxes(user)).toEqual({ @@ -988,26 +989,26 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr aria.html opt e10s fission stylo webrender', ' rev: spam', - ' - Linux 18.04, Regression, 1.2, Not significant, 44.00 %', - ' - macOS 10.15, Improvement, 1.3, Not significant, 24.00 %', - ' - Windows 10, , 1.2, Significant, 99.00 %', - ' - Windows 10, , 1.2, Significant, 49.00 %', + ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', + ' - Windows 10, 0 %, , 1.2, Significant, 99.00 %', + ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', ' rev: tictactoe', - ' - Linux 18.04, Regression, 2, Not significant, 43.00 %', - ' - macOS 10.15, Improvement, 2.1, Not significant, 23.00 %', - ' - Windows 10, , 2, Significant, 98.00 %', - ' - Windows 10, , 2, Significant, 48.00 %', + ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', + ' - Windows 10, 0 %, , 2, Significant, 98.00 %', + ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: spam', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, , -, Significant, 100.00 %', - ' - Windows 10, , -, Significant, 50.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ' rev: tictactoe', - ' - Linux 18.04, Regression, 0.8, Not significant, 44.00 %', - ' - macOS 10.15, Improvement, 0.9, Not significant, 24.00 %', - ' - Windows 10, , 0.8, Significant, 99.00 %', - ' - Windows 10, , 0.8, Significant, 49.00 %', + ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', + ' - Windows 10, 0 %, , 0.8, Significant, 99.00 %', + ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', ]); // It should have the "descending" SVG. expect(deltaButton).toMatchSnapshot(); @@ -1019,26 +1020,26 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr aria.html opt e10s fission stylo webrender', ' rev: tictactoe', - ' - macOS 10.15, Improvement, 2.1, Not significant, 23.00 %', - ' - Linux 18.04, Regression, 2, Not significant, 43.00 %', - ' - Windows 10, , 2, Significant, 48.00 %', - ' - Windows 10, , 2, Significant, 98.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', + ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', + ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', + ' - Windows 10, 0 %, , 2, Significant, 98.00 %', ' rev: spam', - ' - macOS 10.15, Improvement, 1.3, Not significant, 24.00 %', - ' - Linux 18.04, Regression, 1.2, Not significant, 44.00 %', - ' - Windows 10, , 1.2, Significant, 49.00 %', - ' - Windows 10, , 1.2, Significant, 99.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', + ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', + ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', + ' - Windows 10, 0 %, , 1.2, Significant, 99.00 %', 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: tictactoe', - ' - macOS 10.15, Improvement, 0.9, Not significant, 24.00 %', - ' - Linux 18.04, Regression, 0.8, Not significant, 44.00 %', - ' - Windows 10, , 0.8, Significant, 49.00 %', - ' - Windows 10, , 0.8, Significant, 99.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', + ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', + ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', + ' - Windows 10, 0 %, , 0.8, Significant, 99.00 %', ' rev: spam', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', - ' - Windows 10, , -, Significant, 50.00 %', - ' - Windows 10, , -, Significant, 100.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', + ' - Windows 10, 0 %, , -, Significant, 100.00 %', ]); // It should have the "ascending" SVG. expect(deltaButton).toMatchSnapshot(); @@ -1053,26 +1054,26 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr aria.html opt e10s fission stylo webrender', ' rev: tictactoe', - ' - macOS 10.15, Improvement, 2.1, Not significant, 23.00 %', - ' - Linux 18.04, Regression, 2, Not significant, 43.00 %', - ' - Windows 10, , 2, Significant, 98.00 %', - ' - Windows 10, , 2, Significant, 48.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', + ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', + ' - Windows 10, 0 %, , 2, Significant, 98.00 %', + ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', ' rev: spam', - ' - macOS 10.15, Improvement, 1.3, Not significant, 24.00 %', - ' - Linux 18.04, Regression, 1.2, Not significant, 44.00 %', - ' - Windows 10, , 1.2, Significant, 99.00 %', - ' - Windows 10, , 1.2, Significant, 49.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', + ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', + ' - Windows 10, 0 %, , 1.2, Significant, 99.00 %', + ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: tictactoe', - ' - macOS 10.15, Improvement, 0.9, Not significant, 24.00 %', - ' - Linux 18.04, Regression, 0.8, Not significant, 44.00 %', - ' - Windows 10, , 0.8, Significant, 99.00 %', - ' - Windows 10, , 0.8, Significant, 49.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', + ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', + ' - Windows 10, 0 %, , 0.8, Significant, 99.00 %', + ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', ' rev: spam', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', - ' - Windows 10, , -, Significant, 100.00 %', - ' - Windows 10, , -, Significant, 50.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); // It should have the "descending" SVG. expect(significanceButton).toMatchSnapshot(); @@ -1084,26 +1085,26 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: spam', - ' - Windows 10, , -, Significant, 50.00 %', - ' - Windows 10, , -, Significant, 100.00 %', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', + ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', + ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', ' rev: tictactoe', - ' - Windows 10, , 0.8, Significant, 49.00 %', - ' - Windows 10, , 0.8, Significant, 99.00 %', - ' - macOS 10.15, Improvement, 0.9, Not significant, 24.00 %', - ' - Linux 18.04, Regression, 0.8, Not significant, 44.00 %', + ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', + ' - Windows 10, 0 %, , 0.8, Significant, 99.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', + ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', 'a11yr aria.html opt e10s fission stylo webrender', ' rev: spam', - ' - Windows 10, , 1.2, Significant, 49.00 %', - ' - Windows 10, , 1.2, Significant, 99.00 %', - ' - macOS 10.15, Improvement, 1.3, Not significant, 24.00 %', - ' - Linux 18.04, Regression, 1.2, Not significant, 44.00 %', + ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', + ' - Windows 10, 0 %, , 1.2, Significant, 99.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', + ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', ' rev: tictactoe', - ' - Windows 10, , 2, Significant, 48.00 %', - ' - Windows 10, , 2, Significant, 98.00 %', - ' - macOS 10.15, Improvement, 2.1, Not significant, 23.00 %', - ' - Linux 18.04, Regression, 2, Not significant, 43.00 %', + ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', + ' - Windows 10, 0 %, , 2, Significant, 98.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', + ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', ]); // It should have the "descending" SVG. expect(significanceButton).toMatchSnapshot(); @@ -1112,32 +1113,32 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio // Sort by Effect Size (%) descending const effectSizeButton = screen.getByRole('button', { - name: /Effect Size \(%\).*sort/, + name: /CLES\(%\).*sort/, }); await user.click(effectSizeButton); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: spam', - ' - Windows 10, , -, Significant, 100.00 %', - ' - Windows 10, , -, Significant, 50.00 %', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', + ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ' rev: tictactoe', - ' - Windows 10, , 0.8, Significant, 99.00 %', - ' - Windows 10, , 0.8, Significant, 49.00 %', - ' - Linux 18.04, Regression, 0.8, Not significant, 44.00 %', - ' - macOS 10.15, Improvement, 0.9, Not significant, 24.00 %', + ' - Windows 10, 0 %, , 0.8, Significant, 99.00 %', + ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', + ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', 'a11yr aria.html opt e10s fission stylo webrender', ' rev: spam', - ' - Windows 10, , 1.2, Significant, 99.00 %', - ' - Windows 10, , 1.2, Significant, 49.00 %', - ' - Linux 18.04, Regression, 1.2, Not significant, 44.00 %', - ' - macOS 10.15, Improvement, 1.3, Not significant, 24.00 %', + ' - Windows 10, 0 %, , 1.2, Significant, 99.00 %', + ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', + ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', ' rev: tictactoe', - ' - Windows 10, , 2, Significant, 98.00 %', - ' - Windows 10, , 2, Significant, 48.00 %', - ' - Linux 18.04, Regression, 2, Not significant, 43.00 %', - ' - macOS 10.15, Improvement, 2.1, Not significant, 23.00 %', + ' - Windows 10, 0 %, , 2, Significant, 98.00 %', + ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', + ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', ]); expect(effectSizeButton).toMatchSnapshot(); @@ -1149,30 +1150,45 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr aria.html opt e10s fission stylo webrender', ' rev: tictactoe', - ' - macOS 10.15, Improvement, 2.1, Not significant, 23.00 %', - ' - Linux 18.04, Regression, 2, Not significant, 43.00 %', - ' - Windows 10, , 2, Significant, 48.00 %', - ' - Windows 10, , 2, Significant, 98.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', + ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', + ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', + ' - Windows 10, 0 %, , 2, Significant, 98.00 %', ' rev: spam', - ' - macOS 10.15, Improvement, 1.3, Not significant, 24.00 %', - ' - Linux 18.04, Regression, 1.2, Not significant, 44.00 %', - ' - Windows 10, , 1.2, Significant, 49.00 %', - ' - Windows 10, , 1.2, Significant, 99.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', + ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', + ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', + ' - Windows 10, 0 %, , 1.2, Significant, 99.00 %', 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: tictactoe', - ' - macOS 10.15, Improvement, 0.9, Not significant, 24.00 %', - ' - Linux 18.04, Regression, 0.8, Not significant, 44.00 %', - ' - Windows 10, , 0.8, Significant, 49.00 %', - ' - Windows 10, , 0.8, Significant, 99.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', + ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', + ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', + ' - Windows 10, 0 %, , 0.8, Significant, 99.00 %', ' rev: spam', - ' - macOS 10.15, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, Regression, -, Not significant, 45.00 %', - ' - Windows 10, , -, Significant, 50.00 %', - ' - Windows 10, , -, Significant, 100.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', + ' - Windows 10, 0 %, , -, Significant, 100.00 %', ]); expect(effectSizeButton).toMatchSnapshot(); // It should be persisted in the URL expectParameterToHaveValue('sort', 'effects|asc'); + + // Sort by MD(%) descending + const medianDiffButton = screen.getByRole('button', { + name: /MD\(%\).*sort/, + }); + await user.click(medianDiffButton); + expect(summarizeVisibleRows('mann-whitney-u')).toMatchSnapshot(); + expect(medianDiffButton).toMatchSnapshot(); + expectParameterToHaveValue('sort', 'median-diff|desc'); + + // Sort by MD(%) ascending + await user.click(medianDiffButton); + expect(summarizeVisibleRows('mann-whitney-u')).toMatchSnapshot(); + expect(medianDiffButton).toMatchSnapshot(); + expectParameterToHaveValue('sort', 'median-diff|asc'); }); it('should switch between Student-T and Mann-Whitney-U test versions', async () => { diff --git a/src/__tests__/CompareResults/RevisionRow.test.tsx b/src/__tests__/CompareResults/RevisionRow.test.tsx index c405cad37..3ac3df184 100644 --- a/src/__tests__/CompareResults/RevisionRow.test.tsx +++ b/src/__tests__/CompareResults/RevisionRow.test.tsx @@ -262,10 +262,10 @@ describe('Expanded row', () => { const newMean = roles[3]?.childNodes[0]; expect(newMean).toHaveTextContent('712.44'); - const directionOfChange = roles[4]?.childNodes[0]; + const directionOfChange = roles[5]?.childNodes[0]; expect(directionOfChange).toHaveTextContent('Improvement'); - const cliffsDelta = roles[5]?.childNodes[0]; + const cliffsDelta = roles[6]?.childNodes[0]; expect(cliffsDelta).toHaveTextContent('.1'); }); diff --git a/src/__tests__/CompareResults/SubtestsResultsView.test.tsx b/src/__tests__/CompareResults/SubtestsResultsView.test.tsx index 15cf744cd..7ac5e214e 100644 --- a/src/__tests__/CompareResults/SubtestsResultsView.test.tsx +++ b/src/__tests__/CompareResults/SubtestsResultsView.test.tsx @@ -59,7 +59,7 @@ function summarizeVisibleRows(testVersion?: TestVersion) { } const rowClasses = testVersion === 'mann-whitney-u' - ? ['.delta', '.significance', '.effects'] + ? ['.median-diff', '.delta', '.significance', '.effects'] : ['.delta', '.confidence']; const rowString = rowClasses .map((selector) => row.querySelector(selector)?.textContent.trim()) @@ -508,11 +508,11 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( await setupForSorting(); // Initial view (alphabetical ordered, even if "sort by subtests" isn't specified expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'browser.html: -0.04, Not significant, 15.00%', - 'dhtml.html: 0.02, Significant, 60.00%', - 'improvement.html: -0.05, Significant, 50.00%', - 'regression.html: 0.12, Significant, 25.00%', - 'tablemutation.html: 0.01, -, 45.00%', + 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', + 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', + 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', + 'regression.html: 1.135 %, 0.12, Significant, 25.00%', + 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', ]); // Sort by Delta @@ -523,11 +523,11 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( // Sort descending await user.click(deltaButton); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'regression.html: 0.12, Significant, 25.00%', - 'improvement.html: -0.05, Significant, 50.00%', - 'browser.html: -0.04, Not significant, 15.00%', - 'dhtml.html: 0.02, Significant, 60.00%', - 'tablemutation.html: 0.01, -, 45.00%', + 'regression.html: 1.135 %, 0.12, Significant, 25.00%', + 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', + 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', + 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', + 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', ]); // It should have the "descending" SVG. @@ -538,11 +538,11 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( // Sort ascending await user.click(deltaButton); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'tablemutation.html: 0.01, -, 45.00%', - 'dhtml.html: 0.02, Significant, 60.00%', - 'browser.html: -0.04, Not significant, 15.00%', - 'improvement.html: -0.05, Significant, 50.00%', - 'regression.html: 0.12, Significant, 25.00%', + 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', + 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', + 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', + 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', + 'regression.html: 1.135 %, 0.12, Significant, 25.00%', ]); // It should have the "ascending" SVG. expect(deltaButton).toMatchSnapshot(); @@ -555,11 +555,11 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( }); await user.click(significanceButton); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'browser.html: -0.04, Not significant, 15.00%', - 'tablemutation.html: 0.01, -, 45.00%', - 'dhtml.html: 0.02, Significant, 60.00%', - 'regression.html: 0.12, Significant, 25.00%', - 'improvement.html: -0.05, Significant, 50.00%', + 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', + 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', + 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', + 'regression.html: 1.135 %, 0.12, Significant, 25.00%', + 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', ]); // It should have the "no sort" SVG. expect(deltaButton).toMatchSnapshot(); @@ -571,25 +571,25 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( // Sort by Significance ascending await user.click(significanceButton); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'improvement.html: -0.05, Significant, 50.00%', - 'regression.html: 0.12, Significant, 25.00%', - 'dhtml.html: 0.02, Significant, 60.00%', - 'tablemutation.html: 0.01, -, 45.00%', - 'browser.html: -0.04, Not significant, 15.00%', + 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', + 'regression.html: 1.135 %, 0.12, Significant, 25.00%', + 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', + 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', + 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', ]); expectParameterToHaveValue('sort', 'significance|asc'); // Sort by Effect Size descending const effectButton = screen.getByRole('button', { - name: /Effect Size \(%\).*sort/, + name: /CLES\(%\).*sort/, }); await user.click(effectButton); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'dhtml.html: 0.02, Significant, 60.00%', - 'improvement.html: -0.05, Significant, 50.00%', - 'tablemutation.html: 0.01, -, 45.00%', - 'regression.html: 0.12, Significant, 25.00%', - 'browser.html: -0.04, Not significant, 15.00%', + 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', + 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', + 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', + 'regression.html: 1.135 %, 0.12, Significant, 25.00%', + 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', ]); // It should have the "descending" SVG. @@ -600,11 +600,11 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( // Sort by Effect Size ascending await user.click(effectButton); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'browser.html: -0.04, Not significant, 15.00%', - 'regression.html: 0.12, Significant, 25.00%', - 'tablemutation.html: 0.01, -, 45.00%', - 'improvement.html: -0.05, Significant, 50.00%', - 'dhtml.html: 0.02, Significant, 60.00%', + 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', + 'regression.html: 1.135 %, 0.12, Significant, 25.00%', + 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', + 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', + 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', ]); expectParameterToHaveValue('sort', 'effects|asc'); }); @@ -613,11 +613,11 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( await setupForSorting({ extraParameters: 'sort=delta|asc' }); await screen.findByText('dhtml.html'); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'tablemutation.html: 0.01, -, 45.00%', - 'dhtml.html: 0.02, Significant, 60.00%', - 'browser.html: -0.04, Not significant, 15.00%', - 'improvement.html: -0.05, Significant, 50.00%', - 'regression.html: 0.12, Significant, 25.00%', + 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', + 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', + 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', + 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', + 'regression.html: 1.135 %, 0.12, Significant, 25.00%', ]); // It should have the "ascending" SVG. expect(screen.getByRole('button', { name: /Delta/ })).toMatchSnapshot(); @@ -627,11 +627,11 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( await setupForSorting({ extraParameters: 'sort=delta' }); await screen.findByText('dhtml.html'); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'regression.html: 0.12, Significant, 25.00%', - 'improvement.html: -0.05, Significant, 50.00%', - 'browser.html: -0.04, Not significant, 15.00%', - 'dhtml.html: 0.02, Significant, 60.00%', - 'tablemutation.html: 0.01, -, 45.00%', + 'regression.html: 1.135 %, 0.12, Significant, 25.00%', + 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', + 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', + 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', + 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', ]); // It should have the "descending" SVG. expect(screen.getByRole('button', { name: /Delta/ })).toMatchSnapshot(); @@ -640,11 +640,11 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( it('initializes the sort from the URL at load time for a descending sort', async () => { await setupForSorting({ extraParameters: 'sort=delta|desc' }); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'regression.html: 0.12, Significant, 25.00%', - 'improvement.html: -0.05, Significant, 50.00%', - 'browser.html: -0.04, Not significant, 15.00%', - 'dhtml.html: 0.02, Significant, 60.00%', - 'tablemutation.html: 0.01, -, 45.00%', + 'regression.html: 1.135 %, 0.12, Significant, 25.00%', + 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', + 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', + 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', + 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', ]); // It should have the "descending" SVG. expect(screen.getByRole('button', { name: /Delta/ })).toMatchSnapshot(); diff --git a/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx b/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx index 8dbe08dec..6b9e4a4b7 100644 --- a/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx +++ b/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx @@ -189,13 +189,13 @@ describe('SubtestsRevisionRow Component', () => { ); const roles = await screen.findAllByRole('cell'); - const effects = roles[7]?.childNodes[0]; + const effects = roles[8]?.childNodes[0]; expect(effects).toHaveTextContent('60.00%'); - const significance = roles[6]?.childNodes[0]; + const significance = roles[7]?.childNodes[0]; expect(significance).toHaveTextContent('Significant'); - const cliffs_delta = roles[5]?.childNodes[1]; + const cliffs_delta = roles[6]?.childNodes[1]; expect(cliffs_delta).toHaveTextContent('0.02'); }); @@ -212,7 +212,7 @@ describe('SubtestsRevisionRow Component', () => { ); const roles = await screen.findAllByRole('cell'); - const status = roles[4]?.childNodes[0]; + const status = roles[5]?.childNodes[0]; expect(status).toHaveTextContent('Regression'); expect(status).toHaveClass('status-hint-regression'); }); @@ -230,7 +230,7 @@ describe('SubtestsRevisionRow Component', () => { ); const roles1 = await screen.findAllByRole('cell'); - const status1 = roles1[4]?.childNodes[0]; + const status1 = roles1[5]?.childNodes[0]; expect(status1).toHaveTextContent('Improvement'); expect(status1).toHaveClass('status-hint-improvement'); }); diff --git a/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap index 029e425c6..93738790d 100644 --- a/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap +++ b/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap @@ -311,7 +311,7 @@ exports[`Results View The table should match snapshot and other elements should
@@ -377,6 +377,39 @@ exports[`Results View The table should match snapshot and other elements should New
+
+ + + +
@@ -668,7 +701,7 @@ exports[`Results View The table should match snapshot and other elements should class="fw0pvlu" >
+
+ 0 % +
+
+ 0 % +
+
+ 0 % +
+
+ 0 % +
@@ -1270,6 +1270,39 @@ exports[`Results Table Should match snapshot 1`] = ` New
+
+ + + +
@@ -1561,7 +1594,7 @@ exports[`Results Table Should match snapshot 1`] = ` class="fw0pvlu" >
+
+ 0 % +
+
+ 0 % +
+
+ 0 % +
@@ -3953,6 +4010,39 @@ exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion New
+
+ + + +
@@ -4244,7 +4334,7 @@ exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion class="fw0pvlu" >
+
+ 1.849 % +
+
+ 1.078 % +
+
+ -2.401 % +
+`; + +exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion can sort params from the URL on mann-whitney-u test_version 8`] = ` +[ + "a11yr dhtml.html opt e10s fission stylo webrender", + " rev: spam", + " - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %", + " - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %", + " - Windows 10, 0 %, , -, Significant, 100.00 %", + " - Windows 10, -2.401 %, , -, Significant, 50.00 %", + " rev: tictactoe", + " - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %", + " - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %", + " - Windows 10, 0 %, , 0.8, Significant, 99.00 %", + " - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %", + "a11yr aria.html opt e10s fission stylo webrender", + " rev: spam", + " - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %", + " - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %", + " - Windows 10, 0 %, , 1.2, Significant, 99.00 %", + " - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %", + " rev: tictactoe", + " - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %", + " - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %", + " - Windows 10, 0 %, , 2, Significant, 98.00 %", + " - Windows 10, -2.401 %, , 2, Significant, 48.00 %", +] +`; + +exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion can sort params from the URL on mann-whitney-u test_version 9`] = ` + +`; + +exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion can sort params from the URL on mann-whitney-u test_version 10`] = ` +[ + "a11yr dhtml.html opt e10s fission stylo webrender", + " rev: spam", + " - Windows 10, -2.401 %, , -, Significant, 50.00 %", + " - Windows 10, 0 %, , -, Significant, 100.00 %", + " - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %", + " - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %", + " rev: tictactoe", + " - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %", + " - Windows 10, 0 %, , 0.8, Significant, 99.00 %", + " - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %", + " - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %", + "a11yr aria.html opt e10s fission stylo webrender", + " rev: spam", + " - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %", + " - Windows 10, 0 %, , 1.2, Significant, 99.00 %", + " - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %", + " - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %", + " rev: tictactoe", + " - Windows 10, -2.401 %, , 2, Significant, 48.00 %", + " - Windows 10, 0 %, , 2, Significant, 98.00 %", + " - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %", + " - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %", +] +`; + +exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion can sort params from the URL on mann-whitney-u test_version 11`] = ` +
+
+ 1.078 % +
+
+ 1.078 % +
+ +
@@ -1517,7 +1550,7 @@ exports[`Results View The table should match snapshot and other elements should class="fw0pvlu" >
+
+ 0 % +
+
+ 0 % +
+
+ 0 % +
+
+ 0 % +
+ +
@@ -1077,7 +1110,7 @@ exports[`SubtestsResultsView Component Tests should render the subtests results />
+
+ 0 % +
+
+ 0 % +
+
+ 0 % +
+
+ 0 % +
+
+ 0 % +
+ +
@@ -2903,7 +2999,7 @@ exports[`SubtestsViewCompareOverTime Component Tests in mann-whitney-u testVersi />
+
+ 0.963 % +
+
+ 1.135 % +
+
+ 0.963 % +
+
+ 1.135 % +
+
+ 0.98 % +
+ +
@@ -4381,7 +4540,7 @@ exports[`SubtestsViewCompareOverTime Component Tests in mann-whitney-u testVersi />
+
+ 0.963 % +
+
+ 1.135 % +
+
+ 0.963 % +
+
+ 1.135 % +
+
+ 0.98 % +
+ +
@@ -5859,7 +6081,7 @@ exports[`SubtestsViewCompareOverTime Component Tests renders over-time view when />
+
+ 0.963 % +
+
+ 1.135 % +
+
+ 0.963 % +
+
+ 1.135 % +
+
+ 0.98 % +
+ +
@@ -7337,7 +7622,7 @@ exports[`SubtestsViewCompareOverTime Component Tests should render the subtests />
+
+ 0 % +
+
+ 0 % +
+
+ 0 % +
+
+ 0 % +
+
+ 0 % +
+
+ {(() => { + const baseMedian = + (result as MannWhitneyResultsItem).base_standard_stats?.median ?? + 0; + const newMedian = + (result as MannWhitneyResultsItem).new_standard_stats?.median ?? + 0; + const pct = + baseMedian !== 0 + ? ((newMedian - baseMedian) / baseMedian) * 100 + : 0; + return `${formatNumber(pct)} %`; + })()} +
+
+ {`${formatNumber(medianDiffPct)} %`} +
Date: Thu, 2 Apr 2026 20:07:49 +0200 Subject: [PATCH 07/11] Median diff gated (#1019) * Use Shapiro-Wilks w/ IQR to cull outlier and ensure of some normality before computing difference of median * Add an icon when it is a good idea to look at the data * Add more tests * Add explicit isDistributionNormal assertions in tests * Reduce horizontal padding on cells --- .../CompareResults/ResultsTable.test.tsx | 64 +++--- .../CompareResults/RevisionRow.test.tsx | 70 ++++++- .../SubtestsRevisionRow.test.tsx | 60 ++++++ .../OverTimeResultsView.test.tsx.snap | 32 ++- .../__snapshots__/ResultsTable.test.tsx.snap | 108 ++++++---- .../__snapshots__/ResultsView.test.tsx.snap | 32 ++- .../SubtestsResultsView.test.tsx.snap | 150 +++++++++++--- .../SubtestsRevisionRow.test.tsx.snap | 12 +- src/__tests__/utils/fixtures.ts | 194 ++++++++++-------- src/common/testVersions/mannWhitney.tsx | 76 ++++++- src/components/CompareResults/RevisionRow.tsx | 2 +- src/utils/shapiroWilk.ts | 154 ++++++++++++++ 12 files changed, 747 insertions(+), 207 deletions(-) create mode 100644 src/utils/shapiroWilk.ts diff --git a/src/__tests__/CompareResults/ResultsTable.test.tsx b/src/__tests__/CompareResults/ResultsTable.test.tsx index 12c1b39f1..123bac3ec 100644 --- a/src/__tests__/CompareResults/ResultsTable.test.tsx +++ b/src/__tests__/CompareResults/ResultsTable.test.tsx @@ -746,7 +746,7 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio ' - inexistant, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -, , -, Significant, 100.00 %', ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); @@ -773,7 +773,7 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio ' - inexistant, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -, , -, Significant, 100.00 %', ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); @@ -807,7 +807,7 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio ' - inexistant, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -, , -, Significant, 100.00 %', ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); @@ -817,7 +817,7 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio 'a11yr dhtml.html spam opt e10s fission stylo webrender', ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -, , -, Significant, 100.00 %', ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ @@ -828,7 +828,7 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -, , -, Significant, 100.00 %', ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ @@ -877,7 +877,7 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio 'a11yr dhtml.html spam opt e10s fission stylo webrender', ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -, , -, Significant, 100.00 %', ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); @@ -907,7 +907,7 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -, , -, Significant, 100.00 %', ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ @@ -919,7 +919,7 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio 'a11yr dhtml.html spam opt e10s fission stylo webrender', ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -, , -, Significant, 100.00 %', ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); @@ -991,23 +991,23 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio ' rev: spam', ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', - ' - Windows 10, 0 %, , 1.2, Significant, 99.00 %', + ' - Windows 10, -, , 1.2, Significant, 99.00 %', ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', ' rev: tictactoe', ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', - ' - Windows 10, 0 %, , 2, Significant, 98.00 %', + ' - Windows 10, -, , 2, Significant, 98.00 %', ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: spam', ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -, , -, Significant, 100.00 %', ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ' rev: tictactoe', ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', - ' - Windows 10, 0 %, , 0.8, Significant, 99.00 %', + ' - Windows 10, -, , 0.8, Significant, 99.00 %', ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', ]); // It should have the "descending" SVG. @@ -1023,23 +1023,23 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', - ' - Windows 10, 0 %, , 2, Significant, 98.00 %', + ' - Windows 10, -, , 2, Significant, 98.00 %', ' rev: spam', ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', - ' - Windows 10, 0 %, , 1.2, Significant, 99.00 %', + ' - Windows 10, -, , 1.2, Significant, 99.00 %', 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: tictactoe', ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', - ' - Windows 10, 0 %, , 0.8, Significant, 99.00 %', + ' - Windows 10, -, , 0.8, Significant, 99.00 %', ' rev: spam', ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', - ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -, , -, Significant, 100.00 %', ]); // It should have the "ascending" SVG. expect(deltaButton).toMatchSnapshot(); @@ -1056,23 +1056,23 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio ' rev: tictactoe', ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', - ' - Windows 10, 0 %, , 2, Significant, 98.00 %', + ' - Windows 10, -, , 2, Significant, 98.00 %', ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', ' rev: spam', ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', - ' - Windows 10, 0 %, , 1.2, Significant, 99.00 %', + ' - Windows 10, -, , 1.2, Significant, 99.00 %', ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: tictactoe', ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', - ' - Windows 10, 0 %, , 0.8, Significant, 99.00 %', + ' - Windows 10, -, , 0.8, Significant, 99.00 %', ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', ' rev: spam', ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -, , -, Significant, 100.00 %', ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ]); // It should have the "descending" SVG. @@ -1086,23 +1086,23 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: spam', ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', - ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -, , -, Significant, 100.00 %', ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', ' rev: tictactoe', ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', - ' - Windows 10, 0 %, , 0.8, Significant, 99.00 %', + ' - Windows 10, -, , 0.8, Significant, 99.00 %', ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', 'a11yr aria.html opt e10s fission stylo webrender', ' rev: spam', ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', - ' - Windows 10, 0 %, , 1.2, Significant, 99.00 %', + ' - Windows 10, -, , 1.2, Significant, 99.00 %', ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', ' rev: tictactoe', ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', - ' - Windows 10, 0 %, , 2, Significant, 98.00 %', + ' - Windows 10, -, , 2, Significant, 98.00 %', ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', ]); @@ -1119,23 +1119,23 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: spam', - ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -, , -, Significant, 100.00 %', ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ' rev: tictactoe', - ' - Windows 10, 0 %, , 0.8, Significant, 99.00 %', + ' - Windows 10, -, , 0.8, Significant, 99.00 %', ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', 'a11yr aria.html opt e10s fission stylo webrender', ' rev: spam', - ' - Windows 10, 0 %, , 1.2, Significant, 99.00 %', + ' - Windows 10, -, , 1.2, Significant, 99.00 %', ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', ' rev: tictactoe', - ' - Windows 10, 0 %, , 2, Significant, 98.00 %', + ' - Windows 10, -, , 2, Significant, 98.00 %', ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', @@ -1153,23 +1153,23 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', - ' - Windows 10, 0 %, , 2, Significant, 98.00 %', + ' - Windows 10, -, , 2, Significant, 98.00 %', ' rev: spam', ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', - ' - Windows 10, 0 %, , 1.2, Significant, 99.00 %', + ' - Windows 10, -, , 1.2, Significant, 99.00 %', 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: tictactoe', ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', - ' - Windows 10, 0 %, , 0.8, Significant, 99.00 %', + ' - Windows 10, -, , 0.8, Significant, 99.00 %', ' rev: spam', ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', - ' - Windows 10, 0 %, , -, Significant, 100.00 %', + ' - Windows 10, -, , -, Significant, 100.00 %', ]); expect(effectSizeButton).toMatchSnapshot(); // It should be persisted in the URL diff --git a/src/__tests__/CompareResults/RevisionRow.test.tsx b/src/__tests__/CompareResults/RevisionRow.test.tsx index 3ac3df184..718881753 100644 --- a/src/__tests__/CompareResults/RevisionRow.test.tsx +++ b/src/__tests__/CompareResults/RevisionRow.test.tsx @@ -4,9 +4,10 @@ import fetchMock from '@fetch-mock/jest'; import userEvent from '@testing-library/user-event'; import { compareView } from '../../common/constants'; +import { isDistributionNormal } from '../../common/testVersions/mannWhitney'; import { loader } from '../../components/CompareResults/loader'; import RevisionRow from '../../components/CompareResults/RevisionRow'; -import { CompareResultsItem } from '../../types/state'; +import { CompareResultsItem, MannWhitneyResultsItem } from '../../types/state'; import { Platform } from '../../types/types'; import getTestData from '../utils/fixtures'; import { screen, renderWithRouter } from '../utils/test-utils'; @@ -337,4 +338,71 @@ describe('Expanded row', () => { expect(writeTextMock).toHaveBeenCalledWith(baseRuns); }); + + describe('median diff column normality gating', () => { + const normalRuns = [5.1, 5.2, 4.9, 5.0, 5.05]; + const tooFewRuns = [5.0]; + + function makeResult( + baseRuns: number[], + newRuns: number[], + ): MannWhitneyResultsItem { + const { testCompareMannWhitneyData } = getTestData(); + return { + ...testCompareMannWhitneyData[0], + base_runs: baseRuns, + new_runs: newRuns, + }; + } + + it('shows dash when neither distribution is normal', async () => { + const result = makeResult(tooFewRuns, tooFewRuns); + expect(isDistributionNormal(result)).toBe(false); + renderWithRoute( + , + ); + const roles = await screen.findAllByRole('cell'); + expect(roles[4]).toHaveTextContent('-'); + }); + + it('shows value with warning icon when only one distribution is normal', async () => { + const result = makeResult(normalRuns, tooFewRuns); + expect(isDistributionNormal(result)).toBe(true); + renderWithRoute( + , + ); + const roles = await screen.findAllByRole('cell'); + expect(roles[4]).not.toHaveTextContent('-'); + expect(roles[4].querySelector('svg[role="img"]')).toBeTruthy(); + }); + + it('shows value without warning icon when both distributions are normal', async () => { + const result = makeResult(normalRuns, normalRuns); + expect(isDistributionNormal(result)).toBe(true); + renderWithRoute( + , + ); + const roles = await screen.findAllByRole('cell'); + expect(roles[4]).not.toHaveTextContent('-'); + expect(roles[4].querySelector('svg[role="img"]')).toBeFalsy(); + }); + }); }); diff --git a/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx b/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx index 6b9e4a4b7..26c443e7c 100644 --- a/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx +++ b/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx @@ -5,6 +5,7 @@ import userEvent from '@testing-library/user-event'; import { loader } from '../../components/CompareResults/loader'; import SubtestsRevisionRow from '../../components/CompareResults/SubtestsResults/SubtestsRevisionRow'; +import { MannWhitneyResultsItem } from '../../types/state'; import getTestData from '../utils/fixtures'; import { screen, renderWithRouter } from '../utils/test-utils'; @@ -234,4 +235,63 @@ describe('SubtestsRevisionRow Component', () => { expect(status1).toHaveTextContent('Improvement'); expect(status1).toHaveClass('status-hint-improvement'); }); + + describe('median diff column normality gating', () => { + const normalRuns = [5.1, 5.2, 4.9, 5.0, 5.05]; + const tooFewRuns = [5.0]; + const mockGridTemplateColumns = '1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr'; + + function makeResult( + baseRuns: number[], + newRuns: number[], + ): MannWhitneyResultsItem { + const { subtestsMannWhitneyResult } = getTestData(); + return { + ...subtestsMannWhitneyResult[0], + base_runs: baseRuns, + new_runs: newRuns, + }; + } + + it('shows dash when neither distribution is normal', async () => { + renderWithRoute( + , + ); + const roles = await screen.findAllByRole('cell'); + expect(roles[4]).toHaveTextContent('-'); + }); + + it('shows value with warning icon when only one distribution is normal', async () => { + renderWithRoute( + , + ); + const roles = await screen.findAllByRole('cell'); + expect(roles[4]).not.toHaveTextContent('-'); + expect(roles[4].querySelector('svg[role="img"]')).toBeTruthy(); + }); + + it('shows value without warning icon when both distributions are normal', async () => { + renderWithRoute( + , + ); + const roles = await screen.findAllByRole('cell'); + expect(roles[4]).not.toHaveTextContent('-'); + expect(roles[4].querySelector('svg[role="img"]')).toBeFalsy(); + }); + }); }); diff --git a/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap index 93738790d..8f01d8e52 100644 --- a/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap +++ b/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap @@ -701,7 +701,7 @@ exports[`Results View The table should match snapshot and other elements should class="fw0pvlu" >
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
- 1.849 % + + 1.849 % +
- 1.078 % + + 1.078 % +
- -2.401 % + + -2.401 % +
- 0 % + -
- 1.078 % + + 1.078 % +
- 1.078 % + + 1.078 % +
B: - 1 + 3 @@ -6488,7 +6524,7 @@ exports[`Results Table should render different blocks when rendering several rev N: - 1 + 3
@@ -6623,7 +6659,7 @@ exports[`Results Table should render different blocks when rendering several rev
B: - 1 + 3 @@ -6734,7 +6770,7 @@ exports[`Results Table should render different blocks when rendering several rev N: - 1 + 3
diff --git a/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap index d39796095..57d72e418 100644 --- a/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap +++ b/src/__tests__/CompareResults/__snapshots__/ResultsView.test.tsx.snap @@ -1550,7 +1550,7 @@ exports[`Results View The table should match snapshot and other elements should class="fw0pvlu" >
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0.963 % + + 0.963 % +
- 1.135 % + + 1.135 % +
- 0.963 % + + 0.963 % +
- 1.135 % + + 1.135 % +
- 0.98 % + + 0.98 % +
- 0.963 % + + 0.963 % +
- 1.135 % + + 1.135 % +
- 0.963 % + + 0.963 % +
- 1.135 % + + 1.135 % +
- 0.98 % + + 0.98 % +
- 0.963 % + + 0.963 % +
- 1.135 % + + 1.135 % +
- 0.963 % + + 0.963 % +
- 1.135 % + + 1.135 % +
- 0.98 % + + 0.98 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
- 0 % + + 0 % +
B: - 2 + 3 @@ -267,7 +267,7 @@ exports[`SubtestsRevisionRow Component renders doesnt render browser name when b N: - 2 + 3
@@ -406,14 +406,14 @@ exports[`SubtestsRevisionRow Component renders the component with correct data 1
B: - 2 + 3 @@ -421,7 +421,7 @@ exports[`SubtestsRevisionRow Component renders the component with correct data 1 N: - 2 + 3
diff --git a/src/__tests__/utils/fixtures.ts b/src/__tests__/utils/fixtures.ts index 8ed43150c..07a083d82 100644 --- a/src/__tests__/utils/fixtures.ts +++ b/src/__tests__/utils/fixtures.ts @@ -164,10 +164,10 @@ const getTestData = () => { is_complete: true, base_measurement_unit: 'ms', new_measurement_unit: 'ms', - base_retriggerable_job_ids: [381594973], - new_retriggerable_job_ids: [381452501], - base_runs: [704.84], - new_runs: [712.44], + base_retriggerable_job_ids: [381594973.0, 381213378.03, 381976567.97], + new_retriggerable_job_ids: [381452501.0, 381071048.5, 381833953.5], + base_runs: [704.84, 704.14, 705.54], + new_runs: [712.44, 711.73, 713.15], base_runs_replicates: [], new_runs_replicates: [], base_avg_value: 704.84, @@ -216,10 +216,10 @@ const getTestData = () => { is_complete: true, base_measurement_unit: 'ms', new_measurement_unit: 'ms', - base_retriggerable_job_ids: [381587080], - new_retriggerable_job_ids: [381451522], - base_runs: [776.97], - new_runs: [791.34], + base_retriggerable_job_ids: [381587080.0, 381205492.92, 381968667.08], + new_retriggerable_job_ids: [381451522.0, 381070070.48, 381832973.52], + base_runs: [776.97, 776.19, 777.75], + new_runs: [791.34, 790.55, 792.13], base_runs_replicates: [], new_runs_replicates: [], base_avg_value: 776.97, @@ -268,10 +268,10 @@ const getTestData = () => { is_complete: true, base_measurement_unit: 'ms', new_measurement_unit: 'ms', - base_retriggerable_job_ids: [381588467], - new_retriggerable_job_ids: [381453172], - base_runs: [643.54], - new_runs: [628.09], + base_retriggerable_job_ids: [381588467.0, 381206878.53, 381970055.47], + new_retriggerable_job_ids: [381453172.0, 381071718.83, 381834625.17], + base_runs: [643.54, 642.9, 644.18], + new_runs: [628.09, 627.46, 628.72], base_runs_replicates: [], new_runs_replicates: [], base_avg_value: 643.54, @@ -320,10 +320,10 @@ const getTestData = () => { is_complete: true, base_measurement_unit: 'ms', new_measurement_unit: 'ms', - base_retriggerable_job_ids: [381588467], - new_retriggerable_job_ids: [381453172], - base_runs: [643.54], - new_runs: [628.09], + base_retriggerable_job_ids: [381588467.0, 381206878.53, 381970055.47], + new_retriggerable_job_ids: [381453172.0, 381071718.83, 381834625.17], + base_runs: [643.54, 642.9, 644.18], + new_runs: [628.09, 627.46, 628.72], base_runs_replicates: [], new_runs_replicates: [], base_avg_value: 643.54, @@ -375,10 +375,10 @@ const getTestData = () => { is_complete: true, base_measurement_unit: 'ms', new_measurement_unit: 'ms', - base_retriggerable_job_ids: [381594973], - new_retriggerable_job_ids: [381452501], - base_runs: [704.84], - new_runs: [712.44], + base_retriggerable_job_ids: [381594973.0, 381213378.03, 381976567.97], + new_retriggerable_job_ids: [381452501.0, 381071048.5, 381833953.5], + base_runs: [704.84, 704.14, 705.54], + new_runs: [712.44, 711.73, 713.15], base_runs_replicates: [], new_runs_replicates: [], base_standard_stats: { @@ -420,8 +420,18 @@ const getTestData = () => { new_signature_id: 12345, has_subtests: false, ks_test: null, - shapiro_wilk_test_base: null, - shapiro_wilk_test_new: null, + shapiro_wilk_test_base: { + test_name: 'Shapiro-Wilk', + stat: 0.95, + pvalue: 0.8, + interpretation: 'normal', + }, + shapiro_wilk_test_new: { + test_name: 'Shapiro-Wilk', + stat: 0.96, + pvalue: 0.85, + interpretation: 'normal', + }, mann_whitney_test: { test_name: 'Mann-Whitney U', stat: null, @@ -486,10 +496,10 @@ const getTestData = () => { is_complete: true, base_measurement_unit: 'ms', new_measurement_unit: 'ms', - base_retriggerable_job_ids: [381587080], - new_retriggerable_job_ids: [381451522], - base_runs: [776.97], - new_runs: [791.34], + base_retriggerable_job_ids: [381587080.0, 381205492.92, 381968667.08], + new_retriggerable_job_ids: [381451522.0, 381070070.48, 381832973.52], + base_runs: [776.97, 776.19, 777.75], + new_runs: [791.34, 790.55, 792.13], base_runs_replicates: [], new_runs_replicates: [], base_standard_stats: { @@ -605,10 +615,10 @@ const getTestData = () => { is_complete: true, base_measurement_unit: 'ms', new_measurement_unit: 'ms', - base_retriggerable_job_ids: [381588467], - new_retriggerable_job_ids: [381453172], - base_runs: [643.54], - new_runs: [628.09], + base_retriggerable_job_ids: [381588467.0, 381206878.53, 381970055.47], + new_retriggerable_job_ids: [381453172.0, 381071718.83, 381834625.17], + base_runs: [643.54, 642.9, 644.18], + new_runs: [628.09, 627.46, 628.72], base_runs_replicates: [], new_runs_replicates: [], base_standard_stats: { @@ -717,8 +727,8 @@ const getTestData = () => { is_complete: true, base_measurement_unit: 'ms', new_measurement_unit: 'ms', - base_retriggerable_job_ids: [381588467], - new_retriggerable_job_ids: [381453172], + base_retriggerable_job_ids: [381588467.0, 381206878.53, 381970055.47], + new_retriggerable_job_ids: [381453172.0, 381071718.83, 381834625.17], base_runs: [], new_runs: [], base_runs_replicates: [], @@ -887,8 +897,8 @@ const getTestData = () => { new_retriggerable_job_ids: [ 411832360, 412140455, 412140456, 412140457, 412140458, ], - base_runs: [587.15, 587.15], - new_runs: [605.16, 587.15], + base_runs: [587.15, 587.15, 587.15], + new_runs: [605.16, 587.15, 596.15], base_runs_replicates: [587.15, 593.04, 600.7, 602.04], new_runs_replicates: [605.16, 605.31, 605.61, 605.81, 607.27], base_avg_value: 595.73, @@ -939,8 +949,8 @@ const getTestData = () => { new_retriggerable_job_ids: [ 411832360, 412140455, 412140456, 412140457, 412140458, ], - base_runs: [587.15], - new_runs: [605.16], + base_runs: [587.15, 586.56, 587.74], + new_runs: [605.16, 604.55, 605.77], base_runs_replicates: [587.15, 593.04, 600.7, 602.04], new_runs_replicates: [605.16, 605.31, 605.61, 605.81, 607.27], base_avg_value: 595.73, @@ -991,8 +1001,8 @@ const getTestData = () => { new_retriggerable_job_ids: [ 411832360, 412140455, 412140456, 412140457, 412140458, ], - base_runs: [587.15], - new_runs: [605.16], + base_runs: [587.15, 586.56, 587.74], + new_runs: [605.16, 604.55, 605.77], base_runs_replicates: [ 587.15, 593.04, 600.7, 602.04, 526.44, 537.37, 537.69, 540.94, 549.67, 551.64, 554.2, 554.87, 555.2, 555.34, 562.14, 566.61, 589.66, 597.78, @@ -1056,10 +1066,10 @@ const getTestData = () => { is_complete: true, base_measurement_unit: 'ms', new_measurement_unit: 'ms', - base_retriggerable_job_ids: [469521067, 469843701], - new_retriggerable_job_ids: [469707477, 469843700], - base_runs: [964.52, 978.24], - new_runs: [977.16, 987.66], + base_retriggerable_job_ids: [469521067.0, 469843701.0, 469682384.0], + new_retriggerable_job_ids: [469707477.0, 469843700.0, 469775588.5], + base_runs: [964.52, 978.24, 971.38], + new_runs: [977.16, 987.66, 982.41], base_avg_value: 971.38, new_avg_value: 982.41, base_median_value: 971.38, @@ -1108,10 +1118,10 @@ const getTestData = () => { is_complete: true, base_measurement_unit: 'ms', new_measurement_unit: 'ms', - base_retriggerable_job_ids: [469521067, 469843701], - new_retriggerable_job_ids: [469707477, 469843700], - base_runs: [312.44, 320.26], - new_runs: [315.78, 323.12], + base_retriggerable_job_ids: [469521067.0, 469843701.0, 469682384.0], + new_retriggerable_job_ids: [469707477.0, 469843700.0, 469775588.5], + base_runs: [312.44, 320.26, 316.35], + new_runs: [315.78, 323.12, 319.45], base_avg_value: 316.35, new_avg_value: 319.45, base_median_value: 316.35, @@ -1160,10 +1170,10 @@ const getTestData = () => { is_complete: true, base_measurement_unit: 'ms', new_measurement_unit: 'ms', - base_retriggerable_job_ids: [469521067, 469843701], - new_retriggerable_job_ids: [469707477, 469843700], - base_runs: [964.52, 978.24], - new_runs: [977.16, 987.66], + base_retriggerable_job_ids: [469521067.0, 469843701.0, 469682384.0], + new_retriggerable_job_ids: [469707477.0, 469843700.0, 469775588.5], + base_runs: [964.52, 978.24, 971.38], + new_runs: [977.16, 987.66, 982.41], base_avg_value: 971.38, new_avg_value: 982.41, base_median_value: 971.38, @@ -1214,8 +1224,8 @@ const getTestData = () => { new_measurement_unit: 'ms', base_retriggerable_job_ids: [469521067, 469843701, 469843701], new_retriggerable_job_ids: [469707477, 469843700, 469843700], - base_runs: [964.52, 978.24, 978.24], - new_runs: [977.16, 987.66, 987.66], + base_runs: [964.52, 978.24, 971.38], + new_runs: [977.16, 987.66, 982.41], base_avg_value: 973.66, new_avg_value: 984.16, base_median_value: 978.24, @@ -1266,8 +1276,8 @@ const getTestData = () => { new_measurement_unit: 'ms', base_retriggerable_job_ids: [469521067, 469843701, 469843701], new_retriggerable_job_ids: [469707477, 469843700, 469843700], - base_runs: [964.52, 978.24, 978.24], - new_runs: [977.16, 987.66, 987.66], + base_runs: [964.52, 978.24, 971.38], + new_runs: [977.16, 987.66, 982.41], base_avg_value: 973.66, new_avg_value: 984.16, base_median_value: 978.24, @@ -1318,10 +1328,10 @@ const getTestData = () => { is_complete: true, base_measurement_unit: null, new_measurement_unit: null, - base_retriggerable_job_ids: [514158485], - new_retriggerable_job_ids: [514158485], - base_runs: [465888.0], - new_runs: [465888.0], + base_retriggerable_job_ids: [514158485.0, 513644326.51, 514672643.48], + new_retriggerable_job_ids: [514158485.0, 513644326.51, 514672643.48], + base_runs: [465888.0, 465422.11, 466353.89], + new_runs: [465888.0, 465422.11, 466353.89], base_runs_replicates: [], new_runs_replicates: [], test: '', @@ -1409,8 +1419,8 @@ const getTestData = () => { bandwidth: 'Silverman', base_mode_count: 1, new_mode_count: 1, - base_locations: [465888.0], - new_locations: [465888.0], + base_locations: [465888.0, 465422.11, 466353.89], + new_locations: [465888.0, 465422.11, 466353.89], base_prominence: 0.08, new_prominence: 0.08, warnings: [], @@ -1434,13 +1444,13 @@ const getTestData = () => { kde_new: { median: 465888.0, sample_count: 1, - kde_x: [465888.0], + kde_x: [465888.0, 465422.11, 466353.89], kde_y: [], }, kde_base: { median: 465888.0, sample_count: 1, - kde_x: [465888.0], + kde_x: [465888.0, 465422.11, 466353.89], kde_y: [], }, kde_warnings: [ @@ -1467,10 +1477,10 @@ const getTestData = () => { is_complete: true, base_measurement_unit: 'ms', new_measurement_unit: 'ms', - base_retriggerable_job_ids: [469521067, 469843701], - new_retriggerable_job_ids: [469707477, 469843700], - base_runs: [964.52, 978.24], - new_runs: [977.16, 987.66], + base_retriggerable_job_ids: [469521067.0, 469843701.0, 469682384.0], + new_retriggerable_job_ids: [469707477.0, 469843700.0, 469775588.5], + base_runs: [964.52, 978.24, 971.38], + new_runs: [977.16, 987.66, 982.41], base_avg_value: 971.38, new_avg_value: 982.41, base_median_value: 971.38, @@ -1520,8 +1530,18 @@ const getTestData = () => { max: 987.66, }, ks_test: null, - shapiro_wilk_test_base: null, - shapiro_wilk_test_new: null, + shapiro_wilk_test_base: { + test_name: 'Shapiro-Wilk', + stat: 0.95, + pvalue: 0.85, + interpretation: 'normal', + }, + shapiro_wilk_test_new: { + test_name: 'Shapiro-Wilk', + stat: 0.96, + pvalue: 0.9, + interpretation: 'normal', + }, shapiro_wilk_warnings: [], mann_whitney_test: { test_name: 'Mann-Whitney U', @@ -1576,10 +1596,10 @@ const getTestData = () => { is_complete: true, base_measurement_unit: 'ms', new_measurement_unit: 'ms', - base_retriggerable_job_ids: [469521067, 469843701], - new_retriggerable_job_ids: [469707477, 469843700], - base_runs: [312.44, 320.26], - new_runs: [315.78, 323.12], + base_retriggerable_job_ids: [469521067.0, 469843701.0, 469682384.0], + new_retriggerable_job_ids: [469707477.0, 469843700.0, 469775588.5], + base_runs: [312.44, 320.26, 316.35], + new_runs: [315.78, 323.12, 319.45], base_avg_value: 316.35, new_avg_value: 319.45, base_median_value: 316.35, @@ -1628,8 +1648,18 @@ const getTestData = () => { max: 323.12, }, ks_test: null, - shapiro_wilk_test_base: null, - shapiro_wilk_test_new: null, + shapiro_wilk_test_base: { + test_name: 'Shapiro-Wilk', + stat: 0.95, + pvalue: 0.82, + interpretation: 'normal', + }, + shapiro_wilk_test_new: { + test_name: 'Shapiro-Wilk', + stat: 0.97, + pvalue: 0.88, + interpretation: 'normal', + }, shapiro_wilk_warnings: [], mann_whitney_test: { test_name: 'Mann-Whitney U', @@ -1683,10 +1713,10 @@ const getTestData = () => { is_complete: true, base_measurement_unit: 'ms', new_measurement_unit: 'ms', - base_retriggerable_job_ids: [469521067, 469843701], - new_retriggerable_job_ids: [469707477, 469843700], - base_runs: [964.52, 978.24], - new_runs: [977.16, 987.66], + base_retriggerable_job_ids: [469521067.0, 469843701.0, 469682384.0], + new_retriggerable_job_ids: [469707477.0, 469843700.0, 469775588.5], + base_runs: [964.52, 978.24, 971.38], + new_runs: [977.16, 987.66, 982.41], base_avg_value: 971.38, new_avg_value: 982.41, base_median_value: 971.38, @@ -1793,8 +1823,8 @@ const getTestData = () => { new_measurement_unit: 'ms', base_retriggerable_job_ids: [469521067, 469843701, 469843701], new_retriggerable_job_ids: [469707477, 469843700, 469843700], - base_runs: [964.52, 978.24, 978.24], - new_runs: [977.16, 987.66, 987.66], + base_runs: [964.52, 978.24, 971.38], + new_runs: [977.16, 987.66, 982.41], base_avg_value: 973.66, new_avg_value: 984.16, base_median_value: 978.24, @@ -1901,8 +1931,8 @@ const getTestData = () => { new_measurement_unit: 'ms', base_retriggerable_job_ids: [469521067, 469843701, 469843701], new_retriggerable_job_ids: [469707477, 469843700, 469843700], - base_runs: [964.52, 978.24, 978.24], - new_runs: [977.16, 987.66, 987.66], + base_runs: [964.52, 978.24, 971.38], + new_runs: [977.16, 987.66, 982.41], base_avg_value: 973.66, new_avg_value: 984.16, base_median_value: 978.24, diff --git a/src/common/testVersions/mannWhitney.tsx b/src/common/testVersions/mannWhitney.tsx index abe838523..ee6dbca24 100644 --- a/src/common/testVersions/mannWhitney.tsx +++ b/src/common/testVersions/mannWhitney.tsx @@ -1,5 +1,6 @@ import ThumbDownIcon from '@mui/icons-material/ThumbDown'; import ThumbUpIcon from '@mui/icons-material/ThumbUp'; +import WarningIcon from '@mui/icons-material/Warning'; import Box from '@mui/material/Box'; import { MannWhitneyCompareMetrics } from '../../components/CompareResults/MannWhitneyCompareMetrics'; @@ -19,6 +20,7 @@ import { determineSign, determineStatusHintClass, } from '../../utils/revisionRowHelpers'; +import { shapiroWilkTest } from '../../utils/shapiroWilk'; import { defaultSortFunction } from '../../utils/sortFunctions'; import { tooltipBaseMean, @@ -76,6 +78,28 @@ const PLATFORM_FILTER_VALUES = [ { label: 'iOS', key: 'ios' }, ]; +const SW_NORMALITY_THRESHOLD = 0.2; + +type NormalityResult = 'both' | 'one' | 'neither'; + +export function checkDistributionNormality( + result: MannWhitneyResultsItem, +): NormalityResult { + const baseResult = shapiroWilkTest(result.base_runs); + const newResult = shapiroWilkTest(result.new_runs); + const baseNormal = + baseResult !== null && baseResult.pvalue > SW_NORMALITY_THRESHOLD; + const newNormal = + newResult !== null && newResult.pvalue > SW_NORMALITY_THRESHOLD; + if (baseNormal && newNormal) return 'both'; + if (baseNormal || newNormal) return 'one'; + return 'neither'; +} + +export function isDistributionNormal(result: MannWhitneyResultsItem): boolean { + return checkDistributionNormality(result) !== 'neither'; +} + export const mannWhitneyStrategy = { getColumns(isSubtestTable: boolean): TableConfig { const platformConfig = isSubtestTable @@ -275,17 +299,32 @@ export const mannWhitneyStrategy = {
{(() => { - const baseMedian = - (result as MannWhitneyResultsItem).base_standard_stats?.median ?? - 0; - const newMedian = - (result as MannWhitneyResultsItem).new_standard_stats?.median ?? - 0; + const mwResult = result as MannWhitneyResultsItem; + const normality = checkDistributionNormality(mwResult); + if (normality === 'neither') return '-'; + const baseMedian = mwResult.base_standard_stats?.median ?? 0; + const newMedian = mwResult.new_standard_stats?.median ?? 0; const pct = baseMedian !== 0 ? ((newMedian - baseMedian) / baseMedian) * 100 : 0; - return `${formatNumber(pct)} %`; + return ( + + {`${formatNumber(pct)} %`} + {normality === 'one' && ( + + )} + + ); })()}
@@ -387,11 +426,32 @@ export const mannWhitneyStrategy = { const newMedian = new_standard_stats?.median ?? 0; const medianDiffPct = baseMedian !== 0 ? ((newMedian - baseMedian) / baseMedian) * 100 : 0; + const normality = checkDistributionNormality( + result as MannWhitneyResultsItem, + ); return ( <>
- {`${formatNumber(medianDiffPct)} %`} + {normality === 'neither' ? ( + '-' + ) : ( + + {`${formatNumber(medianDiffPct)} %`} + {normality === 'one' && ( + + )} + + )}
= 0 ? p : 1 - p; +} + +function poly5(coeffs: number[], u: number): number { + return ( + ((((coeffs[0] * u + coeffs[1]) * u + coeffs[2]) * u + coeffs[3]) * u + + coeffs[4]) * + u + + coeffs[5] + ); +} + +function iqrFilter(data: number[]): number[] { + if (data.length < 4) return data; + const s = [...data].sort((a, b) => a - b); + const n = s.length; + const q1 = s[Math.floor(n * 0.25)]; + const q3 = s[Math.floor(n * 0.75)]; + const iqr = q3 - q1; + return s.filter((x) => x >= q1 - 1.5 * iqr && x <= q3 + 1.5 * iqr); +} + +export function shapiroWilkTest( + data: number[], +): { w: number; pvalue: number } | null { + const x = iqrFilter(data).sort((a, b) => a - b); + const n = x.length; + if (n < 3 || n > 5000) return null; + + // Expected normal order statistics + const m = Array.from({ length: n }, (_, i) => + normalQuantile((i + 1 - 0.375) / (n + 0.25)), + ); + const md = m.reduce((s, v) => s + v * v, 0); + const sqrtMd = Math.sqrt(md); + + // Royston (1992) polynomial corrections for the first two a coefficients + // Coefficients from AS R94, Table 1 + const c1 = [-2.706056, 4.434685, -2.07119, -0.147981, 0.221157, 0]; + const c2 = [-3.582633, 5.682633, -1.752461, -0.293762, 0.042981, 0]; + const u = 1 / Math.sqrt(n); + c1[5] = m[n - 1] / sqrtMd; + c2[5] = m[n - 2] / sqrtMd; + const an = poly5(c1, u); // corrected a_n (largest coeff) + const ann = poly5(c2, u); // corrected a_{n-1} + + // phi normalizes the remaining middle coefficients + const half = Math.floor(n / 2); + let phi: number; + if (n > 5) { + phi = + (md - 2 * m[n - 1] ** 2 - 2 * m[n - 2] ** 2) / + (1 - 2 * an ** 2 - 2 * ann ** 2); + } else { + phi = (md - 2 * m[n - 1] ** 2) / (1 - 2 * an ** 2); + } + const sqrtPhi = Math.sqrt(phi); + + // Build half-length a array: a[j] is the coefficient for (x[n-1-j] - x[j]) + const a: number[] = Array.from({ length: half }); + a[0] = an; + if (n > 5 && half > 1) a[1] = ann; + const startJ = n > 5 ? 2 : 1; + for (let j = startJ; j < half; j++) { + a[j] = m[n - 1 - j] / sqrtPhi; + } + + // W statistic + const xbar = x.reduce((s, v) => s + v, 0) / n; + const ss = x.reduce((s, v) => s + (v - xbar) ** 2, 0); + if (ss === 0) return null; + + let num = 0; + for (let j = 0; j < half; j++) num += a[j] * (x[n - 1 - j] - x[j]); + const w = Math.min(num ** 2 / ss, 1); + + // p-value via Royston (1995) log-normal approximation + const logn = Math.log(n); + let g: number, mu: number, sigma: number; + if (n < 12) { + const gamma = 0.459 * n - 2.273; + g = -Math.log(gamma - Math.log(1 - w)); + mu = -0.0006714 * n ** 3 + 0.025054 * n ** 2 - 0.39978 * n + 0.544; + sigma = Math.exp( + -0.0020322 * n ** 3 + 0.062767 * n ** 2 - 0.77857 * n + 1.3822, + ); + } else { + g = Math.log(1 - w); + mu = 0.0038915 * logn ** 3 - 0.083751 * logn ** 2 - 0.31082 * logn - 1.5861; + sigma = Math.exp(0.0030302 * logn ** 2 - 0.082676 * logn - 0.4803); + } + + const pvalue = 1 - normalCDF((g - mu) / sigma); + return { w, pvalue }; +} From bd39067bf237b540d66a23543999b60bde02e739 Mon Sep 17 00:00:00 2001 From: Kala Severe Date: Thu, 2 Apr 2026 15:43:29 -0700 Subject: [PATCH 08/11] Bug 2027906 Test Version Refactor: remove hard coded array in Test Version Dropdown and replace with call to label options in registry (#1020) created label options for test version in strategy Deleted the the hard-coded test version array in TestVersionDropDown.tsx and replaced it with a call to getTestVersionOptions in the test version strategy file --- src/common/testVersions/index.ts | 15 +++++++++++++++ src/components/Shared/TestVersionDropdown.tsx | 8 ++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/common/testVersions/index.ts b/src/common/testVersions/index.ts index 4fc8b3e47..0d2103a30 100644 --- a/src/common/testVersions/index.ts +++ b/src/common/testVersions/index.ts @@ -30,6 +30,21 @@ const registry: Record = { 'mann-whitney-u': mannWhitneyStrategy, }; +const labels: Record = { + 'student-t': 'Student-T', + 'mann-whitney-u': 'Mann-Whitney-U', +}; + +export function getTestVersionOptions(): { + type: TestVersion; + label: string; +}[] { + return (Object.keys(registry) as TestVersion[]).map((type) => ({ + type, + label: labels[type], + })); +} + export function getStrategy(testVersion: TestVersion): TestVersionStrategy { return registry[testVersion]; } diff --git a/src/components/Shared/TestVersionDropdown.tsx b/src/components/Shared/TestVersionDropdown.tsx index 882d4de50..e3c214da5 100644 --- a/src/components/Shared/TestVersionDropdown.tsx +++ b/src/components/Shared/TestVersionDropdown.tsx @@ -1,6 +1,7 @@ import MenuItem from '@mui/material/MenuItem'; import Select, { SelectChangeEvent } from '@mui/material/Select'; +import { getTestVersionOptions } from '../../common/testVersions'; import { ThemeMode } from '../../types/state'; import { TestVersion } from '../../types/types'; @@ -12,11 +13,6 @@ interface TestVersionDropdownProps { onChange: (test_version: TestVersion) => void; } -const TEST_VERSIONS = [ - { type: 'mann-whitney-u', label: 'Mann-Whitney-U' }, - { type: 'student-t', label: 'Student-T' }, -]; - function TestVersionDropdown({ testType, variant, @@ -48,7 +44,7 @@ function TestVersionDropdown({ 'aria-label': 'Stats Test Version', }} > - {TEST_VERSIONS.map(({ label, type }) => ( + {getTestVersionOptions().map(({ label, type }) => ( {label} From 9e063c8685778821da8fb13fefa83714f4667994 Mon Sep 17 00:00:00 2001 From: "depfu[bot]" <23717796+depfu[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2026 16:00:34 -0700 Subject: [PATCH 09/11] Update all npm dependencies (2026-04-02) (#1021) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⬆️ Update all npm dependencies (2026-04-02) Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> --- package-lock.json | 272 +++++++++++++++++++++++++++------------------- package.json | 8 +- 2 files changed, 165 insertions(+), 115 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9bb91c41e..133e38a98 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,7 @@ "react-chartjs-2": "^5.3.1", "react-dom": "^19.2.4", "react-redux": "^9.2.0", - "react-router": "^7.13.1", + "react-router": "^7.13.2", "react-virtuoso": "^4.18.3", "stream-browserify": "^3.0.0", "taskcluster-client-web": "^87.1.3", @@ -48,7 +48,7 @@ "@eslint/js": "^9.39.4", "@fetch-mock/jest": "^0.2.20", "@jest/types": "^30.3.0", - "@swc/core": "^1.15.18", + "@swc/core": "^1.15.21", "@swc/jest": "^0.2.39", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", @@ -70,10 +70,10 @@ "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-typescript": "^4.4.4", "eslint-plugin-import": "^2.32.0", - "eslint-plugin-jest": "^29.15.0", + "eslint-plugin-jest": "^29.15.1", "eslint-plugin-jest-dom": "^5.5.0", "eslint-plugin-react": "^7.37.5", - "eslint-plugin-testing-library": "^7.16.0", + "eslint-plugin-testing-library": "^7.16.2", "globals": "^17.4.0", "history": "^5.3.0", "html-webpack-plugin": "^5.6.6", @@ -3906,9 +3906,9 @@ "license": "MIT" }, "node_modules/@swc/core": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.18.tgz", - "integrity": "sha512-z87aF9GphWp//fnkRsqvtY+inMVPgYW3zSlXH1kJFvRT5H/wiAn+G32qW5l3oEk63KSF1x3Ov0BfHCObAmT8RA==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.21.tgz", + "integrity": "sha512-fkk7NJcBscrR3/F8jiqlMptRHP650NxqDnspBMrRe5d8xOoCy9MLL5kOBLFXjFLfMo3KQQHhk+/jUULOMlR1uQ==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -3923,16 +3923,18 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.15.18", - "@swc/core-darwin-x64": "1.15.18", - "@swc/core-linux-arm-gnueabihf": "1.15.18", - "@swc/core-linux-arm64-gnu": "1.15.18", - "@swc/core-linux-arm64-musl": "1.15.18", - "@swc/core-linux-x64-gnu": "1.15.18", - "@swc/core-linux-x64-musl": "1.15.18", - "@swc/core-win32-arm64-msvc": "1.15.18", - "@swc/core-win32-ia32-msvc": "1.15.18", - "@swc/core-win32-x64-msvc": "1.15.18" + "@swc/core-darwin-arm64": "1.15.21", + "@swc/core-darwin-x64": "1.15.21", + "@swc/core-linux-arm-gnueabihf": "1.15.21", + "@swc/core-linux-arm64-gnu": "1.15.21", + "@swc/core-linux-arm64-musl": "1.15.21", + "@swc/core-linux-ppc64-gnu": "1.15.21", + "@swc/core-linux-s390x-gnu": "1.15.21", + "@swc/core-linux-x64-gnu": "1.15.21", + "@swc/core-linux-x64-musl": "1.15.21", + "@swc/core-win32-arm64-msvc": "1.15.21", + "@swc/core-win32-ia32-msvc": "1.15.21", + "@swc/core-win32-x64-msvc": "1.15.21" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" @@ -3944,9 +3946,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.18.tgz", - "integrity": "sha512-+mIv7uBuSaywN3C9LNuWaX1jJJ3SKfiJuE6Lr3bd+/1Iv8oMU7oLBjYMluX1UrEPzwN2qCdY6Io0yVicABoCwQ==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.21.tgz", + "integrity": "sha512-SA8SFg9dp0qKRH8goWsax6bptFE2EdmPf2YRAQW9WoHGf3XKM1bX0nd5UdwxmC5hXsBUZAYf7xSciCler6/oyA==", "cpu": [ "arm64" ], @@ -3960,9 +3962,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.18.tgz", - "integrity": "sha512-wZle0eaQhnzxWX5V/2kEOI6Z9vl/lTFEC6V4EWcn+5pDjhemCpQv9e/TDJ0GIoiClX8EDWRvuZwh+Z3dhL1NAg==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.21.tgz", + "integrity": "sha512-//fOVntgowz9+V90lVsNCtyyrtbHp3jWH6Rch7MXHXbcvbLmbCTmssl5DeedUWLLGiAAW1wksBdqdGYOTjaNLw==", "cpu": [ "x64" ], @@ -3976,9 +3978,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.18.tgz", - "integrity": "sha512-ao61HGXVqrJFHAcPtF4/DegmwEkVCo4HApnotLU8ognfmU8x589z7+tcf3hU+qBiU1WOXV5fQX6W9Nzs6hjxDw==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.21.tgz", + "integrity": "sha512-meNI4Sh6h9h8DvIfEc0l5URabYMSuNvyisLmG6vnoYAS43s8ON3NJR8sDHvdP7NJTrLe0q/x2XCn6yL/BeHcZg==", "cpu": [ "arm" ], @@ -3992,9 +3994,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.18.tgz", - "integrity": "sha512-3xnctOBLIq3kj8PxOCgPrGjBLP/kNOddr6f5gukYt/1IZxsITQaU9TDyjeX6jG+FiCIHjCuWuffsyQDL5Ew1bg==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.21.tgz", + "integrity": "sha512-QrXlNQnHeXqU2EzLlnsPoWEh8/GtNJLvfMiPsDhk+ht6Xv8+vhvZ5YZ/BokNWSIZiWPKLAqR0M7T92YF5tmD3g==", "cpu": [ "arm64" ], @@ -4008,9 +4010,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.18.tgz", - "integrity": "sha512-0a+Lix+FSSHBSBOA0XznCcHo5/1nA6oLLjcnocvzXeqtdjnPb+SvchItHI+lfeiuj1sClYPDvPMLSLyXFaiIKw==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.21.tgz", + "integrity": "sha512-8/yGCMO333ultDaMQivE5CjO6oXDPeeg1IV4sphojPkb0Pv0i6zvcRIkgp60xDB+UxLr6VgHgt+BBgqS959E9g==", "cpu": [ "arm64" ], @@ -4023,10 +4025,42 @@ "node": ">=10" } }, + "node_modules/@swc/core-linux-ppc64-gnu": { + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.21.tgz", + "integrity": "sha512-ucW0HzPx0s1dgRvcvuLSPSA/2Kk/VYTv9st8qe1Kc22Gu0Q0rH9+6TcBTmMuNIp0Xs4BPr1uBttmbO1wEGI49Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-s390x-gnu": { + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.21.tgz", + "integrity": "sha512-ulTnOGc5I7YRObE/9NreAhQg94QkiR5qNhhcUZ1iFAYjzg/JGAi1ch+s/Ixe61pMIr8bfVrF0NOaB0f8wjaAfA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.18.tgz", - "integrity": "sha512-wG9J8vReUlpaHz4KOD/5UE1AUgirimU4UFT9oZmupUDEofxJKYb1mTA/DrMj0s78bkBiNI+7Fo2EgPuvOJfuAA==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.21.tgz", + "integrity": "sha512-D0RokxtM+cPvSqJIKR6uja4hbD+scI9ezo95mBhfSyLUs9wnPPl26sLp1ZPR/EXRdYm3F3S6RUtVi+8QXhT24Q==", "cpu": [ "x64" ], @@ -4040,9 +4074,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.18.tgz", - "integrity": "sha512-4nwbVvCphKzicwNWRmvD5iBaZj8JYsRGa4xOxJmOyHlMDpsvvJ2OR2cODlvWyGFH6BYL1MfIAK3qph3hp0Az6g==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.21.tgz", + "integrity": "sha512-nER8u7VeRfmU6fMDzl1NQAbbB/G7O2avmvCOwIul1uGkZ2/acbPH+DCL9h5+0yd/coNcxMBTL6NGepIew+7C2w==", "cpu": [ "x64" ], @@ -4056,9 +4090,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.18.tgz", - "integrity": "sha512-zk0RYO+LjiBCat2RTMHzAWaMky0cra9loH4oRrLKLLNuL+jarxKLFDA8xTZWEkCPLjUTwlRN7d28eDLLMgtUcQ==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.21.tgz", + "integrity": "sha512-+/AgNBnjYugUA8C0Do4YzymgvnGbztv7j8HKSQLvR/DQgZPoXQ2B3PqB2mTtGh/X5DhlJWiqnunN35JUgWcAeQ==", "cpu": [ "arm64" ], @@ -4072,9 +4106,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.18.tgz", - "integrity": "sha512-yVuTrZ0RccD5+PEkpcLOBAuPbYBXS6rslENvIXfvJGXSdX5QGi1ehC4BjAMl5FkKLiam4kJECUI0l7Hq7T1vwg==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.21.tgz", + "integrity": "sha512-IkSZj8PX/N4HcaFhMQtzmkV8YSnuNoJ0E6OvMwFiOfejPhiKXvl7CdDsn1f4/emYEIDO3fpgZW9DTaCRMDxaDA==", "cpu": [ "ia32" ], @@ -4088,9 +4122,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.18.tgz", - "integrity": "sha512-7NRmE4hmUQNCbYU3Hn9Tz57mK9Qq4c97ZS+YlamlK6qG9Fb5g/BB3gPDe0iLlJkns/sYv2VWSkm8c3NmbEGjbg==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.21.tgz", + "integrity": "sha512-zUyWso7OOENB6e1N1hNuNn8vbvLsTdKQ5WKLgt/JcBNfJhKy/6jmBmqI3GXk/MyvQKd5SLvP7A0F36p7TeDqvw==", "cpu": [ "x64" ], @@ -8302,9 +8336,9 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "29.15.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.0.tgz", - "integrity": "sha512-ZCGr7vTH2WSo2hrK5oM2RULFmMruQ7W3cX7YfwoTiPfzTGTFBMmrVIz45jZHd++cGKj/kWf02li/RhTGcANJSA==", + "version": "29.15.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.1.tgz", + "integrity": "sha512-6BjyErCQauz3zfJvzLw/kAez2lf4LEpbHLvWBfEcG4EI0ZiRSwjoH2uZulMouU8kRkBH+S0rhqn11IhTvxKgKw==", "dev": true, "dependencies": { "@typescript-eslint/utils": "^8.0.0" @@ -8316,7 +8350,7 @@ "@typescript-eslint/eslint-plugin": "^8.0.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "jest": "*", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <7.0.0" }, "peerDependenciesMeta": { "@typescript-eslint/eslint-plugin": { @@ -8426,9 +8460,9 @@ } }, "node_modules/eslint-plugin-testing-library": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-7.16.0.tgz", - "integrity": "sha512-lHZI6/Olb2oZqxd1+s1nOLCtL2PXKrc1ERz6oDbUKS0xZAMFH3Fy6wJo75z3pXTop3BV6+loPi2MSjIYt3vpAg==", + "version": "7.16.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-7.16.2.tgz", + "integrity": "sha512-8gleGnQXK2ZA3hHwjCwpYTZvM+9VsrJ+/9kDI8CjqAQGAdMQOdn/rJNu7ZySENuiWlGKQWyZJ4ZjEg2zamaRHw==", "dev": true, "dependencies": { "@typescript-eslint/scope-manager": "^8.56.0", @@ -13723,9 +13757,9 @@ } }, "node_modules/react-router": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.1.tgz", - "integrity": "sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA==", + "version": "7.13.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.2.tgz", + "integrity": "sha512-tX1Aee+ArlKQP+NIUd7SE6Li+CiGKwQtbS+FfRxPX6Pe4vHOo6nr9d++u5cwg+Z8K/x8tP+7qLmujDtfrAoUJA==", "dependencies": { "cookie": "^1.0.1", "set-cookie-parser": "^2.6.0" @@ -19674,92 +19708,108 @@ "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==" }, "@swc/core": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.18.tgz", - "integrity": "sha512-z87aF9GphWp//fnkRsqvtY+inMVPgYW3zSlXH1kJFvRT5H/wiAn+G32qW5l3oEk63KSF1x3Ov0BfHCObAmT8RA==", - "dev": true, - "requires": { - "@swc/core-darwin-arm64": "1.15.18", - "@swc/core-darwin-x64": "1.15.18", - "@swc/core-linux-arm-gnueabihf": "1.15.18", - "@swc/core-linux-arm64-gnu": "1.15.18", - "@swc/core-linux-arm64-musl": "1.15.18", - "@swc/core-linux-x64-gnu": "1.15.18", - "@swc/core-linux-x64-musl": "1.15.18", - "@swc/core-win32-arm64-msvc": "1.15.18", - "@swc/core-win32-ia32-msvc": "1.15.18", - "@swc/core-win32-x64-msvc": "1.15.18", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.21.tgz", + "integrity": "sha512-fkk7NJcBscrR3/F8jiqlMptRHP650NxqDnspBMrRe5d8xOoCy9MLL5kOBLFXjFLfMo3KQQHhk+/jUULOMlR1uQ==", + "dev": true, + "requires": { + "@swc/core-darwin-arm64": "1.15.21", + "@swc/core-darwin-x64": "1.15.21", + "@swc/core-linux-arm-gnueabihf": "1.15.21", + "@swc/core-linux-arm64-gnu": "1.15.21", + "@swc/core-linux-arm64-musl": "1.15.21", + "@swc/core-linux-ppc64-gnu": "1.15.21", + "@swc/core-linux-s390x-gnu": "1.15.21", + "@swc/core-linux-x64-gnu": "1.15.21", + "@swc/core-linux-x64-musl": "1.15.21", + "@swc/core-win32-arm64-msvc": "1.15.21", + "@swc/core-win32-ia32-msvc": "1.15.21", + "@swc/core-win32-x64-msvc": "1.15.21", "@swc/counter": "^0.1.3", "@swc/types": "^0.1.25" } }, "@swc/core-darwin-arm64": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.18.tgz", - "integrity": "sha512-+mIv7uBuSaywN3C9LNuWaX1jJJ3SKfiJuE6Lr3bd+/1Iv8oMU7oLBjYMluX1UrEPzwN2qCdY6Io0yVicABoCwQ==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.21.tgz", + "integrity": "sha512-SA8SFg9dp0qKRH8goWsax6bptFE2EdmPf2YRAQW9WoHGf3XKM1bX0nd5UdwxmC5hXsBUZAYf7xSciCler6/oyA==", "dev": true, "optional": true }, "@swc/core-darwin-x64": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.18.tgz", - "integrity": "sha512-wZle0eaQhnzxWX5V/2kEOI6Z9vl/lTFEC6V4EWcn+5pDjhemCpQv9e/TDJ0GIoiClX8EDWRvuZwh+Z3dhL1NAg==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.21.tgz", + "integrity": "sha512-//fOVntgowz9+V90lVsNCtyyrtbHp3jWH6Rch7MXHXbcvbLmbCTmssl5DeedUWLLGiAAW1wksBdqdGYOTjaNLw==", "dev": true, "optional": true }, "@swc/core-linux-arm-gnueabihf": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.18.tgz", - "integrity": "sha512-ao61HGXVqrJFHAcPtF4/DegmwEkVCo4HApnotLU8ognfmU8x589z7+tcf3hU+qBiU1WOXV5fQX6W9Nzs6hjxDw==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.21.tgz", + "integrity": "sha512-meNI4Sh6h9h8DvIfEc0l5URabYMSuNvyisLmG6vnoYAS43s8ON3NJR8sDHvdP7NJTrLe0q/x2XCn6yL/BeHcZg==", "dev": true, "optional": true }, "@swc/core-linux-arm64-gnu": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.18.tgz", - "integrity": "sha512-3xnctOBLIq3kj8PxOCgPrGjBLP/kNOddr6f5gukYt/1IZxsITQaU9TDyjeX6jG+FiCIHjCuWuffsyQDL5Ew1bg==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.21.tgz", + "integrity": "sha512-QrXlNQnHeXqU2EzLlnsPoWEh8/GtNJLvfMiPsDhk+ht6Xv8+vhvZ5YZ/BokNWSIZiWPKLAqR0M7T92YF5tmD3g==", "dev": true, "optional": true }, "@swc/core-linux-arm64-musl": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.18.tgz", - "integrity": "sha512-0a+Lix+FSSHBSBOA0XznCcHo5/1nA6oLLjcnocvzXeqtdjnPb+SvchItHI+lfeiuj1sClYPDvPMLSLyXFaiIKw==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.21.tgz", + "integrity": "sha512-8/yGCMO333ultDaMQivE5CjO6oXDPeeg1IV4sphojPkb0Pv0i6zvcRIkgp60xDB+UxLr6VgHgt+BBgqS959E9g==", + "dev": true, + "optional": true + }, + "@swc/core-linux-ppc64-gnu": { + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-ppc64-gnu/-/core-linux-ppc64-gnu-1.15.21.tgz", + "integrity": "sha512-ucW0HzPx0s1dgRvcvuLSPSA/2Kk/VYTv9st8qe1Kc22Gu0Q0rH9+6TcBTmMuNIp0Xs4BPr1uBttmbO1wEGI49Q==", + "dev": true, + "optional": true + }, + "@swc/core-linux-s390x-gnu": { + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-s390x-gnu/-/core-linux-s390x-gnu-1.15.21.tgz", + "integrity": "sha512-ulTnOGc5I7YRObE/9NreAhQg94QkiR5qNhhcUZ1iFAYjzg/JGAi1ch+s/Ixe61pMIr8bfVrF0NOaB0f8wjaAfA==", "dev": true, "optional": true }, "@swc/core-linux-x64-gnu": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.18.tgz", - "integrity": "sha512-wG9J8vReUlpaHz4KOD/5UE1AUgirimU4UFT9oZmupUDEofxJKYb1mTA/DrMj0s78bkBiNI+7Fo2EgPuvOJfuAA==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.21.tgz", + "integrity": "sha512-D0RokxtM+cPvSqJIKR6uja4hbD+scI9ezo95mBhfSyLUs9wnPPl26sLp1ZPR/EXRdYm3F3S6RUtVi+8QXhT24Q==", "dev": true, "optional": true }, "@swc/core-linux-x64-musl": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.18.tgz", - "integrity": "sha512-4nwbVvCphKzicwNWRmvD5iBaZj8JYsRGa4xOxJmOyHlMDpsvvJ2OR2cODlvWyGFH6BYL1MfIAK3qph3hp0Az6g==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.21.tgz", + "integrity": "sha512-nER8u7VeRfmU6fMDzl1NQAbbB/G7O2avmvCOwIul1uGkZ2/acbPH+DCL9h5+0yd/coNcxMBTL6NGepIew+7C2w==", "dev": true, "optional": true }, "@swc/core-win32-arm64-msvc": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.18.tgz", - "integrity": "sha512-zk0RYO+LjiBCat2RTMHzAWaMky0cra9loH4oRrLKLLNuL+jarxKLFDA8xTZWEkCPLjUTwlRN7d28eDLLMgtUcQ==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.21.tgz", + "integrity": "sha512-+/AgNBnjYugUA8C0Do4YzymgvnGbztv7j8HKSQLvR/DQgZPoXQ2B3PqB2mTtGh/X5DhlJWiqnunN35JUgWcAeQ==", "dev": true, "optional": true }, "@swc/core-win32-ia32-msvc": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.18.tgz", - "integrity": "sha512-yVuTrZ0RccD5+PEkpcLOBAuPbYBXS6rslENvIXfvJGXSdX5QGi1ehC4BjAMl5FkKLiam4kJECUI0l7Hq7T1vwg==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.21.tgz", + "integrity": "sha512-IkSZj8PX/N4HcaFhMQtzmkV8YSnuNoJ0E6OvMwFiOfejPhiKXvl7CdDsn1f4/emYEIDO3fpgZW9DTaCRMDxaDA==", "dev": true, "optional": true }, "@swc/core-win32-x64-msvc": { - "version": "1.15.18", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.18.tgz", - "integrity": "sha512-7NRmE4hmUQNCbYU3Hn9Tz57mK9Qq4c97ZS+YlamlK6qG9Fb5g/BB3gPDe0iLlJkns/sYv2VWSkm8c3NmbEGjbg==", + "version": "1.15.21", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.21.tgz", + "integrity": "sha512-zUyWso7OOENB6e1N1hNuNn8vbvLsTdKQ5WKLgt/JcBNfJhKy/6jmBmqI3GXk/MyvQKd5SLvP7A0F36p7TeDqvw==", "dev": true, "optional": true }, @@ -22842,9 +22892,9 @@ } }, "eslint-plugin-jest": { - "version": "29.15.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.0.tgz", - "integrity": "sha512-ZCGr7vTH2WSo2hrK5oM2RULFmMruQ7W3cX7YfwoTiPfzTGTFBMmrVIz45jZHd++cGKj/kWf02li/RhTGcANJSA==", + "version": "29.15.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.15.1.tgz", + "integrity": "sha512-6BjyErCQauz3zfJvzLw/kAez2lf4LEpbHLvWBfEcG4EI0ZiRSwjoH2uZulMouU8kRkBH+S0rhqn11IhTvxKgKw==", "dev": true, "requires": { "@typescript-eslint/utils": "^8.0.0" @@ -22915,9 +22965,9 @@ } }, "eslint-plugin-testing-library": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-7.16.0.tgz", - "integrity": "sha512-lHZI6/Olb2oZqxd1+s1nOLCtL2PXKrc1ERz6oDbUKS0xZAMFH3Fy6wJo75z3pXTop3BV6+loPi2MSjIYt3vpAg==", + "version": "7.16.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-7.16.2.tgz", + "integrity": "sha512-8gleGnQXK2ZA3hHwjCwpYTZvM+9VsrJ+/9kDI8CjqAQGAdMQOdn/rJNu7ZySENuiWlGKQWyZJ4ZjEg2zamaRHw==", "dev": true, "requires": { "@typescript-eslint/scope-manager": "^8.56.0", @@ -26565,9 +26615,9 @@ "dev": true }, "react-router": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.1.tgz", - "integrity": "sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA==", + "version": "7.13.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.2.tgz", + "integrity": "sha512-tX1Aee+ArlKQP+NIUd7SE6Li+CiGKwQtbS+FfRxPX6Pe4vHOo6nr9d++u5cwg+Z8K/x8tP+7qLmujDtfrAoUJA==", "requires": { "cookie": "^1.0.1", "set-cookie-parser": "^2.6.0" diff --git a/package.json b/package.json index 9e6c0cc0c..605bb4c30 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "react-chartjs-2": "^5.3.1", "react-dom": "^19.2.4", "react-redux": "^9.2.0", - "react-router": "^7.13.1", + "react-router": "^7.13.2", "react-virtuoso": "^4.18.3", "stream-browserify": "^3.0.0", "taskcluster-client-web": "^87.1.3", @@ -90,7 +90,7 @@ "@eslint/js": "^9.39.4", "@fetch-mock/jest": "^0.2.20", "@jest/types": "^30.3.0", - "@swc/core": "^1.15.18", + "@swc/core": "^1.15.21", "@swc/jest": "^0.2.39", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", @@ -112,10 +112,10 @@ "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-typescript": "^4.4.4", "eslint-plugin-import": "^2.32.0", - "eslint-plugin-jest": "^29.15.0", + "eslint-plugin-jest": "^29.15.1", "eslint-plugin-jest-dom": "^5.5.0", "eslint-plugin-react": "^7.37.5", - "eslint-plugin-testing-library": "^7.16.0", + "eslint-plugin-testing-library": "^7.16.2", "globals": "^17.4.0", "history": "^5.3.0", "html-webpack-plugin": "^5.6.6", From 700b3c1387944ad7934b0f0d48df9697b8f5e196 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 3 Apr 2026 22:13:40 +0530 Subject: [PATCH 10/11] Bug-2022758: Remove redundant Dark fonts (#1011) * Bug-2022758: Remove redundant Dark fonts Refactor fonts.ts to remove the redundant Dark fonts Also updated the settings where Dark fonts were conditionally used. * Bug-2022758: Fix lint errors * Cleanup lint errors in `SearchContainerStyles.ts` * Fix snapshots * Bug-2022758: Removed the mode parameter from SearchContainerStyles * Removed the `mode` parameter from SearchContainerStyles * Updated all calls to SearchContainerStyles * Bug-2022758: Remove comment * Bug-2022758: Add the comment back * Bug-2022758: Update snapshots Update snapshots after running `npm ci`. --- .../CompareResults/OverTimeResultsView.tsx | 2 +- src/components/CompareResults/ResultsView.tsx | 2 +- src/components/Search/SearchContainer.tsx | 4 +-- src/components/Shared/PageError.tsx | 2 +- .../Shared/ToggleDarkModeButton.tsx | 4 +-- src/styles/CompareCards.ts | 8 ++--- src/styles/Fonts.ts | 35 ++++--------------- src/styles/SearchContainerStyles.ts | 6 ++-- src/styles/SelectedRevsStyle.ts | 2 +- 9 files changed, 18 insertions(+), 47 deletions(-) diff --git a/src/components/CompareResults/OverTimeResultsView.tsx b/src/components/CompareResults/OverTimeResultsView.tsx index e3d8730aa..ff457871e 100644 --- a/src/components/CompareResults/OverTimeResultsView.tsx +++ b/src/components/CompareResults/OverTimeResultsView.tsx @@ -33,7 +33,7 @@ function ResultsView(props: ResultsViewProps) { }), }; - const sectionStyles = SearchContainerStyles(themeMode, /* isHome */ false); + const sectionStyles = SearchContainerStyles(/* isHome */ false); useEffect(() => { document.title = title; diff --git a/src/components/CompareResults/ResultsView.tsx b/src/components/CompareResults/ResultsView.tsx index f9cb29bc4..18897affc 100644 --- a/src/components/CompareResults/ResultsView.tsx +++ b/src/components/CompareResults/ResultsView.tsx @@ -41,7 +41,7 @@ function ResultsView(props: ResultsViewProps) { }), }; - const sectionStyles = SearchContainerStyles(themeMode, /* isHome */ false); + const sectionStyles = SearchContainerStyles(/* isHome */ false); useEffect(() => { document.title = title; diff --git a/src/components/Search/SearchContainer.tsx b/src/components/Search/SearchContainer.tsx index a4c4e5d54..f4ffddf3a 100644 --- a/src/components/Search/SearchContainer.tsx +++ b/src/components/Search/SearchContainer.tsx @@ -8,7 +8,6 @@ import CompareWithBase from './CompareWithBase'; import type { LoaderReturnValue } from './loader'; import SearchFormHeader from './SearchFormHeader'; import { STUDENT_T } from '../../common/constants'; -import { useAppSelector } from '../../hooks/app'; import { Strings } from '../../resources/Strings'; import { SearchContainerStyles } from '../../styles'; import type { TimeRange } from '../../types/types'; @@ -16,8 +15,7 @@ import type { TimeRange } from '../../types/types'; const strings = Strings.components.searchDefault; function SearchContainer(props: SearchViewProps) { - const themeMode = useAppSelector((state) => state.theme.mode); - const styles = SearchContainerStyles(themeMode, /* isHome */ true); + const styles = SearchContainerStyles(/* isHome */ true); const [isBaseSearchExpanded, setIsBaseSearchExpanded] = useState(true); const { newRevInfo, newRepo, frameworkId } = useLoaderData(); diff --git a/src/components/Shared/PageError.tsx b/src/components/Shared/PageError.tsx index dfc527da2..bdf3ac0f4 100644 --- a/src/components/Shared/PageError.tsx +++ b/src/components/Shared/PageError.tsx @@ -24,7 +24,7 @@ export function PageError({ title }: PageErrorProps) { }), }; - const sectionStyles = SearchContainerStyles(themeMode, /* isHome */ false); + const sectionStyles = SearchContainerStyles(/* isHome */ false); const error = useRouteError() as Error; console.error(error); diff --git a/src/components/Shared/ToggleDarkModeButton.tsx b/src/components/Shared/ToggleDarkModeButton.tsx index 2dd55309c..aabaf9875 100644 --- a/src/components/Shared/ToggleDarkModeButton.tsx +++ b/src/components/Shared/ToggleDarkModeButton.tsx @@ -31,9 +31,7 @@ function ToggleDarkMode() { margin: 0, $nest: { '.toggle-text': { - ...(theme === 'light' - ? FontsRaw.BodyDefault - : FontsRaw.BodyDefaultDark), + ...FontsRaw.BodyDefault, margin: 0, }, '.toggle-switch': { diff --git a/src/styles/CompareCards.ts b/src/styles/CompareCards.ts index 9ef9c3396..48c4b4ec8 100644 --- a/src/styles/CompareCards.ts +++ b/src/styles/CompareCards.ts @@ -122,12 +122,10 @@ export const CompareCardsStyles = (mode: string) => { width: '76%', $nest: { '.compare-card-title': { - ...(isTrueLight - ? FontsRaw.HeadingDefault - : FontsRaw.HeadingDefaultDark), + ...FontsRaw.HeadingDefault, }, '.compare-card-tagline': { - ...(isTrueLight ? FontsRaw.BodyDefault : FontsRaw.BodyDefaultDark), + ...FontsRaw.BodyDefault, margin: '0px', }, }, @@ -166,7 +164,7 @@ export const SearchStyles = (mode: string) => { marginBottom: `${Spacing.xSmall + 2}px`, $nest: { '.dropdown-select-label,.base_label': { - ...(isTrueLight ? FontsRaw.BodyDefault : FontsRaw.BodyDefaultDark), + ...FontsRaw.BodyDefault, fontWeight: '600', display: 'flex', alignItems: 'center', diff --git a/src/styles/Fonts.ts b/src/styles/Fonts.ts index 19ba3e124..39017b2f1 100644 --- a/src/styles/Fonts.ts +++ b/src/styles/Fonts.ts @@ -59,37 +59,16 @@ export const FontsRaw = { fontSize: FontSizeRaw.Normal.fontSize, fontFamily: 'SF Pro', }, - - //DARK MODE FONTS - - HeadingDefaultDark: { - ...sharedFontStyles, - fontWeight: '600', - fontSize: '17px', - fontFamily: 'SF Pro', - }, - - HeadingXSDark: { - ...sharedFontStyles, - fontSize: '24px', - fontFamily: 'Metropolis', - }, - - BodyDefaultDark: { - ...sharedFontStyles, - fontWeight: '400', - fontSize: FontSizeRaw.Normal.fontSize, - fontFamily: 'SF Pro', - }, }; +const headingDefault = style(FontsRaw.HeadingDefault); +const headingXS = style(FontsRaw.HeadingXS); +const bodyDefault = style(FontsRaw.BodyDefault); + export const Fonts = { - HeadingDefault: style(FontsRaw.HeadingDefault), - HeadingXS: style(FontsRaw.HeadingXS), - BodyDefault: style(FontsRaw.BodyDefault), - HeadingDefaultDark: style(FontsRaw.HeadingDefaultDark), - HeadingXSDark: style(FontsRaw.HeadingXSDark), - BodyDefaultDark: style(FontsRaw.BodyDefaultDark), + HeadingDefault: headingDefault, + HeadingXS: headingXS, + BodyDefault: bodyDefault, }; export const FontSize = { diff --git a/src/styles/SearchContainerStyles.ts b/src/styles/SearchContainerStyles.ts index a1588ea39..a7279f9b8 100644 --- a/src/styles/SearchContainerStyles.ts +++ b/src/styles/SearchContainerStyles.ts @@ -2,9 +2,7 @@ import { stylesheet } from 'typestyle'; import { FontsRaw, Spacing } from '../styles'; -export const SearchContainerStyles = (mode: string, isHome: boolean) => { - const isTrueLight = mode == 'light'; - +export const SearchContainerStyles = (isHome: boolean) => { const styles = stylesheet({ container: { /*** maxWidth based on mozilla protocol large cards size; see https://protocol.mozilla.org/components/detail/card--large @@ -18,7 +16,7 @@ export const SearchContainerStyles = (mode: string, isHome: boolean) => { flexDirection: 'column', $nest: { '.search-default-title': { - ...(isTrueLight ? FontsRaw.HeadingXS : FontsRaw.HeadingXSDark), + ...FontsRaw.HeadingXS, marginBottom: `${Spacing.xLarge + 10}px`, textAlign: 'center', }, diff --git a/src/styles/SelectedRevsStyle.ts b/src/styles/SelectedRevsStyle.ts index a201a2ec8..b511e52c2 100644 --- a/src/styles/SelectedRevsStyle.ts +++ b/src/styles/SelectedRevsStyle.ts @@ -27,7 +27,7 @@ export const SelectRevsStyles = (mode: string) => { }, }, '.item-container': { - ...(isTrueLight ? FontsRaw.BodyDefault : FontsRaw.BodyDefaultDark), + ...FontsRaw.BodyDefault, backgroundColor: isTrueLight ? Colors.Background200 : Colors.Background300Dark, From b83ad27eeb61c0bdc3ce87c10063f80e82af83cb Mon Sep 17 00:00:00 2001 From: Kala Severe Date: Tue, 7 Apr 2026 10:45:48 -0700 Subject: [PATCH 11/11] Bug 2026342 : Replace truncated subtest names with full name (#1023) * subtest names wrapped vs truncated Reduce significance col and switched places with cles; updated test to reflect col changes. * removed extra padding --- src/__tests__/App.test.tsx | 6 +- .../CompareResults/ResultsTable.test.tsx | 314 +++---- .../SubtestsResultsView.test.tsx | 92 +- .../SubtestsRevisionRow.test.tsx | 6 +- .../OverTimeResultsView.test.tsx.snap | 110 +-- .../__snapshots__/ResultsTable.test.tsx.snap | 491 +++++----- .../__snapshots__/ResultsView.test.tsx.snap | 110 +-- .../SubtestsResultsView.test.tsx.snap | 853 ++++++++++-------- .../SubtestsRevisionRow.test.tsx.snap | 6 +- src/common/testVersions/mannWhitney.tsx | 93 +- .../CompareResults/ResultsTable.tsx | 9 +- src/components/CompareResults/RevisionRow.tsx | 1 - .../SubtestsResults/SubtestsRevisionRow.tsx | 9 +- src/components/CompareResults/TableHeader.tsx | 23 +- src/types/types.ts | 6 +- src/utils/gridTemplateColumns.ts | 11 + src/utils/rowTemplateColumns.ts | 2 + 17 files changed, 1156 insertions(+), 986 deletions(-) create mode 100644 src/utils/gridTemplateColumns.ts diff --git a/src/__tests__/App.test.tsx b/src/__tests__/App.test.tsx index 8dfcdbdbc..d0697ce41 100644 --- a/src/__tests__/App.test.tsx +++ b/src/__tests__/App.test.tsx @@ -398,9 +398,9 @@ describe('App', () => { // Verify that Mann-Whitney-U specific columns are rendered // (this indicates the testVersion defaulted to mann-whitney-u) - expect(screen.getByText("Cliff's Delta")).toBeInTheDocument(); - expect(screen.getByText('Significance')).toBeInTheDocument(); - expect(screen.getByText('CLES(%)')).toBeInTheDocument(); + expect(screen.getByText('CD')).toBeInTheDocument(); + expect(screen.getByText('Sig')).toBeInTheDocument(); + expect(screen.getByText('CLES (%)')).toBeInTheDocument(); // Verify the Stats Test Version dropdown shows Mann-Whitney-U as selected const testVersionDropdown = screen.getByRole('combobox', { diff --git a/src/__tests__/CompareResults/ResultsTable.test.tsx b/src/__tests__/CompareResults/ResultsTable.test.tsx index 123bac3ec..b855a8be7 100644 --- a/src/__tests__/CompareResults/ResultsTable.test.tsx +++ b/src/__tests__/CompareResults/ResultsTable.test.tsx @@ -716,9 +716,9 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: spam', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', ' rev: devilrabbit', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', ]); expect(screen.getByRole('rowgroup')).toMatchSnapshot(); }); @@ -742,12 +742,12 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await screen.findByText('a11yr'); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - inexistant, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, -, , -, Significant, 100.00 %', - ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', + ' - Android, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - inexistant, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Windows 10, -, , -, , 100.00 %', + ' - Windows 10, -2.401 %, , -, , 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); @@ -756,9 +756,9 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Platform', /Windows/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Android, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['osx', 'linux', 'android', 'ios'], @@ -769,12 +769,12 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Platform', /Windows/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - inexistant, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, -, , -, Significant, 100.00 %', - ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', + ' - Android, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - inexistant, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Windows 10, -, , -, , 100.00 %', + ' - Windows 10, -2.401 %, , -, , 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); @@ -782,8 +782,8 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Platform', /Linux/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Android, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['osx', 'android', 'ios'], @@ -792,9 +792,9 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Platform', /Linux/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Android, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['osx', 'android', 'ios', 'linux'], @@ -803,22 +803,22 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Platform', 'Select all values'); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - inexistant, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, -, , -, Significant, 100.00 %', - ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', + ' - Android, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - inexistant, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Windows 10, -, , -, , 100.00 %', + ' - Windows 10, -2.401 %, , -, , 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); await clickMenuItem(user, 'Platform', /macOS/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - Windows 10, -, , -, Significant, 100.00 %', - ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', + ' - Android, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - Windows 10, -, , -, , 100.00 %', + ' - Windows 10, -2.401 %, , -, , 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['windows', 'linux', 'android', 'ios'], @@ -827,9 +827,9 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Platform', /Android/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - Windows 10, -, , -, Significant, 100.00 %', - ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - Windows 10, -, , -, , 100.00 %', + ' - Windows 10, -2.401 %, , -, , 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['windows', 'linux', 'ios'], @@ -838,7 +838,7 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Platform', /Select only.*Android/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Android, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Android, 1.078 %, Improvement, 0.1, -, 25.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ platform: ['android'], @@ -853,8 +853,10 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); // Filter only "Significant" - const signifianceMenu = await screen.findAllByText(/Significance/); - await user.click(signifianceMenu[1]); + const signifianceMenu = await screen.findByRole('button', { + name: /Sig.*filter/, + }); + await user.click(signifianceMenu); expect(signifianceMenu).toMatchSnapshot(); // significant item 0 and Not significant item 1 @@ -875,10 +877,10 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await screen.findByText('a11yr'); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, -, , -, Significant, 100.00 %', - ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Windows 10, -, , -, , 100.00 %', + ' - Windows 10, -2.401 %, , -, , 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); @@ -886,8 +888,8 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Status', /No changes/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ status: ['improvement', 'regression'], @@ -896,7 +898,7 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Status', /Improvement/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ status: ['regression'], @@ -906,9 +908,9 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Status', /Regression/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, -, , -, Significant, 100.00 %', - ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Windows 10, -, , -, , 100.00 %', + ' - Windows 10, -2.401 %, , -, , 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ status: ['none', 'improvement'], @@ -917,17 +919,17 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Status', /Regression/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, -, , -, Significant, 100.00 %', - ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Windows 10, -, , -, , 100.00 %', + ' - Windows 10, -2.401 %, , -, , 50.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({}); await clickMenuItem(user, 'Status', /Select only.*Regression/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ status: ['regression'], @@ -936,7 +938,7 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio await clickMenuItem(user, 'Status', /Select only.*Improvement/); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', ]); expect(summarizeTableFiltersFromUrl()).toEqual({ status: ['improvement'], @@ -953,12 +955,12 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html spam opt e10s fission stylo webrender', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', ]); const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); expect(await summarizeTableFiltersFromCheckboxes(user)).toEqual({ 'Platform(2)': ['macOS', 'Android'], - 'Significance(2)': ['Significant', 'Not Significant'], + 'Sig(2)': ['Significant', 'Not Significant-'], 'Status(3)': ['No changes', 'Improvement', 'Regression'], }); @@ -982,33 +984,33 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); // Sort by Cliff's Delta - const deltaButton = screen.getByRole('button', { name: /Cliff's Delta/ }); + const deltaButton = screen.getByRole('button', { name: /CD/ }); expect(deltaButton).toMatchSnapshot(); // // Sort descending expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr aria.html opt e10s fission stylo webrender', ' rev: spam', - ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', - ' - Windows 10, -, , 1.2, Significant, 99.00 %', - ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', + ' - Linux 18.04, 1.849 %, Regression, 1.2, -, 44.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 1.3, -, 24.00 %', + ' - Windows 10, -, , 1.2, , 99.00 %', + ' - Windows 10, -2.401 %, , 1.2, , 49.00 %', ' rev: tictactoe', - ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', - ' - Windows 10, -, , 2, Significant, 98.00 %', - ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', + ' - Linux 18.04, 1.849 %, Regression, 2, -, 43.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 2.1, -, 23.00 %', + ' - Windows 10, -, , 2, , 98.00 %', + ' - Windows 10, -2.401 %, , 2, , 48.00 %', 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: spam', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Windows 10, -, , -, Significant, 100.00 %', - ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Windows 10, -, , -, , 100.00 %', + ' - Windows 10, -2.401 %, , -, , 50.00 %', ' rev: tictactoe', - ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', - ' - Windows 10, -, , 0.8, Significant, 99.00 %', - ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', + ' - Linux 18.04, 1.849 %, Regression, 0.8, -, 44.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.9, -, 24.00 %', + ' - Windows 10, -, , 0.8, , 99.00 %', + ' - Windows 10, -2.401 %, , 0.8, , 49.00 %', ]); // It should have the "descending" SVG. expect(deltaButton).toMatchSnapshot(); @@ -1020,26 +1022,26 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr aria.html opt e10s fission stylo webrender', ' rev: tictactoe', - ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', - ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', - ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', - ' - Windows 10, -, , 2, Significant, 98.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 2.1, -, 23.00 %', + ' - Linux 18.04, 1.849 %, Regression, 2, -, 43.00 %', + ' - Windows 10, -2.401 %, , 2, , 48.00 %', + ' - Windows 10, -, , 2, , 98.00 %', ' rev: spam', - ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', - ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', - ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', - ' - Windows 10, -, , 1.2, Significant, 99.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 1.3, -, 24.00 %', + ' - Linux 18.04, 1.849 %, Regression, 1.2, -, 44.00 %', + ' - Windows 10, -2.401 %, , 1.2, , 49.00 %', + ' - Windows 10, -, , 1.2, , 99.00 %', 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: tictactoe', - ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', - ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', - ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', - ' - Windows 10, -, , 0.8, Significant, 99.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.9, -, 24.00 %', + ' - Linux 18.04, 1.849 %, Regression, 0.8, -, 44.00 %', + ' - Windows 10, -2.401 %, , 0.8, , 49.00 %', + ' - Windows 10, -, , 0.8, , 99.00 %', ' rev: spam', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', - ' - Windows 10, -, , -, Significant, 100.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - Windows 10, -2.401 %, , -, , 50.00 %', + ' - Windows 10, -, , -, , 100.00 %', ]); // It should have the "ascending" SVG. expect(deltaButton).toMatchSnapshot(); @@ -1048,32 +1050,32 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio // Sort by Significance descending const significanceButton = screen.getByRole('button', { - name: /Significance.*sort/, + name: /Sig.*sort/, }); await user.click(significanceButton); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr aria.html opt e10s fission stylo webrender', ' rev: tictactoe', - ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', - ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', - ' - Windows 10, -, , 2, Significant, 98.00 %', - ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 2.1, -, 23.00 %', + ' - Linux 18.04, 1.849 %, Regression, 2, -, 43.00 %', + ' - Windows 10, -, , 2, , 98.00 %', + ' - Windows 10, -2.401 %, , 2, , 48.00 %', ' rev: spam', - ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', - ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', - ' - Windows 10, -, , 1.2, Significant, 99.00 %', - ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 1.3, -, 24.00 %', + ' - Linux 18.04, 1.849 %, Regression, 1.2, -, 44.00 %', + ' - Windows 10, -, , 1.2, , 99.00 %', + ' - Windows 10, -2.401 %, , 1.2, , 49.00 %', 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: tictactoe', - ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', - ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', - ' - Windows 10, -, , 0.8, Significant, 99.00 %', - ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.9, -, 24.00 %', + ' - Linux 18.04, 1.849 %, Regression, 0.8, -, 44.00 %', + ' - Windows 10, -, , 0.8, , 99.00 %', + ' - Windows 10, -2.401 %, , 0.8, , 49.00 %', ' rev: spam', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - Windows 10, -, , -, Significant, 100.00 %', - ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - Windows 10, -, , -, , 100.00 %', + ' - Windows 10, -2.401 %, , -, , 50.00 %', ]); // It should have the "descending" SVG. expect(significanceButton).toMatchSnapshot(); @@ -1085,26 +1087,26 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: spam', - ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', - ' - Windows 10, -, , -, Significant, 100.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', + ' - Windows 10, -2.401 %, , -, , 50.00 %', + ' - Windows 10, -, , -, , 100.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', ' rev: tictactoe', - ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', - ' - Windows 10, -, , 0.8, Significant, 99.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', - ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', + ' - Windows 10, -2.401 %, , 0.8, , 49.00 %', + ' - Windows 10, -, , 0.8, , 99.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.9, -, 24.00 %', + ' - Linux 18.04, 1.849 %, Regression, 0.8, -, 44.00 %', 'a11yr aria.html opt e10s fission stylo webrender', ' rev: spam', - ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', - ' - Windows 10, -, , 1.2, Significant, 99.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', - ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', + ' - Windows 10, -2.401 %, , 1.2, , 49.00 %', + ' - Windows 10, -, , 1.2, , 99.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 1.3, -, 24.00 %', + ' - Linux 18.04, 1.849 %, Regression, 1.2, -, 44.00 %', ' rev: tictactoe', - ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', - ' - Windows 10, -, , 2, Significant, 98.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', - ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', + ' - Windows 10, -2.401 %, , 2, , 48.00 %', + ' - Windows 10, -, , 2, , 98.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 2.1, -, 23.00 %', + ' - Linux 18.04, 1.849 %, Regression, 2, -, 43.00 %', ]); // It should have the "descending" SVG. expect(significanceButton).toMatchSnapshot(); @@ -1113,32 +1115,32 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio // Sort by Effect Size (%) descending const effectSizeButton = screen.getByRole('button', { - name: /CLES\(%\).*sort/, + name: /CLES \(%\).*sort/, }); await user.click(effectSizeButton); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: spam', - ' - Windows 10, -, , -, Significant, 100.00 %', - ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', + ' - Windows 10, -, , -, , 100.00 %', + ' - Windows 10, -2.401 %, , -, , 50.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', ' rev: tictactoe', - ' - Windows 10, -, , 0.8, Significant, 99.00 %', - ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', - ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', + ' - Windows 10, -, , 0.8, , 99.00 %', + ' - Windows 10, -2.401 %, , 0.8, , 49.00 %', + ' - Linux 18.04, 1.849 %, Regression, 0.8, -, 44.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.9, -, 24.00 %', 'a11yr aria.html opt e10s fission stylo webrender', ' rev: spam', - ' - Windows 10, -, , 1.2, Significant, 99.00 %', - ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', - ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', + ' - Windows 10, -, , 1.2, , 99.00 %', + ' - Windows 10, -2.401 %, , 1.2, , 49.00 %', + ' - Linux 18.04, 1.849 %, Regression, 1.2, -, 44.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 1.3, -, 24.00 %', ' rev: tictactoe', - ' - Windows 10, -, , 2, Significant, 98.00 %', - ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', - ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', - ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', + ' - Windows 10, -, , 2, , 98.00 %', + ' - Windows 10, -2.401 %, , 2, , 48.00 %', + ' - Linux 18.04, 1.849 %, Regression, 2, -, 43.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 2.1, -, 23.00 %', ]); expect(effectSizeButton).toMatchSnapshot(); @@ -1150,26 +1152,26 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'a11yr aria.html opt e10s fission stylo webrender', ' rev: tictactoe', - ' - macOS 10.15, 1.078 %, Improvement, 2.1, Not significant, 23.00 %', - ' - Linux 18.04, 1.849 %, Regression, 2, Not significant, 43.00 %', - ' - Windows 10, -2.401 %, , 2, Significant, 48.00 %', - ' - Windows 10, -, , 2, Significant, 98.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 2.1, -, 23.00 %', + ' - Linux 18.04, 1.849 %, Regression, 2, -, 43.00 %', + ' - Windows 10, -2.401 %, , 2, , 48.00 %', + ' - Windows 10, -, , 2, , 98.00 %', ' rev: spam', - ' - macOS 10.15, 1.078 %, Improvement, 1.3, Not significant, 24.00 %', - ' - Linux 18.04, 1.849 %, Regression, 1.2, Not significant, 44.00 %', - ' - Windows 10, -2.401 %, , 1.2, Significant, 49.00 %', - ' - Windows 10, -, , 1.2, Significant, 99.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 1.3, -, 24.00 %', + ' - Linux 18.04, 1.849 %, Regression, 1.2, -, 44.00 %', + ' - Windows 10, -2.401 %, , 1.2, , 49.00 %', + ' - Windows 10, -, , 1.2, , 99.00 %', 'a11yr dhtml.html opt e10s fission stylo webrender', ' rev: tictactoe', - ' - macOS 10.15, 1.078 %, Improvement, 0.9, Not significant, 24.00 %', - ' - Linux 18.04, 1.849 %, Regression, 0.8, Not significant, 44.00 %', - ' - Windows 10, -2.401 %, , 0.8, Significant, 49.00 %', - ' - Windows 10, -, , 0.8, Significant, 99.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.9, -, 24.00 %', + ' - Linux 18.04, 1.849 %, Regression, 0.8, -, 44.00 %', + ' - Windows 10, -2.401 %, , 0.8, , 49.00 %', + ' - Windows 10, -, , 0.8, , 99.00 %', ' rev: spam', - ' - macOS 10.15, 1.078 %, Improvement, 0.1, Not significant, 25.00 %', - ' - Linux 18.04, 1.849 %, Regression, -, Not significant, 45.00 %', - ' - Windows 10, -2.401 %, , -, Significant, 50.00 %', - ' - Windows 10, -, , -, Significant, 100.00 %', + ' - macOS 10.15, 1.078 %, Improvement, 0.1, -, 25.00 %', + ' - Linux 18.04, 1.849 %, Regression, -, -, 45.00 %', + ' - Windows 10, -2.401 %, , -, , 50.00 %', + ' - Windows 10, -, , -, , 100.00 %', ]); expect(effectSizeButton).toMatchSnapshot(); // It should be persisted in the URL @@ -1177,7 +1179,7 @@ describe('Results Table for MannWhitneyResultsItem for mann-whitney-u testVersio // Sort by MD(%) descending const medianDiffButton = screen.getByRole('button', { - name: /MD\(%\).*sort/, + name: /MD \(%\).*sort/, }); await user.click(medianDiffButton); expect(summarizeVisibleRows('mann-whitney-u')).toMatchSnapshot(); diff --git a/src/__tests__/CompareResults/SubtestsResultsView.test.tsx b/src/__tests__/CompareResults/SubtestsResultsView.test.tsx index 7ac5e214e..4b6c2ae76 100644 --- a/src/__tests__/CompareResults/SubtestsResultsView.test.tsx +++ b/src/__tests__/CompareResults/SubtestsResultsView.test.tsx @@ -508,25 +508,25 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( await setupForSorting(); // Initial view (alphabetical ordered, even if "sort by subtests" isn't specified expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', - 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', - 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', - 'regression.html: 1.135 %, 0.12, Significant, 25.00%', + 'browser.html: 0.963 %, -0.04, -, 15.00%', + 'dhtml.html: 1.135 %, 0.02, , 60.00%', + 'improvement.html: 0.963 %, -0.05, , 50.00%', + 'regression.html: 1.135 %, 0.12, , 25.00%', 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', ]); // Sort by Delta const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime }); - const deltaButton = screen.getByRole('button', { name: /Delta/ }); + const deltaButton = screen.getByRole('button', { name: /CD/ }); expect(deltaButton).toMatchSnapshot(); expect(window.location.search).not.toContain('sort='); // Sort descending await user.click(deltaButton); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'regression.html: 1.135 %, 0.12, Significant, 25.00%', - 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', - 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', - 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', + 'regression.html: 1.135 %, 0.12, , 25.00%', + 'improvement.html: 0.963 %, -0.05, , 50.00%', + 'browser.html: 0.963 %, -0.04, -, 15.00%', + 'dhtml.html: 1.135 %, 0.02, , 60.00%', 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', ]); @@ -539,10 +539,10 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( await user.click(deltaButton); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', - 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', - 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', - 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', - 'regression.html: 1.135 %, 0.12, Significant, 25.00%', + 'dhtml.html: 1.135 %, 0.02, , 60.00%', + 'browser.html: 0.963 %, -0.04, -, 15.00%', + 'improvement.html: 0.963 %, -0.05, , 50.00%', + 'regression.html: 1.135 %, 0.12, , 25.00%', ]); // It should have the "ascending" SVG. expect(deltaButton).toMatchSnapshot(); @@ -551,15 +551,15 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( // Sort by Significance descending const significanceButton = screen.getByRole('button', { - name: /Significance.*sort/, + name: /Sig.*sort/, }); await user.click(significanceButton); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', + 'browser.html: 0.963 %, -0.04, -, 15.00%', 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', - 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', - 'regression.html: 1.135 %, 0.12, Significant, 25.00%', - 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', + 'dhtml.html: 1.135 %, 0.02, , 60.00%', + 'regression.html: 1.135 %, 0.12, , 25.00%', + 'improvement.html: 0.963 %, -0.05, , 50.00%', ]); // It should have the "no sort" SVG. expect(deltaButton).toMatchSnapshot(); @@ -571,25 +571,25 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( // Sort by Significance ascending await user.click(significanceButton); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', - 'regression.html: 1.135 %, 0.12, Significant, 25.00%', - 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', + 'improvement.html: 0.963 %, -0.05, , 50.00%', + 'regression.html: 1.135 %, 0.12, , 25.00%', + 'dhtml.html: 1.135 %, 0.02, , 60.00%', 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', - 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', + 'browser.html: 0.963 %, -0.04, -, 15.00%', ]); expectParameterToHaveValue('sort', 'significance|asc'); // Sort by Effect Size descending const effectButton = screen.getByRole('button', { - name: /CLES\(%\).*sort/, + name: /CLES \(%\).*sort/, }); await user.click(effectButton); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', - 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', + 'dhtml.html: 1.135 %, 0.02, , 60.00%', + 'improvement.html: 0.963 %, -0.05, , 50.00%', 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', - 'regression.html: 1.135 %, 0.12, Significant, 25.00%', - 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', + 'regression.html: 1.135 %, 0.12, , 25.00%', + 'browser.html: 0.963 %, -0.04, -, 15.00%', ]); // It should have the "descending" SVG. @@ -600,11 +600,11 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( // Sort by Effect Size ascending await user.click(effectButton); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', - 'regression.html: 1.135 %, 0.12, Significant, 25.00%', + 'browser.html: 0.963 %, -0.04, -, 15.00%', + 'regression.html: 1.135 %, 0.12, , 25.00%', 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', - 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', - 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', + 'improvement.html: 0.963 %, -0.05, , 50.00%', + 'dhtml.html: 1.135 %, 0.02, , 60.00%', ]); expectParameterToHaveValue('sort', 'effects|asc'); }); @@ -614,40 +614,40 @@ describe('SubtestsResultsView Component Tests for mann-whitney-u testVersion', ( await screen.findByText('dhtml.html'); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', - 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', - 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', - 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', - 'regression.html: 1.135 %, 0.12, Significant, 25.00%', + 'dhtml.html: 1.135 %, 0.02, , 60.00%', + 'browser.html: 0.963 %, -0.04, -, 15.00%', + 'improvement.html: 0.963 %, -0.05, , 50.00%', + 'regression.html: 1.135 %, 0.12, , 25.00%', ]); // It should have the "ascending" SVG. - expect(screen.getByRole('button', { name: /Delta/ })).toMatchSnapshot(); + expect(screen.getByRole('button', { name: /CD/ })).toMatchSnapshot(); }); it('initializes the sort from the URL at load time for an implicit descending sort', async () => { await setupForSorting({ extraParameters: 'sort=delta' }); await screen.findByText('dhtml.html'); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'regression.html: 1.135 %, 0.12, Significant, 25.00%', - 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', - 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', - 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', + 'regression.html: 1.135 %, 0.12, , 25.00%', + 'improvement.html: 0.963 %, -0.05, , 50.00%', + 'browser.html: 0.963 %, -0.04, -, 15.00%', + 'dhtml.html: 1.135 %, 0.02, , 60.00%', 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', ]); // It should have the "descending" SVG. - expect(screen.getByRole('button', { name: /Delta/ })).toMatchSnapshot(); + expect(screen.getByRole('button', { name: /CD/ })).toMatchSnapshot(); }); it('initializes the sort from the URL at load time for a descending sort', async () => { await setupForSorting({ extraParameters: 'sort=delta|desc' }); expect(summarizeVisibleRows('mann-whitney-u')).toEqual([ - 'regression.html: 1.135 %, 0.12, Significant, 25.00%', - 'improvement.html: 0.963 %, -0.05, Significant, 50.00%', - 'browser.html: 0.963 %, -0.04, Not significant, 15.00%', - 'dhtml.html: 1.135 %, 0.02, Significant, 60.00%', + 'regression.html: 1.135 %, 0.12, , 25.00%', + 'improvement.html: 0.963 %, -0.05, , 50.00%', + 'browser.html: 0.963 %, -0.04, -, 15.00%', + 'dhtml.html: 1.135 %, 0.02, , 60.00%', 'tablemutation.html: 0.98 %, 0.01, -, 45.00%', ]); // It should have the "descending" SVG. - expect(screen.getByRole('button', { name: /Delta/ })).toMatchSnapshot(); + expect(screen.getByRole('button', { name: /CD/ })).toMatchSnapshot(); }); }); }); diff --git a/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx b/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx index 26c443e7c..d8941e030 100644 --- a/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx +++ b/src/__tests__/CompareResults/SubtestsRevisionRow.test.tsx @@ -190,11 +190,11 @@ describe('SubtestsRevisionRow Component', () => { ); const roles = await screen.findAllByRole('cell'); - const effects = roles[8]?.childNodes[0]; + const effects = roles[7]?.childNodes[0]; expect(effects).toHaveTextContent('60.00%'); - const significance = roles[7]?.childNodes[0]; - expect(significance).toHaveTextContent('Significant'); + const significanceCell = roles[8]; + expect(significanceCell?.querySelector('svg')).not.toBeNull(); const cliffs_delta = roles[6]?.childNodes[1]; expect(cliffs_delta).toHaveTextContent('0.02'); diff --git a/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap index 8f01d8e52..b8ff6f67f 100644 --- a/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap +++ b/src/__tests__/CompareResults/__snapshots__/OverTimeResultsView.test.tsx.snap @@ -311,7 +311,7 @@ exports[`Results View The table should match snapshot and other elements should
@@ -387,7 +387,7 @@ exports[`Results View The table should match snapshot and other elements should data-mui-internal-clone-element="true" >
@@ -453,7 +453,7 @@ exports[`Results View The table should match snapshot and other elements should data-mui-internal-clone-element="true" > + +
+
+ +
@@ -485,7 +517,7 @@ exports[`Results View The table should match snapshot and other elements should role="group" >
-
- - - -
-
- @@ -899,7 +899,7 @@ exports[`Results View The table should match snapshot and other elements should
-
- @@ -1098,7 +1098,7 @@ exports[`Results View The table should match snapshot and other elements should
-
- @@ -1297,7 +1297,7 @@ exports[`Results View The table should match snapshot and other elements should
-
- diff --git a/src/__tests__/CompareResults/__snapshots__/ResultsTable.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/ResultsTable.test.tsx.snap index 893e4c2ce..4380e7929 100644 --- a/src/__tests__/CompareResults/__snapshots__/ResultsTable.test.tsx.snap +++ b/src/__tests__/CompareResults/__snapshots__/ResultsTable.test.tsx.snap @@ -1204,7 +1204,7 @@ exports[`Results Table Should match snapshot 1`] = `
@@ -1280,7 +1280,7 @@ exports[`Results Table Should match snapshot 1`] = ` data-mui-internal-clone-element="true" >
@@ -1346,7 +1346,7 @@ exports[`Results Table Should match snapshot 1`] = ` data-mui-internal-clone-element="true" > + +
+
+ +
@@ -1378,7 +1410,7 @@ exports[`Results Table Should match snapshot 1`] = ` role="group" >
-
- - - -
-
- @@ -1792,7 +1792,7 @@ exports[`Results Table Should match snapshot 1`] = `
-
- @@ -1991,7 +1991,7 @@ exports[`Results Table Should match snapshot 1`] = `
-
- @@ -2271,7 +2271,7 @@ exports[`Results Table Should match snapshot 1`] = ` class="fw0pvlu" >
-
- @@ -3960,7 +3960,7 @@ exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion
@@ -4036,7 +4036,7 @@ exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion data-mui-internal-clone-element="true" >
@@ -4102,7 +4102,7 @@ exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion data-mui-internal-clone-element="true" > + +
+
+ +
@@ -4134,7 +4166,7 @@ exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion role="group" >
-
- - - -
- Not significant + 45.00 %
- 45.00 % + -
- Not significant + 25.00 %
- 25.00 % + -
- Significant + 50.00 %
- 50.00 % +
- Significant + 100.00 %
- 100.00 % +
- Not sorted by Cliff's Delta + Not sorted by CD - Cliff's Delta + CD `; exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion can sort params from the URL on mann-whitney-u test_version 2`] = ` `; exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion can sort params from the URL on mann-whitney-u test_version 3`] = ` , -] + + `; exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion should render different blocks when rendering several revisions 1`] = ` @@ -5854,7 +5875,7 @@ exports[`Results Table for MannWhitneyResultsItem for mann-whitney-u testVersion
- Not significant + 25.00 %
- 25.00 % + -
- Not significant + 25.00 %
- 25.00 % + -
@@ -1236,7 +1236,7 @@ exports[`Results View The table should match snapshot and other elements should data-mui-internal-clone-element="true" >
@@ -1302,7 +1302,7 @@ exports[`Results View The table should match snapshot and other elements should data-mui-internal-clone-element="true" > + +
+
+ +
@@ -1334,7 +1366,7 @@ exports[`Results View The table should match snapshot and other elements should role="group" >
-
- - - -
-
- @@ -1748,7 +1748,7 @@ exports[`Results View The table should match snapshot and other elements should
-
- @@ -1947,7 +1947,7 @@ exports[`Results View The table should match snapshot and other elements should
-
- @@ -2146,7 +2146,7 @@ exports[`Results View The table should match snapshot and other elements should
-
- diff --git a/src/__tests__/CompareResults/__snapshots__/SubtestsResultsView.test.tsx.snap b/src/__tests__/CompareResults/__snapshots__/SubtestsResultsView.test.tsx.snap index 6d15a26f0..15a64e285 100644 --- a/src/__tests__/CompareResults/__snapshots__/SubtestsResultsView.test.tsx.snap +++ b/src/__tests__/CompareResults/__snapshots__/SubtestsResultsView.test.tsx.snap @@ -2,7 +2,7 @@ exports[`SubtestsResultsView Component Tests for mann-whitney-u testVersion table sorting can sort the table and persist the information to the URL of mann-whitney-u values 1`] = ` `; exports[`SubtestsResultsView Component Tests for mann-whitney-u testVersion table sorting can sort the table and persist the information to the URL of mann-whitney-u values 2`] = ` `; exports[`SubtestsResultsView Component Tests for mann-whitney-u testVersion table sorting initializes the sort from the URL at load time for an ascending sort 1`] = ` `; exports[`SubtestsResultsView Component Tests for mann-whitney-u testVersion table sorting initializes the sort from the URL at load time for an implicit descending sort 1`] = ` `; @@ -838,7 +838,7 @@ exports[`SubtestsResultsView Component Tests should render the subtests results role="table" >
@@ -907,7 +907,7 @@ exports[`SubtestsResultsView Component Tests should render the subtests results data-mui-internal-clone-element="true" >
@@ -973,7 +973,7 @@ exports[`SubtestsResultsView Component Tests should render the subtests results data-mui-internal-clone-element="true" > + +
+
+ +
@@ -1005,7 +1037,7 @@ exports[`SubtestsResultsView Component Tests should render the subtests results role="group" >
-
- - - -
- - + 0.00%
- 0.00% + -
- - + 0.00%
- 0.00% + -
- - + 0.00%
- 0.00% + -
- - + 0.00%
- 0.00% + -
- - + 0.00%
- 0.00% + -
@@ -2816,7 +2816,7 @@ exports[`SubtestsViewCompareOverTime Component Tests in mann-whitney-u testVersi data-mui-internal-clone-element="true" >
@@ -2882,7 +2882,39 @@ exports[`SubtestsViewCompareOverTime Component Tests in mann-whitney-u testVersi data-mui-internal-clone-element="true" > + +
+
+ +
@@ -2914,7 +2946,7 @@ exports[`SubtestsViewCompareOverTime Component Tests in mann-whitney-u testVersi role="group" >
-
- - - -
- Not significant + 15.00%
- 15.00% + -
- Significant + 60.00%
- 60.00% +
- Significant + 50.00%
- 50.00% +
- Significant + 25.00%
- 25.00% +
- - + 45.00%
- 45.00% + -
@@ -4377,7 +4416,7 @@ exports[`SubtestsViewCompareOverTime Component Tests in mann-whitney-u testVersi data-mui-internal-clone-element="true" >
@@ -4443,7 +4482,39 @@ exports[`SubtestsViewCompareOverTime Component Tests in mann-whitney-u testVersi data-mui-internal-clone-element="true" > + +
+
+ +
@@ -4475,7 +4546,7 @@ exports[`SubtestsViewCompareOverTime Component Tests in mann-whitney-u testVersi role="group" > - -
-
- @@ -4580,7 +4619,7 @@ exports[`SubtestsViewCompareOverTime Component Tests in mann-whitney-u testVersi />
- Not significant + 15.00%
- 15.00% + -
- Significant + 60.00%
- 60.00% +
- Significant + 50.00%
- 50.00% +
- Significant + 25.00%
- 25.00% +
- - + 45.00%
- 45.00% + -
@@ -5938,7 +6016,7 @@ exports[`SubtestsViewCompareOverTime Component Tests renders over-time view when data-mui-internal-clone-element="true" >
@@ -6004,7 +6082,7 @@ exports[`SubtestsViewCompareOverTime Component Tests renders over-time view when data-mui-internal-clone-element="true" > + +
+
+ +
@@ -6036,7 +6146,7 @@ exports[`SubtestsViewCompareOverTime Component Tests renders over-time view when role="group" >
-
- - - -
- Not significant + 15.00%
- 15.00% + -
- Significant + 60.00%
- 60.00% +
- Significant + 50.00%
- 50.00% +
- Significant + 25.00%
- 25.00% +
- - + 45.00%
- 45.00% + -
@@ -7499,7 +7616,7 @@ exports[`SubtestsViewCompareOverTime Component Tests should render the subtests data-mui-internal-clone-element="true" >
@@ -7565,7 +7682,7 @@ exports[`SubtestsViewCompareOverTime Component Tests should render the subtests data-mui-internal-clone-element="true" > + +
+
+ +
@@ -7597,7 +7746,7 @@ exports[`SubtestsViewCompareOverTime Component Tests should render the subtests role="group" >
-
- - - -
- - + 0.00%
- 0.00% + -
- - + 0.00%
- 0.00% + -
- - + 0.00%
- 0.00% + -
- - + 0.00%
- 0.00% + -
- - + 0.00%
- 0.00% + -
key === valueKey?.toLowerCase(), - )?.label; - return ( - result.mann_whitney_test?.interpretation === label?.toLowerCase() - ); - }, + name: 'CLES (%)', + key: 'effects', + gridWidth: '1.25fr', sortFunction( resultA: MannWhitneyResultsItem, resultB: MannWhitneyResultsItem, ) { return ( - Math.abs(resultA.mann_whitney_test?.pvalue ?? 0) - - Math.abs(resultB.mann_whitney_test?.pvalue ?? 0) + Math.abs(resultA.cles?.cles ?? 0) - + Math.abs(resultB.cles?.cles ?? 0) ); }, + tooltip: tooltipEffectSize, }, { - name: 'CLES(%)', - key: 'effects', + name: 'Sig', + key: 'significance', + filter: true, gridWidth: '1.25fr', + tooltip: tooltipSignificance, + possibleValues: [ + { + label: 'Significant', + key: 'significant', + icon: , + }, + { + label: 'Not Significant', + key: 'not significant', + icon:
-
, + }, + ], + matchesFunction(result: MannWhitneyResultsItem, valueKey: string) { + return result.mann_whitney_test?.interpretation === valueKey; + }, sortFunction( resultA: MannWhitneyResultsItem, resultB: MannWhitneyResultsItem, ) { return ( - Math.abs(resultA.cles?.cles ?? 0) - - Math.abs(resultB.cles?.cles ?? 0) + Math.abs(resultA.mann_whitney_test?.pvalue ?? 0) - + Math.abs(resultB.mann_whitney_test?.pvalue ?? 0) ); }, - tooltip: tooltipEffectSize, }, + { name: 'Total Trials', key: 'trials', @@ -269,9 +274,6 @@ export const mannWhitneyStrategy = { base_app: baseApp, new_app: newApp, } = result as MannWhitneyResultsItem; - const mann_whitney_interpretation = mann_whitney_test?.interpretation - ? capitalize(mann_whitney_test.interpretation) - : '-'; const clesVal = ((cles?.cles ?? 0) * 100).toFixed(2); const baseAvgValue = (result as MannWhitneyResultsItem).base_standard_stats?.mean ?? 0; @@ -355,12 +357,17 @@ export const mannWhitneyStrategy = { {' '} {cliffs_delta || '-'}
-
- {mann_whitney_interpretation} -
+
{clesVal ? `${clesVal}% ` : '-'}
+
+ {mann_whitney_test?.interpretation === 'significant' ? ( + + ) : ( + '-' + )} +
); }, @@ -480,14 +487,16 @@ export const mannWhitneyStrategy = {
{cliffs_delta || '-'}
-
- {mann_whitney_test?.interpretation - ? capitalize(mann_whitney_test.interpretation) - : '-'} -
{clesValue}
+
+ {mann_whitney_test?.interpretation === 'significant' ? ( + + ) : ( + '-' + )} +
); }, diff --git a/src/components/CompareResults/ResultsTable.tsx b/src/components/CompareResults/ResultsTable.tsx index 4ccf0a0d8..0fbedaf33 100644 --- a/src/components/CompareResults/ResultsTable.tsx +++ b/src/components/CompareResults/ResultsTable.tsx @@ -14,7 +14,10 @@ import useRawSearchParams from '../../hooks/useRawSearchParams'; import useTableFilters from '../../hooks/useTableFilters'; import useTableSort from '../../hooks/useTableSort'; import { Framework, TestVersion } from '../../types/types'; -import { getColumnsConfiguration } from '../../utils/rowTemplateColumns'; +import { + getColumnsConfiguration, + toGridTemplateColumns, +} from '../../utils/rowTemplateColumns'; type CombinedLoaderReturnValue = LoaderReturnValue | OverTimeLoaderReturnValue; export default function ResultsTable() { @@ -76,9 +79,7 @@ export default function ResultsTable() { setSearchParams(searchParams); }; - const rowGridTemplateColumns = columnsConfig - .map((config) => config.gridWidth) - .join(' '); + const rowGridTemplateColumns = toGridTemplateColumns(columnsConfig); return ( diff --git a/src/components/CompareResults/RevisionRow.tsx b/src/components/CompareResults/RevisionRow.tsx index b912fd086..d33982f91 100644 --- a/src/components/CompareResults/RevisionRow.tsx +++ b/src/components/CompareResults/RevisionRow.tsx @@ -67,7 +67,6 @@ const revisionRow = style({ '.significance': { gap: '10px', justifyContent: 'center', - paddingInlineStart: '15%', }, '.expand-button-container': { justifyContent: 'right', diff --git a/src/components/CompareResults/SubtestsResults/SubtestsRevisionRow.tsx b/src/components/CompareResults/SubtestsResults/SubtestsRevisionRow.tsx index 0a882525e..e3046385a 100644 --- a/src/components/CompareResults/SubtestsResults/SubtestsRevisionRow.tsx +++ b/src/components/CompareResults/SubtestsResults/SubtestsRevisionRow.tsx @@ -33,18 +33,12 @@ const revisionRow = style({ }, '.significance': { gap: '10px', - justifyContent: 'left', + justifyContent: 'center', }, '.subtests': { borderRadius: '4px 0 0 4px', paddingLeft: Spacing.Medium, // Synchronize with its header justifyContent: 'left', - whiteSpace: 'nowrap', - overflow: 'hidden', - textOverflow: 'ellipsis', - }, - '.subtests-mannwhitney': { - maxWidth: '150px', }, '.status': { @@ -98,7 +92,6 @@ const typography = style({ fontStyle: 'normal', fontWeight: 400, fontSize: '16px', - whiteSpace: 'nowrap', lineHeight: '1.5', }); diff --git a/src/components/CompareResults/TableHeader.tsx b/src/components/CompareResults/TableHeader.tsx index 94ea349c9..6e6c55490 100644 --- a/src/components/CompareResults/TableHeader.tsx +++ b/src/components/CompareResults/TableHeader.tsx @@ -26,6 +26,7 @@ import type { CompareResultsTableColumn, CompareMannWhitneyResultsTableConfig, } from '../../types/types'; +import { toGridTemplateColumns } from '../../utils/gridTemplateColumns'; function SortDirectionIcon({ columnName, @@ -180,7 +181,23 @@ function FilterableColumnHeader({ sx={{ padding: 0 }} /> - + + {possibleValue.label} + {possibleValue.icon} + + ) : ( + possibleValue.label + ) + } + /> ); })} @@ -283,9 +300,7 @@ function TableHeader({ tableHeader: style({ display: 'grid', // Should be kept in sync with the gridTemplateColumns from RevisionRow - gridTemplateColumns: columnsConfiguration - .map((config) => config.gridWidth) - .join(' '), + gridTemplateColumns: toGridTemplateColumns(columnsConfiguration), background: themeMode == 'light' ? Colors.Background100 : Colors.Background300Dark, borderRadius: '4px', diff --git a/src/types/types.ts b/src/types/types.ts index d54d77ecb..18dde35ea 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -25,7 +25,7 @@ interface FilterableColumnMixin { // Always true for filterable columns. filter: true; // All values this column might have. - possibleValues: Array<{ label: string; key: string }>; + possibleValues: Array<{ label: string; key: string; icon?: React.ReactNode }>; // This function returns whether this result matches the value for this column. matchesFunction: ( this: FilterableColumnMixin, @@ -39,7 +39,7 @@ interface FilterableMannWhitneyColumnMixin { // Always true for filterable columns. filter: true; // All values this column might have. - possibleValues: Array<{ label: string; key: string }>; + possibleValues: Array<{ label: string; key: string; icon?: React.ReactNode }>; // This function returns whether this result matches the value for this column. matchesFunction: ( this: FilterableMannWhitneyColumnMixin, @@ -118,7 +118,7 @@ interface FilterableColumnGenericMixin< // Always true for filterable columns. filter: true; // All values this column might have. - possibleValues: Array<{ label: string; key: string }>; + possibleValues: Array<{ label: string; key: string; icon?: React.ReactNode }>; // Returns whether the given result row matches the selected filter value for // this column. "this" is typed so the function can access other column // properties (e.g. possibleValues) if needed. diff --git a/src/utils/gridTemplateColumns.ts b/src/utils/gridTemplateColumns.ts new file mode 100644 index 000000000..08dbdce00 --- /dev/null +++ b/src/utils/gridTemplateColumns.ts @@ -0,0 +1,11 @@ +// Builds a CSS grid-template-columns string from a columns config. +// Uses minmax(0, Xfr) for fr tracks so that min-content of individual cells +// (e.g. header button groups vs icon-only cells) cannot expand a track beyond +// its fr allocation across separate grid instances. +export function toGridTemplateColumns(config: { gridWidth: string }[]): string { + return config + .map(({ gridWidth }) => + gridWidth.endsWith('fr') ? `minmax(0, ${gridWidth})` : gridWidth, + ) + .join(' '); +} diff --git a/src/utils/rowTemplateColumns.ts b/src/utils/rowTemplateColumns.ts index bcf810efb..1caa4d4a1 100644 --- a/src/utils/rowTemplateColumns.ts +++ b/src/utils/rowTemplateColumns.ts @@ -12,3 +12,5 @@ export const getColumnsConfiguration = ( isSubtestTable: boolean, testVersion: TestVersion, ): TableConfig => getColumnsForVersion(testVersion, isSubtestTable); + +export { toGridTemplateColumns } from './gridTemplateColumns';