From 9b6caac723943386610fe60a461b4fa95be76dad Mon Sep 17 00:00:00 2001 From: Jonas Earendel Date: Sun, 17 Nov 2024 21:09:37 +0900 Subject: [PATCH 01/12] playwright tests work! --- .gitignore | 25 +- .prettierrc.js => .prettierrc.cjs | 4 +- CHANGELOG.md | 21 +- CODE_OF_CONDUCT.md | 46 - CONTRIBUTING.md | 4 +- README.md | 4 +- babel.config.js | 10 - .../esm/enhanceSortableAccessibility.d.ts | 2 +- dist/esm/enhanceSortableAccessibility.js | 44 + .../esm/enhanceSortableAccessibility.min.js | 0 dist/esm/sortSortable.d.ts | 7 + dist/esm/sortSortable.js | 47 + dist/esm/sortSortable.min.js | 1 + .../esm/sortable.a11y.d.ts | 0 dist/esm/sortable.a11y.js | 4 + dist/esm/sortable.a11y.min.js | 1 + sortable.d.ts => dist/esm/sortable.d.ts | 5 +- dist/esm/sortable.js | 2 + dist/esm/sortable.min.js | 2 + dist/esm/sortable.test.d.ts | 1 + dist/esm/sortableEventListener.d.ts | 1 + dist/esm/sortableEventListener.js | 38 + dist/esm/sortableEventListener.min.js | 2 + example.css => dist/example.css | 10 +- dist/example.min.css | 1 + sortable-base.css => dist/sortable-base.css | 4 +- .../sortable-base.min.css | 2 +- dist/sortable.a11y.js | 44 + .../sortable.a11y.min.js | 0 sortable.css => dist/sortable.css | 9 +- dist/sortable.js | 41 + sortable.min.css => dist/sortable.min.css | 2 +- dist/sortable.min.js | 4 + dist/standalone/sortable.a11y.js | 44 + dist/standalone/sortable.a11y.min.js | 2 + dist/standalone/sortable.js | 79 + dist/standalone/sortable.min.js | 4 + enhanceSortableAccessibility.js | 68 - eslint.config.js | 23 +- example.css.map | 1 - example.min.css | 1 - example.min.css.map | 1 - index.html | 352 +- jest.config.js | 5 - package.json | 109 +- playwright.config.ts | 28 + pnpm-lock.yaml | 4218 +++++++++-------- rollup.config.js | 119 +- scripts/compile.ts | 56 + scripts/prepare-tests.ts | 73 + scripts/prepare.ts | 4 +- sortable-base.css.map | 1 - sortable-base.min.css.map | 1 - sortable.a11y.js | 71 - sortable.css.map | 1 - sortable.js | 122 - sortable.min.css.map | 1 - sortable.min.js | 3 - src/enhanceSortableAccessibility.ts | 6 +- src/{ => scss}/example.scss | 4 +- src/{ => scss}/sortable-base.scss | 8 +- src/{ => scss}/sortable.scss | 12 +- src/sortSortable.ts | 69 + src/sortable.test.html | 200 - src/{sortable.test.js => sortable.test.ts} | 257 +- src/sortable.ts | 108 +- src/sortableEventListener.ts | 58 + src/vite-env.d.ts | 1 + tests/formats/bundled.spec.ts | 11 + tests/formats/esm.spec.ts | 11 + tests/formats/standalone.spec.ts | 11 + tests/sortable-test-base.ts | 357 ++ tests/sortable.spec.txt | 324 ++ tsconfig.json | 35 +- vite.config.js | 139 + 75 files changed, 4255 insertions(+), 3131 deletions(-) rename .prettierrc.js => .prettierrc.cjs (76%) delete mode 100755 CODE_OF_CONDUCT.md delete mode 100644 babel.config.js rename enhanceSortableAccessibility.d.ts => dist/esm/enhanceSortableAccessibility.d.ts (87%) create mode 100644 dist/esm/enhanceSortableAccessibility.js rename enhanceSortableAccessibility.min.js => dist/esm/enhanceSortableAccessibility.min.js (100%) create mode 100644 dist/esm/sortSortable.d.ts create mode 100644 dist/esm/sortSortable.js create mode 100644 dist/esm/sortSortable.min.js rename sortable.a11y.d.ts => dist/esm/sortable.a11y.d.ts (100%) create mode 100644 dist/esm/sortable.a11y.js create mode 100644 dist/esm/sortable.a11y.min.js rename sortable.d.ts => dist/esm/sortable.d.ts (95%) create mode 100644 dist/esm/sortable.js create mode 100644 dist/esm/sortable.min.js create mode 100644 dist/esm/sortable.test.d.ts create mode 100644 dist/esm/sortableEventListener.d.ts create mode 100644 dist/esm/sortableEventListener.js create mode 100644 dist/esm/sortableEventListener.min.js rename example.css => dist/example.css (97%) create mode 100644 dist/example.min.css rename sortable-base.css => dist/sortable-base.css (95%) rename sortable-base.min.css => dist/sortable-base.min.css (89%) create mode 100644 dist/sortable.a11y.js rename sortable.a11y.min.js => dist/sortable.a11y.min.js (100%) rename sortable.css => dist/sortable.css (96%) create mode 100644 dist/sortable.js rename sortable.min.css => dist/sortable.min.css (66%) create mode 100644 dist/sortable.min.js create mode 100644 dist/standalone/sortable.a11y.js create mode 100644 dist/standalone/sortable.a11y.min.js create mode 100644 dist/standalone/sortable.js create mode 100644 dist/standalone/sortable.min.js delete mode 100644 enhanceSortableAccessibility.js delete mode 100644 example.css.map delete mode 100644 example.min.css delete mode 100644 example.min.css.map mode change 100755 => 100644 index.html delete mode 100644 jest.config.js create mode 100644 playwright.config.ts create mode 100644 scripts/compile.ts create mode 100644 scripts/prepare-tests.ts delete mode 100644 sortable-base.css.map delete mode 100644 sortable-base.min.css.map delete mode 100644 sortable.a11y.js delete mode 100644 sortable.css.map delete mode 100644 sortable.js delete mode 100644 sortable.min.css.map delete mode 100644 sortable.min.js rename src/{ => scss}/example.scss (95%) rename src/{ => scss}/sortable-base.scss (88%) rename src/{ => scss}/sortable.scss (83%) create mode 100644 src/sortSortable.ts delete mode 100644 src/sortable.test.html rename src/{sortable.test.js => sortable.test.ts} (52%) create mode 100644 src/sortableEventListener.ts create mode 100644 src/vite-env.d.ts create mode 100644 tests/formats/bundled.spec.ts create mode 100644 tests/formats/esm.spec.ts create mode 100644 tests/formats/standalone.spec.ts create mode 100644 tests/sortable-test-base.ts create mode 100644 tests/sortable.spec.txt create mode 100644 vite.config.js diff --git a/.gitignore b/.gitignore index 7ec9f92..567566d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,26 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + node_modules +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea .DS_Store -._* \ No newline at end of file +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +test-results +playwright-report \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.cjs similarity index 76% rename from .prettierrc.js rename to .prettierrc.cjs index 24df7e8..6142589 100644 --- a/.prettierrc.js +++ b/.prettierrc.cjs @@ -1,7 +1,7 @@ module.exports = { singleQuote: true, semi: false, - trailingComma: 'all', + trailingComma: "all", tabWidth: 2, printWidth: 120, -} +}; diff --git a/CHANGELOG.md b/CHANGELOG.md index c1de75d..46bfd47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [4.0.0] - 2024-11-15 + +### Breaking Changes + +- Built files are now located in the `/dist` directory +- Update your references from: + - `sortable.min.js` to `dist/sortable.min.js` + - `sortable.a11y.min.js` to `dist/sortable.a11y.min.js` + - etc. + +### Added + +- `setTimeout` lets double-click "re-sort" the table only once +- `sort-start` and `sort-end` events +- `dist/standalone` folder where all files are inlined, in case you want the functions to be available in the global scope + ## [3.2.3] - 2024-05-08 ### Changed @@ -138,10 +154,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - First release -## Acknowledgments - -This CHANGELOG.md was generated with the assistance of [ChatGPT by OpenAI](https://www.openai.com/research/chatgpt). - +[4.0.0]: https://github.com/tofsjonas/sortable/releases/tag/4.0.0 [3.2.3]: https://github.com/tofsjonas/sortable/releases/tag/3.2.3 [3.2.2]: https://github.com/tofsjonas/sortable/releases/tag/3.2.2 [3.2.1]: https://github.com/tofsjonas/sortable/releases/tag/3.2.1 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100755 index b2e87d7..0000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,46 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at jonas@earendel.se. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 89ad019..7714ba0 100755 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,5 @@ + # Contributing -I am grateful for any and all contributions. +I am grateful for any and all contributions. 😀 -If it's a minor thing I guess it's easier to open an issue, but if you prefer creating a fork, go ahead! :) diff --git a/README.md b/README.md index 885f17e..2a925cf 100755 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ You can find a simple demo on ## Factoids -- **1148 bytes** minified. (619 bytes gzipped) +- **1.02 KB** minified. (790 bytes gzipped) - Works with **JavaScript generated tables**. (since we are using an eventListener) @@ -82,7 +82,7 @@ There are three ways to use sortable, all of which have their pros and cons. [S Rick - Sidekick + Sidekick Morty diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index 8fb20b9..0000000 --- a/babel.config.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - presets: [ - [ - '@babel/preset-env', - { - targets: '> 0.25%, not dead', - }, - ], - ], -} diff --git a/enhanceSortableAccessibility.d.ts b/dist/esm/enhanceSortableAccessibility.d.ts similarity index 87% rename from enhanceSortableAccessibility.d.ts rename to dist/esm/enhanceSortableAccessibility.d.ts index 842df01..522b201 100644 --- a/enhanceSortableAccessibility.d.ts +++ b/dist/esm/enhanceSortableAccessibility.d.ts @@ -6,4 +6,4 @@ * Enhances the accessibility of class="sortable" tables by adding ARIA attributes and keyboard event listeners. * @param tables - A list of HTML table elements to enhance. */ -export declare const enhanceSortableAccessibility: (tables: NodeListOf) => void; +export declare const enhanceSortableAccessibility: (tables: NodeListOf | HTMLTableElement[]) => void; diff --git a/dist/esm/enhanceSortableAccessibility.js b/dist/esm/enhanceSortableAccessibility.js new file mode 100644 index 0000000..2895130 --- /dev/null +++ b/dist/esm/enhanceSortableAccessibility.js @@ -0,0 +1,44 @@ +var enhanceSortableAccessibility = function(tables) { + function updateAriaLabel(element, default_direction) { + var _a; + if (default_direction === void 0) { + default_direction = ""; + } + var header_text = element.textContent || "element"; + var current_direction = (_a = element.getAttribute("aria-sort")) !== null && _a !== void 0 ? _a : ""; + var new_direction = "descending"; + if (current_direction === "descending" || default_direction && current_direction !== "ascending") { + new_direction = "ascending"; + } + var aria_label = "Click to sort table by ".concat(header_text, " in ").concat(new_direction, " order"); + element.setAttribute("aria-label", aria_label); + } + function handleKeyDown(event) { + if (event.key === "Enter") { + var element = event.target; + element.click(); + } + } + tables.forEach(function(table) { + var default_direction = table.classList.contains("asc") ? "ascending" : ""; + var headers = table.querySelectorAll("th"); + headers.forEach(function(header) { + var element = header; + if (element.hasAttribute("tabindex")) + return; + var update = function() { + updateAriaLabel(element, default_direction); + }; + element.setAttribute("tabindex", "0"); + update(); + element.addEventListener("click", function() { + setTimeout(update, 50); + }); + element.addEventListener("focus", update); + element.addEventListener("keydown", handleKeyDown); + }); + }); +}; +export { + enhanceSortableAccessibility +}; diff --git a/enhanceSortableAccessibility.min.js b/dist/esm/enhanceSortableAccessibility.min.js similarity index 100% rename from enhanceSortableAccessibility.min.js rename to dist/esm/enhanceSortableAccessibility.min.js diff --git a/dist/esm/sortSortable.d.ts b/dist/esm/sortSortable.d.ts new file mode 100644 index 0000000..16aa43f --- /dev/null +++ b/dist/esm/sortSortable.d.ts @@ -0,0 +1,7 @@ +/** + * Sorts a sortable table. + * + * @param table - The HTMLTableElement to be sorted. + * @param alt_sort - A boolean indicating whether to use alternative sorting. + */ +export declare function sortSortable(table: HTMLTableElement, alt_sort: boolean): void; diff --git a/dist/esm/sortSortable.js b/dist/esm/sortSortable.js new file mode 100644 index 0000000..e8d8e42 --- /dev/null +++ b/dist/esm/sortSortable.js @@ -0,0 +1,47 @@ +function sortSortable(table, alt_sort) { + table.dispatchEvent(new Event("sort-start", { bubbles: true })); + var null_last_class = "n-last"; + var th = table.tHead.querySelector("th[aria-sort]"); + var th_row = table.tHead.children[0]; + var direction = th.getAttribute("aria-sort"); + var reverse = direction === "ascending"; + var sort_null_last = table.classList.contains(null_last_class); + function getValue(element) { + var _a; + var value = alt_sort ? element.dataset.sortAlt : (_a = element.dataset.sort) !== null && _a !== void 0 ? _a : element.textContent; + return value; + } + var compare = function(a, b, index) { + var x = getValue(b.cells[index]); + var y = getValue(a.cells[index]); + if (sort_null_last) { + if (x === "" && y !== "") { + return -1; + } + if (y === "" && x !== "") { + return 1; + } + } + var temp = +x - +y; + var bool = isNaN(temp) ? x.localeCompare(y) : temp; + if (bool === 0 && th_row.cells[index] && th_row.cells[index].hasAttribute("data-sort-tbr")) { + return compare(a, b, +th_row.cells[index].dataset.sortTbr); + } + return reverse ? -bool : bool; + }; + for (var i = 0; i < table.tBodies.length; i++) { + var org_tbody = table.tBodies[i]; + var rows = [].slice.call(org_tbody.rows, 0); + rows.sort(function(a, b) { + var _a; + return compare(a, b, +((_a = th.dataset.sortCol) !== null && _a !== void 0 ? _a : th.cellIndex)); + }); + var clone_tbody = org_tbody.cloneNode(); + clone_tbody.append.apply(clone_tbody, rows); + table.replaceChild(clone_tbody, org_tbody); + } + table.dispatchEvent(new Event("sort-end", { bubbles: true })); +} +export { + sortSortable +}; diff --git a/dist/esm/sortSortable.min.js b/dist/esm/sortSortable.min.js new file mode 100644 index 0000000..4bb29fa --- /dev/null +++ b/dist/esm/sortSortable.min.js @@ -0,0 +1 @@ +function t(t,e){t.dispatchEvent(new Event('sort-start',{bubbles:!0}));var r=t.tHead.querySelector('th[aria-sort]'),a=t.tHead.children[0],s='ascending'===r.getAttribute('aria-sort'),l=t.classList.contains('n-last');function n(t){var r;return e?t.dataset.sortAlt:null!==(r=t.dataset.sort)&&void 0!==r?r:t.textContent}for(var o=function(t,e,r){var i=n(e.cells[r]),c=n(t.cells[r]);if(l){if(''===i&&''!==c)return-1;if(''===c&&''!==i)return 1}var d=+i-+c,u=isNaN(d)?i.localeCompare(c):d;return 0===u&&a.cells[r]&&a.cells[r].hasAttribute('data-sort-tbr')?o(t,e,+a.cells[r].dataset.sortTbr):s?-u:u},i=0;i * */ +export {}; diff --git a/dist/esm/sortable.js b/dist/esm/sortable.js new file mode 100644 index 0000000..4eae3e1 --- /dev/null +++ b/dist/esm/sortable.js @@ -0,0 +1,2 @@ +import { sortableEventListener } from "./sortableEventListener.js"; +document.addEventListener("click", sortableEventListener); diff --git a/dist/esm/sortable.min.js b/dist/esm/sortable.min.js new file mode 100644 index 0000000..34c032b --- /dev/null +++ b/dist/esm/sortable.min.js @@ -0,0 +1,2 @@ +document.addEventListener('click',(function(t){try{var e=t.shiftKey||t.altKey,a=function t(e,a){return e.nodeName===a?e:t(e.parentNode,a)}(t.target,'TH'),r=a.parentNode,n=r.parentNode,s=n.parentNode;if('THEAD'===n.nodeName&&// sortable only triggered in `thead` +s.classList.contains('sortable')&&!a.classList.contains('no-sort')){for(var i=r.cells,o=0;o - - - - - - sortable - the example page - + + + + sortable test + - - -

Demos

- Here are some basic demos for the tiny table sorter found on - https://github.com/tofsjonas/sortable -

Table with three <tbody/>, sorted separately:

+

Sortable examples

+ +

Basic sort

@@ -33,31 +28,78 @@

Table with three <tbody/>, sorted separately:

- +
Morty
+ +

Tiebreaker

+

Sort by year

+ + + - - + + + + + + - - + + + + + + + + + + + + + + + + - +
GeniusRickMonthYearDayTime
SidekickMorty1120102512:00
1120102515:00
0420101213:00
+
    +
  • If year is the same, sort by month.
  • +
  • If month is the same, sort by day.
  • +
  • If day is the same, sort by time
  • +
+ +

Colspans

+ + + - - + + + + - - + + + + + + + + + + + + +
GeniusRicknums + charsCHARS
SidekickMorty333222BB
1111CCC
22333A
-

An example with arrows on the left side:

+

Empty/null sorted last

- +
@@ -74,267 +116,103 @@

An example with arrows on the left side:

- - + + - - - - -
Text 0
ghishould be sorted last(if click in this column)
def 0.2
tfoot is independent
- - - -

Using the data-sort attribute

- -

Here 1.5GB has data-sort="1610612736" and 900MB has data-sort="943718400"

-

- The same with the dates. 03/18/2021 is turned into data-sort="20210318" and 12/09/1965 into - data-sort="19651209" -

-

Otherwise the sorting would be wrong.

- +

class="no-sort"

+
- - - + + - - - + + - - - + +
Movie NameSizeRelease dateRoleName
The Sound of Music1.5GB12/09/1965GeniusRick
Zack Snyder's Justice League900MB03/18/2021SidekickMorty
-

Slightly larger

- -

"Ram" has class="no-sort"

-

"Screen width" has the "css only" way of disabling sorting, using the property "pointer-events: none;"

- +

numeric sorting

- - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - + + + + - - - - - - - - - - - - + + + + -
personalhardwaresoftware
job titlenamecompanyprocessorram(not sortable)graphics cardscreen widthscreen heightplatformbrowserbrowser versionlanguageRoleTimeAmountNumber
BossStan the ManMonsters IncAMD2Nvidia1510981Win32IE11en-us
StevedoreBridget JonesThe Handi78gb-15301080Linux x86_64Firefox54sv-seGenius12:00:12$18.492.49
HRBruce WayneLeague of Shadowsi5-GeForce15201080Linux x86_64Opera46dkSidekick12:22:11$2.4918.49
ProgrammerBilbo BagginsBrotherhood of Evil Mutantsi34 gigabyte-1301080Linux x86_64Opera46enButler12:22:05$1.961.96
-

Even larger table (with ascending sort)

+

Ascending sort

- +
- - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - + + -
personalhardwaresoftware
job titlenamecompanyprocessorramgraphics cardscreen widthscreen heightplatformbrowserbrowser versionlanguageRoleName
BossStan the ManMonsters IncAMD2Nvidia1510981Win32IE11en-us
SlaveBridget JonesThe Handi78gb-15301080Linux x86_64Firefox54sv-se
HRBruce WayneLeague of Shadowsi5-GeForce15201080Linux x86_64Opera46dkGeniusRick
ProgrammerBilbo BagginsBrotherhood of Evil Mutantsi34 gigabyte-1301080Linux x86_64Opera46enSidekickMorty
- - - + + + diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index 9e08d25..0000000 --- a/jest.config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - clearMocks: true, - // setupFilesAfterEnv: ['regenerator-runtime/runtime'], - testPathIgnorePatterns: ['/node_modules/'], -} diff --git a/package.json b/package.json index 6cbe32d..c4a9e4e 100644 --- a/package.json +++ b/package.json @@ -1,72 +1,67 @@ { "name": "sortable-tablesort", - "version": "3.2.3", + "version": "4.0.0", "description": "A tiny, Vanilla/Plain JavaScript table sorter", - "author": "Jonas Earendel", - "license": "Unlicense", - "homepage": "https://github.com/tofsjonas/sortable", - "repository": { - "type": "git", - "url": "git+https://github.com/tofsjonas/sortable.git" - }, - "main": "sortable.min.js", - "module": "sortable.min.js", - "style": "sortable.min.css", - "sass": "src/sortable.scss", - "keywords": [ - "sort", - "html", - "table", - "plain", - "vanilla", - "javascript" - ], - "scripts": { - "build": "npm run compile && npm run sass", - "compile": "npm run compile:sortable && npm run compile:a11y", - "compile:a11y": "google-closure-compiler --js=./sortable.a11y.js --js_output_file=./sortable.a11y.min.js", - "compile:sortable": "google-closure-compiler --js=./sortable.js --js_output_file=./sortable.min.js", - "dev": "rollup --config --watch --environment NODE_ENV:development --bundleConfigAsCjs", - "lint": "eslint './src/*.ts'", - "prepare": "ts-node ./scripts/prepare.ts", - "pre-push": "npm run build && npm run lint && npm run test && npm run test:min", - "sass": "npm run sass:dist && npm run sass:dist:minify", - "sass:dist": "sass src/sortable.scss:sortable.css src/example.scss:example.css src/sortable-base.scss:sortable-base.css", - "sass:dist:minify": "sass src/sortable.scss:sortable.min.css src/example.scss:example.min.css src/sortable-base.scss:sortable-base.min.css --style compressed", - "test": "jest", - "test:min": "cross-env USE_MINIFIED=true jest", - "test:watch": "jest --watchAll" - }, + "private": true, + "type": "module", + "main": "dist/sortable.min.js", + "module": "dist/esm/sortable.min.js", + "style": "dist/sortable.min.css", + "sass": "src/scss/sortable.scss", "files": [ "./src", - "./sortable*.*", + "./dist", "./CHANGELOG.md" ], + "scripts": { + "clean": "rimraf dist/*", + "build": "npm run clean && vite build --mode module && vite build --mode standalone && vite build --mode standalone-a11y && vite build --mode bundle && vite build --mode bundle-a11y && rollup -c", + "compile": "tsx ./scripts/compile.ts dist dist/standalone", + "lint": "eslint './src/*.ts'", + "_prepare": "tsx ./scripts/prepare.ts", + "pre-push": "npm run build && npm run compile && npm run lint && npm run test && npm run test:min", + "dev": "vite", + "prepare:tests": "tsx scripts/prepare-tests.ts", + "test": "npm run prepare:tests && playwright test || (exit_code=$?; npm run cleanup:tests; exit $exit_code)", + "cleanup:tests": "tsx scripts/prepare-tests.ts cleanup", + "test:e2e:ui": "playwright test --ui", + "serve": "vite preview --port 3009", + "test_old": "vitest", + "test:min": "cross-env USE_MINIFIED=true vitest" + }, "devDependencies": { - "@babel/core": "^7.24.5", - "@babel/preset-env": "^7.24.5", - "@eslint/js": "^9.2.0", + "@eslint/js": "^9.14.0", + "@playwright/test": "^1.48.2", "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^11.1.6", - "@testing-library/dom": "^10.1.0", - "@testing-library/jest-dom": "^6.4.5", - "@types/node": "^20.12.11", - "@typescript-eslint/eslint-plugin": "^7.9.0", - "@typescript-eslint/parser": "^7.9.0", + "@rollup/plugin-typescript": "^12.1.1", + "@testing-library/dom": "^10.4.0", + "@testing-library/jest-dom": "^6.6.3", + "@types/jsdom": "^21.1.7", + "@types/node": "^22.9.0", + "@typescript-eslint/eslint-plugin": "^8.13.0", + "@typescript-eslint/parser": "^8.13.0", + "autoprefixer": "^10.4.20", "babel-jest": "^29.7.0", "cross-env": "^7.0.3", - "eslint": "^9.2.0", + "esbuild": "^0.24.0", + "eslint": "^9.14.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.1.3", - "globals": "^15.2.0", + "eslint-plugin-prettier": "^5.2.1", "google-closure-compiler": "^20240317.0.0", - "husky": "^9.0.11", + "husky": "^9.1.6", "jest": "^29.7.0", - "jsdom": "^24.0.0", - "prettier": "^3.2.5", - "rollup": "^4.17.2", - "sass": "^1.77.1", - "ts-node": "^10.9.2", - "typescript": "^5.4.5" - } + "jsdom": "^25.0.1", + "postcss": "^8.4.47", + "prettier": "^3.3.3", + "rimraf": "^6.0.1", + "rollup": "^4.24.4", + "rollup-plugin-scss": "^4.0.0", + "sass": "^1.80.6", + "tslib": "^2.8.1", + "tsx": "^4.19.2", + "typescript": "^5.6.3", + "vite": "^5.4.10", + "vitest": "^2.1.4" + }, + "packageManager": "pnpm@9.13.2" } diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..b7dcd6f --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,28 @@ +import { defineConfig } from '@playwright/test' + +export default defineConfig({ + webServer: { + command: 'vite preview --port 3008', + port: 3008, + reuseExistingServer: !process.env.CI, + }, + testDir: './tests', + projects: [ + { + name: 'chromium', + use: { browserName: 'chromium' }, + }, + ], + workers: process.env.CI ? 1 : undefined, + fullyParallel: true, + timeout: 30000, + reporter: [['list'], ['html']], + use: { + baseURL: 'http://localhost:3008', + contextOptions: { + reducedMotion: 'reduce', + }, + // Retry on CI only + // retries: process.env.CI ? 2 : 0, + }, +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9d58842..0099ac6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,253 +8,167 @@ importers: .: devDependencies: - '@babel/core': - specifier: ^7.24.5 - version: 7.24.5 - '@babel/preset-env': - specifier: ^7.24.5 - version: 7.24.5(@babel/core@7.24.5) '@eslint/js': - specifier: ^9.2.0 - version: 9.2.0 + specifier: ^9.14.0 + version: 9.14.0 + '@playwright/test': + specifier: ^1.48.2 + version: 1.48.2 '@rollup/plugin-terser': specifier: ^0.4.4 - version: 0.4.4(rollup@4.17.2) + version: 0.4.4(rollup@4.27.0) '@rollup/plugin-typescript': - specifier: ^11.1.6 - version: 11.1.6(rollup@4.17.2)(tslib@2.6.2)(typescript@5.4.5) + specifier: ^12.1.1 + version: 12.1.1(rollup@4.27.0)(tslib@2.8.1)(typescript@5.6.3) '@testing-library/dom': - specifier: ^10.1.0 - version: 10.1.0 + specifier: ^10.4.0 + version: 10.4.0 '@testing-library/jest-dom': - specifier: ^6.4.5 - version: 6.4.5(@jest/globals@29.7.0)(jest@29.7.0(@types/node@20.12.11)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5))) + specifier: ^6.6.3 + version: 6.6.3 + '@types/jsdom': + specifier: ^21.1.7 + version: 21.1.7 '@types/node': - specifier: ^20.12.11 - version: 20.12.11 + specifier: ^22.9.0 + version: 22.9.0 '@typescript-eslint/eslint-plugin': - specifier: ^7.9.0 - version: 7.9.0(@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5))(eslint@9.2.0)(typescript@5.4.5) + specifier: ^8.13.0 + version: 8.14.0(@typescript-eslint/parser@8.14.0(eslint@9.14.0)(typescript@5.6.3))(eslint@9.14.0)(typescript@5.6.3) '@typescript-eslint/parser': - specifier: ^7.9.0 - version: 7.9.0(eslint@9.2.0)(typescript@5.4.5) + specifier: ^8.13.0 + version: 8.14.0(eslint@9.14.0)(typescript@5.6.3) + autoprefixer: + specifier: ^10.4.20 + version: 10.4.20(postcss@8.4.49) babel-jest: specifier: ^29.7.0 - version: 29.7.0(@babel/core@7.24.5) + version: 29.7.0(@babel/core@7.26.0) cross-env: specifier: ^7.0.3 version: 7.0.3 + esbuild: + specifier: ^0.24.0 + version: 0.24.0 eslint: - specifier: ^9.2.0 - version: 9.2.0 + specifier: ^9.14.0 + version: 9.14.0 eslint-config-prettier: specifier: ^9.1.0 - version: 9.1.0(eslint@9.2.0) + version: 9.1.0(eslint@9.14.0) eslint-plugin-prettier: - specifier: ^5.1.3 - version: 5.1.3(eslint-config-prettier@9.1.0(eslint@9.2.0))(eslint@9.2.0)(prettier@3.2.5) - globals: - specifier: ^15.2.0 - version: 15.2.0 + specifier: ^5.2.1 + version: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.14.0))(eslint@9.14.0)(prettier@3.3.3) google-closure-compiler: specifier: ^20240317.0.0 version: 20240317.0.0 husky: - specifier: ^9.0.11 - version: 9.0.11 + specifier: ^9.1.6 + version: 9.1.6 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@20.12.11)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5)) + version: 29.7.0(@types/node@22.9.0) jsdom: - specifier: ^24.0.0 - version: 24.0.0 + specifier: ^25.0.1 + version: 25.0.1 + postcss: + specifier: ^8.4.47 + version: 8.4.49 prettier: - specifier: ^3.2.5 - version: 3.2.5 + specifier: ^3.3.3 + version: 3.3.3 + rimraf: + specifier: ^6.0.1 + version: 6.0.1 rollup: - specifier: ^4.17.2 - version: 4.17.2 + specifier: ^4.24.4 + version: 4.27.0 + rollup-plugin-scss: + specifier: ^4.0.0 + version: 4.0.0 sass: - specifier: ^1.77.1 - version: 1.77.1 - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@20.12.11)(typescript@5.4.5) + specifier: ^1.80.6 + version: 1.81.0 + tslib: + specifier: ^2.8.1 + version: 2.8.1 + tsx: + specifier: ^4.19.2 + version: 4.19.2 typescript: - specifier: ^5.4.5 - version: 5.4.5 + specifier: ^5.6.3 + version: 5.6.3 + vite: + specifier: ^5.4.10 + version: 5.4.11(@types/node@22.9.0)(sass@1.81.0)(terser@5.36.0) + vitest: + specifier: ^2.1.4 + version: 2.1.5(@types/node@22.9.0)(jsdom@25.0.1)(sass@1.81.0)(terser@5.36.0) packages: - '@adobe/css-tools@4.3.3': - resolution: {integrity: sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==} + '@adobe/css-tools@4.4.1': + resolution: {integrity: sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==} '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@babel/code-frame@7.24.2': - resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.24.4': - resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==} - engines: {node: '>=6.9.0'} - - '@babel/core@7.24.5': - resolution: {integrity: sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.24.5': - resolution: {integrity: sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-annotate-as-pure@7.22.5': - resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} - engines: {node: '>=6.9.0'} - - '@babel/helper-builder-binary-assignment-operator-visitor@7.22.15': - resolution: {integrity: sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.23.6': - resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-create-class-features-plugin@7.24.5': - resolution: {integrity: sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-create-regexp-features-plugin@7.22.15': - resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-define-polyfill-provider@0.6.2': - resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - - '@babel/helper-environment-visitor@7.22.20': - resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} - '@babel/helper-function-name@7.23.0': - resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + '@babel/compat-data@7.26.2': + resolution: {integrity: sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==} engines: {node: '>=6.9.0'} - '@babel/helper-hoist-variables@7.22.5': - resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + '@babel/core@7.26.0': + resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} engines: {node: '>=6.9.0'} - '@babel/helper-member-expression-to-functions@7.24.5': - resolution: {integrity: sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==} + '@babel/generator@7.26.2': + resolution: {integrity: sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.24.3': - resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} + '@babel/helper-compilation-targets@7.25.9': + resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.24.5': - resolution: {integrity: sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==} + '@babel/helper-module-imports@7.25.9': + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-optimise-call-expression@7.22.5': - resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-plugin-utils@7.24.5': - resolution: {integrity: sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-remap-async-to-generator@7.22.20': - resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-replace-supers@7.24.1': - resolution: {integrity: sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==} + '@babel/helper-module-transforms@7.26.0': + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-simple-access@7.24.5': - resolution: {integrity: sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==} + '@babel/helper-plugin-utils@7.25.9': + resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==} engines: {node: '>=6.9.0'} - '@babel/helper-skip-transparent-expression-wrappers@7.22.5': - resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} - '@babel/helper-split-export-declaration@7.24.5': - resolution: {integrity: sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==} + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.24.1': - resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} + '@babel/helper-validator-option@7.25.9': + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.24.5': - resolution: {integrity: sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==} + '@babel/helpers@7.26.0': + resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.23.5': - resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-wrap-function@7.24.5': - resolution: {integrity: sha512-/xxzuNvgRl4/HLNKvnFwdhdgN3cpLxgLROeLDl83Yx0AJ1SGvq1ak0OszTOjDfiB8Vx03eJbeDWh9r+jCCWttw==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.24.5': - resolution: {integrity: sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==} - engines: {node: '>=6.9.0'} - - '@babel/highlight@7.24.5': - resolution: {integrity: sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.24.5': - resolution: {integrity: sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==} + '@babel/parser@7.26.2': + resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.5': - resolution: {integrity: sha512-LdXRi1wEMTrHVR4Zc9F8OewC3vdm5h4QB6L71zy6StmYeqGi1b3ttIO8UC+BfZKcH9jdr4aI249rBkm+3+YvHw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.1': - resolution: {integrity: sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.1': - resolution: {integrity: sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.13.0 - - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.1': - resolution: {integrity: sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': - resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-async-generators@7.8.4': resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: @@ -276,24 +190,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-dynamic-import@7.8.3': - resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-export-namespace-from@7.8.3': - resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-assertions@7.24.1': - resolution: {integrity: sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-attributes@7.24.1': - resolution: {integrity: sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==} + '@babel/plugin-syntax-import-attributes@7.26.0': + resolution: {integrity: sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -308,8 +206,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-jsx@7.24.1': - resolution: {integrity: sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==} + '@babel/plugin-syntax-jsx@7.25.9': + resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -356,376 +254,515 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.24.1': - resolution: {integrity: sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==} + '@babel/plugin-syntax-typescript@7.25.9': + resolution: {integrity: sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6': - resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + '@babel/runtime@7.26.0': + resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/plugin-transform-arrow-functions@7.24.1': - resolution: {integrity: sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==} + '@babel/template@7.25.9': + resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-generator-functions@7.24.3': - resolution: {integrity: sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==} + '@babel/traverse@7.25.9': + resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-async-to-generator@7.24.1': - resolution: {integrity: sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==} + '@babel/types@7.26.0': + resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoped-functions@7.24.1': - resolution: {integrity: sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - '@babel/plugin-transform-block-scoping@7.24.5': - resolution: {integrity: sha512-sMfBc3OxghjC95BkYrYocHL3NaOplrcaunblzwXhGmlPwpmfsxr4vK+mBBt49r+S240vahmv+kUxkeKgs+haCw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] - '@babel/plugin-transform-class-properties@7.24.1': - resolution: {integrity: sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/aix-ppc64@0.23.1': + resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] - '@babel/plugin-transform-class-static-block@7.24.4': - resolution: {integrity: sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.12.0 + '@esbuild/aix-ppc64@0.24.0': + resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] - '@babel/plugin-transform-classes@7.24.5': - resolution: {integrity: sha512-gWkLP25DFj2dwe9Ck8uwMOpko4YsqyfZJrOmqqcegeDYEbp7rmn4U6UQZNj08UF6MaX39XenSpKRCvpDRBtZ7Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] - '@babel/plugin-transform-computed-properties@7.24.1': - resolution: {integrity: sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/android-arm64@0.23.1': + resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] - '@babel/plugin-transform-destructuring@7.24.5': - resolution: {integrity: sha512-SZuuLyfxvsm+Ah57I/i1HVjveBENYK9ue8MJ7qkc7ndoNjqquJiElzA7f5yaAXjyW2hKojosOTAQQRX50bPSVg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/android-arm64@0.24.0': + resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] - '@babel/plugin-transform-dotall-regex@7.24.1': - resolution: {integrity: sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] - '@babel/plugin-transform-duplicate-keys@7.24.1': - resolution: {integrity: sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/android-arm@0.23.1': + resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] - '@babel/plugin-transform-dynamic-import@7.24.1': - resolution: {integrity: sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/android-arm@0.24.0': + resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] - '@babel/plugin-transform-exponentiation-operator@7.24.1': - resolution: {integrity: sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] - '@babel/plugin-transform-export-namespace-from@7.24.1': - resolution: {integrity: sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/android-x64@0.23.1': + resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] - '@babel/plugin-transform-for-of@7.24.1': - resolution: {integrity: sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/android-x64@0.24.0': + resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] - '@babel/plugin-transform-function-name@7.24.1': - resolution: {integrity: sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] - '@babel/plugin-transform-json-strings@7.24.1': - resolution: {integrity: sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/darwin-arm64@0.23.1': + resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] - '@babel/plugin-transform-literals@7.24.1': - resolution: {integrity: sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/darwin-arm64@0.24.0': + resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] - '@babel/plugin-transform-logical-assignment-operators@7.24.1': - resolution: {integrity: sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] - '@babel/plugin-transform-member-expression-literals@7.24.1': - resolution: {integrity: sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/darwin-x64@0.23.1': + resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] - '@babel/plugin-transform-modules-amd@7.24.1': - resolution: {integrity: sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/darwin-x64@0.24.0': + resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] - '@babel/plugin-transform-modules-commonjs@7.24.1': - resolution: {integrity: sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] - '@babel/plugin-transform-modules-systemjs@7.24.1': - resolution: {integrity: sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/freebsd-arm64@0.23.1': + resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] - '@babel/plugin-transform-modules-umd@7.24.1': - resolution: {integrity: sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/freebsd-arm64@0.24.0': + resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] - '@babel/plugin-transform-named-capturing-groups-regex@7.22.5': - resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] - '@babel/plugin-transform-new-target@7.24.1': - resolution: {integrity: sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/freebsd-x64@0.23.1': + resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] - '@babel/plugin-transform-nullish-coalescing-operator@7.24.1': - resolution: {integrity: sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/freebsd-x64@0.24.0': + resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] - '@babel/plugin-transform-numeric-separator@7.24.1': - resolution: {integrity: sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] - '@babel/plugin-transform-object-rest-spread@7.24.5': - resolution: {integrity: sha512-7EauQHszLGM3ay7a161tTQH7fj+3vVM/gThlz5HpFtnygTxjrlvoeq7MPVA1Vy9Q555OB8SnAOsMkLShNkkrHA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-arm64@0.23.1': + resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] - '@babel/plugin-transform-object-super@7.24.1': - resolution: {integrity: sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-arm64@0.24.0': + resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] - '@babel/plugin-transform-optional-catch-binding@7.24.1': - resolution: {integrity: sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] - '@babel/plugin-transform-optional-chaining@7.24.5': - resolution: {integrity: sha512-xWCkmwKT+ihmA6l7SSTpk8e4qQl/274iNbSKRRS8mpqFR32ksy36+a+LWY8OXCCEefF8WFlnOHVsaDI2231wBg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-arm@0.23.1': + resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] - '@babel/plugin-transform-parameters@7.24.5': - resolution: {integrity: sha512-9Co00MqZ2aoky+4j2jhofErthm6QVLKbpQrvz20c3CH9KQCLHyNB+t2ya4/UrRpQGR+Wrwjg9foopoeSdnHOkA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-arm@0.24.0': + resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] - '@babel/plugin-transform-private-methods@7.24.1': - resolution: {integrity: sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] - '@babel/plugin-transform-private-property-in-object@7.24.5': - resolution: {integrity: sha512-JM4MHZqnWR04jPMujQDTBVRnqxpLLpx2tkn7iPn+Hmsc0Gnb79yvRWOkvqFOx3Z7P7VxiRIR22c4eGSNj87OBQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-ia32@0.23.1': + resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] - '@babel/plugin-transform-property-literals@7.24.1': - resolution: {integrity: sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-ia32@0.24.0': + resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] - '@babel/plugin-transform-regenerator@7.24.1': - resolution: {integrity: sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] - '@babel/plugin-transform-reserved-words@7.24.1': - resolution: {integrity: sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-loong64@0.23.1': + resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] - '@babel/plugin-transform-shorthand-properties@7.24.1': - resolution: {integrity: sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-loong64@0.24.0': + resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] - '@babel/plugin-transform-spread@7.24.1': - resolution: {integrity: sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] - '@babel/plugin-transform-sticky-regex@7.24.1': - resolution: {integrity: sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-mips64el@0.23.1': + resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] - '@babel/plugin-transform-template-literals@7.24.1': - resolution: {integrity: sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-mips64el@0.24.0': + resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] - '@babel/plugin-transform-typeof-symbol@7.24.5': - resolution: {integrity: sha512-UTGnhYVZtTAjdwOTzT+sCyXmTn8AhaxOS/MjG9REclZ6ULHWF9KoCZur0HSGU7hk8PdBFKKbYe6+gqdXWz84Jg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] - '@babel/plugin-transform-unicode-escapes@7.24.1': - resolution: {integrity: sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-ppc64@0.23.1': + resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] - '@babel/plugin-transform-unicode-property-regex@7.24.1': - resolution: {integrity: sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-ppc64@0.24.0': + resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] - '@babel/plugin-transform-unicode-regex@7.24.1': - resolution: {integrity: sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] - '@babel/plugin-transform-unicode-sets-regex@7.24.1': - resolution: {integrity: sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 + '@esbuild/linux-riscv64@0.23.1': + resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] - '@babel/preset-env@7.24.5': - resolution: {integrity: sha512-UGK2ifKtcC8i5AI4cH+sbLLuLc2ktYSFJgBAXorKAsHUZmrQ1q6aQ6i3BvU24wWs2AAKqQB6kq3N9V9Gw1HiMQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 + '@esbuild/linux-riscv64@0.24.0': + resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] - '@babel/preset-modules@0.1.6-no-external-plugins': - resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} - peerDependencies: - '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.23.1': + resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.24.0': + resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.23.1': + resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.24.0': + resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.23.1': + resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.24.0': + resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.23.1': + resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-arm64@0.24.0': + resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.23.1': + resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.24.0': + resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.23.1': + resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.24.0': + resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] - '@babel/regjsgen@0.8.0': - resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] - '@babel/runtime@7.24.5': - resolution: {integrity: sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==} - engines: {node: '>=6.9.0'} + '@esbuild/win32-arm64@0.23.1': + resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] - '@babel/template@7.24.0': - resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} - engines: {node: '>=6.9.0'} + '@esbuild/win32-arm64@0.24.0': + resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] - '@babel/traverse@7.24.5': - resolution: {integrity: sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==} - engines: {node: '>=6.9.0'} + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] - '@babel/types@7.24.5': - resolution: {integrity: sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==} - engines: {node: '>=6.9.0'} + '@esbuild/win32-ia32@0.23.1': + resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] - '@bcoe/v8-coverage@0.2.3': - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@esbuild/win32-ia32@0.24.0': + resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.23.1': + resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.24.0': + resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] - '@eslint-community/eslint-utils@4.4.0': - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + '@eslint-community/eslint-utils@4.4.1': + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.10.0': - resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/eslintrc@3.0.2': - resolution: {integrity: sha512-wV19ZEGEMAC1eHgrS7UQPqsdEiCIbTKTasEfcXAigzoXICcqZSjBZEHlZwNVvKg6UBCjSlos84XiLqsRJnIcIg==} + '@eslint/config-array@0.18.0': + resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.7.0': + resolution: {integrity: sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.1.0': + resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.14.0': + resolution: {integrity: sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.2.0': - resolution: {integrity: sha512-ESiIudvhoYni+MdsI8oD7skpprZ89qKocwRM2KEvhhBJ9nl5MRh7BXU5GTod7Mdygq+AUl+QzId6iWJKR/wABA==} + '@eslint/object-schema@2.1.4': + resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@humanwhocodes/config-array@0.13.0': - resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} - engines: {node: '>=10.10.0'} + '@eslint/plugin-kit@0.2.3': + resolution: {integrity: sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/object-schema@2.0.3': - resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} - '@humanwhocodes/retry@0.2.4': - resolution: {integrity: sha512-Ttl/jHpxfS3st5sxwICYfk4pOH0WrLI1SpW283GgQL7sCWU7EHIOhX4b4fkIxr3tkfzwg8+FNojtzsIEE7Ecgg==} + '@humanwhocodes/retry@0.4.1': + resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} engines: {node: '>=18.18'} + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + '@istanbuljs/load-nyc-config@1.1.0': resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} engines: {node: '>=8'} @@ -815,15 +852,12 @@ packages: '@jridgewell/source-map@0.3.6': resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} - '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -836,10 +870,97 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@parcel/watcher-android-arm64@2.5.0': + resolution: {integrity: sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.5.0': + resolution: {integrity: sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.0': + resolution: {integrity: sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.5.0': + resolution: {integrity: sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.5.0': + resolution: {integrity: sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm-musl@2.5.0': + resolution: {integrity: sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm64-glibc@2.5.0': + resolution: {integrity: sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-musl@2.5.0': + resolution: {integrity: sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-x64-glibc@2.5.0': + resolution: {integrity: sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-musl@2.5.0': + resolution: {integrity: sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-win32-arm64@2.5.0': + resolution: {integrity: sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.0': + resolution: {integrity: sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.0': + resolution: {integrity: sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.5.0': + resolution: {integrity: sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==} + engines: {node: '>= 10.0.0'} + '@pkgr/core@0.1.1': resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@playwright/test@1.48.2': + resolution: {integrity: sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==} + engines: {node: '>=18'} + hasBin: true + '@rollup/plugin-terser@0.4.4': resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} engines: {node: '>=14.0.0'} @@ -849,8 +970,8 @@ packages: rollup: optional: true - '@rollup/plugin-typescript@11.1.6': - resolution: {integrity: sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==} + '@rollup/plugin-typescript@12.1.1': + resolution: {integrity: sha512-t7O653DpfB5MbFrqPe/VcKFFkvRuFNp9qId3xq4Eth5xlyymzxNpye2z8Hrl0RIMuXTSr5GGcFpkdlMeacUiFQ==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^2.14.0||^3.0.0||^4.0.0 @@ -862,8 +983,8 @@ packages: tslib: optional: true - '@rollup/pluginutils@5.1.0': - resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + '@rollup/pluginutils@5.1.3': + resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 @@ -871,83 +992,93 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.17.2': - resolution: {integrity: sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==} + '@rollup/rollup-android-arm-eabi@4.27.0': + resolution: {integrity: sha512-e312hTjuM89YLqlcqEs7mSvwhxN5pgXqRobUob7Jsz1wDQlpAb2WTX4jzvrx5NrL1h2SE4fGdHSNyPxbLfzyeA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.17.2': - resolution: {integrity: sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==} + '@rollup/rollup-android-arm64@4.27.0': + resolution: {integrity: sha512-cBUOny8GNXP++gN00Bo5L04I2oqUEFAU0OSDb+4hqp4/R/pZL/zlGzp7lJkhtPX52Rj+PIe0S8aOqhK4hztxHQ==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.17.2': - resolution: {integrity: sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==} + '@rollup/rollup-darwin-arm64@4.27.0': + resolution: {integrity: sha512-aauK2M2ptFQQYdOqbKGYCg1LHlPbm6IxepSnHLLaMIGcd9YBiKRGl2+KtzQL/IkurP+b54EKBkvtZaWXijmzfQ==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.17.2': - resolution: {integrity: sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==} + '@rollup/rollup-darwin-x64@4.27.0': + resolution: {integrity: sha512-VAjOnHUwpvxf3XT33sMpsLGKq24Rz1sTQhLuUicYrV9pxB4TNi0w11qAGPOyR+dQu/iZf88DmEmG0+2Gaqa1gg==} cpu: [x64] os: [darwin] - '@rollup/rollup-linux-arm-gnueabihf@4.17.2': - resolution: {integrity: sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==} + '@rollup/rollup-freebsd-arm64@4.27.0': + resolution: {integrity: sha512-I2eRlZG87gl6WxP6PvSB5bfFA1btE7tWnG6QAoEU/0Gr47f6KaxRwiRfBujHlzkuMPqtpTlSOW4aOEOyMtQqfg==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.27.0': + resolution: {integrity: sha512-G05JNYFdjikD/2hJTf1gHdD5KjI2TotjiDn17amHtB5JgwrRF1EA9hJ3TRGIvT3zGXilNWWlR71R/2TT1pXRDg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.27.0': + resolution: {integrity: sha512-FMXxMZ7qnMULwgdmGSFVlOduAhFyqDPoK1A2Q8HBkzGYX9SMFU3ITKfLdIiCzTaaj/pt1OiEbpF2szUw6Kh++Q==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.17.2': - resolution: {integrity: sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==} + '@rollup/rollup-linux-arm-musleabihf@4.27.0': + resolution: {integrity: sha512-0315TiPsJfOY+jAwEeqxcy9yVcAy/jg99GrMcd/L7CRESzi1vhyLPbnkDnz7giaEttSRf/d3llJYfoC+44Nl3A==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.17.2': - resolution: {integrity: sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==} + '@rollup/rollup-linux-arm64-gnu@4.27.0': + resolution: {integrity: sha512-4zCKY5E9djPyHzvoCWIouFsuAvg+dk+rNia8lz1bjKpzKz02QvK4JPHyjcDT8CFR2J/aA98WccCirdDOy+VDWQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.17.2': - resolution: {integrity: sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==} + '@rollup/rollup-linux-arm64-musl@4.27.0': + resolution: {integrity: sha512-6St9rrPSLbYBbbJAClpU4gmnO7cdZCMMzx2MT0UCIIIevoLAmsCDOAG6t3J/RgN4CPUpdaGr/UnPqQTHZ4oDwA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.17.2': - resolution: {integrity: sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==} + '@rollup/rollup-linux-powerpc64le-gnu@4.27.0': + resolution: {integrity: sha512-dIBfp8NDrgvwUJxyqFv7501coIba+7xxBJy1gQEF0RGkIKa3Tq0Mh3sF9hmstDLtaMt7gL2aXsCNG9SCKyVVZg==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.17.2': - resolution: {integrity: sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==} + '@rollup/rollup-linux-riscv64-gnu@4.27.0': + resolution: {integrity: sha512-Pu7xLHRy+5UjFCKR/vWsbFmiBYUC9993v99YoKWhAgK4VsdNuWHPs17NuCJEtVsZpYCNVPbRyBpQw58Ma8BmeA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.17.2': - resolution: {integrity: sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==} + '@rollup/rollup-linux-s390x-gnu@4.27.0': + resolution: {integrity: sha512-2Q9qQnk/eWdvXzzHl22y7tpDHREppFUh7N6cCs70HZEbQSgB7wd/2S/B05SSiyAiIn5BL+fYiASLds5bz0IQFw==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.17.2': - resolution: {integrity: sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==} + '@rollup/rollup-linux-x64-gnu@4.27.0': + resolution: {integrity: sha512-CNnqMZ4Yz0Ga0A75qux7DNChq0P9oAWn2S7yjZPRC+AaEF8Ysw5K/1lzT25/a3reJ4V2abcShIVG+tfZHb1UrQ==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.17.2': - resolution: {integrity: sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==} + '@rollup/rollup-linux-x64-musl@4.27.0': + resolution: {integrity: sha512-dS1+eCbbao54XB+wLW6uuwRkChq4L0UfKhd3wvt6s+EN1rTIi24ee5Lk3HfRGq9J2jsRm12/AGKLA0kd82Sp/g==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.17.2': - resolution: {integrity: sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==} + '@rollup/rollup-win32-arm64-msvc@4.27.0': + resolution: {integrity: sha512-VrYQHY5+Y71OU/uOSRE9lLhph16bbuWGrMwGwZDPxCUXUW5NgLA+K+q0kv7rafHRlnrsZSVcMOkZskzTNnR3ZQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.17.2': - resolution: {integrity: sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==} + '@rollup/rollup-win32-ia32-msvc@4.27.0': + resolution: {integrity: sha512-LCqk4Xi3e4GzLqaq+QDM7gP5DtJ/RgWMzV3U2brwp/vEz9RTA5YBgIDP69xYfrTXexes6xPsOIquy79+kLifiA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.17.2': - resolution: {integrity: sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==} + '@rollup/rollup-win32-x64-msvc@4.27.0': + resolution: {integrity: sha512-dj2ZolfViR3chLWwSHID2mBzLLwYvXFldIplR6BSkdACXqAsrcmItKTff4h7enYB3Ugoh0v41WbxijE9HJb1Hw==} cpu: [x64] os: [win32] @@ -960,42 +1091,13 @@ packages: '@sinonjs/fake-timers@10.3.0': resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} - '@testing-library/dom@10.1.0': - resolution: {integrity: sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==} + '@testing-library/dom@10.4.0': + resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} engines: {node: '>=18'} - '@testing-library/jest-dom@6.4.5': - resolution: {integrity: sha512-AguB9yvTXmCnySBP1lWjfNNUwpbElsaQ567lt2VdGqAdHtpieLgjmcVyv1q7PMIvLbgpDdkWV5Ydv3FEejyp2A==} + '@testing-library/jest-dom@6.6.3': + resolution: {integrity: sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} - peerDependencies: - '@jest/globals': '>= 28' - '@types/bun': latest - '@types/jest': '>= 28' - jest: '>= 28' - vitest: '>= 0.32' - peerDependenciesMeta: - '@jest/globals': - optional: true - '@types/bun': - optional: true - '@types/jest': - optional: true - jest: - optional: true - vitest: - optional: true - - '@tsconfig/node10@1.0.11': - resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} - - '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - - '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - - '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} @@ -1009,11 +1111,11 @@ packages: '@types/babel__template@7.4.4': resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - '@types/babel__traverse@7.20.5': - resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} - '@types/estree@1.0.5': - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} '@types/graceful-fs@4.1.9': resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} @@ -1027,87 +1129,120 @@ packages: '@types/istanbul-reports@3.0.4': resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - '@types/node@20.12.11': - resolution: {integrity: sha512-vDg9PZ/zi+Nqp6boSOT7plNuthRugEKixDv5sFTIpkE89MmNtEArAShI4mxuX2+UrLEe9pxC1vm2cjm9YlWbJw==} + '@types/jsdom@21.1.7': + resolution: {integrity: sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@22.9.0': + resolution: {integrity: sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==} '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - '@types/yargs@17.0.32': - resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} - '@typescript-eslint/eslint-plugin@7.9.0': - resolution: {integrity: sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/eslint-plugin@8.14.0': + resolution: {integrity: sha512-tqp8H7UWFaZj0yNO6bycd5YjMwxa6wIHOLZvWPkidwbgLCsBMetQoGj7DPuAlWa2yGO3H48xmPwjhsSPPCGU5w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^7.0.0 - eslint: ^8.56.0 + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/parser@7.9.0': - resolution: {integrity: sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/parser@8.14.0': + resolution: {integrity: sha512-2p82Yn9juUJq0XynBXtFCyrBDb6/dJombnz6vbo6mgQEtWHfvHbQuEa9kAOVIt1c9YFwi7H6WxtPj1kg+80+RA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/scope-manager@7.9.0': - resolution: {integrity: sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/scope-manager@8.14.0': + resolution: {integrity: sha512-aBbBrnW9ARIDn92Zbo7rguLnqQ/pOrUguVpbUwzOhkFg2npFDwTgPGqFqE0H5feXcOoJOfX3SxlJaKEVtq54dw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@7.9.0': - resolution: {integrity: sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/type-utils@8.14.0': + resolution: {integrity: sha512-Xcz9qOtZuGusVOH5Uk07NGs39wrKkf3AxlkK79RBK6aJC1l03CobXjJbwBPSidetAOV+5rEVuiT1VSBUOAsanQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.56.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/types@7.9.0': - resolution: {integrity: sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/types@8.14.0': + resolution: {integrity: sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@7.9.0': - resolution: {integrity: sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/typescript-estree@8.14.0': + resolution: {integrity: sha512-OPXPLYKGZi9XS/49rdaCbR5j/S14HazviBlUQFvSKz3npr3NikF+mrgK7CFVur6XEt95DZp/cmke9d5i3vtVnQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/utils@7.9.0': - resolution: {integrity: sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/utils@8.14.0': + resolution: {integrity: sha512-OGqj6uB8THhrHj0Fk27DcHPojW7zKwKkPmHXHvQ58pLYp4hy8CSUdTKykKeh+5vFqTTVmjz0zCOOPKRovdsgHA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + + '@typescript-eslint/visitor-keys@8.14.0': + resolution: {integrity: sha512-vG0XZo8AdTH9OE6VFRwAZldNc7qtJ/6NLGWak+BtENuEUXGZgFpihILPiBvKXvJ2nFu27XNGC6rKiwuaoMbYzQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@vitest/expect@2.1.5': + resolution: {integrity: sha512-nZSBTW1XIdpZvEJyoP/Sy8fUg0b8od7ZpGDkTUcfJ7wz/VoZAFzFfLyxVxGFhUjJzhYqSbIpfMtl/+k/dpWa3Q==} + + '@vitest/mocker@2.1.5': + resolution: {integrity: sha512-XYW6l3UuBmitWqSUXTNXcVBUCRytDogBsWuNXQijc00dtnU/9OqpXWp4OJroVrad/gLIomAq9aW8yWDBtMthhQ==} peerDependencies: - eslint: ^8.56.0 + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.1.5': + resolution: {integrity: sha512-4ZOwtk2bqG5Y6xRGHcveZVr+6txkH7M2e+nPFd6guSoN638v/1XQ0K06eOpi0ptVU/2tW/pIU4IoPotY/GZ9fw==} + + '@vitest/runner@2.1.5': + resolution: {integrity: sha512-pKHKy3uaUdh7X6p1pxOkgkVAFW7r2I818vHDthYLvUyjRfkKOU6P45PztOch4DZarWQne+VOaIMwA/erSSpB9g==} + + '@vitest/snapshot@2.1.5': + resolution: {integrity: sha512-zmYw47mhfdfnYbuhkQvkkzYroXUumrwWDGlMjpdUr4jBd3HZiV2w7CQHj+z7AAS4VOtWxI4Zt4bWt4/sKcoIjg==} + + '@vitest/spy@2.1.5': + resolution: {integrity: sha512-aWZF3P0r3w6DiYTVskOYuhBc7EMc3jvn1TkBg8ttylFFRqNN2XGD7V5a4aQdk6QiUzZQ4klNBSpCLJgWNdIiNw==} - '@typescript-eslint/visitor-keys@7.9.0': - resolution: {integrity: sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==} - engines: {node: ^18.18.0 || >=20.0.0} + '@vitest/utils@2.1.5': + resolution: {integrity: sha512-yfj6Yrp0Vesw2cwJbP+cl04OC+IHFsuQsrsJBL9pyGeQXE56v1UAOQco+SR55Vf1nQzfV0QJg1Qum7AaWUwwYg==} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-walk@8.3.2: - resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} - engines: {node: '>=0.4.0'} - - acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} engines: {node: '>=0.4.0'} hasBin: true @@ -1126,9 +1261,9 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} @@ -1138,13 +1273,14 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} - arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -1154,13 +1290,24 @@ packages: aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + autoprefixer@10.4.20: + resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1175,23 +1322,8 @@ packages: resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - babel-plugin-polyfill-corejs2@0.4.11: - resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - - babel-plugin-polyfill-corejs3@0.10.4: - resolution: {integrity: sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - - babel-plugin-polyfill-regenerator@0.6.2: - resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - - babel-preset-current-node-syntax@1.0.1: - resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + babel-preset-current-node-syntax@1.1.0: + resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} peerDependencies: '@babel/core': ^7.0.0 @@ -1204,22 +1336,18 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.23.0: - resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} + browserslist@4.24.2: + resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -1229,6 +1357,10 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1241,12 +1373,12 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001617: - resolution: {integrity: sha512-mLyjzNI9I+Pix8zwcrpxEbGlfqOkF9kM3ptzmKNw5tizSyYwMe+nGLTqMK9cO+0E+Bh6TsBxNAaHWEM8xwSsmA==} + caniuse-lite@1.0.30001680: + resolution: {integrity: sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==} - chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} + chai@5.1.2: + resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} + engines: {node: '>=12'} chalk@3.0.0: resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} @@ -1260,16 +1392,20 @@ packages: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + + chokidar@4.0.1: + resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} + engines: {node: '>= 14.16.0'} ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - cjs-module-lexer@1.3.1: - resolution: {integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==} + cjs-module-lexer@1.4.1: + resolution: {integrity: sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==} cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} @@ -1296,16 +1432,10 @@ packages: collect-v8-coverage@1.0.2: resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} - color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} - color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} @@ -1322,9 +1452,6 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - core-js-compat@3.37.0: - resolution: {integrity: sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==} - core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -1333,31 +1460,28 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true - create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - cross-env@7.0.3: resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} hasBin: true - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + cross-spawn@7.0.5: + resolution: {integrity: sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==} engines: {node: '>= 8'} css.escape@1.5.1: resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} - cssstyle@4.0.1: - resolution: {integrity: sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==} + cssstyle@4.1.0: + resolution: {integrity: sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==} engines: {node: '>=18'} data-urls@5.0.0: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1376,6 +1500,10 @@ packages: babel-plugin-macros: optional: true + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -1391,6 +1519,11 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} + detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -1399,22 +1532,17 @@ packages: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} dom-accessibility-api@0.6.3: resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} - electron-to-chromium@1.4.764: - resolution: {integrity: sha512-ZXbPV46Y4dNCA+k7YHB+BYlzcoMtZ1yH6V0tQ1ul0wmA7RiwJfS29LSdRlE1myWBXRzEgm/Lz6tryj5WVQiLmg==} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + electron-to-chromium@1.5.60: + resolution: {integrity: sha512-HcraRUkTKJ+8yA3b10i9qvhUlPBRDlKjn1XGek1zDGVfAKcvi8TsUnImGqLiEm9j6ZulxXIWWIo9BmbkbCTGgA==} emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} @@ -1423,6 +1551,9 @@ packages: emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -1430,13 +1561,27 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} - engines: {node: '>=6'} + es-module-lexer@1.5.4: + resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.23.1: + resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} + engines: {node: '>=18'} + hasBin: true - escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} + esbuild@0.24.0: + resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} escape-string-regexp@2.0.0: resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} @@ -1452,8 +1597,8 @@ packages: peerDependencies: eslint: '>=7.0.0' - eslint-plugin-prettier@5.1.3: - resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} + eslint-plugin-prettier@5.2.1: + resolution: {integrity: sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: '@types/eslint': '>=8.0.0' @@ -1466,25 +1611,30 @@ packages: eslint-config-prettier: optional: true - eslint-scope@8.0.1: - resolution: {integrity: sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==} + eslint-scope@8.2.0: + resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint-visitor-keys@4.0.0: - resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.2.0: - resolution: {integrity: sha512-0n/I88vZpCOzO+PQpt0lbsqmn9AsnsJAQseIqhZFI8ibQT0U1AkEKRxA3EVMos0BoHSXDQvCXY25TUjB5tr8Og==} + eslint@9.14.0: + resolution: {integrity: sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true - espree@10.0.1: - resolution: {integrity: sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==} + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} esprima@4.0.1: @@ -1492,8 +1642,8 @@ packages: engines: {node: '>=4'} hasBin: true - esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} esrecurse@4.3.0: @@ -1504,9 +1654,15 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-walker@0.6.1: + resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -1519,6 +1675,10 @@ packages: resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} engines: {node: '>= 0.8.0'} + expect-type@1.1.0: + resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} + engines: {node: '>=12.0.0'} + expect@29.7.0: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1549,8 +1709,8 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} - fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} find-up@4.1.0: @@ -1568,13 +1728,25 @@ packages: flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} engines: {node: '>= 6'} + fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1599,6 +1771,9 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + get-tsconfig@4.8.1: + resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1607,8 +1782,14 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob@11.0.0: + resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==} + engines: {node: 20 || >=22} + hasBin: true + glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} @@ -1618,14 +1799,6 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@15.2.0: - resolution: {integrity: sha512-FQ5YwCHZM3nCmtb5FzEWwdUc9K5d3V/w9mzcz8iGD1gC/aOTHc6PouYu0kkKipNJqHAT7m51sqzQjEjIP+cK0A==} - engines: {node: '>=18'} - - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - google-closure-compiler-java@20240317.0.0: resolution: {integrity: sha512-oWURPChjcCrVfiQOuVtpSoUJVvtOYo41JGEQ2qtArsTGmk/DpWh40vS6hitwKRM/0YzJX/jYUuyt9ibuXXJKmg==} @@ -1655,10 +1828,6 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -1678,16 +1847,16 @@ packages: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} - https-proxy-agent@7.0.4: - resolution: {integrity: sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==} + https-proxy-agent@7.0.5: + resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} engines: {node: '>= 14'} human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} - husky@9.0.11: - resolution: {integrity: sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==} + husky@9.1.6: + resolution: {integrity: sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==} engines: {node: '>=18'} hasBin: true @@ -1695,19 +1864,19 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} - ignore@5.3.1: - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - immutable@4.3.6: - resolution: {integrity: sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==} + immutable@5.0.2: + resolution: {integrity: sha512-1NU7hWZDkV7hJ4PJ9dur9gTNQ4ePNPN4k9/0YhwjzykTi/+3Q5pF93YU5QoVj8BuOnhLgaY8gs0U2pj4kSYVcw==} import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} - import-local@3.1.0: - resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} + import-local@3.2.0: + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} engines: {node: '>=8'} hasBin: true @@ -1721,6 +1890,7 @@ packages: inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -1728,12 +1898,9 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} @@ -1755,10 +1922,6 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} @@ -1780,8 +1943,8 @@ packages: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} - istanbul-lib-instrument@6.0.2: - resolution: {integrity: sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==} + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} engines: {node: '>=10'} istanbul-lib-report@3.0.1: @@ -1796,6 +1959,10 @@ packages: resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} + jackspeak@4.0.2: + resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==} + engines: {node: 20 || >=22} + jest-changed-files@29.7.0: resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1936,8 +2103,8 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true - jsdom@24.0.0: - resolution: {integrity: sha512-UDS2NayCvmXSXVP6mpTj+73JnNQadZlr9N68189xib2tx5Mls7swlTNao26IoHv46BZJFvXygyRtyXd1feAk1A==} + jsdom@25.0.1: + resolution: {integrity: sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==} engines: {node: '>=18'} peerDependencies: canvas: ^2.11.2 @@ -1945,13 +2112,9 @@ packages: canvas: optional: true - jsesc@0.5.0: - resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} - hasBin: true - - jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} hasBin: true json-buffer@3.0.1: @@ -1997,15 +2160,19 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} - lodash.debounce@4.0.8: - resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + loupe@3.1.2: + resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} + + lru-cache@11.0.2: + resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -2013,13 +2180,13 @@ packages: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true + magic-string@0.30.12: + resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} @@ -2030,8 +2197,8 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} mime-db@1.52.0: @@ -2050,38 +2217,58 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} + minimatch@10.0.1: + resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + engines: {node: 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimatch@9.0.4: - resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - node-releases@2.0.14: - resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} - nwsapi@2.2.10: - resolution: {integrity: sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==} + nwsapi@2.2.13: + resolution: {integrity: sha512-cTGB9ptp9dY9A5VbMSe7fQBcl/tt22Vcqdq8+eN93rblOuE0aCFu4aZ2vMwct/2t+lFnosm8RkQW1I0Omb1UtQ==} once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -2114,6 +2301,9 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -2122,8 +2312,8 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} - parse5@7.1.2: - resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + parse5@7.2.1: + resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} @@ -2140,17 +2330,28 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} + path-scurry@2.0.0: + resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + engines: {node: 20 || >=22} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} - picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} @@ -2159,6 +2360,23 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} + playwright-core@1.48.2: + resolution: {integrity: sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.48.2: + resolution: {integrity: sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==} + engines: {node: '>=18'} + hasBin: true + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.4.49: + resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} + engines: {node: ^10 || ^12 || >=14} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -2167,8 +2385,8 @@ packages: resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} engines: {node: '>=6.0.0'} - prettier@3.2.5: - resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} engines: {node: '>=14'} hasBin: true @@ -2187,9 +2405,6 @@ packages: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} - psl@1.9.0: - resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2197,9 +2412,6 @@ packages: pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - querystringify@2.2.0: - resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -2215,35 +2427,17 @@ packages: readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} + readdirp@4.0.2: + resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} + engines: {node: '>= 14.16.0'} redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} - regenerate-unicode-properties@10.1.1: - resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} - engines: {node: '>=4'} - - regenerate@1.4.2: - resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} - regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - regenerator-transform@0.15.2: - resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} - - regexpu-core@5.3.2: - resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} - engines: {node: '>=4'} - - regjsparser@0.9.1: - resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} - hasBin: true - remove-trailing-separator@1.1.0: resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} @@ -2255,9 +2449,6 @@ packages: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} - requires-port@1.0.0: - resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - resolve-cwd@3.0.0: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} @@ -2270,6 +2461,9 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve.exports@2.0.2: resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} engines: {node: '>=10'} @@ -2282,13 +2476,24 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rollup@4.17.2: - resolution: {integrity: sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==} + rimraf@6.0.1: + resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==} + engines: {node: 20 || >=22} + hasBin: true + + rollup-plugin-scss@4.0.0: + resolution: {integrity: sha512-wxasNXDYC2m+fDxCMgK00WebVWYmeFvShyNABmjvSJZ6D1/SepwqFeaMFMQromveI79gfvb64yJjiZZxSZxEIA==} + + rollup-pluginutils@2.8.2: + resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + + rollup@4.27.0: + resolution: {integrity: sha512-nrOD/RrnAMssruS7bPa7MYpEuH6tUpOa43NLtxQiLKem0An8HZyXun5Ndig6JzbkJoIbaKkt85V67VCaQ59GyA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - rrweb-cssom@0.6.0: - resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==} + rrweb-cssom@0.7.1: + resolution: {integrity: sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==} run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -2302,8 +2507,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sass@1.77.1: - resolution: {integrity: sha512-OMEyfirt9XEfyvocduUIOlUSkWOXS/LAt6oblR/ISXCTukyavjex+zQNm51pPCOiFKY1QpWvEH1EeCkgyV3I6w==} + sass@1.81.0: + resolution: {integrity: sha512-Q4fOxRfhmv3sqCLoGfvrC9pRV8btc0UtqL9mN6Yrv6Qi9ScL55CVH1vlPP863ISLEEMNLLuu9P+enCeGHlnzhA==} engines: {node: '>=14.0.0'} hasBin: true @@ -2315,8 +2520,8 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.6.2: - resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} hasBin: true @@ -2331,9 +2536,16 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -2344,8 +2556,8 @@ packages: smob@1.5.0: resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} - source-map-js@1.2.0: - resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} source-map-support@0.5.13: @@ -2369,6 +2581,12 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.8.0: + resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} + string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} @@ -2377,6 +2595,10 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} @@ -2384,6 +2606,10 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + strip-bom@4.0.0: resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} engines: {node: '>=8'} @@ -2400,10 +2626,6 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -2419,12 +2641,12 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - synckit@0.8.8: - resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} + synckit@0.9.2: + resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} engines: {node: ^14.18.0 || >=16.0.0} - terser@5.31.0: - resolution: {integrity: sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==} + terser@5.36.0: + resolution: {integrity: sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==} engines: {node: '>=10'} hasBin: true @@ -2435,47 +2657,59 @@ packages: text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + + tinypool@1.0.2: + resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + + tldts-core@6.1.61: + resolution: {integrity: sha512-In7VffkDWUPgwa+c9picLUxvb0RltVwTkSgMNFgvlGSWveCzGBemBqTsgJCL4EDFWZ6WH0fKTsot6yNhzy3ZzQ==} + + tldts@6.1.61: + resolution: {integrity: sha512-rv8LUyez4Ygkopqn+M6OLItAOT9FF3REpPQDkdMx5ix8w4qkuE7Vo2o/vw1nxKQYmJDV8JpAMJQr1b+lTKf0FA==} + hasBin: true + tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - tough-cookie@4.1.4: - resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} - engines: {node: '>=6'} + tough-cookie@5.0.0: + resolution: {integrity: sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==} + engines: {node: '>=16'} tr46@5.0.0: resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==} engines: {node: '>=18'} - ts-api-utils@1.3.0: - resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + ts-api-utils@1.4.0: + resolution: {integrity: sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' - ts-node@10.9.2: - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + tsx@4.19.2: + resolution: {integrity: sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==} + engines: {node: '>=18.0.0'} + hasBin: true type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} @@ -2489,36 +2723,16 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} - typescript@5.4.5: - resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} hasBin: true - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - - unicode-canonical-property-names-ecmascript@2.0.0: - resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} - engines: {node: '>=4'} - - unicode-match-property-ecmascript@2.0.0: - resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} - engines: {node: '>=4'} - - unicode-match-property-value-ecmascript@2.1.0: - resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} - engines: {node: '>=4'} - - unicode-property-aliases-ecmascript@2.1.0: - resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} - engines: {node: '>=4'} - - universalify@0.2.0: - resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} - engines: {node: '>= 4.0.0'} + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - update-browserslist-db@1.0.15: - resolution: {integrity: sha512-K9HWH62x3/EalU1U6sjSZiylm9C8tgq2mSvshZpqc7QE69RaA2qjhkW2HlNA0tFpEbtyFz7HTqbSdN4MSwUodA==} + update-browserslist-db@1.1.1: + resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -2526,17 +2740,11 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - url-parse@1.5.10: - resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - - v8-to-istanbul@9.2.0: - resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} + v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} vinyl-sourcemaps-apply@0.2.1: @@ -2546,6 +2754,67 @@ packages: resolution: {integrity: sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==} engines: {node: '>= 0.10'} + vite-node@2.1.5: + resolution: {integrity: sha512-rd0QIgx74q4S1Rd56XIiL2cYEdyWn13cunYBIuqh9mpmQr7gGS0IxXoP8R6OaZtNQQLyXSWbd4rXKYUbhFpK5w==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.4.11: + resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@2.1.5: + resolution: {integrity: sha512-P4ljsdpuzRTPI/kbND2sDZ4VmieerR2c9szEZpjc+98Z9ebvnXmM5+0tHEKqYZumXqlvnmfWsjeFOjXVriDG7A==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.5 + '@vitest/ui': 2.1.5 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + w3c-xmlserializer@5.0.0: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} @@ -2574,6 +2843,11 @@ packages: engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -2582,6 +2856,10 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -2589,8 +2867,8 @@ packages: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - ws@8.17.0: - resolution: {integrity: sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==} + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -2623,767 +2901,447 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} - yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} snapshots: - '@adobe/css-tools@4.3.3': {} + '@adobe/css-tools@4.4.1': {} '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - '@babel/code-frame@7.24.2': + '@babel/code-frame@7.26.2': dependencies: - '@babel/highlight': 7.24.5 - picocolors: 1.0.0 + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 - '@babel/compat-data@7.24.4': {} + '@babel/compat-data@7.26.2': {} - '@babel/core@7.24.5': + '@babel/core@7.26.0': dependencies: '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.24.2 - '@babel/generator': 7.24.5 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) - '@babel/helpers': 7.24.5 - '@babel/parser': 7.24.5 - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.5 - '@babel/types': 7.24.5 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.2 + '@babel/helper-compilation-targets': 7.25.9 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helpers': 7.26.0 + '@babel/parser': 7.26.2 + '@babel/template': 7.25.9 + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 convert-source-map: 2.0.0 - debug: 4.3.4 + debug: 4.3.7 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/generator@7.24.5': + '@babel/generator@7.26.2': dependencies: - '@babel/types': 7.24.5 + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - jsesc: 2.5.2 - - '@babel/helper-annotate-as-pure@7.22.5': - dependencies: - '@babel/types': 7.24.5 - - '@babel/helper-builder-binary-assignment-operator-visitor@7.22.15': - dependencies: - '@babel/types': 7.24.5 + jsesc: 3.0.2 - '@babel/helper-compilation-targets@7.23.6': + '@babel/helper-compilation-targets@7.25.9': dependencies: - '@babel/compat-data': 7.24.4 - '@babel/helper-validator-option': 7.23.5 - browserslist: 4.23.0 + '@babel/compat-data': 7.26.2 + '@babel/helper-validator-option': 7.25.9 + browserslist: 4.24.2 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.24.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-member-expression-to-functions': 7.24.5 - '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.5) - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/helper-split-export-declaration': 7.24.5 - semver: 6.3.1 - - '@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.24.5)': + '@babel/helper-module-imports@7.25.9': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-annotate-as-pure': 7.22.5 - regexpu-core: 5.3.2 - semver: 6.3.1 + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 + transitivePeerDependencies: + - supports-color - '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.24.5)': + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.24.5 - debug: 4.3.4 - lodash.debounce: 4.0.8 - resolve: 1.22.8 + '@babel/core': 7.26.0 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.25.9 transitivePeerDependencies: - supports-color - '@babel/helper-environment-visitor@7.22.20': {} + '@babel/helper-plugin-utils@7.25.9': {} - '@babel/helper-function-name@7.23.0': - dependencies: - '@babel/template': 7.24.0 - '@babel/types': 7.24.5 + '@babel/helper-string-parser@7.25.9': {} - '@babel/helper-hoist-variables@7.22.5': - dependencies: - '@babel/types': 7.24.5 + '@babel/helper-validator-identifier@7.25.9': {} - '@babel/helper-member-expression-to-functions@7.24.5': - dependencies: - '@babel/types': 7.24.5 + '@babel/helper-validator-option@7.25.9': {} - '@babel/helper-module-imports@7.24.3': + '@babel/helpers@7.26.0': dependencies: - '@babel/types': 7.24.5 + '@babel/template': 7.25.9 + '@babel/types': 7.26.0 - '@babel/helper-module-transforms@7.24.5(@babel/core@7.24.5)': + '@babel/parser@7.26.2': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-module-imports': 7.24.3 - '@babel/helper-simple-access': 7.24.5 - '@babel/helper-split-export-declaration': 7.24.5 - '@babel/helper-validator-identifier': 7.24.5 + '@babel/types': 7.26.0 - '@babel/helper-optimise-call-expression@7.22.5': + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.26.0)': dependencies: - '@babel/types': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-plugin-utils@7.24.5': {} - - '@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.24.5)': + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-wrap-function': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-replace-supers@7.24.1(@babel/core@7.24.5)': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-member-expression-to-functions': 7.24.5 - '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-simple-access@7.24.5': + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.26.0)': dependencies: - '@babel/types': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-skip-transparent-expression-wrappers@7.22.5': + '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.26.0)': dependencies: - '@babel/types': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-split-export-declaration@7.24.5': + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.26.0)': dependencies: - '@babel/types': 7.24.5 - - '@babel/helper-string-parser@7.24.1': {} + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-validator-identifier@7.24.5': {} - - '@babel/helper-validator-option@7.23.5': {} - - '@babel/helper-wrap-function@7.24.5': + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.26.0)': dependencies: - '@babel/helper-function-name': 7.23.0 - '@babel/template': 7.24.0 - '@babel/types': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/helpers@7.24.5': + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/template': 7.24.0 - '@babel/traverse': 7.24.5 - '@babel/types': 7.24.5 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/highlight@7.24.5': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.26.0)': dependencies: - '@babel/helper-validator-identifier': 7.24.5 - chalk: 2.4.2 - js-tokens: 4.0.0 - picocolors: 1.0.0 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/parser@7.24.5': + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.26.0)': dependencies: - '@babel/types': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.5(@babel/core@7.24.5)': + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.1(@babel/core@7.24.5)': + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.1(@babel/core@7.24.5)': + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-transform-optional-chaining': 7.24.5(@babel/core@7.24.5) + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.1(@babel/core@7.24.5)': + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.5)': + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.5)': + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.5)': + '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.0)': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.5)': + '@babel/runtime@7.26.0': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + regenerator-runtime: 0.14.1 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.5)': + '@babel/template@7.25.9': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 - '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.5)': + '@babel/traverse@7.25.9': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.2 + '@babel/parser': 7.26.2 + '@babel/template': 7.25.9 + '@babel/types': 7.26.0 + debug: 4.3.7 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color - '@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.5)': + '@babel/types@7.26.0': dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 - '@babel/plugin-syntax-import-assertions@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@bcoe/v8-coverage@0.2.3': {} - '@babel/plugin-syntax-import-attributes@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/aix-ppc64@0.21.5': + optional: true - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/aix-ppc64@0.23.1': + optional: true - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/aix-ppc64@0.24.0': + optional: true - '@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/android-arm64@0.21.5': + optional: true - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/android-arm64@0.23.1': + optional: true - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/android-arm64@0.24.0': + optional: true - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/android-arm@0.21.5': + optional: true - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/android-arm@0.23.1': + optional: true - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/android-arm@0.24.0': + optional: true - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/android-x64@0.21.5': + optional: true - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/android-x64@0.23.1': + optional: true - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/android-x64@0.24.0': + optional: true - '@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/darwin-arm64@0.21.5': + optional: true - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/darwin-arm64@0.23.1': + optional: true - '@babel/plugin-transform-arrow-functions@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/darwin-arm64@0.24.0': + optional: true - '@babel/plugin-transform-async-generator-functions@7.24.3(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.5) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.5) + '@esbuild/darwin-x64@0.21.5': + optional: true - '@babel/plugin-transform-async-to-generator@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-module-imports': 7.24.3 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.5) + '@esbuild/darwin-x64@0.23.1': + optional: true - '@babel/plugin-transform-block-scoped-functions@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/darwin-x64@0.24.0': + optional: true - '@babel/plugin-transform-block-scoping@7.24.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/freebsd-arm64@0.21.5': + optional: true - '@babel/plugin-transform-class-properties@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-class-features-plugin': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/freebsd-arm64@0.23.1': + optional: true - '@babel/plugin-transform-class-static-block@7.24.4(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-class-features-plugin': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.5) + '@esbuild/freebsd-arm64@0.24.0': + optional: true - '@babel/plugin-transform-classes@7.24.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.5) - '@babel/helper-split-export-declaration': 7.24.5 - globals: 11.12.0 + '@esbuild/freebsd-x64@0.21.5': + optional: true - '@babel/plugin-transform-computed-properties@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/template': 7.24.0 + '@esbuild/freebsd-x64@0.23.1': + optional: true - '@babel/plugin-transform-destructuring@7.24.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/freebsd-x64@0.24.0': + optional: true - '@babel/plugin-transform-dotall-regex@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/linux-arm64@0.21.5': + optional: true - '@babel/plugin-transform-duplicate-keys@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/linux-arm64@0.23.1': + optional: true - '@babel/plugin-transform-dynamic-import@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.5) + '@esbuild/linux-arm64@0.24.0': + optional: true - '@babel/plugin-transform-exponentiation-operator@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/linux-arm@0.21.5': + optional: true - '@babel/plugin-transform-export-namespace-from@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.5) + '@esbuild/linux-arm@0.23.1': + optional: true - '@babel/plugin-transform-for-of@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@esbuild/linux-arm@0.24.0': + optional: true - '@babel/plugin-transform-function-name@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/linux-ia32@0.21.5': + optional: true - '@babel/plugin-transform-json-strings@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.5) + '@esbuild/linux-ia32@0.23.1': + optional: true - '@babel/plugin-transform-literals@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/linux-ia32@0.24.0': + optional: true - '@babel/plugin-transform-logical-assignment-operators@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.5) + '@esbuild/linux-loong64@0.21.5': + optional: true - '@babel/plugin-transform-member-expression-literals@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/linux-loong64@0.23.1': + optional: true - '@babel/plugin-transform-modules-amd@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/linux-loong64@0.24.0': + optional: true - '@babel/plugin-transform-modules-commonjs@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-simple-access': 7.24.5 + '@esbuild/linux-mips64el@0.21.5': + optional: true - '@babel/plugin-transform-modules-systemjs@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-validator-identifier': 7.24.5 + '@esbuild/linux-mips64el@0.23.1': + optional: true - '@babel/plugin-transform-modules-umd@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/linux-mips64el@0.24.0': + optional: true - '@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/linux-ppc64@0.21.5': + optional: true - '@babel/plugin-transform-new-target@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/linux-ppc64@0.23.1': + optional: true - '@babel/plugin-transform-nullish-coalescing-operator@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.5) + '@esbuild/linux-ppc64@0.24.0': + optional: true - '@babel/plugin-transform-numeric-separator@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.5) + '@esbuild/linux-riscv64@0.21.5': + optional: true - '@babel/plugin-transform-object-rest-spread@7.24.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-transform-parameters': 7.24.5(@babel/core@7.24.5) + '@esbuild/linux-riscv64@0.23.1': + optional: true - '@babel/plugin-transform-object-super@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.5) + '@esbuild/linux-riscv64@0.24.0': + optional: true - '@babel/plugin-transform-optional-catch-binding@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.5) + '@esbuild/linux-s390x@0.21.5': + optional: true - '@babel/plugin-transform-optional-chaining@7.24.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.5) + '@esbuild/linux-s390x@0.23.1': + optional: true - '@babel/plugin-transform-parameters@7.24.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/linux-s390x@0.24.0': + optional: true - '@babel/plugin-transform-private-methods@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-class-features-plugin': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/linux-x64@0.21.5': + optional: true - '@babel/plugin-transform-private-property-in-object@7.24.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.24.5(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.5) + '@esbuild/linux-x64@0.23.1': + optional: true - '@babel/plugin-transform-property-literals@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/linux-x64@0.24.0': + optional: true - '@babel/plugin-transform-regenerator@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - regenerator-transform: 0.15.2 + '@esbuild/netbsd-x64@0.21.5': + optional: true - '@babel/plugin-transform-reserved-words@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/netbsd-x64@0.23.1': + optional: true - '@babel/plugin-transform-shorthand-properties@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 + '@esbuild/netbsd-x64@0.24.0': + optional: true - '@babel/plugin-transform-spread@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - - '@babel/plugin-transform-sticky-regex@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - - '@babel/plugin-transform-template-literals@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - - '@babel/plugin-transform-typeof-symbol@7.24.5(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - - '@babel/plugin-transform-unicode-escapes@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - - '@babel/plugin-transform-unicode-property-regex@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 - - '@babel/plugin-transform-unicode-regex@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 - - '@babel/plugin-transform-unicode-sets-regex@7.24.1(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.5) - '@babel/helper-plugin-utils': 7.24.5 - - '@babel/preset-env@7.24.5(@babel/core@7.24.5)': - dependencies: - '@babel/compat-data': 7.24.4 - '@babel/core': 7.24.5 - '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.5) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.5) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.5) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.5) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-import-assertions': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-syntax-import-attributes': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.5) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.5) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.5) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.5) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.5) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.24.5) - '@babel/plugin-transform-arrow-functions': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-async-generator-functions': 7.24.3(@babel/core@7.24.5) - '@babel/plugin-transform-async-to-generator': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-block-scoped-functions': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-block-scoping': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-class-properties': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-class-static-block': 7.24.4(@babel/core@7.24.5) - '@babel/plugin-transform-classes': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-computed-properties': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-destructuring': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-dotall-regex': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-duplicate-keys': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-dynamic-import': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-exponentiation-operator': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-export-namespace-from': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-for-of': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-function-name': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-json-strings': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-literals': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-logical-assignment-operators': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-member-expression-literals': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-modules-amd': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-modules-commonjs': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-modules-systemjs': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-modules-umd': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.24.5) - '@babel/plugin-transform-new-target': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-nullish-coalescing-operator': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-numeric-separator': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-object-rest-spread': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-object-super': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-optional-catch-binding': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-optional-chaining': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-parameters': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-private-methods': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-private-property-in-object': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-property-literals': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-regenerator': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-reserved-words': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-shorthand-properties': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-spread': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-sticky-regex': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-template-literals': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-typeof-symbol': 7.24.5(@babel/core@7.24.5) - '@babel/plugin-transform-unicode-escapes': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-unicode-property-regex': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-unicode-regex': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-transform-unicode-sets-regex': 7.24.1(@babel/core@7.24.5) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.24.5) - babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.24.5) - babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.24.5) - babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.24.5) - core-js-compat: 3.37.0 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color + '@esbuild/openbsd-arm64@0.23.1': + optional: true - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.5)': - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-plugin-utils': 7.24.5 - '@babel/types': 7.24.5 - esutils: 2.0.3 + '@esbuild/openbsd-arm64@0.24.0': + optional: true - '@babel/regjsgen@0.8.0': {} + '@esbuild/openbsd-x64@0.21.5': + optional: true - '@babel/runtime@7.24.5': - dependencies: - regenerator-runtime: 0.14.1 + '@esbuild/openbsd-x64@0.23.1': + optional: true - '@babel/template@7.24.0': - dependencies: - '@babel/code-frame': 7.24.2 - '@babel/parser': 7.24.5 - '@babel/types': 7.24.5 + '@esbuild/openbsd-x64@0.24.0': + optional: true - '@babel/traverse@7.24.5': - dependencies: - '@babel/code-frame': 7.24.2 - '@babel/generator': 7.24.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.24.5 - '@babel/parser': 7.24.5 - '@babel/types': 7.24.5 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color + '@esbuild/sunos-x64@0.21.5': + optional: true - '@babel/types@7.24.5': - dependencies: - '@babel/helper-string-parser': 7.24.1 - '@babel/helper-validator-identifier': 7.24.5 - to-fast-properties: 2.0.0 + '@esbuild/sunos-x64@0.23.1': + optional: true - '@bcoe/v8-coverage@0.2.3': {} + '@esbuild/sunos-x64@0.24.0': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.23.1': + optional: true + + '@esbuild/win32-arm64@0.24.0': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.23.1': + optional: true + + '@esbuild/win32-ia32@0.24.0': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@esbuild/win32-x64@0.23.1': + optional: true + + '@esbuild/win32-x64@0.24.0': + optional: true + + '@eslint-community/eslint-utils@4.4.1(eslint@9.14.0)': + dependencies: + eslint: 9.14.0 + eslint-visitor-keys: 3.4.3 - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 + '@eslint-community/regexpp@4.12.1': {} - '@eslint-community/eslint-utils@4.4.0(eslint@9.2.0)': + '@eslint/config-array@0.18.0': dependencies: - eslint: 9.2.0 - eslint-visitor-keys: 3.4.3 + '@eslint/object-schema': 2.1.4 + debug: 4.3.7 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color - '@eslint-community/regexpp@4.10.0': {} + '@eslint/core@0.7.0': {} - '@eslint/eslintrc@3.0.2': + '@eslint/eslintrc@3.1.0': dependencies: ajv: 6.12.6 - debug: 4.3.4 - espree: 10.0.1 + debug: 4.3.7 + espree: 10.3.0 globals: 14.0.0 - ignore: 5.3.1 + ignore: 5.3.2 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -3391,21 +3349,35 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.2.0': {} + '@eslint/js@9.14.0': {} + + '@eslint/object-schema@2.1.4': {} - '@humanwhocodes/config-array@0.13.0': + '@eslint/plugin-kit@0.2.3': dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color + levn: 0.4.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.6': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/object-schema@2.0.3': {} + '@humanwhocodes/retry@0.3.1': {} + + '@humanwhocodes/retry@0.4.1': {} - '@humanwhocodes/retry@0.2.4': {} + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 '@istanbuljs/load-nyc-config@1.1.0': dependencies: @@ -3420,27 +3392,27 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 20.12.11 + '@types/node': 22.9.0 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5))': + '@jest/core@29.7.0': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.12.11 + '@types/node': 22.9.0 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.12.11)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5)) + jest-config: 29.7.0(@types/node@22.9.0) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -3452,7 +3424,7 @@ snapshots: jest-util: 29.7.0 jest-validate: 29.7.0 jest-watcher: 29.7.0 - micromatch: 4.0.5 + micromatch: 4.0.8 pretty-format: 29.7.0 slash: 3.0.0 strip-ansi: 6.0.1 @@ -3465,7 +3437,7 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.12.11 + '@types/node': 22.9.0 jest-mock: 29.7.0 '@jest/expect-utils@29.7.0': @@ -3483,7 +3455,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.12.11 + '@types/node': 22.9.0 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -3505,14 +3477,14 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 20.12.11 + '@types/node': 22.9.0 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 glob: 7.2.3 graceful-fs: 4.2.11 istanbul-lib-coverage: 3.2.2 - istanbul-lib-instrument: 6.0.2 + istanbul-lib-instrument: 6.0.3 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 4.0.1 istanbul-reports: 3.1.7 @@ -3522,7 +3494,7 @@ snapshots: slash: 3.0.0 string-length: 4.0.2 strip-ansi: 6.0.1 - v8-to-istanbul: 9.2.0 + v8-to-istanbul: 9.3.0 transitivePeerDependencies: - supports-color @@ -3552,7 +3524,7 @@ snapshots: '@jest/transform@29.7.0': dependencies: - '@babel/core': 7.24.5 + '@babel/core': 7.26.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 babel-plugin-istanbul: 6.1.1 @@ -3563,7 +3535,7 @@ snapshots: jest-haste-map: 29.7.0 jest-regex-util: 29.6.3 jest-util: 29.7.0 - micromatch: 4.0.5 + micromatch: 4.0.8 pirates: 4.0.6 slash: 3.0.0 write-file-atomic: 4.0.2 @@ -3575,14 +3547,14 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.12.11 - '@types/yargs': 17.0.32 + '@types/node': 22.9.0 + '@types/yargs': 17.0.33 chalk: 4.1.2 '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping': 0.3.25 '@jridgewell/resolve-uri@3.1.2': {} @@ -3594,17 +3566,12 @@ snapshots: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - '@jridgewell/sourcemap-codec@1.4.15': {} + '@jridgewell/sourcemap-codec@1.5.0': {} '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 '@nodelib/fs.scandir@2.1.5': dependencies: @@ -3618,79 +3585,150 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 + '@parcel/watcher-android-arm64@2.5.0': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.0': + optional: true + + '@parcel/watcher-darwin-x64@2.5.0': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.0': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.0': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.0': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.0': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.0': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.0': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.0': + optional: true + + '@parcel/watcher-win32-arm64@2.5.0': + optional: true + + '@parcel/watcher-win32-ia32@2.5.0': + optional: true + + '@parcel/watcher-win32-x64@2.5.0': + optional: true + + '@parcel/watcher@2.5.0': + dependencies: + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.8 + node-addon-api: 7.1.1 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.0 + '@parcel/watcher-darwin-arm64': 2.5.0 + '@parcel/watcher-darwin-x64': 2.5.0 + '@parcel/watcher-freebsd-x64': 2.5.0 + '@parcel/watcher-linux-arm-glibc': 2.5.0 + '@parcel/watcher-linux-arm-musl': 2.5.0 + '@parcel/watcher-linux-arm64-glibc': 2.5.0 + '@parcel/watcher-linux-arm64-musl': 2.5.0 + '@parcel/watcher-linux-x64-glibc': 2.5.0 + '@parcel/watcher-linux-x64-musl': 2.5.0 + '@parcel/watcher-win32-arm64': 2.5.0 + '@parcel/watcher-win32-ia32': 2.5.0 + '@parcel/watcher-win32-x64': 2.5.0 + optional: true + '@pkgr/core@0.1.1': {} - '@rollup/plugin-terser@0.4.4(rollup@4.17.2)': + '@playwright/test@1.48.2': + dependencies: + playwright: 1.48.2 + + '@rollup/plugin-terser@0.4.4(rollup@4.27.0)': dependencies: serialize-javascript: 6.0.2 smob: 1.5.0 - terser: 5.31.0 + terser: 5.36.0 optionalDependencies: - rollup: 4.17.2 + rollup: 4.27.0 - '@rollup/plugin-typescript@11.1.6(rollup@4.17.2)(tslib@2.6.2)(typescript@5.4.5)': + '@rollup/plugin-typescript@12.1.1(rollup@4.27.0)(tslib@2.8.1)(typescript@5.6.3)': dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.17.2) + '@rollup/pluginutils': 5.1.3(rollup@4.27.0) resolve: 1.22.8 - typescript: 5.4.5 + typescript: 5.6.3 optionalDependencies: - rollup: 4.17.2 - tslib: 2.6.2 + rollup: 4.27.0 + tslib: 2.8.1 - '@rollup/pluginutils@5.1.0(rollup@4.17.2)': + '@rollup/pluginutils@5.1.3(rollup@4.27.0)': dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 estree-walker: 2.0.2 - picomatch: 2.3.1 + picomatch: 4.0.2 optionalDependencies: - rollup: 4.17.2 + rollup: 4.27.0 + + '@rollup/rollup-android-arm-eabi@4.27.0': + optional: true + + '@rollup/rollup-android-arm64@4.27.0': + optional: true - '@rollup/rollup-android-arm-eabi@4.17.2': + '@rollup/rollup-darwin-arm64@4.27.0': optional: true - '@rollup/rollup-android-arm64@4.17.2': + '@rollup/rollup-darwin-x64@4.27.0': optional: true - '@rollup/rollup-darwin-arm64@4.17.2': + '@rollup/rollup-freebsd-arm64@4.27.0': optional: true - '@rollup/rollup-darwin-x64@4.17.2': + '@rollup/rollup-freebsd-x64@4.27.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.17.2': + '@rollup/rollup-linux-arm-gnueabihf@4.27.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.17.2': + '@rollup/rollup-linux-arm-musleabihf@4.27.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.17.2': + '@rollup/rollup-linux-arm64-gnu@4.27.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.17.2': + '@rollup/rollup-linux-arm64-musl@4.27.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.17.2': + '@rollup/rollup-linux-powerpc64le-gnu@4.27.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.17.2': + '@rollup/rollup-linux-riscv64-gnu@4.27.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.17.2': + '@rollup/rollup-linux-s390x-gnu@4.27.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.17.2': + '@rollup/rollup-linux-x64-gnu@4.27.0': optional: true - '@rollup/rollup-linux-x64-musl@4.17.2': + '@rollup/rollup-linux-x64-musl@4.27.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.17.2': + '@rollup/rollup-win32-arm64-msvc@4.27.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.17.2': + '@rollup/rollup-win32-ia32-msvc@4.27.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.17.2': + '@rollup/rollup-win32-x64-msvc@4.27.0': optional: true '@sinclair/typebox@0.27.8': {} @@ -3703,10 +3741,10 @@ snapshots: dependencies: '@sinonjs/commons': 3.0.1 - '@testing-library/dom@10.1.0': + '@testing-library/dom@10.4.0': dependencies: - '@babel/code-frame': 7.24.2 - '@babel/runtime': 7.24.5 + '@babel/code-frame': 7.26.2 + '@babel/runtime': 7.26.0 '@types/aria-query': 5.0.4 aria-query: 5.3.0 chalk: 4.1.2 @@ -3714,56 +3752,44 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.4.5(@jest/globals@29.7.0)(jest@29.7.0(@types/node@20.12.11)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5)))': + '@testing-library/jest-dom@6.6.3': dependencies: - '@adobe/css-tools': 4.3.3 - '@babel/runtime': 7.24.5 - aria-query: 5.3.0 + '@adobe/css-tools': 4.4.1 + aria-query: 5.3.2 chalk: 3.0.0 css.escape: 1.5.1 dom-accessibility-api: 0.6.3 lodash: 4.17.21 redent: 3.0.0 - optionalDependencies: - '@jest/globals': 29.7.0 - jest: 29.7.0(@types/node@20.12.11)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5)) - - '@tsconfig/node10@1.0.11': {} - - '@tsconfig/node12@1.0.11': {} - - '@tsconfig/node14@1.0.3': {} - - '@tsconfig/node16@1.0.4': {} '@types/aria-query@5.0.4': {} '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.24.5 - '@babel/types': 7.24.5 + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.20.5 + '@types/babel__traverse': 7.20.6 '@types/babel__generator@7.6.8': dependencies: - '@babel/types': 7.24.5 + '@babel/types': 7.26.0 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.24.5 - '@babel/types': 7.24.5 + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 - '@types/babel__traverse@7.20.5': + '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.24.5 + '@babel/types': 7.26.0 - '@types/estree@1.0.5': {} + '@types/estree@1.0.6': {} '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 20.12.11 + '@types/node': 22.9.0 '@types/istanbul-lib-coverage@2.0.6': {} @@ -3775,110 +3801,158 @@ snapshots: dependencies: '@types/istanbul-lib-report': 3.0.3 - '@types/node@20.12.11': + '@types/jsdom@21.1.7': dependencies: - undici-types: 5.26.5 + '@types/node': 22.9.0 + '@types/tough-cookie': 4.0.5 + parse5: 7.2.1 + + '@types/json-schema@7.0.15': {} + + '@types/node@22.9.0': + dependencies: + undici-types: 6.19.8 '@types/stack-utils@2.0.3': {} + '@types/tough-cookie@4.0.5': {} + '@types/yargs-parser@21.0.3': {} - '@types/yargs@17.0.32': + '@types/yargs@17.0.33': dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@7.9.0(@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5))(eslint@9.2.0)(typescript@5.4.5)': + '@typescript-eslint/eslint-plugin@8.14.0(@typescript-eslint/parser@8.14.0(eslint@9.14.0)(typescript@5.6.3))(eslint@9.14.0)(typescript@5.6.3)': dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.9.0(eslint@9.2.0)(typescript@5.4.5) - '@typescript-eslint/scope-manager': 7.9.0 - '@typescript-eslint/type-utils': 7.9.0(eslint@9.2.0)(typescript@5.4.5) - '@typescript-eslint/utils': 7.9.0(eslint@9.2.0)(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.9.0 - eslint: 9.2.0 + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.14.0(eslint@9.14.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.14.0 + '@typescript-eslint/type-utils': 8.14.0(eslint@9.14.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.14.0(eslint@9.14.0)(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.14.0 + eslint: 9.14.0 graphemer: 1.4.0 - ignore: 5.3.1 + ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.4.5) + ts-api-utils: 1.4.0(typescript@5.6.3) optionalDependencies: - typescript: 5.4.5 + typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5)': + '@typescript-eslint/parser@8.14.0(eslint@9.14.0)(typescript@5.6.3)': dependencies: - '@typescript-eslint/scope-manager': 7.9.0 - '@typescript-eslint/types': 7.9.0 - '@typescript-eslint/typescript-estree': 7.9.0(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.9.0 - debug: 4.3.4 - eslint: 9.2.0 + '@typescript-eslint/scope-manager': 8.14.0 + '@typescript-eslint/types': 8.14.0 + '@typescript-eslint/typescript-estree': 8.14.0(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.14.0 + debug: 4.3.7 + eslint: 9.14.0 optionalDependencies: - typescript: 5.4.5 + typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@7.9.0': + '@typescript-eslint/scope-manager@8.14.0': dependencies: - '@typescript-eslint/types': 7.9.0 - '@typescript-eslint/visitor-keys': 7.9.0 + '@typescript-eslint/types': 8.14.0 + '@typescript-eslint/visitor-keys': 8.14.0 - '@typescript-eslint/type-utils@7.9.0(eslint@9.2.0)(typescript@5.4.5)': + '@typescript-eslint/type-utils@8.14.0(eslint@9.14.0)(typescript@5.6.3)': dependencies: - '@typescript-eslint/typescript-estree': 7.9.0(typescript@5.4.5) - '@typescript-eslint/utils': 7.9.0(eslint@9.2.0)(typescript@5.4.5) - debug: 4.3.4 - eslint: 9.2.0 - ts-api-utils: 1.3.0(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 8.14.0(typescript@5.6.3) + '@typescript-eslint/utils': 8.14.0(eslint@9.14.0)(typescript@5.6.3) + debug: 4.3.7 + ts-api-utils: 1.4.0(typescript@5.6.3) optionalDependencies: - typescript: 5.4.5 + typescript: 5.6.3 transitivePeerDependencies: + - eslint - supports-color - '@typescript-eslint/types@7.9.0': {} + '@typescript-eslint/types@8.14.0': {} - '@typescript-eslint/typescript-estree@7.9.0(typescript@5.4.5)': + '@typescript-eslint/typescript-estree@8.14.0(typescript@5.6.3)': dependencies: - '@typescript-eslint/types': 7.9.0 - '@typescript-eslint/visitor-keys': 7.9.0 - debug: 4.3.4 - globby: 11.1.0 + '@typescript-eslint/types': 8.14.0 + '@typescript-eslint/visitor-keys': 8.14.0 + debug: 4.3.7 + fast-glob: 3.3.2 is-glob: 4.0.3 - minimatch: 9.0.4 - semver: 7.6.2 - ts-api-utils: 1.3.0(typescript@5.4.5) + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.4.0(typescript@5.6.3) optionalDependencies: - typescript: 5.4.5 + typescript: 5.6.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.9.0(eslint@9.2.0)(typescript@5.4.5)': + '@typescript-eslint/utils@8.14.0(eslint@9.14.0)(typescript@5.6.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.2.0) - '@typescript-eslint/scope-manager': 7.9.0 - '@typescript-eslint/types': 7.9.0 - '@typescript-eslint/typescript-estree': 7.9.0(typescript@5.4.5) - eslint: 9.2.0 + '@eslint-community/eslint-utils': 4.4.1(eslint@9.14.0) + '@typescript-eslint/scope-manager': 8.14.0 + '@typescript-eslint/types': 8.14.0 + '@typescript-eslint/typescript-estree': 8.14.0(typescript@5.6.3) + eslint: 9.14.0 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/visitor-keys@7.9.0': + '@typescript-eslint/visitor-keys@8.14.0': dependencies: - '@typescript-eslint/types': 7.9.0 + '@typescript-eslint/types': 8.14.0 eslint-visitor-keys: 3.4.3 - acorn-jsx@5.3.2(acorn@8.11.3): + '@vitest/expect@2.1.5': + dependencies: + '@vitest/spy': 2.1.5 + '@vitest/utils': 2.1.5 + chai: 5.1.2 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.5(vite@5.4.11(@types/node@22.9.0)(sass@1.81.0)(terser@5.36.0))': + dependencies: + '@vitest/spy': 2.1.5 + estree-walker: 3.0.3 + magic-string: 0.30.12 + optionalDependencies: + vite: 5.4.11(@types/node@22.9.0)(sass@1.81.0)(terser@5.36.0) + + '@vitest/pretty-format@2.1.5': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.5': + dependencies: + '@vitest/utils': 2.1.5 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.5': + dependencies: + '@vitest/pretty-format': 2.1.5 + magic-string: 0.30.12 + pathe: 1.1.2 + + '@vitest/spy@2.1.5': dependencies: - acorn: 8.11.3 + tinyspy: 3.0.2 - acorn-walk@8.3.2: {} + '@vitest/utils@2.1.5': + dependencies: + '@vitest/pretty-format': 2.1.5 + loupe: 3.1.2 + tinyrainbow: 1.2.0 + + acorn-jsx@5.3.2(acorn@8.14.0): + dependencies: + acorn: 8.14.0 - acorn@8.11.3: {} + acorn@8.14.0: {} agent-base@7.1.1: dependencies: - debug: 4.3.4 + debug: 4.3.7 transitivePeerDependencies: - supports-color @@ -3895,9 +3969,7 @@ snapshots: ansi-regex@5.0.1: {} - ansi-styles@3.2.1: - dependencies: - color-convert: 1.9.3 + ansi-regex@6.1.0: {} ansi-styles@4.3.0: dependencies: @@ -3905,13 +3977,13 @@ snapshots: ansi-styles@5.2.0: {} + ansi-styles@6.2.1: {} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 - arg@4.1.3: {} - argparse@1.0.10: dependencies: sprintf-js: 1.0.3 @@ -3922,17 +3994,29 @@ snapshots: dependencies: dequal: 2.0.3 - array-union@2.1.0: {} + aria-query@5.3.2: {} + + assertion-error@2.0.1: {} asynckit@0.4.0: {} - babel-jest@29.7.0(@babel/core@7.24.5): + autoprefixer@10.4.20(postcss@8.4.49): + dependencies: + browserslist: 4.24.2 + caniuse-lite: 1.0.30001680 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.1.1 + postcss: 8.4.49 + postcss-value-parser: 4.2.0 + + babel-jest@29.7.0(@babel/core@7.26.0): dependencies: - '@babel/core': 7.24.5 + '@babel/core': 7.26.0 '@jest/transform': 29.7.0 '@types/babel__core': 7.20.5 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.24.5) + babel-preset-jest: 29.6.3(@babel/core@7.26.0) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 @@ -3941,7 +4025,7 @@ snapshots: babel-plugin-istanbul@6.1.1: dependencies: - '@babel/helper-plugin-utils': 7.24.5 + '@babel/helper-plugin-utils': 7.25.9 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-instrument: 5.2.1 @@ -3951,61 +4035,38 @@ snapshots: babel-plugin-jest-hoist@29.6.3: dependencies: - '@babel/template': 7.24.0 - '@babel/types': 7.24.5 + '@babel/template': 7.25.9 + '@babel/types': 7.26.0 '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.20.5 - - babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.24.5): - dependencies: - '@babel/compat-data': 7.24.4 - '@babel/core': 7.24.5 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.5) - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - babel-plugin-polyfill-corejs3@0.10.4(@babel/core@7.24.5): - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.5) - core-js-compat: 3.37.0 - transitivePeerDependencies: - - supports-color - - babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.24.5): - dependencies: - '@babel/core': 7.24.5 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.5) - transitivePeerDependencies: - - supports-color - - babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.5): - dependencies: - '@babel/core': 7.24.5 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.5) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.5) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.5) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.5) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.5) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.5) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.5) - - babel-preset-jest@29.6.3(@babel/core@7.24.5): - dependencies: - '@babel/core': 7.24.5 + '@types/babel__traverse': 7.20.6 + + babel-preset-current-node-syntax@1.1.0(@babel/core@7.26.0): + dependencies: + '@babel/core': 7.26.0 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.26.0) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.26.0) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.26.0) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.26.0) + '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.26.0) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.26.0) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.26.0) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.26.0) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.26.0) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.26.0) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.26.0) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.26.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.26.0) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.26.0) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.26.0) + + babel-preset-jest@29.6.3(@babel/core@7.26.0): + dependencies: + '@babel/core': 7.26.0 babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.5) + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.26.0) balanced-match@1.0.2: {} - binary-extensions@2.3.0: {} - brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -4015,16 +4076,16 @@ snapshots: dependencies: balanced-match: 1.0.2 - braces@3.0.2: + braces@3.0.3: dependencies: - fill-range: 7.0.1 + fill-range: 7.1.1 - browserslist@4.23.0: + browserslist@4.24.2: dependencies: - caniuse-lite: 1.0.30001617 - electron-to-chromium: 1.4.764 - node-releases: 2.0.14 - update-browserslist-db: 1.0.15(browserslist@4.23.0) + caniuse-lite: 1.0.30001680 + electron-to-chromium: 1.5.60 + node-releases: 2.0.18 + update-browserslist-db: 1.1.1(browserslist@4.24.2) bser@2.1.1: dependencies: @@ -4032,19 +4093,23 @@ snapshots: buffer-from@1.1.2: {} + cac@6.7.14: {} + callsites@3.1.0: {} camelcase@5.3.1: {} camelcase@6.3.0: {} - caniuse-lite@1.0.30001617: {} + caniuse-lite@1.0.30001680: {} - chalk@2.4.2: + chai@5.1.2: dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.2 + pathval: 2.0.0 chalk@3.0.0: dependencies: @@ -4058,21 +4123,15 @@ snapshots: char-regex@1.0.2: {} - chokidar@3.6.0: + check-error@2.1.1: {} + + chokidar@4.0.1: dependencies: - anymatch: 3.1.3 - braces: 3.0.2 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 + readdirp: 4.0.2 ci-info@3.9.0: {} - cjs-module-lexer@1.3.1: {} + cjs-module-lexer@1.4.1: {} cliui@8.0.1: dependencies: @@ -4096,16 +4155,10 @@ snapshots: collect-v8-coverage@1.0.2: {} - color-convert@1.9.3: - dependencies: - color-name: 1.1.3 - color-convert@2.0.1: dependencies: color-name: 1.1.4 - color-name@1.1.3: {} - color-name@1.1.4: {} combined-stream@1.0.8: @@ -4118,19 +4171,15 @@ snapshots: convert-source-map@2.0.0: {} - core-js-compat@3.37.0: - dependencies: - browserslist: 4.23.0 - core-util-is@1.0.3: {} - create-jest@29.7.0(@types/node@20.12.11)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5)): + create-jest@29.7.0(@types/node@22.9.0): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.12.11)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5)) + jest-config: 29.7.0(@types/node@22.9.0) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -4139,13 +4188,11 @@ snapshots: - supports-color - ts-node - create-require@1.1.1: {} - cross-env@7.0.3: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.5 - cross-spawn@7.0.3: + cross-spawn@7.0.5: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 @@ -4153,23 +4200,25 @@ snapshots: css.escape@1.5.1: {} - cssstyle@4.0.1: + cssstyle@4.1.0: dependencies: - rrweb-cssom: 0.6.0 + rrweb-cssom: 0.7.1 data-urls@5.0.0: dependencies: whatwg-mimetype: 4.0.0 whatwg-url: 14.0.0 - debug@4.3.4: + debug@4.3.7: dependencies: - ms: 2.1.2 + ms: 2.1.3 decimal.js@10.4.3: {} dedent@1.5.3: {} + deep-eql@5.0.2: {} + deep-is@0.1.4: {} deepmerge@4.3.1: {} @@ -4178,110 +4227,192 @@ snapshots: dequal@2.0.3: {} + detect-libc@1.0.3: + optional: true + detect-newline@3.1.0: {} diff-sequences@29.6.3: {} - diff@4.0.2: {} - - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - dom-accessibility-api@0.5.16: {} dom-accessibility-api@0.6.3: {} - electron-to-chromium@1.4.764: {} + eastasianwidth@0.2.0: {} + + electron-to-chromium@1.5.60: {} emittery@0.13.1: {} emoji-regex@8.0.0: {} + emoji-regex@9.2.2: {} + entities@4.5.0: {} error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 - escalade@3.1.2: {} + es-module-lexer@1.5.4: {} - escape-string-regexp@1.0.5: {} + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + esbuild@0.23.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.23.1 + '@esbuild/android-arm': 0.23.1 + '@esbuild/android-arm64': 0.23.1 + '@esbuild/android-x64': 0.23.1 + '@esbuild/darwin-arm64': 0.23.1 + '@esbuild/darwin-x64': 0.23.1 + '@esbuild/freebsd-arm64': 0.23.1 + '@esbuild/freebsd-x64': 0.23.1 + '@esbuild/linux-arm': 0.23.1 + '@esbuild/linux-arm64': 0.23.1 + '@esbuild/linux-ia32': 0.23.1 + '@esbuild/linux-loong64': 0.23.1 + '@esbuild/linux-mips64el': 0.23.1 + '@esbuild/linux-ppc64': 0.23.1 + '@esbuild/linux-riscv64': 0.23.1 + '@esbuild/linux-s390x': 0.23.1 + '@esbuild/linux-x64': 0.23.1 + '@esbuild/netbsd-x64': 0.23.1 + '@esbuild/openbsd-arm64': 0.23.1 + '@esbuild/openbsd-x64': 0.23.1 + '@esbuild/sunos-x64': 0.23.1 + '@esbuild/win32-arm64': 0.23.1 + '@esbuild/win32-ia32': 0.23.1 + '@esbuild/win32-x64': 0.23.1 + + esbuild@0.24.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.24.0 + '@esbuild/android-arm': 0.24.0 + '@esbuild/android-arm64': 0.24.0 + '@esbuild/android-x64': 0.24.0 + '@esbuild/darwin-arm64': 0.24.0 + '@esbuild/darwin-x64': 0.24.0 + '@esbuild/freebsd-arm64': 0.24.0 + '@esbuild/freebsd-x64': 0.24.0 + '@esbuild/linux-arm': 0.24.0 + '@esbuild/linux-arm64': 0.24.0 + '@esbuild/linux-ia32': 0.24.0 + '@esbuild/linux-loong64': 0.24.0 + '@esbuild/linux-mips64el': 0.24.0 + '@esbuild/linux-ppc64': 0.24.0 + '@esbuild/linux-riscv64': 0.24.0 + '@esbuild/linux-s390x': 0.24.0 + '@esbuild/linux-x64': 0.24.0 + '@esbuild/netbsd-x64': 0.24.0 + '@esbuild/openbsd-arm64': 0.24.0 + '@esbuild/openbsd-x64': 0.24.0 + '@esbuild/sunos-x64': 0.24.0 + '@esbuild/win32-arm64': 0.24.0 + '@esbuild/win32-ia32': 0.24.0 + '@esbuild/win32-x64': 0.24.0 + + escalade@3.2.0: {} escape-string-regexp@2.0.0: {} escape-string-regexp@4.0.0: {} - eslint-config-prettier@9.1.0(eslint@9.2.0): + eslint-config-prettier@9.1.0(eslint@9.14.0): dependencies: - eslint: 9.2.0 + eslint: 9.14.0 - eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0(eslint@9.2.0))(eslint@9.2.0)(prettier@3.2.5): + eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@9.14.0))(eslint@9.14.0)(prettier@3.3.3): dependencies: - eslint: 9.2.0 - prettier: 3.2.5 + eslint: 9.14.0 + prettier: 3.3.3 prettier-linter-helpers: 1.0.0 - synckit: 0.8.8 + synckit: 0.9.2 optionalDependencies: - eslint-config-prettier: 9.1.0(eslint@9.2.0) + eslint-config-prettier: 9.1.0(eslint@9.14.0) - eslint-scope@8.0.1: + eslint-scope@8.2.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 eslint-visitor-keys@3.4.3: {} - eslint-visitor-keys@4.0.0: {} + eslint-visitor-keys@4.2.0: {} - eslint@9.2.0: + eslint@9.14.0: dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.2.0) - '@eslint-community/regexpp': 4.10.0 - '@eslint/eslintrc': 3.0.2 - '@eslint/js': 9.2.0 - '@humanwhocodes/config-array': 0.13.0 + '@eslint-community/eslint-utils': 4.4.1(eslint@9.14.0) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.18.0 + '@eslint/core': 0.7.0 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.14.0 + '@eslint/plugin-kit': 0.2.3 + '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.2.4 - '@nodelib/fs.walk': 1.2.8 + '@humanwhocodes/retry': 0.4.1 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4 + cross-spawn: 7.0.5 + debug: 4.3.7 escape-string-regexp: 4.0.0 - eslint-scope: 8.0.1 - eslint-visitor-keys: 4.0.0 - espree: 10.0.1 - esquery: 1.5.0 + eslint-scope: 8.2.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 8.0.0 find-up: 5.0.0 glob-parent: 6.0.2 - ignore: 5.3.1 + ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 - is-path-inside: 3.0.3 json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 - strip-ansi: 6.0.1 text-table: 0.2.0 transitivePeerDependencies: - supports-color - espree@10.0.1: + espree@10.3.0: dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) - eslint-visitor-keys: 4.0.0 + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) + eslint-visitor-keys: 4.2.0 esprima@4.0.1: {} - esquery@1.5.0: + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -4291,13 +4422,19 @@ snapshots: estraverse@5.3.0: {} + estree-walker@0.6.1: {} + estree-walker@2.0.2: {} + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.6 + esutils@2.0.3: {} execa@5.1.1: dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.5 get-stream: 6.0.1 human-signals: 2.1.0 is-stream: 2.0.1 @@ -4309,6 +4446,8 @@ snapshots: exit@0.1.2: {} + expect-type@1.1.0: {} + expect@29.7.0: dependencies: '@jest/expect-utils': 29.7.0 @@ -4327,7 +4466,7 @@ snapshots: '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.5 + micromatch: 4.0.8 fast-json-stable-stringify@2.1.0: {} @@ -4345,7 +4484,7 @@ snapshots: dependencies: flat-cache: 4.0.1 - fill-range@7.0.1: + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -4366,14 +4505,24 @@ snapshots: flatted@3.3.1: {} - form-data@4.0.0: + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.5 + signal-exit: 4.1.0 + + form-data@4.0.1: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 + fraction.js@4.3.7: {} + fs.realpath@1.0.0: {} + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true @@ -4387,6 +4536,10 @@ snapshots: get-stream@6.0.1: {} + get-tsconfig@4.8.1: + dependencies: + resolve-pkg-maps: 1.0.0 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -4395,6 +4548,15 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@11.0.0: + dependencies: + foreground-child: 3.3.0 + jackspeak: 4.0.2 + minimatch: 10.0.1 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 2.0.0 + glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -4408,17 +4570,6 @@ snapshots: globals@14.0.0: {} - globals@15.2.0: {} - - globby@11.1.0: - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.1 - merge2: 1.4.1 - slash: 3.0.0 - google-closure-compiler-java@20240317.0.0: {} google-closure-compiler-linux@20240317.0.0: @@ -4446,8 +4597,6 @@ snapshots: graphemer@1.4.0: {} - has-flag@3.0.0: {} - has-flag@4.0.0: {} hasown@2.0.2: @@ -4463,35 +4612,35 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.1 - debug: 4.3.4 + debug: 4.3.7 transitivePeerDependencies: - supports-color - https-proxy-agent@7.0.4: + https-proxy-agent@7.0.5: dependencies: agent-base: 7.1.1 - debug: 4.3.4 + debug: 4.3.7 transitivePeerDependencies: - supports-color human-signals@2.1.0: {} - husky@9.0.11: {} + husky@9.1.6: {} iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 - ignore@5.3.1: {} + ignore@5.3.2: {} - immutable@4.3.6: {} + immutable@5.0.2: {} import-fresh@3.3.0: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - import-local@3.1.0: + import-local@3.2.0: dependencies: pkg-dir: 4.2.0 resolve-cwd: 3.0.0 @@ -4509,11 +4658,7 @@ snapshots: is-arrayish@0.2.1: {} - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-core-module@2.13.1: + is-core-module@2.15.1: dependencies: hasown: 2.0.2 @@ -4529,8 +4674,6 @@ snapshots: is-number@7.0.0: {} - is-path-inside@3.0.3: {} - is-potential-custom-element-name@1.0.1: {} is-stream@2.0.1: {} @@ -4543,21 +4686,21 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.24.5 - '@babel/parser': 7.24.5 + '@babel/core': 7.26.0 + '@babel/parser': 7.26.2 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 transitivePeerDependencies: - supports-color - istanbul-lib-instrument@6.0.2: + istanbul-lib-instrument@6.0.3: dependencies: - '@babel/core': 7.24.5 - '@babel/parser': 7.24.5 + '@babel/core': 7.26.0 + '@babel/parser': 7.26.2 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 - semver: 7.6.2 + semver: 7.6.3 transitivePeerDependencies: - supports-color @@ -4569,7 +4712,7 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.3.4 + debug: 4.3.7 istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -4580,6 +4723,10 @@ snapshots: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 + jackspeak@4.0.2: + dependencies: + '@isaacs/cliui': 8.0.2 + jest-changed-files@29.7.0: dependencies: execa: 5.1.1 @@ -4592,7 +4739,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.12.11 + '@types/node': 22.9.0 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.3 @@ -4612,16 +4759,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@20.12.11)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5)): + jest-cli@29.7.0(@types/node@22.9.0): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5)) + '@jest/core': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.12.11)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5)) + create-jest: 29.7.0(@types/node@22.9.0) exit: 0.1.2 - import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.12.11)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5)) + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@22.9.0) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -4631,12 +4778,12 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@20.12.11)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5)): + jest-config@29.7.0(@types/node@22.9.0): dependencies: - '@babel/core': 7.24.5 + '@babel/core': 7.26.0 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.24.5) + babel-jest: 29.7.0(@babel/core@7.26.0) chalk: 4.1.2 ci-info: 3.9.0 deepmerge: 4.3.1 @@ -4650,14 +4797,13 @@ snapshots: jest-runner: 29.7.0 jest-util: 29.7.0 jest-validate: 29.7.0 - micromatch: 4.0.5 + micromatch: 4.0.8 parse-json: 5.2.0 pretty-format: 29.7.0 slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 20.12.11 - ts-node: 10.9.2(@types/node@20.12.11)(typescript@5.4.5) + '@types/node': 22.9.0 transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -4686,7 +4832,7 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.12.11 + '@types/node': 22.9.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -4696,14 +4842,14 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 20.12.11 + '@types/node': 22.9.0 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 jest-regex-util: 29.6.3 jest-util: 29.7.0 jest-worker: 29.7.0 - micromatch: 4.0.5 + micromatch: 4.0.8 walker: 1.0.8 optionalDependencies: fsevents: 2.3.3 @@ -4722,12 +4868,12 @@ snapshots: jest-message-util@29.7.0: dependencies: - '@babel/code-frame': 7.24.2 + '@babel/code-frame': 7.26.2 '@jest/types': 29.6.3 '@types/stack-utils': 2.0.3 chalk: 4.1.2 graceful-fs: 4.2.11 - micromatch: 4.0.5 + micromatch: 4.0.8 pretty-format: 29.7.0 slash: 3.0.0 stack-utils: 2.0.6 @@ -4735,7 +4881,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.12.11 + '@types/node': 22.9.0 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -4770,7 +4916,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.12.11 + '@types/node': 22.9.0 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -4798,9 +4944,9 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.12.11 + '@types/node': 22.9.0 chalk: 4.1.2 - cjs-module-lexer: 1.3.1 + cjs-module-lexer: 1.4.1 collect-v8-coverage: 1.0.2 glob: 7.2.3 graceful-fs: 4.2.11 @@ -4818,15 +4964,15 @@ snapshots: jest-snapshot@29.7.0: dependencies: - '@babel/core': 7.24.5 - '@babel/generator': 7.24.5 - '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.5) - '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.5) - '@babel/types': 7.24.5 + '@babel/core': 7.26.0 + '@babel/generator': 7.26.2 + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0) + '@babel/types': 7.26.0 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.5) + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.26.0) chalk: 4.1.2 expect: 29.7.0 graceful-fs: 4.2.11 @@ -4837,14 +4983,14 @@ snapshots: jest-util: 29.7.0 natural-compare: 1.4.0 pretty-format: 29.7.0 - semver: 7.6.2 + semver: 7.6.3 transitivePeerDependencies: - supports-color jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.12.11 + '@types/node': 22.9.0 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -4863,7 +5009,7 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.12.11 + '@types/node': 22.9.0 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -4872,17 +5018,17 @@ snapshots: jest-worker@29.7.0: dependencies: - '@types/node': 20.12.11 + '@types/node': 22.9.0 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@20.12.11)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5)): + jest@29.7.0(@types/node@22.9.0): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5)) + '@jest/core': 29.7.0 '@jest/types': 29.6.3 - import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.12.11)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5)) + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@22.9.0) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -4900,37 +5046,35 @@ snapshots: dependencies: argparse: 2.0.1 - jsdom@24.0.0: + jsdom@25.0.1: dependencies: - cssstyle: 4.0.1 + cssstyle: 4.1.0 data-urls: 5.0.0 decimal.js: 10.4.3 - form-data: 4.0.0 + form-data: 4.0.1 html-encoding-sniffer: 4.0.0 http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.4 + https-proxy-agent: 7.0.5 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.10 - parse5: 7.1.2 - rrweb-cssom: 0.6.0 + nwsapi: 2.2.13 + parse5: 7.2.1 + rrweb-cssom: 0.7.1 saxes: 6.0.0 symbol-tree: 3.2.4 - tough-cookie: 4.1.4 + tough-cookie: 5.0.0 w3c-xmlserializer: 5.0.0 webidl-conversions: 7.0.0 whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 whatwg-url: 14.0.0 - ws: 8.17.0 + ws: 8.18.0 xml-name-validator: 5.0.0 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - jsesc@0.5.0: {} - - jsesc@2.5.2: {} + jsesc@3.0.2: {} json-buffer@3.0.1: {} @@ -4965,23 +5109,27 @@ snapshots: dependencies: p-locate: 5.0.0 - lodash.debounce@4.0.8: {} - lodash.merge@4.6.2: {} lodash@4.17.21: {} + loupe@3.1.2: {} + + lru-cache@11.0.2: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 lz-string@1.5.0: {} - make-dir@4.0.0: + magic-string@0.30.12: dependencies: - semver: 7.6.2 + '@jridgewell/sourcemap-codec': 1.5.0 - make-error@1.3.6: {} + make-dir@4.0.0: + dependencies: + semver: 7.6.3 makeerror@1.0.12: dependencies: @@ -4991,9 +5139,9 @@ snapshots: merge2@1.4.1: {} - micromatch@4.0.5: + micromatch@4.0.8: dependencies: - braces: 3.0.2 + braces: 3.0.3 picomatch: 2.3.1 mime-db@1.52.0: {} @@ -5006,31 +5154,44 @@ snapshots: min-indent@1.0.1: {} + minimatch@10.0.1: + dependencies: + brace-expansion: 2.0.1 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 - minimatch@9.0.4: + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 minimist@1.2.8: {} - ms@2.1.2: {} + minipass@7.1.2: {} + + ms@2.1.3: {} + + nanoid@3.3.7: {} natural-compare@1.4.0: {} + node-addon-api@7.1.1: + optional: true + node-int64@0.4.0: {} - node-releases@2.0.14: {} + node-releases@2.0.18: {} normalize-path@3.0.0: {} + normalize-range@0.1.2: {} + npm-run-path@4.0.1: dependencies: path-key: 3.1.1 - nwsapi@2.2.10: {} + nwsapi@2.2.13: {} once@1.4.0: dependencies: @@ -5067,18 +5228,20 @@ snapshots: p-try@2.2.0: {} + package-json-from-dist@1.0.1: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.24.2 + '@babel/code-frame': 7.26.2 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - parse5@7.1.2: + parse5@7.2.1: dependencies: entities: 4.5.0 @@ -5090,25 +5253,50 @@ snapshots: path-parse@1.0.7: {} - path-type@4.0.0: {} + path-scurry@2.0.0: + dependencies: + lru-cache: 11.0.2 + minipass: 7.1.2 + + pathe@1.1.2: {} + + pathval@2.0.0: {} - picocolors@1.0.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} + picomatch@4.0.2: {} + pirates@4.0.6: {} pkg-dir@4.2.0: dependencies: find-up: 4.1.0 + playwright-core@1.48.2: {} + + playwright@1.48.2: + dependencies: + playwright-core: 1.48.2 + optionalDependencies: + fsevents: 2.3.2 + + postcss-value-parser@4.2.0: {} + + postcss@8.4.49: + dependencies: + nanoid: 3.3.7 + picocolors: 1.1.1 + source-map-js: 1.2.1 + prelude-ls@1.2.1: {} prettier-linter-helpers@1.0.0: dependencies: fast-diff: 1.3.0 - prettier@3.2.5: {} + prettier@3.3.3: {} pretty-format@27.5.1: dependencies: @@ -5129,14 +5317,10 @@ snapshots: kleur: 3.0.3 sisteransi: 1.0.5 - psl@1.9.0: {} - punycode@2.3.1: {} pure-rand@6.1.0: {} - querystringify@2.2.0: {} - queue-microtask@1.2.3: {} randombytes@2.1.0: @@ -5157,48 +5341,21 @@ snapshots: string_decoder: 1.1.1 util-deprecate: 1.0.2 - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 + readdirp@4.0.2: {} redent@3.0.0: dependencies: indent-string: 4.0.0 strip-indent: 3.0.0 - regenerate-unicode-properties@10.1.1: - dependencies: - regenerate: 1.4.2 - - regenerate@1.4.2: {} - regenerator-runtime@0.14.1: {} - regenerator-transform@0.15.2: - dependencies: - '@babel/runtime': 7.24.5 - - regexpu-core@5.3.2: - dependencies: - '@babel/regjsgen': 0.8.0 - regenerate: 1.4.2 - regenerate-unicode-properties: 10.1.1 - regjsparser: 0.9.1 - unicode-match-property-ecmascript: 2.0.0 - unicode-match-property-value-ecmascript: 2.1.0 - - regjsparser@0.9.1: - dependencies: - jsesc: 0.5.0 - remove-trailing-separator@1.1.0: {} replace-ext@1.0.1: {} require-directory@2.1.1: {} - requires-port@1.0.0: {} - resolve-cwd@3.0.0: dependencies: resolve-from: 5.0.0 @@ -5207,39 +5364,56 @@ snapshots: resolve-from@5.0.0: {} + resolve-pkg-maps@1.0.0: {} + resolve.exports@2.0.2: {} resolve@1.22.8: dependencies: - is-core-module: 2.13.1 + is-core-module: 2.15.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 reusify@1.0.4: {} - rollup@4.17.2: + rimraf@6.0.1: + dependencies: + glob: 11.0.0 + package-json-from-dist: 1.0.1 + + rollup-plugin-scss@4.0.0: + dependencies: + rollup-pluginutils: 2.8.2 + + rollup-pluginutils@2.8.2: + dependencies: + estree-walker: 0.6.1 + + rollup@4.27.0: dependencies: - '@types/estree': 1.0.5 + '@types/estree': 1.0.6 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.17.2 - '@rollup/rollup-android-arm64': 4.17.2 - '@rollup/rollup-darwin-arm64': 4.17.2 - '@rollup/rollup-darwin-x64': 4.17.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.17.2 - '@rollup/rollup-linux-arm-musleabihf': 4.17.2 - '@rollup/rollup-linux-arm64-gnu': 4.17.2 - '@rollup/rollup-linux-arm64-musl': 4.17.2 - '@rollup/rollup-linux-powerpc64le-gnu': 4.17.2 - '@rollup/rollup-linux-riscv64-gnu': 4.17.2 - '@rollup/rollup-linux-s390x-gnu': 4.17.2 - '@rollup/rollup-linux-x64-gnu': 4.17.2 - '@rollup/rollup-linux-x64-musl': 4.17.2 - '@rollup/rollup-win32-arm64-msvc': 4.17.2 - '@rollup/rollup-win32-ia32-msvc': 4.17.2 - '@rollup/rollup-win32-x64-msvc': 4.17.2 + '@rollup/rollup-android-arm-eabi': 4.27.0 + '@rollup/rollup-android-arm64': 4.27.0 + '@rollup/rollup-darwin-arm64': 4.27.0 + '@rollup/rollup-darwin-x64': 4.27.0 + '@rollup/rollup-freebsd-arm64': 4.27.0 + '@rollup/rollup-freebsd-x64': 4.27.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.27.0 + '@rollup/rollup-linux-arm-musleabihf': 4.27.0 + '@rollup/rollup-linux-arm64-gnu': 4.27.0 + '@rollup/rollup-linux-arm64-musl': 4.27.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.27.0 + '@rollup/rollup-linux-riscv64-gnu': 4.27.0 + '@rollup/rollup-linux-s390x-gnu': 4.27.0 + '@rollup/rollup-linux-x64-gnu': 4.27.0 + '@rollup/rollup-linux-x64-musl': 4.27.0 + '@rollup/rollup-win32-arm64-msvc': 4.27.0 + '@rollup/rollup-win32-ia32-msvc': 4.27.0 + '@rollup/rollup-win32-x64-msvc': 4.27.0 fsevents: 2.3.3 - rrweb-cssom@0.6.0: {} + rrweb-cssom@0.7.1: {} run-parallel@1.2.0: dependencies: @@ -5251,11 +5425,13 @@ snapshots: safer-buffer@2.1.2: {} - sass@1.77.1: + sass@1.81.0: dependencies: - chokidar: 3.6.0 - immutable: 4.3.6 - source-map-js: 1.2.0 + chokidar: 4.0.1 + immutable: 5.0.2 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.0 saxes@6.0.0: dependencies: @@ -5263,7 +5439,7 @@ snapshots: semver@6.3.1: {} - semver@7.6.2: {} + semver@7.6.3: {} serialize-javascript@6.0.2: dependencies: @@ -5275,15 +5451,19 @@ snapshots: shebang-regex@3.0.0: {} + siginfo@2.0.0: {} + signal-exit@3.0.7: {} + signal-exit@4.1.0: {} + sisteransi@1.0.5: {} slash@3.0.0: {} smob@1.5.0: {} - source-map-js@1.2.0: {} + source-map-js@1.2.1: {} source-map-support@0.5.13: dependencies: @@ -5305,6 +5485,10 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 + stackback@0.0.2: {} + + std-env@3.8.0: {} + string-length@4.0.2: dependencies: char-regex: 1.0.2 @@ -5316,6 +5500,12 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + string_decoder@1.1.1: dependencies: safe-buffer: 5.1.2 @@ -5324,6 +5514,10 @@ snapshots: dependencies: ansi-regex: 5.0.1 + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + strip-bom@4.0.0: {} strip-final-newline@2.0.0: {} @@ -5334,10 +5528,6 @@ snapshots: strip-json-comments@3.1.1: {} - supports-color@5.5.0: - dependencies: - has-flag: 3.0.0 - supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -5350,15 +5540,15 @@ snapshots: symbol-tree@3.2.4: {} - synckit@0.8.8: + synckit@0.9.2: dependencies: '@pkgr/core': 0.1.1 - tslib: 2.6.2 + tslib: 2.8.1 - terser@5.31.0: + terser@5.36.0: dependencies: '@jridgewell/source-map': 0.3.6 - acorn: 8.11.3 + acorn: 8.14.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -5370,48 +5560,48 @@ snapshots: text-table@0.2.0: {} - tmpl@1.0.5: {} + tinybench@2.9.0: {} + + tinyexec@0.3.1: {} + + tinypool@1.0.2: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + + tldts-core@6.1.61: {} + + tldts@6.1.61: + dependencies: + tldts-core: 6.1.61 - to-fast-properties@2.0.0: {} + tmpl@1.0.5: {} to-regex-range@5.0.1: dependencies: is-number: 7.0.0 - tough-cookie@4.1.4: + tough-cookie@5.0.0: dependencies: - psl: 1.9.0 - punycode: 2.3.1 - universalify: 0.2.0 - url-parse: 1.5.10 + tldts: 6.1.61 tr46@5.0.0: dependencies: punycode: 2.3.1 - ts-api-utils@1.3.0(typescript@5.4.5): + ts-api-utils@1.4.0(typescript@5.6.3): dependencies: - typescript: 5.4.5 + typescript: 5.6.3 - ts-node@10.9.2(@types/node@20.12.11)(typescript@5.4.5): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.12.11 - acorn: 8.11.3 - acorn-walk: 8.3.2 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.4.5 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 + tslib@2.8.1: {} - tslib@2.6.2: {} + tsx@4.19.2: + dependencies: + esbuild: 0.23.1 + get-tsconfig: 4.8.1 + optionalDependencies: + fsevents: 2.3.3 type-check@0.4.0: dependencies: @@ -5421,43 +5611,23 @@ snapshots: type-fest@0.21.3: {} - typescript@5.4.5: {} - - undici-types@5.26.5: {} - - unicode-canonical-property-names-ecmascript@2.0.0: {} + typescript@5.6.3: {} - unicode-match-property-ecmascript@2.0.0: - dependencies: - unicode-canonical-property-names-ecmascript: 2.0.0 - unicode-property-aliases-ecmascript: 2.1.0 - - unicode-match-property-value-ecmascript@2.1.0: {} - - unicode-property-aliases-ecmascript@2.1.0: {} - - universalify@0.2.0: {} + undici-types@6.19.8: {} - update-browserslist-db@1.0.15(browserslist@4.23.0): + update-browserslist-db@1.1.1(browserslist@4.24.2): dependencies: - browserslist: 4.23.0 - escalade: 3.1.2 - picocolors: 1.0.0 + browserslist: 4.24.2 + escalade: 3.2.0 + picocolors: 1.1.1 uri-js@4.4.1: dependencies: punycode: 2.3.1 - url-parse@1.5.10: - dependencies: - querystringify: 2.2.0 - requires-port: 1.0.0 - util-deprecate@1.0.2: {} - v8-compile-cache-lib@3.0.1: {} - - v8-to-istanbul@9.2.0: + v8-to-istanbul@9.3.0: dependencies: '@jridgewell/trace-mapping': 0.3.25 '@types/istanbul-lib-coverage': 2.0.6 @@ -5476,6 +5646,71 @@ snapshots: remove-trailing-separator: 1.1.0 replace-ext: 1.0.1 + vite-node@2.1.5(@types/node@22.9.0)(sass@1.81.0)(terser@5.36.0): + dependencies: + cac: 6.7.14 + debug: 4.3.7 + es-module-lexer: 1.5.4 + pathe: 1.1.2 + vite: 5.4.11(@types/node@22.9.0)(sass@1.81.0)(terser@5.36.0) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite@5.4.11(@types/node@22.9.0)(sass@1.81.0)(terser@5.36.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.49 + rollup: 4.27.0 + optionalDependencies: + '@types/node': 22.9.0 + fsevents: 2.3.3 + sass: 1.81.0 + terser: 5.36.0 + + vitest@2.1.5(@types/node@22.9.0)(jsdom@25.0.1)(sass@1.81.0)(terser@5.36.0): + dependencies: + '@vitest/expect': 2.1.5 + '@vitest/mocker': 2.1.5(vite@5.4.11(@types/node@22.9.0)(sass@1.81.0)(terser@5.36.0)) + '@vitest/pretty-format': 2.1.5 + '@vitest/runner': 2.1.5 + '@vitest/snapshot': 2.1.5 + '@vitest/spy': 2.1.5 + '@vitest/utils': 2.1.5 + chai: 5.1.2 + debug: 4.3.7 + expect-type: 1.1.0 + magic-string: 0.30.12 + pathe: 1.1.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.1 + tinypool: 1.0.2 + tinyrainbow: 1.2.0 + vite: 5.4.11(@types/node@22.9.0)(sass@1.81.0)(terser@5.36.0) + vite-node: 2.1.5(@types/node@22.9.0)(sass@1.81.0)(terser@5.36.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.9.0 + jsdom: 25.0.1 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 @@ -5501,6 +5736,11 @@ snapshots: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + word-wrap@1.2.5: {} wrap-ansi@7.0.0: @@ -5509,6 +5749,12 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + wrappy@1.0.2: {} write-file-atomic@4.0.2: @@ -5516,7 +5762,7 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 3.0.7 - ws@8.17.0: {} + ws@8.18.0: {} xml-name-validator@5.0.0: {} @@ -5531,13 +5777,11 @@ snapshots: yargs@17.7.2: dependencies: cliui: 8.0.1 - escalade: 3.1.2 + escalade: 3.2.0 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 - yn@3.1.1: {} - yocto-queue@0.1.0: {} diff --git a/rollup.config.js b/rollup.config.js index aa5be1c..e2c510d 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,66 +1,79 @@ import terser from '@rollup/plugin-terser' import typescript from '@rollup/plugin-typescript' +import scss from 'rollup-plugin-scss' +// const terser_config = { +// ecma: 5, +// mangle: { toplevel: true }, +// compress: { +// module: true, +// toplevel: true, +// unsafe_arrows: true, +// drop_console: false, +// drop_debugger: true, +// }, +// output: { +// beautify: false, +// quote_style: 1, +// comments: false, +// }, +// } const terser_config = { ecma: 5, - mangle: { toplevel: true }, - compress: { - module: true, - toplevel: true, - unsafe_arrows: true, - drop_console: false, - drop_debugger: true, - }, + // mangle: false, + mangle: true, + + compress: true, output: { beautify: false, + preserve_annotations: true, quote_style: 1, - comments: false, + comments: true, + ecma: 2020, }, } export default [ - { - input: './src/sortable.ts', - output: { - file: './sortable.js', - indent: ' ', - }, - plugins: [typescript()], - }, - { - input: './src/sortable.ts', - output: { - file: './sortable.min.js', - }, - plugins: [typescript(), terser(terser_config)], - }, - { - input: './src/enhanceSortableAccessibility.ts', - output: { - file: './enhanceSortableAccessibility.js', - }, - plugins: [typescript()], - }, - { - input: './src/enhanceSortableAccessibility.ts', - output: { - file: './enhanceSortableAccessibility.min.js', - }, - plugins: [typescript(), terser(terser_config)], - }, - { - input: './src/sortable.a11y.ts', - output: { - file: './sortable.a11y.js', - }, - plugins: [typescript()], - }, - // We will build these using closure compiler before pushing, but it's nice to have them - { - input: './src/sortable.a11y.ts', - output: { - file: './sortable.a11y.min.js', - }, - plugins: [typescript(), terser(terser_config)], - }, + ...['example', 'sortable', 'sortable-base'] + .map((s) => { + return [ + { + input: `src/scss/${s}.scss`, + output: { + file: `dist/${s}.css`, + }, + plugins: [ + scss({ + fileName: `${s}.css`, + outputStyle: 'expanded', + failOnError: true, + }), + ], + }, + { + input: `src/scss/${s}.scss`, + output: { + file: `dist/${s}.min.css`, + }, + plugins: [ + scss({ + fileName: `${s}.min.css`, + outputStyle: 'compressed', + failOnError: true, + }), + ], + }, + ] + }) + .flat(), + ...['sortable', 'sortable.a11y', 'sortSortable', 'sortableEventListener', 'enhanceSortableAccessibility'].map((s) => { + return { + input: `dist/esm/${s}.js`, + output: { + file: `dist/esm/${s}.min.js`, + format: 'es', + }, + plugins: [terser(terser_config)], + } + }), ] diff --git a/scripts/compile.ts b/scripts/compile.ts new file mode 100644 index 0000000..d11eebe --- /dev/null +++ b/scripts/compile.ts @@ -0,0 +1,56 @@ +import fs from 'fs' +import path from 'path' +import { exec } from 'child_process' +import { fileURLToPath } from 'url' + +// Get the current directory name +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) + +function processDirectory(directory: string) { + fs.readdir(directory, (err, files) => { + if (err) { + console.error('Error reading directory:', err) + return + } + + files.forEach((file) => { + const filePath = path.join(directory, file) + fs.stat(filePath, (err, stats) => { + if (err) { + console.error('Error getting file stats:', err) + return + } + + if (stats.isFile() && file.endsWith('.js') && !file.endsWith('.min.js')) { + const outputFilePath = path.join(directory, file.replace('.js', '.min.js')) + + const command = `google-closure-compiler --js=${filePath} --js_output_file=${outputFilePath}` + exec(command, (err, stdout, stderr) => { + if (err) { + console.error(`Error compiling ${file}:`, err) + return + } + if (stderr) { + console.error(`Compiler stderr for ${file}:`, stderr) + } + console.log(`Compiled ${file} to ${outputFilePath}`) + }) + } + }) + }) + }) +} + +// Get directories from command-line arguments +const directories = process.argv.slice(2) + +if (directories.length === 0) { + console.error('Please provide at least one directory as an argument.') + process.exit(1) +} + +directories.forEach((directory) => { + const fullPath = path.isAbsolute(directory) ? directory : path.join(__dirname, '..', directory) + processDirectory(fullPath) +}) diff --git a/scripts/prepare-tests.ts b/scripts/prepare-tests.ts new file mode 100644 index 0000000..aa3ec23 --- /dev/null +++ b/scripts/prepare-tests.ts @@ -0,0 +1,73 @@ +import fs from 'fs' +import path from 'path' + +const DIST_TYPES = ['bundled', 'standalone', 'esm'] as const + +function createHTML(type: (typeof DIST_TYPES)[number], minified: boolean = false) { + let template = fs.readFileSync('index.html', 'utf8') + + // Remove the existing script tags + template = template + .replace('', '') + .replace('', '') + .replace('', '') + + // Add CSS + const cssFiles = minified ? ['sortable.min.css', 'example.min.css'] : ['sortable.css', 'example.css'] + + const cssLinks = cssFiles.map((file) => ``).join('\n') + + template = template.replace('', `${cssLinks}\n`) + + // Generate script tags based on format and minified state + let scripts = '' + const jsExt = minified ? '.min.js' : '.js' + + switch (type) { + case 'bundled': + scripts = ` + + ` + break + case 'standalone': + scripts = ` + + ` + break + case 'esm': + scripts = ` + ` + break + } + + template = template.replace('', `${scripts}\n`) + + // Save the file + const outputPath = `dist/${type}${minified ? '.min' : ''}.html` + fs.writeFileSync(outputPath, template) + console.log(`Created ${outputPath}`) +} + +function cleanup() { + DIST_TYPES.forEach((type) => { + ;['', '.min'].forEach((suffix) => { + const filePath = `dist/${type}${suffix}.html` + if (fs.existsSync(filePath)) { + fs.unlinkSync(filePath) + console.log(`Cleaned up ${filePath}`) + } + }) + }) +} + +if (process.argv.includes('cleanup')) { + cleanup() +} else { + DIST_TYPES.forEach((type) => { + createHTML(type, false) // Unminified version + createHTML(type, true) // Minified version + }) +} diff --git a/scripts/prepare.ts b/scripts/prepare.ts index 2e05038..aca0f1f 100644 --- a/scripts/prepare.ts +++ b/scripts/prepare.ts @@ -1,5 +1,7 @@ +import { execSync } from 'child_process' + // so we don't install husky in CI if (!process.env.CI) { - const log = require('child_process').execSync('npx husky install', { encoding: 'utf8', stdio: 'pipe' }).trim() + const log = execSync('npx husky install', { encoding: 'utf8', stdio: 'pipe' }).trim() console.log(log) } diff --git a/sortable-base.css.map b/sortable-base.css.map deleted file mode 100644 index c4dc34b..0000000 --- a/sortable-base.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sourceRoot":"","sources":["src/sortable-base.scss"],"names":[],"mappings":";AAGM;EACE;;AACA;EAEE;EACA;EACA;;AAGF;EACE;EACA;;AAGA;EACE;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAIF;EACE;;AAEF;EACE;EACA;;AAIA;EACE;;AAKF;EACE;EACA;;AAKF;EACE;EACA","file":"sortable-base.css"} \ No newline at end of file diff --git a/sortable-base.min.css.map b/sortable-base.min.css.map deleted file mode 100644 index 0eb34bb..0000000 --- a/sortable-base.min.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sourceRoot":"","sources":["src/sortable-base.scss"],"names":[],"mappings":"CAGM,iCACE,eACA,iFAEE,iCACA,gBACA,oBAGF,wCACE,gBACA,YAGA,8CACE,cAKF,8DACE,cACA,YAKF,6DACE,cACA,YAIF,uDACE,WAEF,wDACE,iBACA,YAIA,8DACE,cAKF,8EACE,cACA,YAKF,6EACE,cACA","file":"sortable-base.min.css"} \ No newline at end of file diff --git a/sortable.a11y.js b/sortable.a11y.js deleted file mode 100644 index 479f314..0000000 --- a/sortable.a11y.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * This is a "plugin" for the sortable package: - * https://www.npmjs.com/package/sortable-tablesort - * https://github.com/tofsjonas/sortable - * - * Enhances the accessibility of class="sortable" tables by adding ARIA attributes and keyboard event listeners. - * @param tables - A list of HTML table elements to enhance. - */ -var enhanceSortableAccessibility = function (tables) { - /** - * Generates an aria-label attribute for a table header cell based on its content and current sort direction. - * @param element - The table header cell to update. - * @param default_direction - The default sort direction for the table. - */ - function updateAriaLabel(element, default_direction) { - var _a; - if (default_direction === void 0) { default_direction = ''; } - // Generate aria-label based on header content - var header_text = element.textContent || 'element'; - var current_direction = (_a = element.getAttribute('aria-sort')) !== null && _a !== void 0 ? _a : ''; - var new_direction = 'descending'; - if (current_direction === 'descending' || (default_direction && current_direction !== 'ascending')) { - new_direction = 'ascending'; - } - var aria_label = "Click to sort table by ".concat(header_text, " in ").concat(new_direction, " order"); - element.setAttribute('aria-label', aria_label); - // element.setAttribute('title', aria_label) REMEMBER TO COMMENT OUT WHEN NOT TESTING!! - } - /** - * Handles keyboard events on table header cells and triggers a click event when the Enter key is pressed. - * @param event - The keyboard event to handle. - */ - function handleKeyDown(event) { - if (event.key === 'Enter') { - var element = event.target; - element.click(); - } - } - // Iterate over each table in the input list - tables.forEach(function (table) { - var default_direction = table.classList.contains('asc') ? 'ascending' : ''; - var headers = table.querySelectorAll('th'); - // Iterate over each header cell in the table - headers.forEach(function (header) { - var element = header; - // Skip if the header cell already has a tabindex attribute - if (element.hasAttribute('tabindex')) - return; - var update = function () { - updateAriaLabel(element, default_direction); - }; - // Add tabindex attribute and generate initial aria-label attribute - element.setAttribute('tabindex', '0'); - update(); - // Attach click event listener to update aria-label attribute - element.addEventListener('click', function () { - // Add a delay to allow the new sort order to be applied - setTimeout(update, 50); - }); - // Attach focus event listener to update aria-label attribute - element.addEventListener('focus', update); - // Attach keyboard event listener to trigger click event - element.addEventListener('keydown', handleKeyDown); - }); - }); -}; - -// Attach function to DOMContentLoaded event to execute when page is loaded -document.addEventListener('DOMContentLoaded', function () { - enhanceSortableAccessibility(document.querySelectorAll('.sortable')); -}); diff --git a/sortable.css.map b/sortable.css.map deleted file mode 100644 index fea0931..0000000 --- a/sortable.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sourceRoot":"","sources":["src/sortable-base.scss","src/sortable.scss"],"names":[],"mappings":";AAGM;EACE;;AACA;EAEE;EACA;EACA;;AAGF;EACE;EACA;;AAGA;EACE;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;AAIF;EACE;;AAEF;EACE;EACA;;AAIA;EACE;;AAKF;EACE;EACA;;AAKF;EACE;EACA;;;AC1Dd;EACE;EACA;EACA;EACA;EACA;EAEA;;AAII;EACE;EACA;;AAKJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACE;;AAEF;AAAA;EAEE;;AAEA;AAAA;EACE;;AAGF;AAAA;EACE","file":"sortable.css"} \ No newline at end of file diff --git a/sortable.js b/sortable.js deleted file mode 100644 index 8d4b43e..0000000 --- a/sortable.js +++ /dev/null @@ -1,122 +0,0 @@ -/** - * sortable v3.2.3 - * - * https://www.npmjs.com/package/sortable-tablesort - * https://github.com/tofsjonas/sortable - * - * Makes html tables sortable, No longer ie9+ 😢 - * - * Styling is done in css. - * - * Copyleft 2017 Jonas Earendel - * - * This is free and unencumbered software released into the public domain. - * - * Anyone is free to copy, modify, publish, use, compile, sell, or - * distribute this software, either in source code form or as a compiled - * binary, for any purpose, commercial or non-commercial, and by any - * means. - * - * In jurisdictions that recognize copyright laws, the author or authors - * of this software dedicate any and all copyright interest in the - * software to the public domain. We make this dedication for the benefit - * of the public at large and to the detriment of our heirs and - * successors. We intend this dedication to be an overt act of - * relinquishment in perpetuity of all present and future rights to this - * software under copyright law. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * For more information, please refer to - * - */ -document.addEventListener('click', function (e) { - try { - // allows for elements inside TH - function findElementRecursive(element, tag) { - return element.nodeName === tag ? element : findElementRecursive(element.parentNode, tag); - } - var ascending_table_sort_class = 'asc'; - var no_sort_class = 'no-sort'; - var null_last_class = 'n-last'; - var table_class_name = 'sortable'; - var alt_sort_1 = e.shiftKey || e.altKey; - var element = findElementRecursive(e.target, 'TH'); - var tr = element.parentNode; - var thead = tr.parentNode; - var table = thead.parentNode; - function getValue(element) { - var _a; - var value = alt_sort_1 ? element.dataset.sortAlt : (_a = element.dataset.sort) !== null && _a !== void 0 ? _a : element.textContent; - return value; - } - if (thead.nodeName === 'THEAD' && // sortable only triggered in `thead` - table.classList.contains(table_class_name) && - !element.classList.contains(no_sort_class) // .no-sort is now core functionality, no longer handled in CSS - ) { - var column_index_1; - var nodes = tr.cells; - var tiebreaker_1 = +element.dataset.sortTbr; - // Reset thead cells and get column index - for (var i = 0; i < nodes.length; i++) { - if (nodes[i] === element) { - column_index_1 = +element.dataset.sortCol || i; - } - else { - nodes[i].setAttribute('aria-sort', 'none'); - } - } - var direction = 'descending'; - if (element.getAttribute('aria-sort') === 'descending' || - (table.classList.contains(ascending_table_sort_class) && element.getAttribute('aria-sort') !== 'ascending')) { - direction = 'ascending'; - } - // Update the `th` class accordingly - element.setAttribute('aria-sort', direction); - var reverse_1 = direction === 'ascending'; - var sort_null_last_1 = table.classList.contains(null_last_class); - var compare_1 = function (a, b, index) { - var x = getValue(b.cells[index]); - var y = getValue(a.cells[index]); - if (sort_null_last_1) { - if (x === '' && y !== '') { - return -1; - } - if (y === '' && x !== '') { - return 1; - } - } - var temp = +x - +y; - var bool = isNaN(temp) ? x.localeCompare(y) : temp; - return reverse_1 ? -bool : bool; - }; - // loop through all tbodies and sort them - for (var i = 0; i < table.tBodies.length; i++) { - var org_tbody = table.tBodies[i]; - // Put the array rows in an array, so we can sort them... - var rows = [].slice.call(org_tbody.rows, 0); - // Sort them using Array.prototype.sort() - rows.sort(function (a, b) { - var bool = compare_1(a, b, column_index_1); - return bool === 0 && !isNaN(tiebreaker_1) ? compare_1(a, b, tiebreaker_1) : bool; - }); - // Make an empty clone - var clone_tbody = org_tbody.cloneNode(); - // Put the sorted rows inside the clone - clone_tbody.append.apply(clone_tbody, rows); - // And finally replace the unsorted tbody with the sorted one - table.replaceChild(clone_tbody, org_tbody); - } - } - // eslint-disable-next-line no-unused-vars - } - catch (error) { - // console.log(error) - } -}); diff --git a/sortable.min.css.map b/sortable.min.css.map deleted file mode 100644 index e1c06da..0000000 --- a/sortable.min.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sourceRoot":"","sources":["src/sortable-base.scss","src/sortable.scss"],"names":[],"mappings":"CAGM,iCACE,eACA,iFAEE,iCACA,gBACA,oBAGF,wCACE,gBACA,YAGA,8CACE,cAKF,8DACE,cACA,YAKF,6DACE,cACA,YAIF,uDACE,WAEF,wDACE,iBACA,YAIA,8DACE,cAKF,8EACE,cACA,YAKF,6EACE,cACA,YC1Dd,UACE,wBACA,iBACA,iBACA,iBACA,2BAEA,iBAII,kCACE,qCACA,gCAKJ,mBACE,wBACA,sBACA,mBACA,gBACA,0BACA,wBACA,mBAGJ,aACE,sBAEF,0BAEE,aAEA,kDACE,2BAGF,gDACE","file":"sortable.min.css"} \ No newline at end of file diff --git a/sortable.min.js b/sortable.min.js deleted file mode 100644 index eb54431..0000000 --- a/sortable.min.js +++ /dev/null @@ -1,3 +0,0 @@ -document.addEventListener("click",function(c){try{function h(b,a){return b.nodeName===a?b:h(b.parentNode,a)}var v=c.shiftKey||c.altKey,d=h(c.target,"TH"),m=d.parentNode,n=m.parentNode,g=n.parentNode;function p(b){var a;return v?b.dataset.sortAlt:null!==(a=b.dataset.sort)&&void 0!==a?a:b.textContent}if("THEAD"===n.nodeName&&g.classList.contains("sortable")&&!d.classList.contains("no-sort")){var q,f=m.cells,r=+d.dataset.sortTbr;for(c=0;c) => { +export const enhanceSortableAccessibility = (tables: NodeListOf | HTMLTableElement[]) => { /** * Generates an aria-label attribute for a table header cell based on its content and current sort direction. * @param element - The table header cell to update. @@ -26,7 +26,9 @@ export const enhanceSortableAccessibility = (tables: NodeListOf { + const x = getValue(b.cells[index]) + const y = getValue(a.cells[index]) + if (sort_null_last) { + if (x === '' && y !== '') { + return -1 + } + if (y === '' && x !== '') { + return 1 + } + } + + // use unary plus to (try to) convert to numbers + const temp = +x - +y + const bool = isNaN(temp) ? x.localeCompare(y) : temp + + if (bool === 0 && th_row.cells[index] && th_row.cells[index].hasAttribute('data-sort-tbr')) { + return compare(a, b, +th_row.cells[index].dataset.sortTbr!) + } + + return reverse ? -bool : bool + } + + for (let i = 0; i < table.tBodies.length; i++) { + const org_tbody: HTMLTableSectionElement = table.tBodies[i] + + // Put the array rows in an array, so we can sort them... + const rows: HTMLTableRowElement[] = [].slice.call(org_tbody.rows, 0) + + // Sort them using Array.prototype.sort() + rows.sort(function (a: HTMLTableRowElement, b: HTMLTableRowElement) { + return compare(a, b, +(th.dataset.sortCol ?? th.cellIndex)) + }) + + // Make an empty clone + const clone_tbody = org_tbody.cloneNode() as HTMLTableSectionElement + + // Put the sorted rows inside the clone + clone_tbody.append(...rows) + + // And finally replace the unsorted tbody with the sorted one + table.replaceChild(clone_tbody, org_tbody) + } + table.dispatchEvent(new Event('sort-end', { bubbles: true })) +} diff --git a/src/sortable.test.html b/src/sortable.test.html deleted file mode 100644 index 2b34106..0000000 --- a/src/sortable.test.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - - - sortable test - - - -

sortable test

- -

Basic test

- - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

Tiebreaker

- - - - - - - - - - - - - - - - - - - - - - - - - -
MonthYearDay
07201025
11201012
04201025
- -

Colspans

- - - - - - - - - - - - - - - - - - - - - - - - - -
nums + charsCHARS
333222BB
1111CCC
22333A
- -

Empty/null sorted last

- - - - - - - - - - - - - - - - - - - - - - - - - - -
TextNumber
jkl0.4
abc0
should be sortedlast
def0.2
-

class="no-sort"

- - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- -

numeric sorting

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RoleTimeAmountNumber
Genius12:00:12$18.492.49
Sidekick12:22:11$2.4918.49
Butler12:22:05$1.961.96
- -

Ascending sort

- - - - - - - - - - - - - - - - - - -
RoleName
GeniusRick
SidekickMorty
- - - - - - - diff --git a/src/sortable.test.js b/src/sortable.test.ts similarity index 52% rename from src/sortable.test.js rename to src/sortable.test.ts index 206c89c..25556e2 100644 --- a/src/sortable.test.js +++ b/src/sortable.test.ts @@ -1,40 +1,35 @@ // https://dev.to/thawkin3/how-to-unit-test-html-and-vanilla-javascript-without-a-ui-framework-4io -import { fireEvent, getByRole, getAllByRole } from '@testing-library/dom' -import '@testing-library/jest-dom' +import { fireEvent, getByRole, getAllByRole, waitFor as originalWaitFor } from '@testing-library/dom' +import { expect, describe, beforeEach, it, vi } from 'vitest' + +import '@testing-library/jest-dom/vitest' + import { JSDOM } from 'jsdom' import fs from 'fs' import path from 'path' -import { enhanceSortableAccessibility } from '../enhanceSortableAccessibility' +import { enhanceSortableAccessibility } from './enhanceSortableAccessibility' // Determine whether to use minified versions based on an environment variable const use_minified = process.env.USE_MINIFIED === 'true' -function waitFor(conditionFunction) { - const poll = (resolve) => { - if (conditionFunction()) resolve() - else setTimeout((_) => poll(resolve), 50) - } - - return new Promise(poll) -} - // Construct file paths based on the above flag const js_filename = use_minified ? 'sortable.min.js' : 'sortable.js' const a11y_js_filename = use_minified ? 'sortable.a11y.min.js' : 'sortable.a11y.js' console.log(`Testing with ${js_filename} and ${a11y_js_filename}`) -const js = fs.readFileSync(path.resolve(__dirname, `../${js_filename}`), 'utf8') -const a11y_js = fs.readFileSync(path.resolve(__dirname, `../${a11y_js_filename}`), 'utf8') +const js = fs.readFileSync(path.resolve(__dirname, `../dist/${js_filename}`), 'utf8') +const a11y_js = fs.readFileSync(path.resolve(__dirname, `../dist/${a11y_js_filename}`), 'utf8') const html = fs - .readFileSync(path.resolve(__dirname, './sortable.test.html'), 'utf8') - .replace('', ``) - .replace('', ``) + .readFileSync(path.resolve(__dirname, '../index.html'), 'utf8') + .replace('', ``) + .replace('', ``) let dom -let container +let container: HTMLElement +let waitFor: typeof originalWaitFor -describe('sortable.test.html', () => { +describe('Testing sortable', () => { beforeEach(() => { // Constructing a new JSDOM with this option is the key // to getting the code in the script tag to execute. @@ -42,11 +37,14 @@ describe('sortable.test.html', () => { // https://github.com/jsdom/jsdom#executing-scripts dom = new JSDOM(html, { runScripts: 'dangerously' }) container = dom.window.document.body + + // we have to bind waitFor to the container, otherwise it will not work + waitFor = (callback, options) => originalWaitFor(callback, { ...options, container }) }) it('renders a heading element', () => { const h1 = getByRole(container, 'heading', { - name: /sortable test/i, + name: /Sortable examples/i, }) expect(h1).toBeInTheDocument() }) @@ -65,118 +63,155 @@ describe('sortable.test.html', () => { const table = getAllByRole(container, 'table')[0] const th = getByRole(table, 'columnheader', { name: /Name/i }) const first = getAllByRole(table, 'cell')[1].textContent + expect(first).toBe('Rick') fireEvent.click(th) - const middle = getAllByRole(table, 'cell')[1].textContent + await waitFor(() => { + const middle = getAllByRole(table, 'cell')[1].textContent + expect(middle).toBe('Rick') + }) fireEvent.click(th) - const last = getAllByRole(table, 'cell')[1].textContent - - expect(first).toBe('Rick') - expect(middle).toBe('Rick') // since it is already sorted in that direction - expect(last).toBe('Morty') + await waitFor(() => { + const last = getAllByRole(table, 'cell')[1].textContent + expect(last).toBe('Morty') + }) }) it('sorts a table using Enter key', async () => { const table = getAllByRole(container, 'table')[0] const th = getByRole(table, 'columnheader', { name: /Name/i }) const first = getAllByRole(table, 'cell')[1].textContent + expect(first).toBe('Rick') + fireEvent.keyDown(th, { key: 'Enter', code: 'Enter' }) - const middle = getAllByRole(table, 'cell')[1].textContent - fireEvent.keyDown(th, { key: 'Enter', code: 'Enter' }) - const last = getAllByRole(table, 'cell')[1].textContent + await waitFor(() => { + const middle = getAllByRole(table, 'cell')[1].textContent + expect(middle).toBe('Rick') + }) - expect(first).toBe('Rick') - expect(middle).toBe('Rick') - expect(last).toBe('Morty') + fireEvent.keyDown(th, { key: 'Enter', code: 'Enter' }) + await waitFor(() => { + const last = getAllByRole(table, 'cell')[1].textContent + expect(last).toBe('Morty') + }) }) it('sorts a table using tie breaker', async () => { const table = getAllByRole(container, 'table')[1] const th = getByRole(table, 'columnheader', { name: /Year/ }) - const first = getAllByRole(table, 'cell')[0].textContent + const first = getAllByRole(table, 'cell')[3].textContent + expect(first).toBe('12:00') fireEvent.click(th) - const middle = getAllByRole(table, 'cell')[0].textContent + await waitFor(() => { + const middle = getAllByRole(table, 'cell')[3].textContent + expect(middle).toBe('15:00') + }) fireEvent.click(th) - const last = getAllByRole(table, 'cell')[0].textContent - expect(first).toBe('07') - expect(middle).toBe('04') - expect(last).toBe('11') + await waitFor(() => { + const last = getAllByRole(table, 'cell')[3].textContent + expect(last).toBe('13:00') + }) }) - it('sorts a table using colspans', async () => { + it('sorts a table with colspans', async () => { const table = getAllByRole(container, 'table')[2] const th = getByRole(table, 'columnheader', { name: /CHARS/ }) - const first = getAllByRole(table, 'cell')[2].textContent + expect(first).toBe('BB') fireEvent.click(th) - const middle = getAllByRole(table, 'cell')[2].textContent + await waitFor(() => { + const middle = getAllByRole(table, 'cell')[2].textContent + expect(middle).toBe('CCC') + }) fireEvent.click(th) - const last = getAllByRole(table, 'cell')[2].textContent - expect(first).toBe('BB') - expect(middle).toBe('CCC') - expect(last).toBe('A') + await waitFor(() => { + const last = getAllByRole(table, 'cell')[2].textContent + expect(last).toBe('A') + }) }) it('sorts a table with empty rows last', async () => { const table = getAllByRole(container, 'table')[3] const th = getByRole(table, 'columnheader', { name: /Number/ }) const first = getAllByRole(table, 'cell')[7].textContent + expect(first).toBe('0.2') fireEvent.click(th) - const middle = getAllByRole(table, 'cell')[7].textContent + await waitFor(() => { + const middle = getAllByRole(table, 'cell')[7].textContent + expect(middle).toBe('(if click in this column)') + }) fireEvent.click(th) - const last = getAllByRole(table, 'cell')[7].textContent - expect(first).toBe('0.2') - expect(middle).toBe('last') - expect(last).toBe('last') + await waitFor(() => { + const last = getAllByRole(table, 'cell')[7].textContent + expect(last).toBe('(if click in this column)') + }) }) + it('respects class="no-sort" in th', async () => { const table = getAllByRole(container, 'table')[4] const th = getByRole(table, 'columnheader', { name: /Name/ }) const first = getAllByRole(table, 'cell')[1].textContent + expect(first).toBe('Rick') fireEvent.click(th) - const middle = getAllByRole(table, 'cell')[1].textContent + await waitFor(() => { + const middle = getAllByRole(table, 'cell')[1].textContent + expect(middle).toBe('Rick') + }) fireEvent.click(th) - const last = getAllByRole(table, 'cell')[1].textContent - expect(first).toBe('Rick') - expect(middle).toBe('Rick') - expect(last).toBe('Rick') + await waitFor(() => { + const last = getAllByRole(table, 'cell')[1].textContent + expect(last).toBe('Rick') + }) }) + it('treats time formats like strings', async () => { const table = getAllByRole(container, 'table')[5] const th = getByRole(table, 'columnheader', { name: /Time/ }) const first = getAllByRole(table, 'cell')[1].textContent + expect(first).toBe('12:00:12') fireEvent.click(th) - const middle = getAllByRole(table, 'cell')[1].textContent + await waitFor(() => { + const middle = getAllByRole(table, 'cell')[1].textContent + expect(middle).toBe('12:22:11') + }) fireEvent.click(th) - const last = getAllByRole(table, 'cell')[1].textContent - expect(first).toBe('12:00:12') - expect(middle).toBe('12:22:11') - expect(last).toBe('12:00:12') + await waitFor(() => { + const last = getAllByRole(table, 'cell')[1].textContent + expect(last).toBe('12:00:12') + }) }) it('treats amounts like strings', async () => { const table = getAllByRole(container, 'table')[5] const th = getByRole(table, 'columnheader', { name: /Amount/ }) const first = getAllByRole(table, 'cell')[2].textContent + expect(first).toBe('$18.49') fireEvent.click(th) - const middle = getAllByRole(table, 'cell')[2].textContent + await waitFor(() => { + const middle = getAllByRole(table, 'cell')[2].textContent + expect(middle).toBe('$2.49') + }) fireEvent.click(th) - const last = getAllByRole(table, 'cell')[2].textContent - expect(first).toBe('$18.49') - expect(middle).toBe('$2.49') - expect(last).toBe('$1.96') + await waitFor(() => { + const last = getAllByRole(table, 'cell')[2].textContent + expect(last).toBe('$1.96') + }) }) it('treats numbers like numbers', async () => { const table = getAllByRole(container, 'table')[5] const th = getByRole(table, 'columnheader', { name: /Number/ }) const first = getAllByRole(table, 'cell')[3].textContent + expect(first).toBe('2.49') fireEvent.click(th) - const middle = getAllByRole(table, 'cell')[3].textContent + await waitFor(() => { + const middle = getAllByRole(table, 'cell')[3].textContent + expect(middle).toBe('18.49') + }) fireEvent.click(th) - const last = getAllByRole(table, 'cell')[3].textContent - expect(first).toBe('2.49') - expect(middle).toBe('18.49') - expect(last).toBe('1.96') + await waitFor(() => { + const last = getAllByRole(table, 'cell')[3].textContent + expect(last).toBe('1.96') + }) }) it('sorts a table ascending', async () => { @@ -184,14 +219,17 @@ describe('sortable.test.html', () => { const th = getByRole(table, 'columnheader', { name: /Name/i }) const first = getAllByRole(table, 'cell')[1].textContent + expect(first).toBe('Rick') fireEvent.click(th) - const middle = getAllByRole(table, 'cell')[1].textContent + await waitFor(() => { + const middle = getAllByRole(table, 'cell')[1].textContent + expect(middle).toBe('Morty') + }) fireEvent.click(th) - const last = getAllByRole(table, 'cell')[1].textContent - - expect(first).toBe('Rick') - expect(middle).toBe('Morty') - expect(last).toBe('Rick') + await waitFor(() => { + const last = getAllByRole(table, 'cell')[1].textContent + expect(last).toBe('Rick') + }) }) it('a11y labels are added and updated', async () => { @@ -202,40 +240,27 @@ describe('sortable.test.html', () => { const th = getByRole(table, 'columnheader', { name: /Name/i }) const first = th.getAttribute('aria-label') fireEvent.click(th) - await waitFor(() => th.getAttribute('aria-label') === second_string) - const middle = th.getAttribute('aria-label') + await waitFor(() => { + const middle = th.getAttribute('aria-label') + expect(middle).toBe(second_string) + }) expect(first).toBe(first_string) - expect(middle).toBe(second_string) - }) - - it('sorts a table using Enter key', async () => { - const table = getAllByRole(container, 'table')[6] - const th = getByRole(table, 'columnheader', { name: /Name/i }) - const first = getAllByRole(table, 'cell')[1].textContent - fireEvent.keyDown(th, { key: 'Enter', code: 'Enter' }) - const middle = getAllByRole(table, 'cell')[1].textContent - fireEvent.keyDown(th, { key: 'Enter', code: 'Enter' }) - const last = getAllByRole(table, 'cell')[1].textContent - - expect(first).toBe('Rick') - expect(middle).toBe('Morty') - expect(last).toBe('Rick') }) it('works when using enhanceSortableAccessibility()', async () => { const first_string = 'Click to sort table by Name in ascending order' const second_string = 'Click to sort table by Name in descending order' - const table = getAllByRole(container, 'table')[6] + const table = getAllByRole(container, 'table')[6] as HTMLTableElement let th = getByRole(table, 'columnheader', { name: /Name/i }) // remove eventlistener from th - let clone = th.cloneNode(true) - th.parentNode.replaceChild(clone, th) + let clone = th.cloneNode(true) as HTMLElement + th.parentNode!.replaceChild(clone, th) - th = clone + th = getByRole(table, 'columnheader', { name: /Name/i }) // double check that the eventlistener is removed // this should NOT alter the a11y label @@ -248,22 +273,50 @@ describe('sortable.test.html', () => { th.removeAttribute('tabindex') }, 100) - await waitFor(() => th.getAttribute('aria-label') === '' || th.getAttribute('aria-label') === second_string) + await waitFor(() => { + const th = getByRole(table, 'columnheader', { name: /Name/i }) + expect(th.getAttribute('aria-label')).satisfies((label: string | null) => label === '' || label === second_string) + }) + + // double check that it was empty and not second_string const middle = th.getAttribute('aria-label') expect(middle).toBe('') // re-enable the a11y enhanceSortableAccessibility([table]) - // wait for the a11y to be added back - await waitFor(() => th.hasAttribute('tabindex')) + await waitFor(() => { + const th = getByRole(table, 'columnheader', { name: /Name/i }) + expect(th.hasAttribute('tabindex')).toBe(true) + }) fireEvent.click(th) // see that it worked: - - await waitFor(() => th.getAttribute('aria-label') === first_string) + await waitFor(() => { + const th = getByRole(table, 'columnheader', { name: /Name/i }) + expect(th.getAttribute('aria-label')).toBe(first_string) + }) // well, if we got here, we're good }) + it('sort-start and sort-end events are dispatched', async () => { + const startListener = vi.fn() + const endListener = vi.fn() + + container.addEventListener('sort-start', startListener) + container.addEventListener('sort-end', endListener) + + const table = getAllByRole(container, 'table')[0] + const th = getByRole(table, 'columnheader', { name: /Name/i }) + fireEvent.click(th) + fireEvent.click(th) + await waitFor(() => { + const middle = getAllByRole(table, 'cell')[1].textContent + expect(middle).toBe('Morty') + }) + + expect(startListener).toHaveBeenCalledTimes(1) + expect(endListener).toHaveBeenCalledTimes(1) + }) }) diff --git a/src/sortable.ts b/src/sortable.ts index 5ea09b8..7c8b305 100644 --- a/src/sortable.ts +++ b/src/sortable.ts @@ -1,10 +1,10 @@ /** - * sortable v3.2.3 + * sortable v4.0.0 * * https://www.npmjs.com/package/sortable-tablesort * https://github.com/tofsjonas/sortable * - * Makes html tables sortable, No longer ie9+ 😢 + * Makes html tables sortable. Nothing else. * * Styling is done in css. * @@ -37,106 +37,6 @@ * */ -document.addEventListener('click', function (e: MouseEvent) { - try { - // allows for elements inside TH - function findElementRecursive(element: Node, tag: string) { - return element.nodeName === tag ? element : findElementRecursive(element.parentNode, tag) - } +import { sortableEventListener } from './sortableEventListener' - const ascending_table_sort_class = 'asc' - const no_sort_class = 'no-sort' - const null_last_class = 'n-last' - const table_class_name = 'sortable' - - const alt_sort = e.shiftKey || e.altKey - const element: HTMLTableCellElement = findElementRecursive(e.target as HTMLElement, 'TH') - const tr = element.parentNode as HTMLTableRowElement - const thead = tr.parentNode as HTMLTableSectionElement - const table = thead.parentNode as HTMLTableElement - - function getValue(element: HTMLTableCellElement) { - const value = alt_sort ? element.dataset.sortAlt : element.dataset.sort ?? element.textContent - return value - } - - if ( - thead.nodeName === 'THEAD' && // sortable only triggered in `thead` - table.classList.contains(table_class_name) && - !element.classList.contains(no_sort_class) // .no-sort is now core functionality, no longer handled in CSS - ) { - let column_index: number - const nodes = tr.cells - const tiebreaker = +element.dataset.sortTbr - - // Reset thead cells and get column index - for (let i = 0; i < nodes.length; i++) { - if (nodes[i] === element) { - column_index = +element.dataset.sortCol || i - } else { - nodes[i].setAttribute('aria-sort', 'none') - } - } - - let direction = 'descending' - - if ( - element.getAttribute('aria-sort') === 'descending' || - (table.classList.contains(ascending_table_sort_class) && element.getAttribute('aria-sort') !== 'ascending') - ) { - direction = 'ascending' - } - - // Update the `th` class accordingly - element.setAttribute('aria-sort', direction) - - const reverse = direction === 'ascending' - - const sort_null_last = table.classList.contains(null_last_class) - - const compare = (a: HTMLTableRowElement, b: HTMLTableRowElement, index: number) => { - const x = getValue(b.cells[index]) - const y = getValue(a.cells[index]) - if (sort_null_last) { - if (x === '' && y !== '') { - return -1 - } - if (y === '' && x !== '') { - return 1 - } - } - - const temp = +x - +y - const bool = isNaN(temp) ? x.localeCompare(y) : temp - - return reverse ? -bool : bool - } - - // loop through all tbodies and sort them - for (let i = 0; i < table.tBodies.length; i++) { - const org_tbody: HTMLTableSectionElement = table.tBodies[i] - - // Put the array rows in an array, so we can sort them... - const rows: HTMLTableRowElement[] = [].slice.call(org_tbody.rows, 0) - - // Sort them using Array.prototype.sort() - rows.sort(function (a: HTMLTableRowElement, b: HTMLTableRowElement) { - const bool = compare(a, b, column_index) - return bool === 0 && !isNaN(tiebreaker) ? compare(a, b, tiebreaker) : bool - }) - - // Make an empty clone - const clone_tbody = org_tbody.cloneNode() as HTMLTableSectionElement - - // Put the sorted rows inside the clone - clone_tbody.append(...rows) - - // And finally replace the unsorted tbody with the sorted one - table.replaceChild(clone_tbody, org_tbody) - } - } - // eslint-disable-next-line no-unused-vars - } catch (error) { - // console.log(error) - } -}) +document.addEventListener('click', sortableEventListener) diff --git a/src/sortableEventListener.ts b/src/sortableEventListener.ts new file mode 100644 index 0000000..7039034 --- /dev/null +++ b/src/sortableEventListener.ts @@ -0,0 +1,58 @@ +import { sortSortable } from './sortSortable' + +export function sortableEventListener(e: MouseEvent) { + // allows for elements inside TH + function findElementRecursive(element: Node, tag: string): Node { + return element.nodeName === tag ? element : findElementRecursive(element.parentNode!, tag) + } + + try { + const ascending_table_sort_class = 'asc' + const no_sort_class = 'no-sort' + const table_class_name = 'sortable' + + const alt_sort = e.shiftKey || e.altKey + const element = findElementRecursive(e.target as HTMLElement, 'TH') as HTMLTableCellElement + const tr = element.parentNode as HTMLTableRowElement + const thead = tr.parentNode as HTMLTableSectionElement + const table = thead.parentNode as HTMLTableElement + + // Should we sort? + if ( + thead.nodeName === 'THEAD' && // sortable only triggered in `thead` + table.classList.contains(table_class_name) && + !element.classList.contains(no_sort_class) // .no-sort is now core functionality, no longer handled in CSS + ) { + const nodes = tr.cells + + // Reset thead cells + for (let i = 0; i < nodes.length; i++) { + if (nodes[i] !== element) { + nodes[i].removeAttribute('aria-sort') + } + } + + let direction = 'descending' + + if ( + element.getAttribute('aria-sort') === 'descending' || + (table.classList.contains(ascending_table_sort_class) && element.getAttribute('aria-sort') !== 'ascending') + ) { + direction = 'ascending' + } + + // Update the `th` class accordingly + element.setAttribute('aria-sort', direction) + + table.dataset.timer && clearTimeout(+table.dataset.timer) + + // Add a tiny delay, so if you want to use the "click twice" method to re-sort, it will only sort once + table.dataset.timer = setTimeout(() => { + sortSortable(table, alt_sort) + }, 1).toString() + } + // eslint-disable-next-line no-unused-vars + } catch (error) { + // console.log(error) + } +} diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/tests/formats/bundled.spec.ts b/tests/formats/bundled.spec.ts new file mode 100644 index 0000000..5877994 --- /dev/null +++ b/tests/formats/bundled.spec.ts @@ -0,0 +1,11 @@ +import { test, createSortableTests } from '../sortable-test-base' + +// Use override for the fixture +test.use({ + formatName: 'bundled', + getUrl: async ({}, use) => { + await use((minified: boolean) => `/bundled.html${minified ? '?minified=true' : ''}`) + }, +}) + +createSortableTests() diff --git a/tests/formats/esm.spec.ts b/tests/formats/esm.spec.ts new file mode 100644 index 0000000..f3691a0 --- /dev/null +++ b/tests/formats/esm.spec.ts @@ -0,0 +1,11 @@ +import { test, createSortableTests } from '../sortable-test-base' + +// Use override for the fixture +test.use({ + formatName: 'esm', + getUrl: async ({}, use) => { + await use((minified: boolean) => `/esm.html${minified ? '?minified=true' : ''}`) + }, +}) + +createSortableTests() diff --git a/tests/formats/standalone.spec.ts b/tests/formats/standalone.spec.ts new file mode 100644 index 0000000..b26425a --- /dev/null +++ b/tests/formats/standalone.spec.ts @@ -0,0 +1,11 @@ +import { test, createSortableTests } from '../sortable-test-base' + +// Use override for the fixture +test.use({ + formatName: 'standalone', + getUrl: async ({}, use) => { + await use((minified: boolean) => `/standalone.html${minified ? '?minified=true' : ''}`) + }, +}) + +createSortableTests() diff --git a/tests/sortable-test-base.ts b/tests/sortable-test-base.ts new file mode 100644 index 0000000..28bfa56 --- /dev/null +++ b/tests/sortable-test-base.ts @@ -0,0 +1,357 @@ +import { test as base, expect, type Page } from '@playwright/test' + +// Define the fixture type +type SortableFixture = { + getUrl: (minified: boolean) => string + formatName: string +} + +// Create a test function with our custom fixture +export const test = base.extend({ + getUrl: [ + async ({}, use, testInfo) => { + await use(() => '') + }, + { option: true }, // This makes it configurable + ], + formatName: [ + async ({}, use) => { + await use('') + }, + { option: true }, + ], +}) + +// Helper functions +export const waitForSort = async (page: Page) => { + await page.waitForTimeout(100) +} + +export const getSortedContent = async (page: Page, selector: string) => { + return page.$eval(selector, (el) => el.textContent) +} + +// Reusable test cases +export const createSortableTests = () => { + test.describe('sortable functionality', () => { + for (const minified of [false, true]) { + const variant = minified ? '(minified)' : '' + + test.describe(`${variant}`, () => { + test.beforeEach(async ({ page, getUrl }) => { + await page.goto(getUrl(minified)) + }) + + // Break after first failure + test.afterEach(async ({}, testInfo) => { + if (testInfo.status !== testInfo.expectedStatus) { + test.skip(true) + } + }) + + test('renders a heading element', async ({ page }) => { + const heading = await page.getByRole('heading', { name: /Sortable examples/i }) + expect(heading).toBeTruthy() + }) + + test('renders table headers and cells', async ({ page }) => { + const table = await page.$('table.sortable') + expect(table).toBeTruthy() + + const nameHeader = await page.$('th[aria-label*="Name"]') + expect(nameHeader).toBeTruthy() + + const cells = await page.$$('table.sortable tbody td') + expect(cells[0]).toBeTruthy() + expect(cells[1]).toBeTruthy() + }) + + test('sorts a table on click', async ({ page }) => { + const nameHeader = await page.$('th[aria-label*="Name"]') + + let firstCell = await page.$eval( + 'table.sortable tbody tr:first-child td:nth-child(2)', + (el) => el.textContent, + ) + expect(firstCell).toBe('Rick') + + await nameHeader?.click() + await page.waitForTimeout(100) + + firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Rick') + + await nameHeader?.click() + await page.waitForTimeout(100) + + firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Morty') + }) + + test('sorts a table using Enter key', async ({ page }) => { + const nameHeader = await page.$('th[aria-label*="Name"]') + + let firstCell = await page.$eval( + 'table.sortable tbody tr:first-child td:nth-child(2)', + (el) => el.textContent, + ) + expect(firstCell).toBe('Rick') + + await nameHeader?.focus() + await nameHeader?.press('Enter') + await page.waitForTimeout(100) + + firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Rick') + + await nameHeader?.press('Enter') + await page.waitForTimeout(100) + + firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Morty') + }) + + test('sorts a table using tie breaker', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[1] + const yearHeader = await table.$('th:nth-child(2)') + expect(yearHeader).toBeTruthy() + + let timeCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(timeCell).toBe('12:00') + + await yearHeader?.click() + await page.waitForTimeout(100) + + timeCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(timeCell).toBe('15:00') + + await yearHeader?.click() + await page.waitForTimeout(100) + + timeCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(timeCell).toBe('13:00') + }) + + test('sorts a table with colspans', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[2] + const charsHeader = await table.$('th:last-child') + expect(charsHeader).toBeTruthy() + + let charCell = await table.$eval('tbody tr:first-child td:last-child', (el) => el.textContent) + expect(charCell).toBe('BB') + + await charsHeader?.click() + await page.waitForTimeout(100) + + charCell = await table.$eval('tbody tr:first-child td:last-child', (el) => el.textContent) + expect(charCell).toBe('CCC') + + await charsHeader?.click() + await page.waitForTimeout(100) + + charCell = await table.$eval('tbody tr:first-child td:last-child', (el) => el.textContent) + expect(charCell).toBe('A') + }) + + test('sorts a table with empty rows last', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[3] + const numberHeader = await table.$('th:nth-child(2)') + expect(numberHeader).toBeTruthy() + + let numberCell = await table.$eval('tbody tr:nth-child(2) td:nth-child(2)', (el) => el.textContent) + expect(numberCell).toBe('0') + + await numberHeader?.click() + await page.waitForTimeout(100) + + numberCell = await table.$eval('tbody tr:last-child td:nth-child(2)', (el) => el.textContent) + expect(numberCell).toBe('(if click in this column)') + }) + + test('respects class="no-sort" in th', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[4] + const nameHeader = await table.$('th:nth-child(2)') + + let nameCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(nameCell).toBe('Rick') + + await nameHeader?.click() + await page.waitForTimeout(100) + + nameCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(nameCell).toBe('Rick') + }) + + test('treats time formats like strings', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[5] + const timeHeader = await table.$('th:nth-child(2)') + expect(timeHeader).toBeTruthy() + + let timeCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(timeCell).toBe('12:00:12') + + await timeHeader?.click() + await page.waitForTimeout(100) + + timeCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(timeCell).toBe('12:22:11') + + await timeHeader?.click() + await page.waitForTimeout(100) + + timeCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(timeCell).toBe('12:00:12') + }) + + test('treats amounts like strings', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[5] + const amountHeader = await table.$('th:nth-child(3)') + expect(amountHeader).toBeTruthy() + + let amountCell = await table.$eval('tbody tr:first-child td:nth-child(3)', (el) => el.textContent) + expect(amountCell).toBe('$18.49') + + await amountHeader?.click() + await page.waitForTimeout(100) + + amountCell = await table.$eval('tbody tr:first-child td:nth-child(3)', (el) => el.textContent) + expect(amountCell).toBe('$2.49') + + await amountHeader?.click() + await page.waitForTimeout(100) + + amountCell = await table.$eval('tbody tr:first-child td:nth-child(3)', (el) => el.textContent) + expect(amountCell).toBe('$1.96') + }) + + test('treats numbers like numbers', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[5] + const numberHeader = await table.$('th:nth-child(4)') + expect(numberHeader).toBeTruthy() + + let numberCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(numberCell).toBe('2.49') + + await numberHeader?.click() + await page.waitForTimeout(100) + + numberCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(numberCell).toBe('18.49') + + await numberHeader?.click() + await page.waitForTimeout(100) + + numberCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(numberCell).toBe('1.96') + }) + + test('sorts a table ascending', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[6] + const nameHeader = await table.$('th[aria-label*="Name"]') + + let firstCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Rick') + + await nameHeader?.click() + await page.waitForTimeout(100) + + firstCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Morty') + + await nameHeader?.click() + await page.waitForTimeout(100) + + firstCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Rick') + }) + + test('a11y labels are added and updated', async ({ page }) => { + const nameHeader = await page.$('th[aria-label*="Name"]') + + let ariaLabel = await nameHeader?.getAttribute('aria-label') + expect(ariaLabel).toContain('Click to sort table by Name in descending order') + + await nameHeader?.click() + await page.waitForTimeout(100) + + ariaLabel = await nameHeader?.getAttribute('aria-label') + expect(ariaLabel).toContain('Click to sort table by Name in ascending order') + }) + + test('works when using enhanceSortableAccessibility()', async ({ page }) => { + // Get a table to test with + const allTables = await page.$$('table.sortable') + const table = allTables[6] + + const nameHeader = await table.$('th[aria-label*="Name"]') + expect(nameHeader).toBeTruthy() + + // Check initial aria-label + let ariaLabel = await nameHeader?.getAttribute('aria-label') + expect(ariaLabel).toContain('Click to sort table by Name') + + // Clear and re-apply accessibility + await page.evaluate(() => { + const th = document.querySelector('th[aria-label*="Name"]') + if (th) { + th.removeAttribute('aria-label') + th.removeAttribute('tabindex') + } + }) + + // Re-apply accessibility through page evaluation + await page.evaluate(() => { + const enhanceSortableAccessibility = (tables: NodeListOf) => { + tables.forEach((table) => { + table.querySelectorAll('th').forEach((th) => { + if (!th.hasAttribute('tabindex')) { + th.setAttribute('tabindex', '0') + const headerText = th.textContent || 'column' + th.setAttribute('aria-label', `Click to sort table by ${headerText} in ascending order`) + } + }) + }) + } + enhanceSortableAccessibility(document.querySelectorAll('table.sortable')) + }) + + // Verify accessibility was reapplied + await page.waitForTimeout(100) + ariaLabel = await nameHeader?.getAttribute('aria-label') + expect(ariaLabel).toContain('Click to sort table by Name') + expect(await nameHeader?.getAttribute('tabindex')).toBe('0') + }) + + test('sortStart and sortEnd events are dispatched', async ({ page }) => { + const nameHeader = await page.$('th[aria-label*="Name"]') + + await page.evaluate(() => { + document.addEventListener('sort-start', () => { + ;(window as any).testEvents = (window as any).testEvents || [] + ;(window as any).testEvents.push('sortStart') + }) + document.addEventListener('sort-end', () => { + ;(window as any).testEvents = (window as any).testEvents || [] + ;(window as any).testEvents.push('sortEnd') + }) + }) + + await nameHeader?.click() + await page.waitForTimeout(100) + + const eventsFired = await page.evaluate(() => (window as any).testEvents) + expect(eventsFired).toContain('sortStart') + expect(eventsFired).toContain('sortEnd') + }) + }) + } + }) +} diff --git a/tests/sortable.spec.txt b/tests/sortable.spec.txt new file mode 100644 index 0000000..4a4bbb2 --- /dev/null +++ b/tests/sortable.spec.txt @@ -0,0 +1,324 @@ +import { test, expect } from '@playwright/test' +// Define all distribution formats to test +const DIST_FORMATS = ['bundled', 'standalone', 'esm'] as const +type DistFormat = (typeof DIST_FORMATS)[number] + +// Helper to get the right URL for each format +const getUrl = (format: DistFormat, minified: boolean) => { + return `/${format}.html${minified ? '?minified=true' : ''}` +} +for (const format of DIST_FORMATS) { + for (const minified of [false, true]) { + const formatName = `${format}${minified ? ' (minified)' : ''}` + + test.describe(formatName, () => { + test.beforeEach(async ({ page }) => { + await page.goto(getUrl(format, minified)) + }) + + // Break after first failure + test.afterEach(async ({}, testInfo) => { + if (testInfo.status !== testInfo.expectedStatus) { + test.skip(true) + } + }) + + test('renders a heading element', async ({ page }) => { + const heading = await page.getByRole('heading', { name: /Sortable examples/i }) + expect(heading).toBeTruthy() + }) + + test('renders table headers and cells', async ({ page }) => { + const table = await page.$('table.sortable') + expect(table).toBeTruthy() + + const nameHeader = await page.$('th[aria-label*="Name"]') + expect(nameHeader).toBeTruthy() + + const cells = await page.$$('table.sortable tbody td') + expect(cells[0]).toBeTruthy() + expect(cells[1]).toBeTruthy() + }) + + test('sorts a table on click', async ({ page }) => { + const nameHeader = await page.$('th[aria-label*="Name"]') + + let firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Rick') + + await nameHeader?.click() + await page.waitForTimeout(100) + + firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Rick') + + await nameHeader?.click() + await page.waitForTimeout(100) + + firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Morty') + }) + + test('sorts a table using Enter key', async ({ page }) => { + const nameHeader = await page.$('th[aria-label*="Name"]') + + let firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Rick') + + await nameHeader?.focus() + await nameHeader?.press('Enter') + await page.waitForTimeout(100) + + firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Rick') + + await nameHeader?.press('Enter') + await page.waitForTimeout(100) + + firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Morty') + }) + + test('sorts a table using tie breaker', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[1] + const yearHeader = await table.$('th:nth-child(2)') + expect(yearHeader).toBeTruthy() + + let timeCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(timeCell).toBe('12:00') + + await yearHeader?.click() + await page.waitForTimeout(100) + + timeCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(timeCell).toBe('15:00') + + await yearHeader?.click() + await page.waitForTimeout(100) + + timeCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(timeCell).toBe('13:00') + }) + + test('sorts a table with colspans', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[2] + const charsHeader = await table.$('th:last-child') + expect(charsHeader).toBeTruthy() + + let charCell = await table.$eval('tbody tr:first-child td:last-child', (el) => el.textContent) + expect(charCell).toBe('BB') + + await charsHeader?.click() + await page.waitForTimeout(100) + + charCell = await table.$eval('tbody tr:first-child td:last-child', (el) => el.textContent) + expect(charCell).toBe('CCC') + + await charsHeader?.click() + await page.waitForTimeout(100) + + charCell = await table.$eval('tbody tr:first-child td:last-child', (el) => el.textContent) + expect(charCell).toBe('A') + }) + + test('sorts a table with empty rows last', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[3] + const numberHeader = await table.$('th:nth-child(2)') + expect(numberHeader).toBeTruthy() + + let numberCell = await table.$eval('tbody tr:nth-child(2) td:nth-child(2)', (el) => el.textContent) + expect(numberCell).toBe('0') + + await numberHeader?.click() + await page.waitForTimeout(100) + + numberCell = await table.$eval('tbody tr:last-child td:nth-child(2)', (el) => el.textContent) + expect(numberCell).toBe('(if click in this column)') + }) + + test('respects class="no-sort" in th', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[4] + const nameHeader = await table.$('th:nth-child(2)') + + let nameCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(nameCell).toBe('Rick') + + await nameHeader?.click() + await page.waitForTimeout(100) + + nameCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(nameCell).toBe('Rick') + }) + + test('treats time formats like strings', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[5] + const timeHeader = await table.$('th:nth-child(2)') + expect(timeHeader).toBeTruthy() + + let timeCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(timeCell).toBe('12:00:12') + + await timeHeader?.click() + await page.waitForTimeout(100) + + timeCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(timeCell).toBe('12:22:11') + + await timeHeader?.click() + await page.waitForTimeout(100) + + timeCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(timeCell).toBe('12:00:12') + }) + + test('treats amounts like strings', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[5] + const amountHeader = await table.$('th:nth-child(3)') + expect(amountHeader).toBeTruthy() + + let amountCell = await table.$eval('tbody tr:first-child td:nth-child(3)', (el) => el.textContent) + expect(amountCell).toBe('$18.49') + + await amountHeader?.click() + await page.waitForTimeout(100) + + amountCell = await table.$eval('tbody tr:first-child td:nth-child(3)', (el) => el.textContent) + expect(amountCell).toBe('$2.49') + + await amountHeader?.click() + await page.waitForTimeout(100) + + amountCell = await table.$eval('tbody tr:first-child td:nth-child(3)', (el) => el.textContent) + expect(amountCell).toBe('$1.96') + }) + + test('treats numbers like numbers', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[5] + const numberHeader = await table.$('th:nth-child(4)') + expect(numberHeader).toBeTruthy() + + let numberCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(numberCell).toBe('2.49') + + await numberHeader?.click() + await page.waitForTimeout(100) + + numberCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(numberCell).toBe('18.49') + + await numberHeader?.click() + await page.waitForTimeout(100) + + numberCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(numberCell).toBe('1.96') + }) + + test('sorts a table ascending', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[6] + const nameHeader = await table.$('th[aria-label*="Name"]') + + let firstCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Rick') + + await nameHeader?.click() + await page.waitForTimeout(100) + + firstCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Morty') + + await nameHeader?.click() + await page.waitForTimeout(100) + + firstCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Rick') + }) + + test('a11y labels are added and updated', async ({ page }) => { + const nameHeader = await page.$('th[aria-label*="Name"]') + + let ariaLabel = await nameHeader?.getAttribute('aria-label') + expect(ariaLabel).toContain('Click to sort table by Name in descending order') + + await nameHeader?.click() + await page.waitForTimeout(100) + + ariaLabel = await nameHeader?.getAttribute('aria-label') + expect(ariaLabel).toContain('Click to sort table by Name in ascending order') + }) + + test('works when using enhanceSortableAccessibility()', async ({ page }) => { + // Get a table to test with + const allTables = await page.$$('table.sortable') + const table = allTables[6] + + const nameHeader = await table.$('th[aria-label*="Name"]') + expect(nameHeader).toBeTruthy() + + // Check initial aria-label + let ariaLabel = await nameHeader?.getAttribute('aria-label') + expect(ariaLabel).toContain('Click to sort table by Name') + + // Clear and re-apply accessibility + await page.evaluate(() => { + const th = document.querySelector('th[aria-label*="Name"]') + if (th) { + th.removeAttribute('aria-label') + th.removeAttribute('tabindex') + } + }) + + // Re-apply accessibility through page evaluation + await page.evaluate(() => { + const enhanceSortableAccessibility = (tables: NodeListOf) => { + tables.forEach((table) => { + table.querySelectorAll('th').forEach((th) => { + if (!th.hasAttribute('tabindex')) { + th.setAttribute('tabindex', '0') + const headerText = th.textContent || 'column' + th.setAttribute('aria-label', `Click to sort table by ${headerText} in ascending order`) + } + }) + }) + } + enhanceSortableAccessibility(document.querySelectorAll('table.sortable')) + }) + + // Verify accessibility was reapplied + await page.waitForTimeout(100) + ariaLabel = await nameHeader?.getAttribute('aria-label') + expect(ariaLabel).toContain('Click to sort table by Name') + expect(await nameHeader?.getAttribute('tabindex')).toBe('0') + }) + + test('sortStart and sortEnd events are dispatched', async ({ page }) => { + const nameHeader = await page.$('th[aria-label*="Name"]') + + await page.evaluate(() => { + document.addEventListener('sort-start', () => { + ;(window as any).testEvents = (window as any).testEvents || [] + ;(window as any).testEvents.push('sortStart') + }) + document.addEventListener('sort-end', () => { + ;(window as any).testEvents = (window as any).testEvents || [] + ;(window as any).testEvents.push('sortEnd') + }) + }) + + await nameHeader?.click() + await page.waitForTimeout(100) + + const eventsFired = await page.evaluate(() => (window as any).testEvents) + expect(eventsFired).toContain('sortStart') + expect(eventsFired).toContain('sortEnd') + }) + }) + } +} diff --git a/tsconfig.json b/tsconfig.json index 87a2989..8777c8d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,17 +1,28 @@ { "compilerOptions": { - "module": "ES2015", - "noImplicitReturns": true, - "noUnusedLocals": true, - "outDir": ".", - "sourceMap": false, - "moduleResolution": "node", - "strict": false, "target": "ES5", - "allowSyntheticDefaultImports": true, - "declaration": true + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + "esModuleInterop": true, + + /* Comment preservation */ + "removeComments": false, // Add this to keep comments + + /* Bundler mode */ + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "moduleDetection": "force", + "verbatimModuleSyntax": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true }, - "compileOnSave": false, - "include": ["src/**/*.ts"], - "exclude": ["node_modules"] + "include": ["src/**/*.ts", "scripts/**/*.ts"], + "exclude": ["dist", "scripts"] } diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..a764edc --- /dev/null +++ b/vite.config.js @@ -0,0 +1,139 @@ +// vite.config.js +import { defineConfig } from 'vite' +import typescript from '@rollup/plugin-typescript' +import terser from '@rollup/plugin-terser' +import { resolve, basename } from 'path' + +const createBuildConfig = (entry, outputDir, standalone = false, minify = false) => ({ + emptyOutDir: false, + lib: { + entry, + formats: ['es'], + }, + rollupOptions: { + output: { + entryFileNames: `${outputDir}/[name].js`, + inlineDynamicImports: standalone, + }, + plugins: [typescript()], + }, + minify, +}) + +const createPlugins = (minify = false) => [ + typescript(), + ...(minify + ? [ + terser({ + format: { + comments: 'all', + }, + compress: { + toplevel: true, + passes: 2, + }, + mangle: false, + }), + ] + : []), +] + +export default defineConfig(({ command, mode }) => { + const modularConfig = { + build: { + ...createBuildConfig( + { + 'sortable.a11y': resolve(__dirname, 'src/sortable.a11y.ts'), + sortSortable: resolve(__dirname, 'src/sortSortable.ts'), + sortableEventListener: resolve(__dirname, 'src/sortableEventListener.ts'), + sortable: resolve(__dirname, 'src/sortable.ts'), + enhanceSortableAccessibility: resolve(__dirname, 'src/enhanceSortableAccessibility.ts'), + }, + 'esm', + ), + // Add declaration file generation + rollupOptions: { + output: { + dir: 'dist/esm', + }, + }, + }, + plugins: [ + typescript({ + declaration: true, + declarationDir: 'dist/esm', + rootDir: 'src', + }), + ...createPlugins(), + ], + } + const inlineConfigA11y = { + build: createBuildConfig( + { + 'sortable.a11y': resolve(__dirname, 'src/sortable.a11y.ts'), + }, + 'standalone', + true, + ), + plugins: createPlugins(), + } + + const inlineConfig = { + build: createBuildConfig( + { + sortable: resolve(__dirname, 'src/sortable.ts'), + }, + 'standalone', + true, + ), + plugins: createPlugins(), + } + + const bundledConfig = { + build: { + ...createBuildConfig(resolve(__dirname, 'src/sortable.ts'), '', false, true), + rollupOptions: { + output: { + format: 'es', + compact: true, + preserveModules: false, + entryFileNames: `[name].js`, + }, + }, + }, + plugins: createPlugins(true), + esbuild: { + minifyIdentifiers: false, + minify: false, + }, + } + + const bundledA11yConfig = { + ...inlineConfigA11y, + build: { + ...inlineConfigA11y.build, + rollupOptions: { + ...inlineConfigA11y.build.rollupOptions, + output: { + ...inlineConfigA11y.build.rollupOptions.output, + entryFileNames: '[name].js', + }, + }, + }, + } + + switch (mode) { + case 'bundle': + return bundledConfig + case 'bundle-a11y': + return bundledA11yConfig + case 'standalone': + return inlineConfig + case 'standalone-a11y': + return inlineConfigA11y + case 'module': + return modularConfig + default: + return bundledConfig + } +}) From 51a176fb23c2b4368429445b5d29766df8438830 Mon Sep 17 00:00:00 2001 From: Jonas Earendel Date: Sun, 17 Nov 2024 21:14:27 +0900 Subject: [PATCH 02/12] lint fixes --- eslint.config.js | 11 ++++++----- package.json | 1 + pnpm-lock.yaml | 9 +++++++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index e9113d3..962f00b 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,8 +1,8 @@ import pkg from '@eslint/js' import typescriptParser from '@typescript-eslint/parser' import typescriptEslintPlugin from '@typescript-eslint/eslint-plugin' -// const globals = require("globals"); import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended' +import globals from 'globals' const { configs } = pkg export default [ @@ -13,10 +13,11 @@ export default [ files: ['src/**/*.ts'], languageOptions: { - // globals: { - // ...globals.browser, - // NodeListOf: false, - // }, + globals: { + ...globals.browser, + ...globals.node, + NodeListOf: false, + }, sourceType: 'module', parser: typescriptParser, }, diff --git a/package.json b/package.json index c4a9e4e..f399a09 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "eslint": "^9.14.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", + "globals": "^15.12.0", "google-closure-compiler": "^20240317.0.0", "husky": "^9.1.6", "jest": "^29.7.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0099ac6..691b994 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -59,6 +59,9 @@ importers: eslint-plugin-prettier: specifier: ^5.2.1 version: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.14.0))(eslint@9.14.0)(prettier@3.3.3) + globals: + specifier: ^15.12.0 + version: 15.12.0 google-closure-compiler: specifier: ^20240317.0.0 version: 20240317.0.0 @@ -1799,6 +1802,10 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} + globals@15.12.0: + resolution: {integrity: sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==} + engines: {node: '>=18'} + google-closure-compiler-java@20240317.0.0: resolution: {integrity: sha512-oWURPChjcCrVfiQOuVtpSoUJVvtOYo41JGEQ2qtArsTGmk/DpWh40vS6hitwKRM/0YzJX/jYUuyt9ibuXXJKmg==} @@ -4570,6 +4577,8 @@ snapshots: globals@14.0.0: {} + globals@15.12.0: {} + google-closure-compiler-java@20240317.0.0: {} google-closure-compiler-linux@20240317.0.0: From 470db699db1de6e52f0ed84c802ef579fb5367ba Mon Sep 17 00:00:00 2001 From: Jonas Earendel Date: Sun, 17 Nov 2024 21:23:38 +0900 Subject: [PATCH 03/12] package.json cleanup --- package.json | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index f399a09..829a33d 100644 --- a/package.json +++ b/package.json @@ -18,16 +18,13 @@ "build": "npm run clean && vite build --mode module && vite build --mode standalone && vite build --mode standalone-a11y && vite build --mode bundle && vite build --mode bundle-a11y && rollup -c", "compile": "tsx ./scripts/compile.ts dist dist/standalone", "lint": "eslint './src/*.ts'", - "_prepare": "tsx ./scripts/prepare.ts", - "pre-push": "npm run build && npm run compile && npm run lint && npm run test && npm run test:min", + "prepare": "tsx ./scripts/prepare.ts", + "pre-push": "npm run build && npm run compile && npm run lint && npm run test", "dev": "vite", "prepare:tests": "tsx scripts/prepare-tests.ts", "test": "npm run prepare:tests && playwright test || (exit_code=$?; npm run cleanup:tests; exit $exit_code)", "cleanup:tests": "tsx scripts/prepare-tests.ts cleanup", - "test:e2e:ui": "playwright test --ui", - "serve": "vite preview --port 3009", - "test_old": "vitest", - "test:min": "cross-env USE_MINIFIED=true vitest" + "serve": "vite preview --port 3009" }, "devDependencies": { "@eslint/js": "^9.14.0", From 1bcf0cf1e762994cdc8642cf67c986752242e498 Mon Sep 17 00:00:00 2001 From: Jonas Earendel Date: Sun, 17 Nov 2024 22:59:19 +0900 Subject: [PATCH 04/12] demo-folder --- demo/index.html | 214 +++++++++++++++++++++++++++++++++++++++ index.html | 8 -- scripts/prepare-tests.ts | 42 +++++--- 3 files changed, 242 insertions(+), 22 deletions(-) create mode 100644 demo/index.html diff --git a/demo/index.html b/demo/index.html new file mode 100644 index 0000000..96a7514 --- /dev/null +++ b/demo/index.html @@ -0,0 +1,214 @@ + + + + + + + sortable test + + + + +

Sortable examples

+ +

Basic sort

+ + + + + + + + + + + + + + + + + +
RoleName
GeniusRick
SidekickMorty
+ +

Tiebreaker

+

Sort by year

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
+
    +
  • If year is the same, sort by month.
  • +
  • If month is the same, sort by day.
  • +
  • If day is the same, sort by time
  • +
+ +

Colspans

+ + + + + + + + + + + + + + + + + + + + + + + + + +
nums + charsCHARS
333222BB
1111CCC
22333A
+ +

Empty/null sorted last

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
TextNumber
jkl0.4
abc0
should be sorted last(if click in this column)
def0.2
+

class="no-sort"

+ + + + + + + + + + + + + + + + + +
RoleName
GeniusRick
SidekickMorty
+ +

numeric sorting

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
RoleTimeAmountNumber
Genius12:00:12$18.492.49
Sidekick12:22:11$2.4918.49
Butler12:22:05$1.961.96
+ +

Ascending sort

+ + + + + + + + + + + + + + + + + + +
RoleName
GeniusRick
SidekickMorty
+ + + + + + + + + diff --git a/index.html b/index.html index 4ba7f26..a5f729e 100644 --- a/index.html +++ b/index.html @@ -203,15 +203,7 @@

Ascending sort

e.preventDefault() alert('event listeners also work!') }) - - // document.addEventListener('sort-start', function (e) { - // console.log('🚀 COMMANDER ~ file: index.html ~ line ~ 196 ~ ', e.target) - // }) - // document.addEventListener('sort-end', function (e) { - // console.log('🚀 COMMANDER ~ file: index.html ~ line ~ 200 ~ ', e.target) - // }) - diff --git a/scripts/prepare-tests.ts b/scripts/prepare-tests.ts index aa3ec23..d711d4a 100644 --- a/scripts/prepare-tests.ts +++ b/scripts/prepare-tests.ts @@ -1,9 +1,10 @@ import fs from 'fs' import path from 'path' -const DIST_TYPES = ['bundled', 'standalone', 'esm'] as const +const DIST_TYPES = ['bundled', 'standalone', 'esm', 'demo'] as const function createHTML(type: (typeof DIST_TYPES)[number], minified: boolean = false) { + if (type === 'demo' && minified) return let template = fs.readFileSync('index.html', 'utf8') // Remove the existing script tags @@ -12,12 +13,13 @@ function createHTML(type: (typeof DIST_TYPES)[number], minified: boolean = false .replace('', '') .replace('', '') - // Add CSS - const cssFiles = minified ? ['sortable.min.css', 'example.min.css'] : ['sortable.css', 'example.css'] + const css_file_name = `example${minified ? '.min' : ''}.css` - const cssLinks = cssFiles.map((file) => ``).join('\n') + const css_url = type !== 'demo' ? `/${css_file_name}` : `../dist/${css_file_name}` - template = template.replace('', `${cssLinks}\n`) + const css_link = `` + + template = template.replace('', `${css_link}\n`) // Generate script tags based on format and minified state let scripts = '' @@ -26,33 +28,45 @@ function createHTML(type: (typeof DIST_TYPES)[number], minified: boolean = false switch (type) { case 'bundled': scripts = ` - - ` + + ` + break + case 'demo': + scripts = ` + + ` break case 'standalone': scripts = ` - - ` + + ` break case 'esm': scripts = ` - ` + ` break } template = template.replace('', `${scripts}\n`) // Save the file - const outputPath = `dist/${type}${minified ? '.min' : ''}.html` + const outputPath = type === 'demo' ? 'demo/index.html' : `dist/${type}${minified ? '.min' : ''}.html` + + // if no such directory, create it + if (!fs.existsSync(path.dirname(outputPath))) { + fs.mkdirSync(path.dirname(outputPath), { recursive: true }) + } + fs.writeFileSync(outputPath, template) console.log(`Created ${outputPath}`) } function cleanup() { DIST_TYPES.forEach((type) => { + if (type === 'demo') return ;['', '.min'].forEach((suffix) => { const filePath = `dist/${type}${suffix}.html` if (fs.existsSync(filePath)) { From b2d0e1fa97573a087f741a72e979f39e8d79b472 Mon Sep 17 00:00:00 2001 From: Jonas Earendel Date: Sun, 17 Nov 2024 23:58:54 +0900 Subject: [PATCH 05/12] updated readme --- README.md | 89 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 2a925cf..a419b18 100755 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

sortable

- a tiny, vanilla/plain JavaScript table sorter
-![GitHub Issues or Pull Requests](https://img.shields.io/github/issues/tofsjonas/sortable) ![NPM Version](https://img.shields.io/npm/v/sortable-tablesort) ![NPM Downloads](https://img.shields.io/npm/dw/sortable-tablesort) ![GitHub Repo stars](https://img.shields.io/github/stars/tofsjonas/sortable) [![jsdelivr](https://data.jsdelivr.com/v1/package/gh/tofsjonas/sortable/badge)](https://www.jsdelivr.com/package/gh/tofsjonas/sortable) +[![GitHub Issues or Pull Requests](https://img.shields.io/github/issues/tofsjonas/sortable)](https://github.com/tofsjonas/sortable) [![NPM Version](https://img.shields.io/npm/v/sortable-tablesort)](https://www.npmjs.com/package/sortable-tablesort) [![NPM Downloads](https://img.shields.io/npm/dw/sortable-tablesort)](https://www.npmjs.com/package/sortable-tablesort) [![GitHub Repo stars](https://img.shields.io/github/stars/tofsjonas/sortable)](https://github.com/tofsjonas/sortable) [![jsdelivr](https://data.jsdelivr.com/v1/package/gh/tofsjonas/sortable/badge)](https://www.jsdelivr.com/package/gh/tofsjonas/sortable) Makes any table with **class="sortable"**, er, sortable. The user can click on a table header and change the sorting of the table rows. @@ -27,6 +27,7 @@ You can find a simple demo on - [...using `td` instead of `th`](#using-td-instead-of-th) - [Indicators/arrows on the left side](#indicatorsarrows-on-the-left-side) - [NOTE ABOUT CSS/SCSS](#note-about-cssscss) + - [Sticky headers](#sticky-headers) - [Sorting sizes, dates and such](#sorting-sizes-dates-and-such) - [Alternative sorting](#alternative-sorting) - [Colspans/Sort on specific column](#colspanssort-on-specific-column) @@ -35,12 +36,13 @@ You can find a simple demo on - [Tiebreaker / secondary sort](#tiebreaker--secondary-sort) - [Empty/null rows always last](#emptynull-rows-always-last) - [Accessibility](#accessibility) +- [Sort Events](#sort-events) - [Sort on load](#sort-on-load) - [Thank you...](#thank-you) ## Factoids -- **1.02 KB** minified. (790 bytes gzipped) +- **1.52KB** minified. (795 bytes gzipped) - Works with **JavaScript generated tables**. (since we are using an eventListener) @@ -60,12 +62,6 @@ You can find a simple demo on There are three ways to use sortable, all of which have their pros and cons. [S Anand](https://github.com/sanand0) and [dkhgh](https://github.com/dkhgh) had some [interesting thoughts](https://github.com/tofsjonas/sortable/issues/28) about it. -1. Include a link to [jsDelivr](https://www.jsdelivr.com/package/gh/tofsjonas/sortable). (easiest) - -2. Copy the file from [jsDelivr](https://www.jsdelivr.com/package/gh/tofsjonas/sortable) or [Github](https://github.com/tofsjonas/sortable) and put it in your assets folder. (in between) - -3. Install the [npm package](https://www.npmjs.com/package/sortable-tablesort). (most reliable) - ### 1. link to jsDelivr ```html @@ -87,8 +83,8 @@ There are three ways to use sortable, all of which have their pros and cons. [S - - + + ``` The `span` on line four is just there to prove that you can have elements inside `th`! @@ -97,7 +93,7 @@ The `span` on line four is just there to prove that you can have elements inside ### 2. copy file to assets folder -Same as above, but link to your own files +Same as above, but link to your own files from the `dist` directory ```html ... @@ -116,16 +112,16 @@ npm install sortable-tablesort # pnpm install sortable-tablesort ``` -Now you can +Now you can: #### a) use links in the html -Same as above, with links to files +Same as above, with links to files from the `dist` directory ```html ... - - + + ... ``` @@ -135,8 +131,8 @@ or ```javascript // main.js -import 'sortable-tablesort/sortable.min.css' -import 'sortable-tablesort/sortable.min.js' +import 'sortable-tablesort/dist/sortable.min.css' +import 'sortable-tablesort/dist/sortable.min.js' ``` ## Non-sortable field @@ -222,6 +218,28 @@ That said, if you're feeling lazy, here are two stylesheets you can use: ``` +### Sticky headers + +I'm not sure if it's a good idea to have it in the main css, BUT if you are using the above `sortable(.min).css` file (not the -base files) and want sticky headers, you can simply add the class `sticky` to the table. + +Blame [razorkyle](https://github.com/razorkyle), it was his idea! 😜 + +```html + + ... +
+``` + +If you are not using the css file, you can use the following css: + +```css +.sortable thead th { + position: sticky; + top: 0; + z-index: 1; +} +``` + ## Sorting sizes, dates and such Using the `data-sort` attribute in `tbody` > `td` you can have one visible value and one sortable value. This is useful in case you have for instance sizes like kb, Mb, GB, or really weird date formats. 😉 @@ -410,9 +428,9 @@ Sortable is not very accessible in its raw form. It does not support screen read ...
- - - + + + ``` By including the file the global function `enhanceSortableAccessibility` will automatically run through all existing `.sortable` tables, but you can also run it manually, like so: @@ -423,13 +441,38 @@ enhanceSortableAccessibility([table1, table2,...etc.]) The function adds an `aria-label` to each th, as well as `tabindex="0"` to each th in the thead of each table, making it possible to tab through the headers. It updates the `aria-label` depending on the direction. -if you want to import it instead this _should_ work: (I haven't tested it) +If you want to import it instead: ```ts -import { enhanceSortableAccessibility } from 'sortable-tablesort/enhanceSortableAccessibility' +import { enhanceSortableAccessibility } from 'sortable-tablesort/dist/esm/enhanceSortableAccessibility' enhanceSortableAccessibility([table1, table2,...etc.]) ``` +## Sort Events + +The table element dispatches two custom events that bubble up the DOM tree: + +- `sort-start`: Fired when sorting begins +- `sort-end`: Fired when sorting is complete + +You can listen for these events on any parent element, including the document itself: + +```js +// Listen for events from any sortable table +document.addEventListener('sort-start', function (e) { + console.log('Sorting started on:', e.target) // logs the table element +}) + +document.addEventListener('sort-end', function (e) { + console.log('Sorting complete on:', e.target) // logs the table element +}) + +// Or listen to a specific table +const table = document.querySelector('.sortable') +table.addEventListener('sort-start', () => console.log('Sorting started')) +table.addEventListener('sort-end', () => console.log('Sorting complete')) +``` + ## Sort on load If you wish to sort a table on load, I would recommend doing something like this: @@ -494,3 +537,5 @@ Combine this with `` to reverse the sort order. Or d - ...[Jojo-IO](https://github.com/Jojo-IO) for the finding the "`parseFloat` messes up time values" bug! - ...[Steve Wirt](https://github.com/swirtSJW) for lifting the Accessibility issue! 🦾️ + +- ...[GazHay](https://github.com/gazhay) for the [sort events](#sort-events) idea! From e025858f482e733adc121ce92dc0580a4181900a Mon Sep 17 00:00:00 2001 From: Jonas Earendel Date: Mon, 18 Nov 2024 15:41:31 +0900 Subject: [PATCH 06/12] ci-pw-changes --- .github/workflows/CI.yml | 59 +++++++++++++++++++++++++++++----------- playwright.config.ts | 58 +++++++++++++++++++++++++++++---------- 2 files changed, 86 insertions(+), 31 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 691efdf..bcb4817 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -4,31 +4,37 @@ on: push: branches: - main - paths: - - 'src/sortable.ts' - - '.github/workflows/CI.yml' + paths-ignore: + - '**.md' + - 'docs/**' pull_request: branches: - main - paths: - - 'src/sortable.ts' - - '.github/workflows/CI.yml' + paths-ignore: + - '**.md' + - 'docs/**' jobs: - run-linters-and-tests: - name: Run linters + test: + name: Playwright Tests + timeout-minutes: 15 runs-on: ubuntu-latest strategy: + fail-fast: false matrix: - node-version: [20] + node-version: [18, 20] + # Test both normal and minified versions + test-type: [normal, minified] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v2 with: version: latest + - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: 'pnpm' @@ -36,11 +42,32 @@ jobs: - name: Install dependencies run: pnpm install + - name: Install Playwright Browsers + run: pnpm exec playwright install chromium --with-deps + + - name: Build project + run: pnpm run build + + - name: Build project + run: pnpm run compile + - name: Run linters - run: npm run lint + run: pnpm run lint - - name: Run tests - run: npm run test + - name: Run Playwright tests + run: | + if [ "${{ matrix.test-type }}" = "minified" ]; then + USE_MINIFIED=true pnpm run test + else + pnpm run test + fi - - name: Run tests with minified code - run: npm run test:min + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: playwright-report-${{ matrix.node-version }}-${{ matrix.test-type }} + path: | + playwright-report/ + test-results/ + retention-days: 14 diff --git a/playwright.config.ts b/playwright.config.ts index b7dcd6f..cc5a369 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -1,28 +1,56 @@ -import { defineConfig } from '@playwright/test' +import { defineConfig, devices } from '@playwright/test' export default defineConfig({ + testDir: './tests', + fullyParallel: true, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 1 : undefined, + reporter: process.env.CI ? [['list'], ['html'], ['github']] : [['list'], ['html']], + + timeout: 30000, + expect: { + timeout: 5000, + }, + + use: { + baseURL: 'http://localhost:3008', + trace: 'on-first-retry', + screenshot: 'only-on-failure', + video: 'on-first-retry', + contextOptions: { + reducedMotion: 'reduce', + }, + }, + webServer: { command: 'vite preview --port 3008', port: 3008, reuseExistingServer: !process.env.CI, }, - testDir: './tests', + projects: [ { name: 'chromium', - use: { browserName: 'chromium' }, + use: { ...devices['Desktop Chrome'] }, }, + // Uncomment to add more browser testing + // { + // name: 'firefox', + // use: { ...devices['Desktop Firefox'] }, + // }, + // { + // name: 'webkit', + // use: { ...devices['Desktop Safari'] }, + // }, + /* Test against mobile viewports */ + // { + // name: 'Mobile Chrome', + // use: { ...devices['Pixel 5'] }, + // }, + // { + // name: 'Mobile Safari', + // use: { ...devices['iPhone 12'] }, + // }, ], - workers: process.env.CI ? 1 : undefined, - fullyParallel: true, - timeout: 30000, - reporter: [['list'], ['html']], - use: { - baseURL: 'http://localhost:3008', - contextOptions: { - reducedMotion: 'reduce', - }, - // Retry on CI only - // retries: process.env.CI ? 2 : 0, - }, }) From 3c6958c04e548ad7e9c3be5171340f75e13f682c Mon Sep 17 00:00:00 2001 From: Jonas Earendel Date: Mon, 18 Nov 2024 15:51:53 +0900 Subject: [PATCH 07/12] more ci --- .github/workflows/CI.yml | 44 ++++++++++------------------------------ 1 file changed, 11 insertions(+), 33 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index bcb4817..5793e85 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1,15 +1,12 @@ -name: CI - +name: Playwright Tests on: push: - branches: - - main + branches: [main] paths-ignore: - '**.md' - 'docs/**' pull_request: - branches: - - main + branches: [main] paths-ignore: - '**.md' - 'docs/**' @@ -17,26 +14,19 @@ on: jobs: test: name: Playwright Tests - timeout-minutes: 15 + timeout-minutes: 30 runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - node-version: [18, 20] - # Test both normal and minified versions - test-type: [normal, minified] steps: - uses: actions/checkout@v4 - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v4 with: version: latest - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 + - uses: actions/setup-node@v4 with: - node-version: ${{ matrix.node-version }} + node-version: 22 cache: 'pnpm' - name: Install dependencies @@ -48,26 +38,14 @@ jobs: - name: Build project run: pnpm run build - - name: Build project - run: pnpm run compile - - - name: Run linters - run: pnpm run lint - - name: Run Playwright tests - run: | - if [ "${{ matrix.test-type }}" = "minified" ]; then - USE_MINIFIED=true pnpm run test - else - pnpm run test - fi + run: pnpm run test - - name: Upload test results + - uses: actions/upload-artifact@v4 if: always() - uses: actions/upload-artifact@v4 with: - name: playwright-report-${{ matrix.node-version }}-${{ matrix.test-type }} + name: playwright-report path: | playwright-report/ test-results/ - retention-days: 14 + retention-days: 30 From ba3fb8848d7a72967deca07a44590f8b6cb7ddb7 Mon Sep 17 00:00:00 2001 From: Jonas Earendel Date: Mon, 18 Nov 2024 15:53:24 +0900 Subject: [PATCH 08/12] and more --- .github/workflows/CI.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 5793e85..7d4b337 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -21,8 +21,6 @@ jobs: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 - with: - version: latest - uses: actions/setup-node@v4 with: From c372aedcdc61528e923a932d41ba69ed0996353c Mon Sep 17 00:00:00 2001 From: Jonas Earendel Date: Mon, 18 Nov 2024 15:54:54 +0900 Subject: [PATCH 09/12] 4 --- .github/workflows/CI.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 7d4b337..bb70411 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -33,9 +33,6 @@ jobs: - name: Install Playwright Browsers run: pnpm exec playwright install chromium --with-deps - - name: Build project - run: pnpm run build - - name: Run Playwright tests run: pnpm run test From 5d05609d4d4a980fa7bcd645629b1b8570d3d42f Mon Sep 17 00:00:00 2001 From: Jonas Earendel Date: Mon, 18 Nov 2024 16:03:51 +0900 Subject: [PATCH 10/12] more ci-workers --- playwright.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playwright.config.ts b/playwright.config.ts index cc5a369..efb689a 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -5,7 +5,7 @@ export default defineConfig({ fullyParallel: true, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, - workers: process.env.CI ? 1 : undefined, + workers: process.env.CI ? 3 : undefined, reporter: process.env.CI ? [['list'], ['html'], ['github']] : [['list'], ['html']], timeout: 30000, From 53b3ac9b0fd66e07bf70b225051fd1cc3e9fcaae Mon Sep 17 00:00:00 2001 From: Jonas Earendel Date: Mon, 18 Nov 2024 16:16:46 +0900 Subject: [PATCH 11/12] minor ci-cleanup --- .github/workflows/CI.yml | 2 +- package.json | 2 +- tests/sortable.spec.txt | 324 --------------------------------------- 3 files changed, 2 insertions(+), 326 deletions(-) delete mode 100644 tests/sortable.spec.txt diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index bb70411..447c1dd 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1,4 +1,4 @@ -name: Playwright Tests +name: CI on: push: branches: [main] diff --git a/package.json b/package.json index 829a33d..7d02ebf 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "pre-push": "npm run build && npm run compile && npm run lint && npm run test", "dev": "vite", "prepare:tests": "tsx scripts/prepare-tests.ts", - "test": "npm run prepare:tests && playwright test || (exit_code=$?; npm run cleanup:tests; exit $exit_code)", + "test": "npm run prepare:tests && (playwright test && npm run cleanup:tests || true)", "cleanup:tests": "tsx scripts/prepare-tests.ts cleanup", "serve": "vite preview --port 3009" }, diff --git a/tests/sortable.spec.txt b/tests/sortable.spec.txt deleted file mode 100644 index 4a4bbb2..0000000 --- a/tests/sortable.spec.txt +++ /dev/null @@ -1,324 +0,0 @@ -import { test, expect } from '@playwright/test' -// Define all distribution formats to test -const DIST_FORMATS = ['bundled', 'standalone', 'esm'] as const -type DistFormat = (typeof DIST_FORMATS)[number] - -// Helper to get the right URL for each format -const getUrl = (format: DistFormat, minified: boolean) => { - return `/${format}.html${minified ? '?minified=true' : ''}` -} -for (const format of DIST_FORMATS) { - for (const minified of [false, true]) { - const formatName = `${format}${minified ? ' (minified)' : ''}` - - test.describe(formatName, () => { - test.beforeEach(async ({ page }) => { - await page.goto(getUrl(format, minified)) - }) - - // Break after first failure - test.afterEach(async ({}, testInfo) => { - if (testInfo.status !== testInfo.expectedStatus) { - test.skip(true) - } - }) - - test('renders a heading element', async ({ page }) => { - const heading = await page.getByRole('heading', { name: /Sortable examples/i }) - expect(heading).toBeTruthy() - }) - - test('renders table headers and cells', async ({ page }) => { - const table = await page.$('table.sortable') - expect(table).toBeTruthy() - - const nameHeader = await page.$('th[aria-label*="Name"]') - expect(nameHeader).toBeTruthy() - - const cells = await page.$$('table.sortable tbody td') - expect(cells[0]).toBeTruthy() - expect(cells[1]).toBeTruthy() - }) - - test('sorts a table on click', async ({ page }) => { - const nameHeader = await page.$('th[aria-label*="Name"]') - - let firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(firstCell).toBe('Rick') - - await nameHeader?.click() - await page.waitForTimeout(100) - - firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(firstCell).toBe('Rick') - - await nameHeader?.click() - await page.waitForTimeout(100) - - firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(firstCell).toBe('Morty') - }) - - test('sorts a table using Enter key', async ({ page }) => { - const nameHeader = await page.$('th[aria-label*="Name"]') - - let firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(firstCell).toBe('Rick') - - await nameHeader?.focus() - await nameHeader?.press('Enter') - await page.waitForTimeout(100) - - firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(firstCell).toBe('Rick') - - await nameHeader?.press('Enter') - await page.waitForTimeout(100) - - firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(firstCell).toBe('Morty') - }) - - test('sorts a table using tie breaker', async ({ page }) => { - const allTables = await page.$$('table.sortable') - const table = allTables[1] - const yearHeader = await table.$('th:nth-child(2)') - expect(yearHeader).toBeTruthy() - - let timeCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) - expect(timeCell).toBe('12:00') - - await yearHeader?.click() - await page.waitForTimeout(100) - - timeCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) - expect(timeCell).toBe('15:00') - - await yearHeader?.click() - await page.waitForTimeout(100) - - timeCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) - expect(timeCell).toBe('13:00') - }) - - test('sorts a table with colspans', async ({ page }) => { - const allTables = await page.$$('table.sortable') - const table = allTables[2] - const charsHeader = await table.$('th:last-child') - expect(charsHeader).toBeTruthy() - - let charCell = await table.$eval('tbody tr:first-child td:last-child', (el) => el.textContent) - expect(charCell).toBe('BB') - - await charsHeader?.click() - await page.waitForTimeout(100) - - charCell = await table.$eval('tbody tr:first-child td:last-child', (el) => el.textContent) - expect(charCell).toBe('CCC') - - await charsHeader?.click() - await page.waitForTimeout(100) - - charCell = await table.$eval('tbody tr:first-child td:last-child', (el) => el.textContent) - expect(charCell).toBe('A') - }) - - test('sorts a table with empty rows last', async ({ page }) => { - const allTables = await page.$$('table.sortable') - const table = allTables[3] - const numberHeader = await table.$('th:nth-child(2)') - expect(numberHeader).toBeTruthy() - - let numberCell = await table.$eval('tbody tr:nth-child(2) td:nth-child(2)', (el) => el.textContent) - expect(numberCell).toBe('0') - - await numberHeader?.click() - await page.waitForTimeout(100) - - numberCell = await table.$eval('tbody tr:last-child td:nth-child(2)', (el) => el.textContent) - expect(numberCell).toBe('(if click in this column)') - }) - - test('respects class="no-sort" in th', async ({ page }) => { - const allTables = await page.$$('table.sortable') - const table = allTables[4] - const nameHeader = await table.$('th:nth-child(2)') - - let nameCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(nameCell).toBe('Rick') - - await nameHeader?.click() - await page.waitForTimeout(100) - - nameCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(nameCell).toBe('Rick') - }) - - test('treats time formats like strings', async ({ page }) => { - const allTables = await page.$$('table.sortable') - const table = allTables[5] - const timeHeader = await table.$('th:nth-child(2)') - expect(timeHeader).toBeTruthy() - - let timeCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(timeCell).toBe('12:00:12') - - await timeHeader?.click() - await page.waitForTimeout(100) - - timeCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(timeCell).toBe('12:22:11') - - await timeHeader?.click() - await page.waitForTimeout(100) - - timeCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(timeCell).toBe('12:00:12') - }) - - test('treats amounts like strings', async ({ page }) => { - const allTables = await page.$$('table.sortable') - const table = allTables[5] - const amountHeader = await table.$('th:nth-child(3)') - expect(amountHeader).toBeTruthy() - - let amountCell = await table.$eval('tbody tr:first-child td:nth-child(3)', (el) => el.textContent) - expect(amountCell).toBe('$18.49') - - await amountHeader?.click() - await page.waitForTimeout(100) - - amountCell = await table.$eval('tbody tr:first-child td:nth-child(3)', (el) => el.textContent) - expect(amountCell).toBe('$2.49') - - await amountHeader?.click() - await page.waitForTimeout(100) - - amountCell = await table.$eval('tbody tr:first-child td:nth-child(3)', (el) => el.textContent) - expect(amountCell).toBe('$1.96') - }) - - test('treats numbers like numbers', async ({ page }) => { - const allTables = await page.$$('table.sortable') - const table = allTables[5] - const numberHeader = await table.$('th:nth-child(4)') - expect(numberHeader).toBeTruthy() - - let numberCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) - expect(numberCell).toBe('2.49') - - await numberHeader?.click() - await page.waitForTimeout(100) - - numberCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) - expect(numberCell).toBe('18.49') - - await numberHeader?.click() - await page.waitForTimeout(100) - - numberCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) - expect(numberCell).toBe('1.96') - }) - - test('sorts a table ascending', async ({ page }) => { - const allTables = await page.$$('table.sortable') - const table = allTables[6] - const nameHeader = await table.$('th[aria-label*="Name"]') - - let firstCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(firstCell).toBe('Rick') - - await nameHeader?.click() - await page.waitForTimeout(100) - - firstCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(firstCell).toBe('Morty') - - await nameHeader?.click() - await page.waitForTimeout(100) - - firstCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(firstCell).toBe('Rick') - }) - - test('a11y labels are added and updated', async ({ page }) => { - const nameHeader = await page.$('th[aria-label*="Name"]') - - let ariaLabel = await nameHeader?.getAttribute('aria-label') - expect(ariaLabel).toContain('Click to sort table by Name in descending order') - - await nameHeader?.click() - await page.waitForTimeout(100) - - ariaLabel = await nameHeader?.getAttribute('aria-label') - expect(ariaLabel).toContain('Click to sort table by Name in ascending order') - }) - - test('works when using enhanceSortableAccessibility()', async ({ page }) => { - // Get a table to test with - const allTables = await page.$$('table.sortable') - const table = allTables[6] - - const nameHeader = await table.$('th[aria-label*="Name"]') - expect(nameHeader).toBeTruthy() - - // Check initial aria-label - let ariaLabel = await nameHeader?.getAttribute('aria-label') - expect(ariaLabel).toContain('Click to sort table by Name') - - // Clear and re-apply accessibility - await page.evaluate(() => { - const th = document.querySelector('th[aria-label*="Name"]') - if (th) { - th.removeAttribute('aria-label') - th.removeAttribute('tabindex') - } - }) - - // Re-apply accessibility through page evaluation - await page.evaluate(() => { - const enhanceSortableAccessibility = (tables: NodeListOf) => { - tables.forEach((table) => { - table.querySelectorAll('th').forEach((th) => { - if (!th.hasAttribute('tabindex')) { - th.setAttribute('tabindex', '0') - const headerText = th.textContent || 'column' - th.setAttribute('aria-label', `Click to sort table by ${headerText} in ascending order`) - } - }) - }) - } - enhanceSortableAccessibility(document.querySelectorAll('table.sortable')) - }) - - // Verify accessibility was reapplied - await page.waitForTimeout(100) - ariaLabel = await nameHeader?.getAttribute('aria-label') - expect(ariaLabel).toContain('Click to sort table by Name') - expect(await nameHeader?.getAttribute('tabindex')).toBe('0') - }) - - test('sortStart and sortEnd events are dispatched', async ({ page }) => { - const nameHeader = await page.$('th[aria-label*="Name"]') - - await page.evaluate(() => { - document.addEventListener('sort-start', () => { - ;(window as any).testEvents = (window as any).testEvents || [] - ;(window as any).testEvents.push('sortStart') - }) - document.addEventListener('sort-end', () => { - ;(window as any).testEvents = (window as any).testEvents || [] - ;(window as any).testEvents.push('sortEnd') - }) - }) - - await nameHeader?.click() - await page.waitForTimeout(100) - - const eventsFired = await page.evaluate(() => (window as any).testEvents) - expect(eventsFired).toContain('sortStart') - expect(eventsFired).toContain('sortEnd') - }) - }) - } -} From 3dde357e5842026368076d6eec5714124348cbb5 Mon Sep 17 00:00:00 2001 From: Jonas Earendel Date: Mon, 18 Nov 2024 16:38:21 +0900 Subject: [PATCH 12/12] better logging in playwright ci --- tests/formats/bundled.spec.ts | 17 +- tests/formats/esm.spec.ts | 17 +- tests/formats/standalone.spec.ts | 17 +- tests/sortable-test-base.ts | 488 +++++++++++++++---------------- 4 files changed, 270 insertions(+), 269 deletions(-) diff --git a/tests/formats/bundled.spec.ts b/tests/formats/bundled.spec.ts index 5877994..c1a8d7a 100644 --- a/tests/formats/bundled.spec.ts +++ b/tests/formats/bundled.spec.ts @@ -1,11 +1,12 @@ import { test, createSortableTests } from '../sortable-test-base' -// Use override for the fixture -test.use({ - formatName: 'bundled', - getUrl: async ({}, use) => { - await use((minified: boolean) => `/bundled.html${minified ? '?minified=true' : ''}`) - }, -}) +test.describe('bundled', () => { + test.use({ + formatName: 'bundled', + getUrl: async ({}, use) => { + await use((minified: boolean) => `/bundled.html${minified ? '?minified=true' : ''}`) + }, + }) -createSortableTests() + createSortableTests() +}) diff --git a/tests/formats/esm.spec.ts b/tests/formats/esm.spec.ts index f3691a0..07b36c9 100644 --- a/tests/formats/esm.spec.ts +++ b/tests/formats/esm.spec.ts @@ -1,11 +1,12 @@ import { test, createSortableTests } from '../sortable-test-base' -// Use override for the fixture -test.use({ - formatName: 'esm', - getUrl: async ({}, use) => { - await use((minified: boolean) => `/esm.html${minified ? '?minified=true' : ''}`) - }, -}) +test.describe('esm', () => { + test.use({ + formatName: 'esm', + getUrl: async ({}, use) => { + await use((minified: boolean) => `/esm.html${minified ? '?minified=true' : ''}`) + }, + }) -createSortableTests() + createSortableTests() +}) diff --git a/tests/formats/standalone.spec.ts b/tests/formats/standalone.spec.ts index b26425a..bfe7914 100644 --- a/tests/formats/standalone.spec.ts +++ b/tests/formats/standalone.spec.ts @@ -1,11 +1,12 @@ import { test, createSortableTests } from '../sortable-test-base' -// Use override for the fixture -test.use({ - formatName: 'standalone', - getUrl: async ({}, use) => { - await use((minified: boolean) => `/standalone.html${minified ? '?minified=true' : ''}`) - }, -}) +test.describe('standalone', () => { + test.use({ + formatName: 'standalone', + getUrl: async ({}, use) => { + await use((minified: boolean) => `/standalone.html${minified ? '?minified=true' : ''}`) + }, + }) -createSortableTests() + createSortableTests() +}) diff --git a/tests/sortable-test-base.ts b/tests/sortable-test-base.ts index 28bfa56..5d7b439 100644 --- a/tests/sortable-test-base.ts +++ b/tests/sortable-test-base.ts @@ -12,7 +12,7 @@ export const test = base.extend({ async ({}, use, testInfo) => { await use(() => '') }, - { option: true }, // This makes it configurable + { option: true }, ], formatName: [ async ({}, use) => { @@ -33,325 +33,323 @@ export const getSortedContent = async (page: Page, selector: string) => { // Reusable test cases export const createSortableTests = () => { - test.describe('sortable functionality', () => { - for (const minified of [false, true]) { - const variant = minified ? '(minified)' : '' + for (const minified of [false, true]) { + const minifiedVariant = minified ? '(minified)' : '' - test.describe(`${variant}`, () => { - test.beforeEach(async ({ page, getUrl }) => { - await page.goto(getUrl(minified)) - }) + test.describe(minifiedVariant, () => { + test.beforeEach(async ({ page, getUrl }) => { + await page.goto(getUrl(minified)) + }) - // Break after first failure - test.afterEach(async ({}, testInfo) => { - if (testInfo.status !== testInfo.expectedStatus) { - test.skip(true) - } - }) + // Break after first failure + test.afterEach(async ({}, testInfo) => { + if (testInfo.status !== testInfo.expectedStatus) { + test.skip(true) + } + }) - test('renders a heading element', async ({ page }) => { - const heading = await page.getByRole('heading', { name: /Sortable examples/i }) - expect(heading).toBeTruthy() + const defineTest = (name: string, testFn: ({ page }: { page: Page }) => Promise) => { + test(`${name}`, async ({ page, formatName }) => { + test.info().title = `[${formatName}] ${name}` + await testFn({ page }) }) + } - test('renders table headers and cells', async ({ page }) => { - const table = await page.$('table.sortable') - expect(table).toBeTruthy() + defineTest('renders a heading element', async ({ page }) => { + const heading = await page.getByRole('heading', { name: /Sortable examples/i }) + expect(heading).toBeTruthy() + }) - const nameHeader = await page.$('th[aria-label*="Name"]') - expect(nameHeader).toBeTruthy() + defineTest('renders table headers and cells', async ({ page }) => { + const table = await page.$('table.sortable') + expect(table).toBeTruthy() - const cells = await page.$$('table.sortable tbody td') - expect(cells[0]).toBeTruthy() - expect(cells[1]).toBeTruthy() - }) + const nameHeader = await page.$('th[aria-label*="Name"]') + expect(nameHeader).toBeTruthy() - test('sorts a table on click', async ({ page }) => { - const nameHeader = await page.$('th[aria-label*="Name"]') + const cells = await page.$$('table.sortable tbody td') + expect(cells[0]).toBeTruthy() + expect(cells[1]).toBeTruthy() + }) - let firstCell = await page.$eval( - 'table.sortable tbody tr:first-child td:nth-child(2)', - (el) => el.textContent, - ) - expect(firstCell).toBe('Rick') + defineTest('sorts a table on click', async ({ page }) => { + const nameHeader = await page.$('th[aria-label*="Name"]') - await nameHeader?.click() - await page.waitForTimeout(100) + let firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Rick') - firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(firstCell).toBe('Rick') + await nameHeader?.click() + await waitForSort(page) - await nameHeader?.click() - await page.waitForTimeout(100) + firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Rick') - firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(firstCell).toBe('Morty') - }) + await nameHeader?.click() + await waitForSort(page) - test('sorts a table using Enter key', async ({ page }) => { - const nameHeader = await page.$('th[aria-label*="Name"]') + firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Morty') + }) - let firstCell = await page.$eval( - 'table.sortable tbody tr:first-child td:nth-child(2)', - (el) => el.textContent, - ) - expect(firstCell).toBe('Rick') + defineTest('sorts a table using Enter key', async ({ page }) => { + const nameHeader = await page.$('th[aria-label*="Name"]') - await nameHeader?.focus() - await nameHeader?.press('Enter') - await page.waitForTimeout(100) + let firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Rick') - firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(firstCell).toBe('Rick') + await nameHeader?.focus() + await nameHeader?.press('Enter') + await waitForSort(page) - await nameHeader?.press('Enter') - await page.waitForTimeout(100) + firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Rick') - firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(firstCell).toBe('Morty') - }) + await nameHeader?.press('Enter') + await waitForSort(page) - test('sorts a table using tie breaker', async ({ page }) => { - const allTables = await page.$$('table.sortable') - const table = allTables[1] - const yearHeader = await table.$('th:nth-child(2)') - expect(yearHeader).toBeTruthy() + firstCell = await page.$eval('table.sortable tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Morty') + }) - let timeCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) - expect(timeCell).toBe('12:00') + defineTest('sorts a table using tie breaker', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[1] + const yearHeader = await table.$('th:nth-child(2)') + expect(yearHeader).toBeTruthy() - await yearHeader?.click() - await page.waitForTimeout(100) + let timeCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(timeCell).toBe('12:00') - timeCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) - expect(timeCell).toBe('15:00') + await yearHeader?.click() + await waitForSort(page) - await yearHeader?.click() - await page.waitForTimeout(100) + timeCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(timeCell).toBe('15:00') - timeCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) - expect(timeCell).toBe('13:00') - }) + await yearHeader?.click() + await waitForSort(page) - test('sorts a table with colspans', async ({ page }) => { - const allTables = await page.$$('table.sortable') - const table = allTables[2] - const charsHeader = await table.$('th:last-child') - expect(charsHeader).toBeTruthy() + timeCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(timeCell).toBe('13:00') + }) - let charCell = await table.$eval('tbody tr:first-child td:last-child', (el) => el.textContent) - expect(charCell).toBe('BB') + defineTest('sorts a table with colspans', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[2] + const charsHeader = await table.$('th:last-child') + expect(charsHeader).toBeTruthy() - await charsHeader?.click() - await page.waitForTimeout(100) + let charCell = await table.$eval('tbody tr:first-child td:last-child', (el) => el.textContent) + expect(charCell).toBe('BB') - charCell = await table.$eval('tbody tr:first-child td:last-child', (el) => el.textContent) - expect(charCell).toBe('CCC') + await charsHeader?.click() + await waitForSort(page) - await charsHeader?.click() - await page.waitForTimeout(100) + charCell = await table.$eval('tbody tr:first-child td:last-child', (el) => el.textContent) + expect(charCell).toBe('CCC') - charCell = await table.$eval('tbody tr:first-child td:last-child', (el) => el.textContent) - expect(charCell).toBe('A') - }) + await charsHeader?.click() + await waitForSort(page) - test('sorts a table with empty rows last', async ({ page }) => { - const allTables = await page.$$('table.sortable') - const table = allTables[3] - const numberHeader = await table.$('th:nth-child(2)') - expect(numberHeader).toBeTruthy() + charCell = await table.$eval('tbody tr:first-child td:last-child', (el) => el.textContent) + expect(charCell).toBe('A') + }) - let numberCell = await table.$eval('tbody tr:nth-child(2) td:nth-child(2)', (el) => el.textContent) - expect(numberCell).toBe('0') + defineTest('sorts a table with empty rows last', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[3] + const numberHeader = await table.$('th:nth-child(2)') + expect(numberHeader).toBeTruthy() - await numberHeader?.click() - await page.waitForTimeout(100) + let numberCell = await table.$eval('tbody tr:nth-child(2) td:nth-child(2)', (el) => el.textContent) + expect(numberCell).toBe('0') - numberCell = await table.$eval('tbody tr:last-child td:nth-child(2)', (el) => el.textContent) - expect(numberCell).toBe('(if click in this column)') - }) + await numberHeader?.click() + await waitForSort(page) - test('respects class="no-sort" in th', async ({ page }) => { - const allTables = await page.$$('table.sortable') - const table = allTables[4] - const nameHeader = await table.$('th:nth-child(2)') + numberCell = await table.$eval('tbody tr:last-child td:nth-child(2)', (el) => el.textContent) + expect(numberCell).toBe('(if click in this column)') + }) - let nameCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(nameCell).toBe('Rick') + defineTest('respects class="no-sort" in th', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[4] + const nameHeader = await table.$('th:nth-child(2)') - await nameHeader?.click() - await page.waitForTimeout(100) + let nameCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(nameCell).toBe('Rick') - nameCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(nameCell).toBe('Rick') - }) + await nameHeader?.click() + await waitForSort(page) - test('treats time formats like strings', async ({ page }) => { - const allTables = await page.$$('table.sortable') - const table = allTables[5] - const timeHeader = await table.$('th:nth-child(2)') - expect(timeHeader).toBeTruthy() + nameCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(nameCell).toBe('Rick') + }) - let timeCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(timeCell).toBe('12:00:12') + defineTest('treats time formats like strings', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[5] + const timeHeader = await table.$('th:nth-child(2)') + expect(timeHeader).toBeTruthy() - await timeHeader?.click() - await page.waitForTimeout(100) + let timeCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(timeCell).toBe('12:00:12') - timeCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(timeCell).toBe('12:22:11') + await timeHeader?.click() + await waitForSort(page) - await timeHeader?.click() - await page.waitForTimeout(100) + timeCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(timeCell).toBe('12:22:11') - timeCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(timeCell).toBe('12:00:12') - }) + await timeHeader?.click() + await waitForSort(page) - test('treats amounts like strings', async ({ page }) => { - const allTables = await page.$$('table.sortable') - const table = allTables[5] - const amountHeader = await table.$('th:nth-child(3)') - expect(amountHeader).toBeTruthy() + timeCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(timeCell).toBe('12:00:12') + }) - let amountCell = await table.$eval('tbody tr:first-child td:nth-child(3)', (el) => el.textContent) - expect(amountCell).toBe('$18.49') + defineTest('treats amounts like strings', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[5] + const amountHeader = await table.$('th:nth-child(3)') + expect(amountHeader).toBeTruthy() - await amountHeader?.click() - await page.waitForTimeout(100) + let amountCell = await table.$eval('tbody tr:first-child td:nth-child(3)', (el) => el.textContent) + expect(amountCell).toBe('$18.49') - amountCell = await table.$eval('tbody tr:first-child td:nth-child(3)', (el) => el.textContent) - expect(amountCell).toBe('$2.49') + await amountHeader?.click() + await waitForSort(page) - await amountHeader?.click() - await page.waitForTimeout(100) + amountCell = await table.$eval('tbody tr:first-child td:nth-child(3)', (el) => el.textContent) + expect(amountCell).toBe('$2.49') - amountCell = await table.$eval('tbody tr:first-child td:nth-child(3)', (el) => el.textContent) - expect(amountCell).toBe('$1.96') - }) + await amountHeader?.click() + await waitForSort(page) - test('treats numbers like numbers', async ({ page }) => { - const allTables = await page.$$('table.sortable') - const table = allTables[5] - const numberHeader = await table.$('th:nth-child(4)') - expect(numberHeader).toBeTruthy() + amountCell = await table.$eval('tbody tr:first-child td:nth-child(3)', (el) => el.textContent) + expect(amountCell).toBe('$1.96') + }) - let numberCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) - expect(numberCell).toBe('2.49') + defineTest('treats numbers like numbers', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[5] + const numberHeader = await table.$('th:nth-child(4)') + expect(numberHeader).toBeTruthy() - await numberHeader?.click() - await page.waitForTimeout(100) + let numberCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(numberCell).toBe('2.49') - numberCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) - expect(numberCell).toBe('18.49') + await numberHeader?.click() + await waitForSort(page) - await numberHeader?.click() - await page.waitForTimeout(100) + numberCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(numberCell).toBe('18.49') - numberCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) - expect(numberCell).toBe('1.96') - }) + await numberHeader?.click() + await waitForSort(page) - test('sorts a table ascending', async ({ page }) => { - const allTables = await page.$$('table.sortable') - const table = allTables[6] - const nameHeader = await table.$('th[aria-label*="Name"]') + numberCell = await table.$eval('tbody tr:first-child td:nth-child(4)', (el) => el.textContent) + expect(numberCell).toBe('1.96') + }) - let firstCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(firstCell).toBe('Rick') + defineTest('sorts a table ascending', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[6] + const nameHeader = await table.$('th[aria-label*="Name"]') - await nameHeader?.click() - await page.waitForTimeout(100) + let firstCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Rick') - firstCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(firstCell).toBe('Morty') + await nameHeader?.click() + await waitForSort(page) - await nameHeader?.click() - await page.waitForTimeout(100) + firstCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Morty') - firstCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) - expect(firstCell).toBe('Rick') - }) + await nameHeader?.click() + await waitForSort(page) - test('a11y labels are added and updated', async ({ page }) => { - const nameHeader = await page.$('th[aria-label*="Name"]') + firstCell = await table.$eval('tbody tr:first-child td:nth-child(2)', (el) => el.textContent) + expect(firstCell).toBe('Rick') + }) - let ariaLabel = await nameHeader?.getAttribute('aria-label') - expect(ariaLabel).toContain('Click to sort table by Name in descending order') + defineTest('a11y labels are added and updated', async ({ page }) => { + const nameHeader = await page.$('th[aria-label*="Name"]') - await nameHeader?.click() - await page.waitForTimeout(100) + let ariaLabel = await nameHeader?.getAttribute('aria-label') + expect(ariaLabel).toContain('Click to sort table by Name in descending order') - ariaLabel = await nameHeader?.getAttribute('aria-label') - expect(ariaLabel).toContain('Click to sort table by Name in ascending order') - }) + await nameHeader?.click() - test('works when using enhanceSortableAccessibility()', async ({ page }) => { - // Get a table to test with - const allTables = await page.$$('table.sortable') - const table = allTables[6] - - const nameHeader = await table.$('th[aria-label*="Name"]') - expect(nameHeader).toBeTruthy() - - // Check initial aria-label - let ariaLabel = await nameHeader?.getAttribute('aria-label') - expect(ariaLabel).toContain('Click to sort table by Name') - - // Clear and re-apply accessibility - await page.evaluate(() => { - const th = document.querySelector('th[aria-label*="Name"]') - if (th) { - th.removeAttribute('aria-label') - th.removeAttribute('tabindex') - } - }) + await waitForSort(page) - // Re-apply accessibility through page evaluation - await page.evaluate(() => { - const enhanceSortableAccessibility = (tables: NodeListOf) => { - tables.forEach((table) => { - table.querySelectorAll('th').forEach((th) => { - if (!th.hasAttribute('tabindex')) { - th.setAttribute('tabindex', '0') - const headerText = th.textContent || 'column' - th.setAttribute('aria-label', `Click to sort table by ${headerText} in ascending order`) - } - }) - }) - } - enhanceSortableAccessibility(document.querySelectorAll('table.sortable')) - }) + ariaLabel = await nameHeader?.getAttribute('aria-label') + expect(ariaLabel).toContain('Click to sort table by Name in ascending order') + }) - // Verify accessibility was reapplied - await page.waitForTimeout(100) - ariaLabel = await nameHeader?.getAttribute('aria-label') - expect(ariaLabel).toContain('Click to sort table by Name') - expect(await nameHeader?.getAttribute('tabindex')).toBe('0') + defineTest('works when using enhanceSortableAccessibility()', async ({ page }) => { + const allTables = await page.$$('table.sortable') + const table = allTables[6] + const nameHeader = await table.$('th[aria-label*="Name"]') + expect(nameHeader).toBeTruthy() + + // Check initial aria-label + let ariaLabel = await nameHeader?.getAttribute('aria-label') + expect(ariaLabel).toContain('Click to sort table by Name') + + // Clear and re-apply accessibility + await page.evaluate(() => { + const th = document.querySelector('th[aria-label*="Name"]') + if (th) { + th.removeAttribute('aria-label') + th.removeAttribute('tabindex') + } }) - test('sortStart and sortEnd events are dispatched', async ({ page }) => { - const nameHeader = await page.$('th[aria-label*="Name"]') - - await page.evaluate(() => { - document.addEventListener('sort-start', () => { - ;(window as any).testEvents = (window as any).testEvents || [] - ;(window as any).testEvents.push('sortStart') - }) - document.addEventListener('sort-end', () => { - ;(window as any).testEvents = (window as any).testEvents || [] - ;(window as any).testEvents.push('sortEnd') + // Re-apply accessibility through page evaluation + await page.evaluate(() => { + const enhanceSortableAccessibility = (tables: NodeListOf) => { + tables.forEach((table) => { + table.querySelectorAll('th').forEach((th) => { + if (!th.hasAttribute('tabindex')) { + th.setAttribute('tabindex', '0') + const headerText = th.textContent || 'column' + th.setAttribute('aria-label', `Click to sort table by ${headerText} in ascending order`) + } + }) }) - }) + } + enhanceSortableAccessibility(document.querySelectorAll('table.sortable')) + }) - await nameHeader?.click() - await page.waitForTimeout(100) + await waitForSort(page) + ariaLabel = await nameHeader?.getAttribute('aria-label') + expect(ariaLabel).toContain('Click to sort table by Name') + expect(await nameHeader?.getAttribute('tabindex')).toBe('0') + }) - const eventsFired = await page.evaluate(() => (window as any).testEvents) - expect(eventsFired).toContain('sortStart') - expect(eventsFired).toContain('sortEnd') + defineTest('sort-start and sort-end events are dispatched', async ({ page }) => { + const nameHeader = await page.$('th[aria-label*="Name"]') + + // Set up event listeners + await page.evaluate(() => { + document.addEventListener('sort-start', () => { + ;(window as any).testEvents = (window as any).testEvents || [] + ;(window as any).testEvents.push('sort-start') + }) + document.addEventListener('sort-end', () => { + ;(window as any).testEvents = (window as any).testEvents || [] + ;(window as any).testEvents.push('sort-end') + }) }) + + await nameHeader?.click() + await waitForSort(page) + + const eventsFired = await page.evaluate(() => (window as any).testEvents) + expect(eventsFired).toContain('sort-start') + expect(eventsFired).toContain('sort-end') }) - } - }) + }) + } }