diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e216e2..dfa7a53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ 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.1.6] - 2025-10-21 + +### Fixed + +- The a11y module no longer marks columns with class="no-sort" as sortable + ## [4.1.5] - 2025-10-16 ### Changed @@ -202,6 +208,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - First release +[4.1.6]: https://github.com/tofsjonas/sortable/releases/tag/4.1.6 [4.1.5]: https://github.com/tofsjonas/sortable/releases/tag/4.1.5 [4.1.4]: https://github.com/tofsjonas/sortable/releases/tag/4.1.4 [4.1.3]: https://github.com/tofsjonas/sortable/releases/tag/4.1.3 diff --git a/dist/auto.html b/dist/auto.html new file mode 100644 index 0000000..3b4bde8 --- /dev/null +++ b/dist/auto.html @@ -0,0 +1,372 @@ + + + + + + + sortable test + + + + +

Sortable examples

+ +

Basic sort

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

Tiebreaker

+

Sort by year

+ + (Appearance manually changed using style attributes. Just for demonstration.) + +
+style="
+  --stripe-bg: #ff0;
+  --stripe-color: #000;
+  --stripe-bg-odd: #f0f;
+  --stripe-color-odd: #111;
+  --th-bg: blue;
+  --th-color: #fff;"
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
+ + +

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
+ +

Alternative sort

+ + + + + + + + + + + + + + + + + + + + + + +
Movie NameSize
AB
DE
JK
+ +

TR element with no TD element (invalid HTML)

+ + + + + + + + + + + + + + + + + + + + +
Letters
CCC
DDD
AAA
+ +

TD with "incorrect" whitespace

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

HTML Tag Support

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EventDateProgressScoreAbbreviation
Meeting75%8.5/10WWW
Conference50%9.2/10API
Workshop90%7.8/10HTML
SeminarUnknownSix point fiveCSS
+ + + + + + + diff --git a/dist/auto.min.html b/dist/auto.min.html new file mode 100644 index 0000000..82a01d7 --- /dev/null +++ b/dist/auto.min.html @@ -0,0 +1,372 @@ + + + + + + + sortable test + + + + +

Sortable examples

+ +

Basic sort

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

Tiebreaker

+

Sort by year

+ + (Appearance manually changed using style attributes. Just for demonstration.) + +
+style="
+  --stripe-bg: #ff0;
+  --stripe-color: #000;
+  --stripe-bg-odd: #f0f;
+  --stripe-color-odd: #111;
+  --th-bg: blue;
+  --th-color: #fff;"
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
+ + +

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
+ +

Alternative sort

+ + + + + + + + + + + + + + + + + + + + + + +
Movie NameSize
AB
DE
JK
+ +

TR element with no TD element (invalid HTML)

+ + + + + + + + + + + + + + + + + + + + +
Letters
CCC
DDD
AAA
+ +

TD with "incorrect" whitespace

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

HTML Tag Support

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EventDateProgressScoreAbbreviation
Meeting75%8.5/10WWW
Conference50%9.2/10API
Workshop90%7.8/10HTML
SeminarUnknownSix point fiveCSS
+ + + + + + + diff --git a/dist/bundled.html b/dist/bundled.html new file mode 100644 index 0000000..12470d3 --- /dev/null +++ b/dist/bundled.html @@ -0,0 +1,373 @@ + + + + + + + sortable test + + + + +

Sortable examples

+ +

Basic sort

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

Tiebreaker

+

Sort by year

+ + (Appearance manually changed using style attributes. Just for demonstration.) + +
+style="
+  --stripe-bg: #ff0;
+  --stripe-color: #000;
+  --stripe-bg-odd: #f0f;
+  --stripe-color-odd: #111;
+  --th-bg: blue;
+  --th-color: #fff;"
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
+ + +

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
+ +

Alternative sort

+ + + + + + + + + + + + + + + + + + + + + + +
Movie NameSize
AB
DE
JK
+ +

TR element with no TD element (invalid HTML)

+ + + + + + + + + + + + + + + + + + + + +
Letters
CCC
DDD
AAA
+ +

TD with "incorrect" whitespace

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

HTML Tag Support

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EventDateProgressScoreAbbreviation
Meeting75%8.5/10WWW
Conference50%9.2/10API
Workshop90%7.8/10HTML
SeminarUnknownSix point fiveCSS
+ + + + + + + + diff --git a/dist/bundled.min.html b/dist/bundled.min.html new file mode 100644 index 0000000..2140440 --- /dev/null +++ b/dist/bundled.min.html @@ -0,0 +1,373 @@ + + + + + + + sortable test + + + + +

Sortable examples

+ +

Basic sort

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

Tiebreaker

+

Sort by year

+ + (Appearance manually changed using style attributes. Just for demonstration.) + +
+style="
+  --stripe-bg: #ff0;
+  --stripe-color: #000;
+  --stripe-bg-odd: #f0f;
+  --stripe-color-odd: #111;
+  --th-bg: blue;
+  --th-color: #fff;"
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
+ + +

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
+ +

Alternative sort

+ + + + + + + + + + + + + + + + + + + + + + +
Movie NameSize
AB
DE
JK
+ +

TR element with no TD element (invalid HTML)

+ + + + + + + + + + + + + + + + + + + + +
Letters
CCC
DDD
AAA
+ +

TD with "incorrect" whitespace

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

HTML Tag Support

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EventDateProgressScoreAbbreviation
Meeting75%8.5/10WWW
Conference50%9.2/10API
Workshop90%7.8/10HTML
SeminarUnknownSix point fiveCSS
+ + + + + + + + diff --git a/dist/esm.html b/dist/esm.html new file mode 100644 index 0000000..35cee2a --- /dev/null +++ b/dist/esm.html @@ -0,0 +1,375 @@ + + + + + + + sortable test + + + + +

Sortable examples

+ +

Basic sort

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

Tiebreaker

+

Sort by year

+ + (Appearance manually changed using style attributes. Just for demonstration.) + +
+style="
+  --stripe-bg: #ff0;
+  --stripe-color: #000;
+  --stripe-bg-odd: #f0f;
+  --stripe-color-odd: #111;
+  --th-bg: blue;
+  --th-color: #fff;"
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
+ + +

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
+ +

Alternative sort

+ + + + + + + + + + + + + + + + + + + + + + +
Movie NameSize
AB
DE
JK
+ +

TR element with no TD element (invalid HTML)

+ + + + + + + + + + + + + + + + + + + + +
Letters
CCC
DDD
AAA
+ +

TD with "incorrect" whitespace

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

HTML Tag Support

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EventDateProgressScoreAbbreviation
Meeting75%8.5/10WWW
Conference50%9.2/10API
Workshop90%7.8/10HTML
SeminarUnknownSix point fiveCSS
+ + + + + + + diff --git a/dist/esm.min.html b/dist/esm.min.html new file mode 100644 index 0000000..ca4ac8d --- /dev/null +++ b/dist/esm.min.html @@ -0,0 +1,375 @@ + + + + + + + sortable test + + + + +

Sortable examples

+ +

Basic sort

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

Tiebreaker

+

Sort by year

+ + (Appearance manually changed using style attributes. Just for demonstration.) + +
+style="
+  --stripe-bg: #ff0;
+  --stripe-color: #000;
+  --stripe-bg-odd: #f0f;
+  --stripe-color-odd: #111;
+  --th-bg: blue;
+  --th-color: #fff;"
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
+ + +

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
+ +

Alternative sort

+ + + + + + + + + + + + + + + + + + + + + + +
Movie NameSize
AB
DE
JK
+ +

TR element with no TD element (invalid HTML)

+ + + + + + + + + + + + + + + + + + + + +
Letters
CCC
DDD
AAA
+ +

TD with "incorrect" whitespace

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

HTML Tag Support

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EventDateProgressScoreAbbreviation
Meeting75%8.5/10WWW
Conference50%9.2/10API
Workshop90%7.8/10HTML
SeminarUnknownSix point fiveCSS
+ + + + + + + diff --git a/dist/esm/enhanceSortableAccessibility.d.ts b/dist/esm/a11y/enhanceSortableAccessibility.d.ts similarity index 100% rename from dist/esm/enhanceSortableAccessibility.d.ts rename to dist/esm/a11y/enhanceSortableAccessibility.d.ts diff --git a/dist/esm/a11y/updateSortableAriaLabel.d.ts b/dist/esm/a11y/updateSortableAriaLabel.d.ts new file mode 100644 index 0000000..6747be7 --- /dev/null +++ b/dist/esm/a11y/updateSortableAriaLabel.d.ts @@ -0,0 +1,8 @@ +/** + * 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. + */ +type Direction = 'ascending' | 'descending' | 'no-sort'; +export declare function updateSortableAriaLabel(element: HTMLTableCellElement, default_direction: Direction): void; +export {}; diff --git a/dist/esm/enhanceSortableAccessibility.js b/dist/esm/enhanceSortableAccessibility.js index ad314da..77d7d15 100644 --- a/dist/esm/enhanceSortableAccessibility.js +++ b/dist/esm/enhanceSortableAccessibility.js @@ -1,12 +1,12 @@ -function enhanceSortableAccessibility(tables) { - function updateAriaLabel(element, default_direction) { - var _a; - default_direction === void 0 && (default_direction = ""); - var header_text = element.textContent || "element", current_direction = (_a = element.getAttribute("aria-sort")) !== null && _a !== void 0 ? _a : "", new_direction = "descending"; - (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 updateSortableAriaLabel(element, default_direction) { + var header_text = element.textContent || "element", aria_label = "Column ".concat(header_text, " is not sortable"); + if (default_direction !== "no-sort") { + var current_direction = element.getAttribute("aria-sort"), new_direction = default_direction; + current_direction && (new_direction = current_direction === "descending" ? "ascending" : "descending"), 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), console.log("🚀 comment me out"); +} +function enhanceSortableAccessibility(tables) { function handleKeyDown(event) { if (event.key === "Enter") { var element = event.target; @@ -14,14 +14,19 @@ function enhanceSortableAccessibility(tables) { } } tables.forEach(function(table) { - var default_direction = table.classList.contains("asc") ? "ascending" : "", headers = table.querySelectorAll("th"); + var default_direction = table.classList.contains("asc") ? "ascending" : "descending", headers = table.querySelectorAll("th"); headers.forEach(function(header) { var element = header; if (!element.hasAttribute("tabindex")) { + if (element.classList.contains("no-sort")) { + updateSortableAriaLabel(element, "no-sort"); + return; + } + element.setAttribute("tabindex", "0"); var update = function() { - updateAriaLabel(element, default_direction); + updateSortableAriaLabel(element, default_direction); }; - element.setAttribute("tabindex", "0"), update(), element.addEventListener("click", function() { + update(), element.addEventListener("click", function() { setTimeout(update, 50); }), element.addEventListener("focus", update), element.addEventListener("keydown", handleKeyDown); } diff --git a/dist/esm/enhanceSortableAccessibility.min.js b/dist/esm/enhanceSortableAccessibility.min.js index 756d8a1..e2c3238 100644 --- a/dist/esm/enhanceSortableAccessibility.min.js +++ b/dist/esm/enhanceSortableAccessibility.min.js @@ -1 +1 @@ -function t(t){function e(t){'Enter'===t.key&&t.target.click()}t.forEach(function(t){var n=t.classList.contains('asc')?'ascending':'';t.querySelectorAll('th').forEach(function(t){var i=t;if(!i.hasAttribute('tabindex')){var a=function(){!function(t,e){var n;void 0===e&&(e='');var i=t.textContent||'element',a=null!==(n=t.getAttribute('aria-sort'))&&void 0!==n?n:'',c='descending';('descending'===a||e&&'ascending'!==a)&&(c='ascending');var r='Click to sort table by '.concat(i,' in ').concat(c,' order');t.setAttribute('aria-label',r)}(i,n)};i.setAttribute('tabindex','0'),a(),i.addEventListener('click',function(){setTimeout(a,50)}),i.addEventListener('focus',a),i.addEventListener('keydown',e)}})})}export{t as enhanceSortableAccessibility}; +function t(t,n){var e=t.textContent||'element',i='Column '.concat(e,' is not sortable');if('no-sort'!==n){var o=t.getAttribute('aria-sort'),c=n;o&&(c='descending'===o?'ascending':'descending'),i='Click to sort table by '.concat(e,' in ').concat(c,' order')}t.setAttribute('aria-label',i),t.setAttribute('title',i),console.log('🚀 comment me out')}function n(n){function e(t){'Enter'===t.key&&t.target.click()}n.forEach(function(n){var i=n.classList.contains('asc')?'ascending':'descending';n.querySelectorAll('th').forEach(function(n){var o=n;if(!o.hasAttribute('tabindex')){if(o.classList.contains('no-sort'))return void t(o,'no-sort');o.setAttribute('tabindex','0');var c=function(){t(o,i)};c(),o.addEventListener('click',function(){setTimeout(c,50)}),o.addEventListener('focus',c),o.addEventListener('keydown',e)}})})}export{n as enhanceSortableAccessibility}; diff --git a/dist/esm/sortable.a11y.min.js b/dist/esm/sortable.a11y.min.js index 417c123..41be421 100644 --- a/dist/esm/sortable.a11y.min.js +++ b/dist/esm/sortable.a11y.min.js @@ -1 +1 @@ -document.addEventListener('DOMContentLoaded',function(){!function(t){function e(t){'Enter'===t.key&&t.target.click()}t.forEach(function(t){var n=t.classList.contains('asc')?'ascending':'';t.querySelectorAll('th').forEach(function(t){var i=t;if(!i.hasAttribute('tabindex')){var a=function(){!function(t,e){var n;void 0===e&&(e='');var i=t.textContent||'element',a=null!==(n=t.getAttribute('aria-sort'))&&void 0!==n?n:'',c='descending';('descending'===a||e&&'ascending'!==a)&&(c='ascending');var o='Click to sort table by '.concat(i,' in ').concat(c,' order');t.setAttribute('aria-label',o)}(i,n)};i.setAttribute('tabindex','0'),a(),i.addEventListener('click',function(){setTimeout(a,50)}),i.addEventListener('focus',a),i.addEventListener('keydown',e)}})})}(document.querySelectorAll('.sortable'))}); +function t(t,e){var n=t.textContent||'element',o='Column '.concat(n,' is not sortable');if('no-sort'!==e){var i=t.getAttribute('aria-sort'),c=e;i&&(c='descending'===i?'ascending':'descending'),o='Click to sort table by '.concat(n,' in ').concat(c,' order')}t.setAttribute('aria-label',o),t.setAttribute('title',o),console.log('🚀 comment me out')}document.addEventListener('DOMContentLoaded',function(){!function(e){function n(t){'Enter'===t.key&&t.target.click()}e.forEach(function(e){var o=e.classList.contains('asc')?'ascending':'descending';e.querySelectorAll('th').forEach(function(e){var i=e;if(!i.hasAttribute('tabindex')){if(i.classList.contains('no-sort'))return void t(i,'no-sort');i.setAttribute('tabindex','0');var c=function(){t(i,o)};c(),i.addEventListener('click',function(){setTimeout(c,50)}),i.addEventListener('focus',c),i.addEventListener('keydown',n)}})})}(document.querySelectorAll('.sortable'))}); diff --git a/dist/esm/sortable.auto.d.ts b/dist/esm/sortable.auto.d.ts index 64b1d98..b6039b7 100644 --- a/dist/esm/sortable.auto.d.ts +++ b/dist/esm/sortable.auto.d.ts @@ -1,5 +1,5 @@ /** - * sortable v4.1.5 + * sortable v4.1.6 * * https://www.npmjs.com/package/sortable-tablesort * https://github.com/tofsjonas/sortable diff --git a/dist/esm/sortable.d.ts b/dist/esm/sortable.d.ts index 64b1d98..b6039b7 100644 --- a/dist/esm/sortable.d.ts +++ b/dist/esm/sortable.d.ts @@ -1,5 +1,5 @@ /** - * sortable v4.1.5 + * sortable v4.1.6 * * https://www.npmjs.com/package/sortable-tablesort * https://github.com/tofsjonas/sortable diff --git a/dist/sortable.a11y.js b/dist/sortable.a11y.js index f2c224c..fcb43f4 100644 --- a/dist/sortable.a11y.js +++ b/dist/sortable.a11y.js @@ -1,12 +1,12 @@ -function enhanceSortableAccessibility(tables) { - function updateAriaLabel(element, default_direction) { - var _a; - default_direction === void 0 && (default_direction = ""); - var header_text = element.textContent || "element", current_direction = (_a = element.getAttribute("aria-sort")) !== null && _a !== void 0 ? _a : "", new_direction = "descending"; - (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 updateSortableAriaLabel(element, default_direction) { + var header_text = element.textContent || "element", aria_label = "Column ".concat(header_text, " is not sortable"); + if (default_direction !== "no-sort") { + var current_direction = element.getAttribute("aria-sort"), new_direction = default_direction; + current_direction && (new_direction = current_direction === "descending" ? "ascending" : "descending"), 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), console.log("🚀 comment me out"); +} +function enhanceSortableAccessibility(tables) { function handleKeyDown(event) { if (event.key === "Enter") { var element = event.target; @@ -14,14 +14,19 @@ function enhanceSortableAccessibility(tables) { } } tables.forEach(function(table) { - var default_direction = table.classList.contains("asc") ? "ascending" : "", headers = table.querySelectorAll("th"); + var default_direction = table.classList.contains("asc") ? "ascending" : "descending", headers = table.querySelectorAll("th"); headers.forEach(function(header) { var element = header; if (!element.hasAttribute("tabindex")) { + if (element.classList.contains("no-sort")) { + updateSortableAriaLabel(element, "no-sort"); + return; + } + element.setAttribute("tabindex", "0"); var update = function() { - updateAriaLabel(element, default_direction); + updateSortableAriaLabel(element, default_direction); }; - element.setAttribute("tabindex", "0"), update(), element.addEventListener("click", function() { + update(), element.addEventListener("click", function() { setTimeout(update, 50); }), element.addEventListener("focus", update), element.addEventListener("keydown", handleKeyDown); } diff --git a/dist/sortable.a11y.min.js b/dist/sortable.a11y.min.js index db098e8..e54181d 100644 --- a/dist/sortable.a11y.min.js +++ b/dist/sortable.a11y.min.js @@ -1,2 +1,3 @@ -function enhanceSortableAccessibility(g){function h(c){c.key==="Enter"&&c.target.click()}g.forEach(function(c){var k=c.classList.contains("asc")?"ascending":"";c.querySelectorAll("th").forEach(function(a){if(!a.hasAttribute("tabindex")){var e=function(){var d=k,b;d===void 0&&(d="");var l=a.textContent||"element",f=(b=a.getAttribute("aria-sort"))!==null&&b!==void 0?b:"";b="descending";(f==="descending"||d&&f!=="ascending")&&(b="ascending");d="Click to sort table by ".concat(l," in ").concat(b," order"); -a.setAttribute("aria-label",d)};a.setAttribute("tabindex","0");e();a.addEventListener("click",function(){setTimeout(e,50)});a.addEventListener("focus",e);a.addEventListener("keydown",h)}})})}document.addEventListener("DOMContentLoaded",function(){enhanceSortableAccessibility(document.querySelectorAll(".sortable"))}); +function updateSortableAriaLabel(d,e){var a=d.textContent||"element",c="Column ".concat(a," is not sortable");e!=="no-sort"&&((c=d.getAttribute("aria-sort"))&&(e=c==="descending"?"ascending":"descending"),c="Click to sort table by ".concat(a," in ").concat(e," order"));d.setAttribute("aria-label",c);d.setAttribute("title",c);console.log("\ud83d\ude80 comment me out")} +function enhanceSortableAccessibility(d){function e(a){a.key==="Enter"&&a.target.click()}d.forEach(function(a){var c=a.classList.contains("asc")?"ascending":"descending";a.querySelectorAll("th").forEach(function(b){if(!b.hasAttribute("tabindex"))if(b.classList.contains("no-sort"))updateSortableAriaLabel(b,"no-sort");else{b.setAttribute("tabindex","0");var f=function(){updateSortableAriaLabel(b,c)};f();b.addEventListener("click",function(){setTimeout(f,50)});b.addEventListener("focus",f);b.addEventListener("keydown", +e)}})})}document.addEventListener("DOMContentLoaded",function(){enhanceSortableAccessibility(document.querySelectorAll(".sortable"))}); diff --git a/dist/sortable.auto.js b/dist/sortable.auto.js index fe44c1d..c9920f9 100644 --- a/dist/sortable.auto.js +++ b/dist/sortable.auto.js @@ -1 +1 @@ -(function(){"use strict";function sortSortable(table,alt_sort){var null_last_class="n-last",th=table.tHead.querySelector("th[aria-sort]");if(!th)return;table.dispatchEvent(new Event("sort-start",{bubbles:!0}));var th_row=table.tHead.children[0],direction=th.getAttribute("aria-sort"),reverse=direction==="ascending",sort_null_last=table.classList.contains(null_last_class);function getValue(element){var _a;if(!element)return"";if(alt_sort&&element.dataset.sortAlt!==void 0)return element.dataset.sortAlt;if(element.dataset.sort!==void 0)return element.dataset.sort;var first_child=element.firstChild;if(first_child)switch(first_child.nodeName){case"TIME":return first_child.dateTime;case"DATA":return first_child.value;case"METER":return first_child.value;case"PROGRESS":return first_child.value;case"ABBR":return first_child.title}return((_a=element.textContent)!==null&&_a!==void 0?_a:"").trim()}for(var compareFn=function(a,b,index){var x=getValue(b.cells[index]),y=getValue(a.cells[index]);if(sort_null_last){if(x===""&&y!=="")return-1;if(y===""&&x!=="")return 1}var temp=+x-+y,bool=isNaN(temp)?x.localeCompare(y):temp;return bool===0&&th_row.cells[index]&&th_row.cells[index].hasAttribute("data-sort-tbr")?compareFn(a,b,+th_row.cells[index].dataset.sortTbr):reverse?-bool:bool},i=0;i + + + + + + sortable test + + + + +

Sortable examples

+ +

Basic sort

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

Tiebreaker

+

Sort by year

+ + (Appearance manually changed using style attributes. Just for demonstration.) + +
+style="
+  --stripe-bg: #ff0;
+  --stripe-color: #000;
+  --stripe-bg-odd: #f0f;
+  --stripe-color-odd: #111;
+  --th-bg: blue;
+  --th-color: #fff;"
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
+ + +

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
+ +

Alternative sort

+ + + + + + + + + + + + + + + + + + + + + + +
Movie NameSize
AB
DE
JK
+ +

TR element with no TD element (invalid HTML)

+ + + + + + + + + + + + + + + + + + + + +
Letters
CCC
DDD
AAA
+ +

TD with "incorrect" whitespace

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

HTML Tag Support

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EventDateProgressScoreAbbreviation
Meeting75%8.5/10WWW
Conference50%9.2/10API
Workshop90%7.8/10HTML
SeminarUnknownSix point fiveCSS
+ + + + + + + + diff --git a/dist/standalone.min.html b/dist/standalone.min.html new file mode 100644 index 0000000..039e0fc --- /dev/null +++ b/dist/standalone.min.html @@ -0,0 +1,373 @@ + + + + + + + sortable test + + + + +

Sortable examples

+ +

Basic sort

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

Tiebreaker

+

Sort by year

+ + (Appearance manually changed using style attributes. Just for demonstration.) + +
+style="
+  --stripe-bg: #ff0;
+  --stripe-color: #000;
+  --stripe-bg-odd: #f0f;
+  --stripe-color-odd: #111;
+  --th-bg: blue;
+  --th-color: #fff;"
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MonthYearDayTime
1120102512:00
1120102515:00
0420101213:00
+ + +

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
+ +

Alternative sort

+ + + + + + + + + + + + + + + + + + + + + + +
Movie NameSize
AB
DE
JK
+ +

TR element with no TD element (invalid HTML)

+ + + + + + + + + + + + + + + + + + + + +
Letters
CCC
DDD
AAA
+ +

TD with "incorrect" whitespace

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

HTML Tag Support

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EventDateProgressScoreAbbreviation
Meeting75%8.5/10WWW
Conference50%9.2/10API
Workshop90%7.8/10HTML
SeminarUnknownSix point fiveCSS
+ + + + + + + + diff --git a/dist/standalone/sortable.a11y.js b/dist/standalone/sortable.a11y.js index f2c224c..fcb43f4 100644 --- a/dist/standalone/sortable.a11y.js +++ b/dist/standalone/sortable.a11y.js @@ -1,12 +1,12 @@ -function enhanceSortableAccessibility(tables) { - function updateAriaLabel(element, default_direction) { - var _a; - default_direction === void 0 && (default_direction = ""); - var header_text = element.textContent || "element", current_direction = (_a = element.getAttribute("aria-sort")) !== null && _a !== void 0 ? _a : "", new_direction = "descending"; - (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 updateSortableAriaLabel(element, default_direction) { + var header_text = element.textContent || "element", aria_label = "Column ".concat(header_text, " is not sortable"); + if (default_direction !== "no-sort") { + var current_direction = element.getAttribute("aria-sort"), new_direction = default_direction; + current_direction && (new_direction = current_direction === "descending" ? "ascending" : "descending"), 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), console.log("🚀 comment me out"); +} +function enhanceSortableAccessibility(tables) { function handleKeyDown(event) { if (event.key === "Enter") { var element = event.target; @@ -14,14 +14,19 @@ function enhanceSortableAccessibility(tables) { } } tables.forEach(function(table) { - var default_direction = table.classList.contains("asc") ? "ascending" : "", headers = table.querySelectorAll("th"); + var default_direction = table.classList.contains("asc") ? "ascending" : "descending", headers = table.querySelectorAll("th"); headers.forEach(function(header) { var element = header; if (!element.hasAttribute("tabindex")) { + if (element.classList.contains("no-sort")) { + updateSortableAriaLabel(element, "no-sort"); + return; + } + element.setAttribute("tabindex", "0"); var update = function() { - updateAriaLabel(element, default_direction); + updateSortableAriaLabel(element, default_direction); }; - element.setAttribute("tabindex", "0"), update(), element.addEventListener("click", function() { + update(), element.addEventListener("click", function() { setTimeout(update, 50); }), element.addEventListener("focus", update), element.addEventListener("keydown", handleKeyDown); } diff --git a/dist/standalone/sortable.a11y.min.js b/dist/standalone/sortable.a11y.min.js index db098e8..e54181d 100644 --- a/dist/standalone/sortable.a11y.min.js +++ b/dist/standalone/sortable.a11y.min.js @@ -1,2 +1,3 @@ -function enhanceSortableAccessibility(g){function h(c){c.key==="Enter"&&c.target.click()}g.forEach(function(c){var k=c.classList.contains("asc")?"ascending":"";c.querySelectorAll("th").forEach(function(a){if(!a.hasAttribute("tabindex")){var e=function(){var d=k,b;d===void 0&&(d="");var l=a.textContent||"element",f=(b=a.getAttribute("aria-sort"))!==null&&b!==void 0?b:"";b="descending";(f==="descending"||d&&f!=="ascending")&&(b="ascending");d="Click to sort table by ".concat(l," in ").concat(b," order"); -a.setAttribute("aria-label",d)};a.setAttribute("tabindex","0");e();a.addEventListener("click",function(){setTimeout(e,50)});a.addEventListener("focus",e);a.addEventListener("keydown",h)}})})}document.addEventListener("DOMContentLoaded",function(){enhanceSortableAccessibility(document.querySelectorAll(".sortable"))}); +function updateSortableAriaLabel(d,e){var a=d.textContent||"element",c="Column ".concat(a," is not sortable");e!=="no-sort"&&((c=d.getAttribute("aria-sort"))&&(e=c==="descending"?"ascending":"descending"),c="Click to sort table by ".concat(a," in ").concat(e," order"));d.setAttribute("aria-label",c);d.setAttribute("title",c);console.log("\ud83d\ude80 comment me out")} +function enhanceSortableAccessibility(d){function e(a){a.key==="Enter"&&a.target.click()}d.forEach(function(a){var c=a.classList.contains("asc")?"ascending":"descending";a.querySelectorAll("th").forEach(function(b){if(!b.hasAttribute("tabindex"))if(b.classList.contains("no-sort"))updateSortableAriaLabel(b,"no-sort");else{b.setAttribute("tabindex","0");var f=function(){updateSortableAriaLabel(b,c)};f();b.addEventListener("click",function(){setTimeout(f,50)});b.addEventListener("focus",f);b.addEventListener("keydown", +e)}})})}document.addEventListener("DOMContentLoaded",function(){enhanceSortableAccessibility(document.querySelectorAll(".sortable"))}); diff --git a/dist/standalone/sortable.auto.js b/dist/standalone/sortable.auto.js index 15e9407..8f6d2e7 100644 --- a/dist/standalone/sortable.auto.js +++ b/dist/standalone/sortable.auto.js @@ -64,15 +64,15 @@ function sortableEventListener(e) { } catch { } } -function enhanceSortableAccessibility(tables) { - function updateAriaLabel(element, default_direction) { - var _a; - default_direction === void 0 && (default_direction = ""); - var header_text = element.textContent || "element", current_direction = (_a = element.getAttribute("aria-sort")) !== null && _a !== void 0 ? _a : "", new_direction = "descending"; - (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 updateSortableAriaLabel(element, default_direction) { + var header_text = element.textContent || "element", aria_label = "Column ".concat(header_text, " is not sortable"); + if (default_direction !== "no-sort") { + var current_direction = element.getAttribute("aria-sort"), new_direction = default_direction; + current_direction && (new_direction = current_direction === "descending" ? "ascending" : "descending"), 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), console.log("🚀 comment me out"); +} +function enhanceSortableAccessibility(tables) { function handleKeyDown(event) { if (event.key === "Enter") { var element = event.target; @@ -80,14 +80,19 @@ function enhanceSortableAccessibility(tables) { } } tables.forEach(function(table) { - var default_direction = table.classList.contains("asc") ? "ascending" : "", headers = table.querySelectorAll("th"); + var default_direction = table.classList.contains("asc") ? "ascending" : "descending", headers = table.querySelectorAll("th"); headers.forEach(function(header) { var element = header; if (!element.hasAttribute("tabindex")) { + if (element.classList.contains("no-sort")) { + updateSortableAriaLabel(element, "no-sort"); + return; + } + element.setAttribute("tabindex", "0"); var update = function() { - updateAriaLabel(element, default_direction); + updateSortableAriaLabel(element, default_direction); }; - element.setAttribute("tabindex", "0"), update(), element.addEventListener("click", function() { + update(), element.addEventListener("click", function() { setTimeout(update, 50); }), element.addEventListener("focus", update), element.addEventListener("keydown", handleKeyDown); } diff --git a/dist/standalone/sortable.auto.min.js b/dist/standalone/sortable.auto.min.js index 7f45846..3678706 100644 --- a/dist/standalone/sortable.auto.min.js +++ b/dist/standalone/sortable.auto.min.js @@ -1,9 +1,9 @@ -function sortSortable(a,k){function b(g){var m;if(!g)return"";if(k&&g.dataset.sortAlt!==void 0)return g.dataset.sortAlt;if(g.dataset.sort!==void 0)return g.dataset.sort;var c=g.firstChild;if(c)switch(c.nodeName){case "TIME":return c.dateTime;case "DATA":return c.value;case "METER":return c.value;case "PROGRESS":return c.value;case "ABBR":return c.title}return((m=g.textContent)!==null&&m!==void 0?m:"").trim()}var d=a.tHead.querySelector("th[aria-sort]");if(d){a.dispatchEvent(new Event("sort-start", -{bubbles:!0}));for(var e=a.tHead.children[0],h=d.getAttribute("aria-sort")==="ascending",f=a.classList.contains("n-last"),l=function(g,m,c){var n=b(m.cells[c]),r=b(g.cells[c]);if(f){if(n===""&&r!=="")return-1;if(r===""&&n!=="")return 1}var u=+n-+r;n=isNaN(u)?n.localeCompare(r):u;return n===0&&e.cells[c]&&e.cells[c].hasAttribute("data-sort-tbr")?l(g,m,+e.cells[c].dataset.sortTbr):h?-n:n},q=0;qBasic sort

Tiebreaker

Sort by year

- Appearance manually changed using style attributes. Just for demonstration. + (Appearance manually changed using style attributes. Just for demonstration.) -
+    
 style="
   --stripe-bg: #ff0;
   --stripe-color: #000;
diff --git a/docs/sortable.auto.js b/docs/sortable.auto.js
index fe44c1d..c9920f9 100644
--- a/docs/sortable.auto.js
+++ b/docs/sortable.auto.js
@@ -1 +1 @@
-(function(){"use strict";function sortSortable(table,alt_sort){var null_last_class="n-last",th=table.tHead.querySelector("th[aria-sort]");if(!th)return;table.dispatchEvent(new Event("sort-start",{bubbles:!0}));var th_row=table.tHead.children[0],direction=th.getAttribute("aria-sort"),reverse=direction==="ascending",sort_null_last=table.classList.contains(null_last_class);function getValue(element){var _a;if(!element)return"";if(alt_sort&&element.dataset.sortAlt!==void 0)return element.dataset.sortAlt;if(element.dataset.sort!==void 0)return element.dataset.sort;var first_child=element.firstChild;if(first_child)switch(first_child.nodeName){case"TIME":return first_child.dateTime;case"DATA":return first_child.value;case"METER":return first_child.value;case"PROGRESS":return first_child.value;case"ABBR":return first_child.title}return((_a=element.textContent)!==null&&_a!==void 0?_a:"").trim()}for(var compareFn=function(a,b,index){var x=getValue(b.cells[index]),y=getValue(a.cells[index]);if(sort_null_last){if(x===""&&y!=="")return-1;if(y===""&&x!=="")return 1}var temp=+x-+y,bool=isNaN(temp)?x.localeCompare(y):temp;return bool===0&&th_row.cells[index]&&th_row.cells[index].hasAttribute("data-sort-tbr")?compareFn(a,b,+th_row.cells[index].dataset.sortTbr):reverse?-bool:bool},i=0;iBasic sort
     

Tiebreaker

Sort by year

- Appearance manually changed using style attributes. Just for demonstration. + (Appearance manually changed using style attributes. Just for demonstration.) -
+    
 style="
   --stripe-bg: #ff0;
   --stripe-color: #000;
diff --git a/package.json b/package.json
index 1d3fdbe..118222c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "sortable-tablesort",
-  "version": "4.1.5",
+  "version": "4.1.6",
   "description": "A tiny, Vanilla/Plain JavaScript table sorter",
   "private": false,
   "type": "module",
@@ -51,39 +51,39 @@
     "serve": "vite preview --port 3009"
   },
   "devDependencies": {
-    "@eslint/js": "^9.37.0",
+    "@eslint/js": "^9.38.0",
     "@playwright/test": "^1.56.1",
     "@rollup/plugin-terser": "^0.4.4",
     "@rollup/plugin-typescript": "^12.1.4",
     "@testing-library/dom": "^10.4.1",
     "@testing-library/jest-dom": "^6.9.1",
     "@types/jsdom": "^27.0.0",
-    "@types/node": "^24.8.1",
-    "@typescript-eslint/eslint-plugin": "^8.46.1",
-    "@typescript-eslint/parser": "^8.46.1",
+    "@types/node": "^24.9.1",
+    "@typescript-eslint/eslint-plugin": "^8.46.2",
+    "@typescript-eslint/parser": "^8.46.2",
     "autoprefixer": "^10.4.21",
     "babel-jest": "^30.2.0",
     "benchmark": "^2.1.4",
     "cross-env": "^10.1.0",
     "esbuild": "^0.25.11",
-    "eslint": "^9.37.0",
+    "eslint": "^9.38.0",
     "eslint-config-prettier": "^10.1.8",
     "eslint-plugin-prettier": "^5.5.4",
     "globals": "^16.4.0",
-    "google-closure-compiler": "^20251013.0.0",
+    "google-closure-compiler": "^20251019.0.0",
     "husky": "^9.1.7",
     "jest": "^30.2.0",
-    "jsdom": "^27.0.0",
+    "jsdom": "^27.0.1",
     "postcss": "^8.5.6",
     "prettier": "^3.6.2",
     "rimraf": "^6.0.1",
-    "rollup": "^4.52.4",
+    "rollup": "^4.52.5",
     "rollup-plugin-scss": "^4.0.1",
     "sass": "^1.93.2",
     "tslib": "^2.8.1",
     "tsx": "^4.20.6",
     "typescript": "^5.9.3",
-    "vite": "^7.1.10",
+    "vite": "^7.1.11",
     "vitest": "^3.2.4"
   }
 }
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index faedcff..f719224 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -9,17 +9,17 @@ importers:
   .:
     devDependencies:
       '@eslint/js':
-        specifier: ^9.37.0
-        version: 9.37.0
+        specifier: ^9.38.0
+        version: 9.38.0
       '@playwright/test':
         specifier: ^1.56.1
         version: 1.56.1
       '@rollup/plugin-terser':
         specifier: ^0.4.4
-        version: 0.4.4(rollup@4.52.4)
+        version: 0.4.4(rollup@4.52.5)
       '@rollup/plugin-typescript':
         specifier: ^12.1.4
-        version: 12.1.4(rollup@4.52.4)(tslib@2.8.1)(typescript@5.9.3)
+        version: 12.1.4(rollup@4.52.5)(tslib@2.8.1)(typescript@5.9.3)
       '@testing-library/dom':
         specifier: ^10.4.1
         version: 10.4.1
@@ -30,14 +30,14 @@ importers:
         specifier: ^27.0.0
         version: 27.0.0
       '@types/node':
-        specifier: ^24.8.1
-        version: 24.8.1
+        specifier: ^24.9.1
+        version: 24.9.1
       '@typescript-eslint/eslint-plugin':
-        specifier: ^8.46.1
-        version: 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3)
+        specifier: ^8.46.2
+        version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0)(typescript@5.9.3))(eslint@9.38.0)(typescript@5.9.3)
       '@typescript-eslint/parser':
-        specifier: ^8.46.1
-        version: 8.46.1(eslint@9.37.0)(typescript@5.9.3)
+        specifier: ^8.46.2
+        version: 8.46.2(eslint@9.38.0)(typescript@5.9.3)
       autoprefixer:
         specifier: ^10.4.21
         version: 10.4.21(postcss@8.5.6)
@@ -54,29 +54,29 @@ importers:
         specifier: ^0.25.11
         version: 0.25.11
       eslint:
-        specifier: ^9.37.0
-        version: 9.37.0
+        specifier: ^9.38.0
+        version: 9.38.0
       eslint-config-prettier:
         specifier: ^10.1.8
-        version: 10.1.8(eslint@9.37.0)
+        version: 10.1.8(eslint@9.38.0)
       eslint-plugin-prettier:
         specifier: ^5.5.4
-        version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.37.0))(eslint@9.37.0)(prettier@3.6.2)
+        version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.38.0))(eslint@9.38.0)(prettier@3.6.2)
       globals:
         specifier: ^16.4.0
         version: 16.4.0
       google-closure-compiler:
-        specifier: ^20251013.0.0
-        version: 20251013.0.0
+        specifier: ^20251019.0.0
+        version: 20251019.0.0
       husky:
         specifier: ^9.1.7
         version: 9.1.7
       jest:
         specifier: ^30.2.0
-        version: 30.2.0(@types/node@24.8.1)
+        version: 30.2.0(@types/node@24.9.1)
       jsdom:
-        specifier: ^27.0.0
-        version: 27.0.0(postcss@8.5.6)
+        specifier: ^27.0.1
+        version: 27.0.1(postcss@8.5.6)
       postcss:
         specifier: ^8.5.6
         version: 8.5.6
@@ -87,8 +87,8 @@ importers:
         specifier: ^6.0.1
         version: 6.0.1
       rollup:
-        specifier: ^4.52.4
-        version: 4.52.4
+        specifier: ^4.52.5
+        version: 4.52.5
       rollup-plugin-scss:
         specifier: ^4.0.1
         version: 4.0.1
@@ -105,11 +105,11 @@ importers:
         specifier: ^5.9.3
         version: 5.9.3
       vite:
-        specifier: ^7.1.10
-        version: 7.1.10(@types/node@24.8.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)
+        specifier: ^7.1.11
+        version: 7.1.11(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)
       vitest:
         specifier: ^3.2.4
-        version: 3.2.4(@types/node@24.8.1)(jsdom@27.0.0(postcss@8.5.6))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)
+        version: 3.2.4(@types/node@24.9.1)(jsdom@27.0.1(postcss@8.5.6))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)
 
 packages:
 
@@ -119,8 +119,8 @@ packages:
   '@asamuzakjp/css-color@4.0.5':
     resolution: {integrity: sha512-lMrXidNhPGsDjytDy11Vwlb6OIGrT3CmLg3VWNFyWkLWtijKl7xjvForlh8vuj0SHGjgl4qZEQzUmYTeQA2JFQ==}
 
-  '@asamuzakjp/dom-selector@6.5.6':
-    resolution: {integrity: sha512-Mj3Hu9ymlsERd7WOsUKNUZnJYL4IZ/I9wVVYgtvOsWYiEFbkQ4G7VRIh2USxTVW4BBDIsLG+gBUgqOqf2Kvqow==}
+  '@asamuzakjp/dom-selector@6.7.2':
+    resolution: {integrity: sha512-ccKogJI+0aiDhOahdjANIc9SDixSud1gbwdVrhn7kMopAtLXqsz9MKmQQtIl6Y5aC2IYq+j4dz/oedL2AVMmVQ==}
 
   '@asamuzakjp/nwsapi@2.3.9':
     resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==}
@@ -328,11 +328,11 @@ packages:
     resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==}
     engines: {node: '>=18'}
 
-  '@emnapi/core@1.5.0':
-    resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==}
+  '@emnapi/core@1.6.0':
+    resolution: {integrity: sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg==}
 
-  '@emnapi/runtime@1.5.0':
-    resolution: {integrity: sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==}
+  '@emnapi/runtime@1.6.0':
+    resolution: {integrity: sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA==}
 
   '@emnapi/wasi-threads@1.1.0':
     resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==}
@@ -506,12 +506,12 @@ packages:
     resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
     engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
 
-  '@eslint/config-array@0.21.0':
-    resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==}
+  '@eslint/config-array@0.21.1':
+    resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 
-  '@eslint/config-helpers@0.4.0':
-    resolution: {integrity: sha512-WUFvV4WoIwW8Bv0KeKCIIEgdSiFOsulyN0xrMu+7z43q/hkOLXjvb5u7UC9jDxvRzcrbEmuZBX5yJZz1741jog==}
+  '@eslint/config-helpers@0.4.1':
+    resolution: {integrity: sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 
   '@eslint/core@0.16.0':
@@ -522,12 +522,12 @@ packages:
     resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 
-  '@eslint/js@9.37.0':
-    resolution: {integrity: sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg==}
+  '@eslint/js@9.38.0':
+    resolution: {integrity: sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 
-  '@eslint/object-schema@2.1.6':
-    resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==}
+  '@eslint/object-schema@2.1.7':
+    resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 
   '@eslint/plugin-kit@0.4.0':
@@ -812,113 +812,113 @@ packages:
       rollup:
         optional: true
 
-  '@rollup/rollup-android-arm-eabi@4.52.4':
-    resolution: {integrity: sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==}
+  '@rollup/rollup-android-arm-eabi@4.52.5':
+    resolution: {integrity: sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==}
     cpu: [arm]
     os: [android]
 
-  '@rollup/rollup-android-arm64@4.52.4':
-    resolution: {integrity: sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==}
+  '@rollup/rollup-android-arm64@4.52.5':
+    resolution: {integrity: sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==}
     cpu: [arm64]
     os: [android]
 
-  '@rollup/rollup-darwin-arm64@4.52.4':
-    resolution: {integrity: sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==}
+  '@rollup/rollup-darwin-arm64@4.52.5':
+    resolution: {integrity: sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==}
     cpu: [arm64]
     os: [darwin]
 
-  '@rollup/rollup-darwin-x64@4.52.4':
-    resolution: {integrity: sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==}
+  '@rollup/rollup-darwin-x64@4.52.5':
+    resolution: {integrity: sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==}
     cpu: [x64]
     os: [darwin]
 
-  '@rollup/rollup-freebsd-arm64@4.52.4':
-    resolution: {integrity: sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==}
+  '@rollup/rollup-freebsd-arm64@4.52.5':
+    resolution: {integrity: sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==}
     cpu: [arm64]
     os: [freebsd]
 
-  '@rollup/rollup-freebsd-x64@4.52.4':
-    resolution: {integrity: sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==}
+  '@rollup/rollup-freebsd-x64@4.52.5':
+    resolution: {integrity: sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==}
     cpu: [x64]
     os: [freebsd]
 
-  '@rollup/rollup-linux-arm-gnueabihf@4.52.4':
-    resolution: {integrity: sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==}
+  '@rollup/rollup-linux-arm-gnueabihf@4.52.5':
+    resolution: {integrity: sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==}
     cpu: [arm]
     os: [linux]
 
-  '@rollup/rollup-linux-arm-musleabihf@4.52.4':
-    resolution: {integrity: sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==}
+  '@rollup/rollup-linux-arm-musleabihf@4.52.5':
+    resolution: {integrity: sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==}
     cpu: [arm]
     os: [linux]
 
-  '@rollup/rollup-linux-arm64-gnu@4.52.4':
-    resolution: {integrity: sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==}
+  '@rollup/rollup-linux-arm64-gnu@4.52.5':
+    resolution: {integrity: sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==}
     cpu: [arm64]
     os: [linux]
 
-  '@rollup/rollup-linux-arm64-musl@4.52.4':
-    resolution: {integrity: sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==}
+  '@rollup/rollup-linux-arm64-musl@4.52.5':
+    resolution: {integrity: sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==}
     cpu: [arm64]
     os: [linux]
 
-  '@rollup/rollup-linux-loong64-gnu@4.52.4':
-    resolution: {integrity: sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==}
+  '@rollup/rollup-linux-loong64-gnu@4.52.5':
+    resolution: {integrity: sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==}
     cpu: [loong64]
     os: [linux]
 
-  '@rollup/rollup-linux-ppc64-gnu@4.52.4':
-    resolution: {integrity: sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==}
+  '@rollup/rollup-linux-ppc64-gnu@4.52.5':
+    resolution: {integrity: sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==}
     cpu: [ppc64]
     os: [linux]
 
-  '@rollup/rollup-linux-riscv64-gnu@4.52.4':
-    resolution: {integrity: sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==}
+  '@rollup/rollup-linux-riscv64-gnu@4.52.5':
+    resolution: {integrity: sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==}
     cpu: [riscv64]
     os: [linux]
 
-  '@rollup/rollup-linux-riscv64-musl@4.52.4':
-    resolution: {integrity: sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==}
+  '@rollup/rollup-linux-riscv64-musl@4.52.5':
+    resolution: {integrity: sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==}
     cpu: [riscv64]
     os: [linux]
 
-  '@rollup/rollup-linux-s390x-gnu@4.52.4':
-    resolution: {integrity: sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==}
+  '@rollup/rollup-linux-s390x-gnu@4.52.5':
+    resolution: {integrity: sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==}
     cpu: [s390x]
     os: [linux]
 
-  '@rollup/rollup-linux-x64-gnu@4.52.4':
-    resolution: {integrity: sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==}
+  '@rollup/rollup-linux-x64-gnu@4.52.5':
+    resolution: {integrity: sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==}
     cpu: [x64]
     os: [linux]
 
-  '@rollup/rollup-linux-x64-musl@4.52.4':
-    resolution: {integrity: sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==}
+  '@rollup/rollup-linux-x64-musl@4.52.5':
+    resolution: {integrity: sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==}
     cpu: [x64]
     os: [linux]
 
-  '@rollup/rollup-openharmony-arm64@4.52.4':
-    resolution: {integrity: sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==}
+  '@rollup/rollup-openharmony-arm64@4.52.5':
+    resolution: {integrity: sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==}
     cpu: [arm64]
     os: [openharmony]
 
-  '@rollup/rollup-win32-arm64-msvc@4.52.4':
-    resolution: {integrity: sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==}
+  '@rollup/rollup-win32-arm64-msvc@4.52.5':
+    resolution: {integrity: sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==}
     cpu: [arm64]
     os: [win32]
 
-  '@rollup/rollup-win32-ia32-msvc@4.52.4':
-    resolution: {integrity: sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==}
+  '@rollup/rollup-win32-ia32-msvc@4.52.5':
+    resolution: {integrity: sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==}
     cpu: [ia32]
     os: [win32]
 
-  '@rollup/rollup-win32-x64-gnu@4.52.4':
-    resolution: {integrity: sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==}
+  '@rollup/rollup-win32-x64-gnu@4.52.5':
+    resolution: {integrity: sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==}
     cpu: [x64]
     os: [win32]
 
-  '@rollup/rollup-win32-x64-msvc@4.52.4':
-    resolution: {integrity: sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==}
+  '@rollup/rollup-win32-x64-msvc@4.52.5':
+    resolution: {integrity: sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==}
     cpu: [x64]
     os: [win32]
 
@@ -957,8 +957,8 @@ packages:
   '@types/babel__traverse@7.28.0':
     resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==}
 
-  '@types/chai@5.2.2':
-    resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==}
+  '@types/chai@5.2.3':
+    resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
 
   '@types/deep-eql@4.0.2':
     resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
@@ -981,8 +981,8 @@ packages:
   '@types/json-schema@7.0.15':
     resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
 
-  '@types/node@24.8.1':
-    resolution: {integrity: sha512-alv65KGRadQVfVcG69MuB4IzdYVpRwMG/mq8KWOaoOdyY617P5ivaDiMCGOFDWD2sAn5Q0mR3mRtUOgm99hL9Q==}
+  '@types/node@24.9.1':
+    resolution: {integrity: sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==}
 
   '@types/stack-utils@2.0.3':
     resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==}
@@ -996,63 +996,63 @@ packages:
   '@types/yargs@17.0.33':
     resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==}
 
-  '@typescript-eslint/eslint-plugin@8.46.1':
-    resolution: {integrity: sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ==}
+  '@typescript-eslint/eslint-plugin@8.46.2':
+    resolution: {integrity: sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     peerDependencies:
-      '@typescript-eslint/parser': ^8.46.1
+      '@typescript-eslint/parser': ^8.46.2
       eslint: ^8.57.0 || ^9.0.0
       typescript: '>=4.8.4 <6.0.0'
 
-  '@typescript-eslint/parser@8.46.1':
-    resolution: {integrity: sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==}
+  '@typescript-eslint/parser@8.46.2':
+    resolution: {integrity: sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     peerDependencies:
       eslint: ^8.57.0 || ^9.0.0
       typescript: '>=4.8.4 <6.0.0'
 
-  '@typescript-eslint/project-service@8.46.1':
-    resolution: {integrity: sha512-FOIaFVMHzRskXr5J4Jp8lFVV0gz5ngv3RHmn+E4HYxSJ3DgDzU7fVI1/M7Ijh1zf6S7HIoaIOtln1H5y8V+9Zg==}
+  '@typescript-eslint/project-service@8.46.2':
+    resolution: {integrity: sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     peerDependencies:
       typescript: '>=4.8.4 <6.0.0'
 
-  '@typescript-eslint/scope-manager@8.46.1':
-    resolution: {integrity: sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A==}
+  '@typescript-eslint/scope-manager@8.46.2':
+    resolution: {integrity: sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 
-  '@typescript-eslint/tsconfig-utils@8.46.1':
-    resolution: {integrity: sha512-X88+J/CwFvlJB+mK09VFqx5FE4H5cXD+H/Bdza2aEWkSb8hnWIQorNcscRl4IEo1Cz9VI/+/r/jnGWkbWPx54g==}
+  '@typescript-eslint/tsconfig-utils@8.46.2':
+    resolution: {integrity: sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     peerDependencies:
       typescript: '>=4.8.4 <6.0.0'
 
-  '@typescript-eslint/type-utils@8.46.1':
-    resolution: {integrity: sha512-+BlmiHIiqufBxkVnOtFwjah/vrkF4MtKKvpXrKSPLCkCtAp8H01/VV43sfqA98Od7nJpDcFnkwgyfQbOG0AMvw==}
+  '@typescript-eslint/type-utils@8.46.2':
+    resolution: {integrity: sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     peerDependencies:
       eslint: ^8.57.0 || ^9.0.0
       typescript: '>=4.8.4 <6.0.0'
 
-  '@typescript-eslint/types@8.46.1':
-    resolution: {integrity: sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==}
+  '@typescript-eslint/types@8.46.2':
+    resolution: {integrity: sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 
-  '@typescript-eslint/typescript-estree@8.46.1':
-    resolution: {integrity: sha512-uIifjT4s8cQKFQ8ZBXXyoUODtRoAd7F7+G8MKmtzj17+1UbdzFl52AzRyZRyKqPHhgzvXunnSckVu36flGy8cg==}
+  '@typescript-eslint/typescript-estree@8.46.2':
+    resolution: {integrity: sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     peerDependencies:
       typescript: '>=4.8.4 <6.0.0'
 
-  '@typescript-eslint/utils@8.46.1':
-    resolution: {integrity: sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ==}
+  '@typescript-eslint/utils@8.46.2':
+    resolution: {integrity: sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     peerDependencies:
       eslint: ^8.57.0 || ^9.0.0
       typescript: '>=4.8.4 <6.0.0'
 
-  '@typescript-eslint/visitor-keys@8.46.1':
-    resolution: {integrity: sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA==}
+  '@typescript-eslint/visitor-keys@8.46.2':
+    resolution: {integrity: sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 
   '@ungap/structured-clone@1.3.0':
@@ -1251,8 +1251,8 @@ packages:
     peerDependencies:
       postcss: ^8.1.0
 
-  b4a@1.7.2:
-    resolution: {integrity: sha512-DyUOdz+E8R6+sruDpQNOaV0y/dBbV6X/8ZkxrDcR0Ifc3BgKlpgG0VAtfOozA0eMtJO5GGe9FsZhueLs00pTww==}
+  b4a@1.7.3:
+    resolution: {integrity: sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==}
     peerDependencies:
       react-native-b4a: '*'
     peerDependenciesMeta:
@@ -1287,11 +1287,16 @@ packages:
   balanced-match@1.0.2:
     resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
 
-  bare-events@2.7.0:
-    resolution: {integrity: sha512-b3N5eTW1g7vXkw+0CXh/HazGTcO5KYuu/RCNaJbDMPI6LHDi+7qe8EmxKUVe1sUbY2KZOVZFyj62x0OEz9qyAA==}
+  bare-events@2.8.0:
+    resolution: {integrity: sha512-AOhh6Bg5QmFIXdViHbMc2tLDsBIRxdkIaIddPslJF9Z5De3APBScuqGP2uThXnIpqFrgoxMNC6km7uXNIMLHXA==}
+    peerDependencies:
+      bare-abort-controller: '*'
+    peerDependenciesMeta:
+      bare-abort-controller:
+        optional: true
 
-  baseline-browser-mapping@2.8.6:
-    resolution: {integrity: sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw==}
+  baseline-browser-mapping@2.8.19:
+    resolution: {integrity: sha512-zoKGUdu6vb2jd3YOq0nnhEDQVbPcHhco3UImJrv5dSkvxTc2pl2WjOPsjZXDwPDSl5eghIMuY3R6J9NDKF3KcQ==}
     hasBin: true
 
   benchmark@2.1.4:
@@ -1310,8 +1315,8 @@ packages:
     resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
     engines: {node: '>=8'}
 
-  browserslist@4.26.2:
-    resolution: {integrity: sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==}
+  browserslist@4.26.3:
+    resolution: {integrity: sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==}
     engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
     hasBin: true
 
@@ -1337,8 +1342,8 @@ packages:
     resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
     engines: {node: '>=10'}
 
-  caniuse-lite@1.0.30001743:
-    resolution: {integrity: sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw==}
+  caniuse-lite@1.0.30001751:
+    resolution: {integrity: sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==}
 
   chai@5.3.3:
     resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==}
@@ -1364,8 +1369,8 @@ packages:
     resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
     engines: {node: '>= 14.16.0'}
 
-  ci-info@4.3.0:
-    resolution: {integrity: sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==}
+  ci-info@4.3.1:
+    resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==}
     engines: {node: '>=8'}
 
   cjs-module-lexer@2.1.0:
@@ -1383,8 +1388,8 @@ packages:
     resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
     engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
 
-  collect-v8-coverage@1.0.2:
-    resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==}
+  collect-v8-coverage@1.0.3:
+    resolution: {integrity: sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==}
 
   color-convert@2.0.1:
     resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
@@ -1479,8 +1484,8 @@ packages:
   eastasianwidth@0.2.0:
     resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
 
-  electron-to-chromium@1.5.223:
-    resolution: {integrity: sha512-qKm55ic6nbEmagFlTFczML33rF90aU+WtrJ9MdTCThrcvDNdUHN4p6QfVN78U06ZmguqXIyMPyYhw2TrbDUwPQ==}
+  electron-to-chromium@1.5.237:
+    resolution: {integrity: sha512-icUt1NvfhGLar5lSWH3tHNzablaA5js3HVHacQimfP8ViEBOQv+L7DKEuHdbTZ0SKCO1ogTJTIL1Gwk9S6Qvcg==}
 
   emittery@0.13.1:
     resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==}
@@ -1551,8 +1556,8 @@ packages:
     resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 
-  eslint@9.37.0:
-    resolution: {integrity: sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==}
+  eslint@9.38.0:
+    resolution: {integrity: sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     hasBin: true
     peerDependencies:
@@ -1710,8 +1715,8 @@ packages:
     resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
     engines: {node: '>=10'}
 
-  get-tsconfig@4.10.1:
-    resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==}
+  get-tsconfig@4.12.0:
+    resolution: {integrity: sha512-LScr2aNr2FbjAjZh2C6X6BxRx1/x+aTDExct/xyq2XKbYOiG5c0aK7pMsSuyc0brz3ibr/lbQiHD9jzt4lccJw==}
 
   glob-parent@5.1.2:
     resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
@@ -1742,31 +1747,31 @@ packages:
     resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==}
     engines: {node: '>=18'}
 
-  google-closure-compiler-java@20251013.0.0:
-    resolution: {integrity: sha512-vpKpCBFixmCAvpXjLUQTTyXn53D6R7quQ8VWJu6s1r54RF7S4f7XnSTqm+b0YVCBsaqVSI/DB4freAAOGRtZJg==}
+  google-closure-compiler-java@20251019.0.0:
+    resolution: {integrity: sha512-cT2YhIWRPkQTkD4gI3IiLY8b0Ah9TrJdp89sASMM/EQqJl6AyMWBkMHNUIXCg2HSk/8O3OPHZziAZgHl/Ey5Vw==}
 
-  google-closure-compiler-linux-arm64@20251013.0.0:
-    resolution: {integrity: sha512-0/sSZBzzRLHPFS9I3B506h/2zy00VwnHXcKqvdOLZjmkp8la3J6QIu4V2PIeFfHpgit4ldgs9yx79p5z/uJ/Yg==}
+  google-closure-compiler-linux-arm64@20251019.0.0:
+    resolution: {integrity: sha512-N5GkKpmWDulaULlXrncLvFluI85ORJcQksDfzThHsnn3yh6PwIOgsdwWHkAB1lZw3LUtgzyRhIvaxLrEQI6vwg==}
     cpu: [arm64]
     os: [linux]
 
-  google-closure-compiler-linux@20251013.0.0:
-    resolution: {integrity: sha512-V6QAoRzvZtA6/CWNQ4o1896mQLdQEbB3h5F7dG6AtlvNvbUw2zlJ8FH8GNrLRJhHgSsVXKlokEMINHQIXBePAw==}
+  google-closure-compiler-linux@20251019.0.0:
+    resolution: {integrity: sha512-XlC9c3NVi+PpcbLY3XtgMvzZFCAoNcBZKqACu742wnZvGYWPhCaYEVow5gLnGsma9RmxDg+T6rc2HMjxg2vesw==}
     cpu: [x32, x64]
     os: [linux]
 
-  google-closure-compiler-macos@20251013.0.0:
-    resolution: {integrity: sha512-i/LY8/DYFO2MFEiaRarUbX8COngQ42bxyO5HlaFXbSw855KKTxda+uzd07ATM6sCWo9jIaVaBBK7MMo9JRwCQQ==}
+  google-closure-compiler-macos@20251019.0.0:
+    resolution: {integrity: sha512-d4skTdyJ2lZHflgdj4vw7bfEAfLqWka4d1dI7vH5pH2iLAWnlF3KN18bwpfOC7eSyEsgwGvoBJyLEs/7lW8adw==}
     cpu: [arm64]
     os: [darwin]
 
-  google-closure-compiler-windows@20251013.0.0:
-    resolution: {integrity: sha512-ko180ysJ5cgNWN6QOgf0dIx2Dk5vqqaXGgdclAm4wQcfS3GKfqX9E3WhHkh0Ph3UGf4PuooYO4i+FprbWDT11g==}
+  google-closure-compiler-windows@20251019.0.0:
+    resolution: {integrity: sha512-i3NRfaSmHVHDCwSz3jVv/at3GKC//eZKgOzHHOSa47usSx0rHag1WuP4xZAB5Xn77P7mPsKY2jXzuqsClYAXjw==}
     cpu: [x32, x64]
     os: [win32]
 
-  google-closure-compiler@20251013.0.0:
-    resolution: {integrity: sha512-DdXD6lpIv+bMV9jU9vm5A6sOZ/dHPkCJleXVL42XpGwpAkhzM/7QkPoKuSwBlJ+jpX0/s8Pwthro8wcOkD/xsQ==}
+  google-closure-compiler@20251019.0.0:
+    resolution: {integrity: sha512-ZmLF/Z7pRibX/7o2MZZ7zZx43VmXpAUB5Ioc76dT+FrY4GOND5lsF1Q9tBmaC25O63OsDqRRoar9vnNGxY1tDg==}
     engines: {node: '>=18'}
     hasBin: true
 
@@ -1820,8 +1825,8 @@ packages:
     resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
     engines: {node: '>= 4'}
 
-  immutable@5.1.3:
-    resolution: {integrity: sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==}
+  immutable@5.1.4:
+    resolution: {integrity: sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==}
 
   import-fresh@3.3.1:
     resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
@@ -2053,8 +2058,8 @@ packages:
     resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
     hasBin: true
 
-  jsdom@27.0.0:
-    resolution: {integrity: sha512-lIHeR1qlIRrIN5VMccd8tI2Sgw6ieYXSVktcSHaNe3Z5nE/tcPQYQWOq00wxMvYOsz+73eAkNenVvmPC6bba9A==}
+  jsdom@27.0.1:
+    resolution: {integrity: sha512-SNSQteBL1IlV2zqhwwolaG9CwhIhTvVHWg3kTss/cLE7H/X4644mtPQqYvCfsSrGQWt9hSZcgOXX8bOZaMN+kA==}
     engines: {node: '>=20'}
     peerDependencies:
       canvas: ^3.0.0
@@ -2187,8 +2192,8 @@ packages:
     engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
     hasBin: true
 
-  napi-postinstall@0.3.3:
-    resolution: {integrity: sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow==}
+  napi-postinstall@0.3.4:
+    resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==}
     engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
     hasBin: true
 
@@ -2201,8 +2206,8 @@ packages:
   node-int64@0.4.0:
     resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
 
-  node-releases@2.0.21:
-    resolution: {integrity: sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==}
+  node-releases@2.0.26:
+    resolution: {integrity: sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==}
 
   normalize-path@3.0.0:
     resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
@@ -2261,6 +2266,9 @@ packages:
   parse5@7.3.0:
     resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
 
+  parse5@8.0.0:
+    resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==}
+
   path-exists@4.0.0:
     resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
     engines: {node: '>=8'}
@@ -2408,8 +2416,8 @@ packages:
   resolve-pkg-maps@1.0.0:
     resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
 
-  resolve@1.22.10:
-    resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==}
+  resolve@1.22.11:
+    resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==}
     engines: {node: '>= 0.4'}
     hasBin: true
 
@@ -2428,8 +2436,8 @@ packages:
   rollup-pluginutils@2.8.2:
     resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==}
 
-  rollup@4.52.4:
-    resolution: {integrity: sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==}
+  rollup@4.52.5:
+    resolution: {integrity: sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==}
     engines: {node: '>=18.0.0', npm: '>=8.0.0'}
     hasBin: true
 
@@ -2458,8 +2466,8 @@ packages:
     resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
     hasBin: true
 
-  semver@7.7.2:
-    resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==}
+  semver@7.7.3:
+    resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==}
     engines: {node: '>=10'}
     hasBin: true
 
@@ -2519,8 +2527,8 @@ packages:
   stackback@0.0.2:
     resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
 
-  std-env@3.9.0:
-    resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==}
+  std-env@3.10.0:
+    resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==}
 
   streamx@2.23.0:
     resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==}
@@ -2561,8 +2569,8 @@ packages:
     resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
     engines: {node: '>=8'}
 
-  strip-literal@3.0.0:
-    resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==}
+  strip-literal@3.1.0:
+    resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==}
 
   supports-color@7.2.0:
     resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
@@ -2620,11 +2628,11 @@ packages:
     resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==}
     engines: {node: '>=14.0.0'}
 
-  tldts-core@7.0.16:
-    resolution: {integrity: sha512-XHhPmHxphLi+LGbH0G/O7dmUH9V65OY20R7vH8gETHsp5AZCjBk9l8sqmRKLaGOxnETU7XNSDUPtewAy/K6jbA==}
+  tldts-core@7.0.17:
+    resolution: {integrity: sha512-DieYoGrP78PWKsrXr8MZwtQ7GLCUeLxihtjC1jZsW1DnvSMdKPitJSe8OSYDM2u5H6g3kWJZpePqkp43TfLh0g==}
 
-  tldts@7.0.16:
-    resolution: {integrity: sha512-5bdPHSwbKTeHmXrgecID4Ljff8rQjv7g8zKQPkCozRo2HWWni+p310FSn5ImI+9kWw9kK4lzOB5q/a6iv0IJsw==}
+  tldts@7.0.17:
+    resolution: {integrity: sha512-Y1KQBgDd/NUc+LfOtKS6mNsC9CCaH+m2P1RoIZy7RAPo3C3/t8X45+zgut31cRZtZ3xKPjfn3TkGTrctC2TQIQ==}
     hasBin: true
 
   tmpl@1.0.5:
@@ -2673,8 +2681,8 @@ packages:
     engines: {node: '>=14.17'}
     hasBin: true
 
-  undici-types@7.14.0:
-    resolution: {integrity: sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==}
+  undici-types@7.16.0:
+    resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
 
   unrs-resolver@1.11.1:
     resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==}
@@ -2704,8 +2712,8 @@ packages:
     engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
     hasBin: true
 
-  vite@7.1.10:
-    resolution: {integrity: sha512-CmuvUBzVJ/e3HGxhg6cYk88NGgTnBoOo7ogtfJJ0fefUWAxN/WDSUa50o+oVBxuIhO8FoEZW0j2eW7sfjs5EtA==}
+  vite@7.1.11:
+    resolution: {integrity: sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==}
     engines: {node: ^20.19.0 || >=22.12.0}
     hasBin: true
     peerDependencies:
@@ -2874,7 +2882,7 @@ snapshots:
       '@csstools/css-tokenizer': 3.0.4
       lru-cache: 11.2.2
 
-  '@asamuzakjp/dom-selector@6.5.6':
+  '@asamuzakjp/dom-selector@6.7.2':
     dependencies:
       '@asamuzakjp/nwsapi': 2.3.9
       bidi-js: 1.0.3
@@ -2924,7 +2932,7 @@ snapshots:
     dependencies:
       '@babel/compat-data': 7.28.4
       '@babel/helper-validator-option': 7.27.1
-      browserslist: 4.26.2
+      browserslist: 4.26.3
       lru-cache: 5.1.1
       semver: 6.3.1
 
@@ -3099,13 +3107,13 @@ snapshots:
 
   '@csstools/css-tokenizer@3.0.4': {}
 
-  '@emnapi/core@1.5.0':
+  '@emnapi/core@1.6.0':
     dependencies:
       '@emnapi/wasi-threads': 1.1.0
       tslib: 2.8.1
     optional: true
 
-  '@emnapi/runtime@1.5.0':
+  '@emnapi/runtime@1.6.0':
     dependencies:
       tslib: 2.8.1
     optional: true
@@ -3195,22 +3203,22 @@ snapshots:
   '@esbuild/win32-x64@0.25.11':
     optional: true
 
-  '@eslint-community/eslint-utils@4.9.0(eslint@9.37.0)':
+  '@eslint-community/eslint-utils@4.9.0(eslint@9.38.0)':
     dependencies:
-      eslint: 9.37.0
+      eslint: 9.38.0
       eslint-visitor-keys: 3.4.3
 
   '@eslint-community/regexpp@4.12.1': {}
 
-  '@eslint/config-array@0.21.0':
+  '@eslint/config-array@0.21.1':
     dependencies:
-      '@eslint/object-schema': 2.1.6
+      '@eslint/object-schema': 2.1.7
       debug: 4.4.3
       minimatch: 3.1.2
     transitivePeerDependencies:
       - supports-color
 
-  '@eslint/config-helpers@0.4.0':
+  '@eslint/config-helpers@0.4.1':
     dependencies:
       '@eslint/core': 0.16.0
 
@@ -3232,9 +3240,9 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
-  '@eslint/js@9.37.0': {}
+  '@eslint/js@9.38.0': {}
 
-  '@eslint/object-schema@2.1.6': {}
+  '@eslint/object-schema@2.1.7': {}
 
   '@eslint/plugin-kit@0.4.0':
     dependencies:
@@ -3280,7 +3288,7 @@ snapshots:
   '@jest/console@30.2.0':
     dependencies:
       '@jest/types': 30.2.0
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       chalk: 4.1.2
       jest-message-util: 30.2.0
       jest-util: 30.2.0
@@ -3294,14 +3302,14 @@ snapshots:
       '@jest/test-result': 30.2.0
       '@jest/transform': 30.2.0
       '@jest/types': 30.2.0
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       ansi-escapes: 4.3.2
       chalk: 4.1.2
-      ci-info: 4.3.0
+      ci-info: 4.3.1
       exit-x: 0.2.2
       graceful-fs: 4.2.11
       jest-changed-files: 30.2.0
-      jest-config: 30.2.0(@types/node@24.8.1)
+      jest-config: 30.2.0(@types/node@24.9.1)
       jest-haste-map: 30.2.0
       jest-message-util: 30.2.0
       jest-regex-util: 30.0.1
@@ -3328,7 +3336,7 @@ snapshots:
     dependencies:
       '@jest/fake-timers': 30.2.0
       '@jest/types': 30.2.0
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       jest-mock: 30.2.0
 
   '@jest/expect-utils@30.2.0':
@@ -3346,7 +3354,7 @@ snapshots:
     dependencies:
       '@jest/types': 30.2.0
       '@sinonjs/fake-timers': 13.0.5
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       jest-message-util: 30.2.0
       jest-mock: 30.2.0
       jest-util: 30.2.0
@@ -3364,7 +3372,7 @@ snapshots:
 
   '@jest/pattern@30.0.1':
     dependencies:
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       jest-regex-util: 30.0.1
 
   '@jest/reporters@30.2.0':
@@ -3375,9 +3383,9 @@ snapshots:
       '@jest/transform': 30.2.0
       '@jest/types': 30.2.0
       '@jridgewell/trace-mapping': 0.3.31
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       chalk: 4.1.2
-      collect-v8-coverage: 1.0.2
+      collect-v8-coverage: 1.0.3
       exit-x: 0.2.2
       glob: 10.4.5
       graceful-fs: 4.2.11
@@ -3417,7 +3425,7 @@ snapshots:
       '@jest/console': 30.2.0
       '@jest/types': 30.2.0
       '@types/istanbul-lib-coverage': 2.0.6
-      collect-v8-coverage: 1.0.2
+      collect-v8-coverage: 1.0.3
 
   '@jest/test-sequencer@30.2.0':
     dependencies:
@@ -3452,7 +3460,7 @@ snapshots:
       '@jest/schemas': 30.0.5
       '@types/istanbul-lib-coverage': 2.0.6
       '@types/istanbul-reports': 3.0.4
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       '@types/yargs': 17.0.33
       chalk: 4.1.2
 
@@ -3482,8 +3490,8 @@ snapshots:
 
   '@napi-rs/wasm-runtime@0.2.12':
     dependencies:
-      '@emnapi/core': 1.5.0
-      '@emnapi/runtime': 1.5.0
+      '@emnapi/core': 1.6.0
+      '@emnapi/runtime': 1.6.0
       '@tybys/wasm-util': 0.10.1
     optional: true
 
@@ -3569,95 +3577,95 @@ snapshots:
     dependencies:
       playwright: 1.56.1
 
-  '@rollup/plugin-terser@0.4.4(rollup@4.52.4)':
+  '@rollup/plugin-terser@0.4.4(rollup@4.52.5)':
     dependencies:
       serialize-javascript: 6.0.2
       smob: 1.5.0
       terser: 5.44.0
     optionalDependencies:
-      rollup: 4.52.4
+      rollup: 4.52.5
 
-  '@rollup/plugin-typescript@12.1.4(rollup@4.52.4)(tslib@2.8.1)(typescript@5.9.3)':
+  '@rollup/plugin-typescript@12.1.4(rollup@4.52.5)(tslib@2.8.1)(typescript@5.9.3)':
     dependencies:
-      '@rollup/pluginutils': 5.3.0(rollup@4.52.4)
-      resolve: 1.22.10
+      '@rollup/pluginutils': 5.3.0(rollup@4.52.5)
+      resolve: 1.22.11
       typescript: 5.9.3
     optionalDependencies:
-      rollup: 4.52.4
+      rollup: 4.52.5
       tslib: 2.8.1
 
-  '@rollup/pluginutils@5.3.0(rollup@4.52.4)':
+  '@rollup/pluginutils@5.3.0(rollup@4.52.5)':
     dependencies:
       '@types/estree': 1.0.8
       estree-walker: 2.0.2
       picomatch: 4.0.3
     optionalDependencies:
-      rollup: 4.52.4
+      rollup: 4.52.5
 
-  '@rollup/rollup-android-arm-eabi@4.52.4':
+  '@rollup/rollup-android-arm-eabi@4.52.5':
     optional: true
 
-  '@rollup/rollup-android-arm64@4.52.4':
+  '@rollup/rollup-android-arm64@4.52.5':
     optional: true
 
-  '@rollup/rollup-darwin-arm64@4.52.4':
+  '@rollup/rollup-darwin-arm64@4.52.5':
     optional: true
 
-  '@rollup/rollup-darwin-x64@4.52.4':
+  '@rollup/rollup-darwin-x64@4.52.5':
     optional: true
 
-  '@rollup/rollup-freebsd-arm64@4.52.4':
+  '@rollup/rollup-freebsd-arm64@4.52.5':
     optional: true
 
-  '@rollup/rollup-freebsd-x64@4.52.4':
+  '@rollup/rollup-freebsd-x64@4.52.5':
     optional: true
 
-  '@rollup/rollup-linux-arm-gnueabihf@4.52.4':
+  '@rollup/rollup-linux-arm-gnueabihf@4.52.5':
     optional: true
 
-  '@rollup/rollup-linux-arm-musleabihf@4.52.4':
+  '@rollup/rollup-linux-arm-musleabihf@4.52.5':
     optional: true
 
-  '@rollup/rollup-linux-arm64-gnu@4.52.4':
+  '@rollup/rollup-linux-arm64-gnu@4.52.5':
     optional: true
 
-  '@rollup/rollup-linux-arm64-musl@4.52.4':
+  '@rollup/rollup-linux-arm64-musl@4.52.5':
     optional: true
 
-  '@rollup/rollup-linux-loong64-gnu@4.52.4':
+  '@rollup/rollup-linux-loong64-gnu@4.52.5':
     optional: true
 
-  '@rollup/rollup-linux-ppc64-gnu@4.52.4':
+  '@rollup/rollup-linux-ppc64-gnu@4.52.5':
     optional: true
 
-  '@rollup/rollup-linux-riscv64-gnu@4.52.4':
+  '@rollup/rollup-linux-riscv64-gnu@4.52.5':
     optional: true
 
-  '@rollup/rollup-linux-riscv64-musl@4.52.4':
+  '@rollup/rollup-linux-riscv64-musl@4.52.5':
     optional: true
 
-  '@rollup/rollup-linux-s390x-gnu@4.52.4':
+  '@rollup/rollup-linux-s390x-gnu@4.52.5':
     optional: true
 
-  '@rollup/rollup-linux-x64-gnu@4.52.4':
+  '@rollup/rollup-linux-x64-gnu@4.52.5':
     optional: true
 
-  '@rollup/rollup-linux-x64-musl@4.52.4':
+  '@rollup/rollup-linux-x64-musl@4.52.5':
     optional: true
 
-  '@rollup/rollup-openharmony-arm64@4.52.4':
+  '@rollup/rollup-openharmony-arm64@4.52.5':
     optional: true
 
-  '@rollup/rollup-win32-arm64-msvc@4.52.4':
+  '@rollup/rollup-win32-arm64-msvc@4.52.5':
     optional: true
 
-  '@rollup/rollup-win32-ia32-msvc@4.52.4':
+  '@rollup/rollup-win32-ia32-msvc@4.52.5':
     optional: true
 
-  '@rollup/rollup-win32-x64-gnu@4.52.4':
+  '@rollup/rollup-win32-x64-gnu@4.52.5':
     optional: true
 
-  '@rollup/rollup-win32-x64-msvc@4.52.4':
+  '@rollup/rollup-win32-x64-msvc@4.52.5':
     optional: true
 
   '@sinclair/typebox@0.34.41': {}
@@ -3718,9 +3726,10 @@ snapshots:
     dependencies:
       '@babel/types': 7.28.4
 
-  '@types/chai@5.2.2':
+  '@types/chai@5.2.3':
     dependencies:
       '@types/deep-eql': 4.0.2
+      assertion-error: 2.0.1
 
   '@types/deep-eql@4.0.2': {}
 
@@ -3738,15 +3747,15 @@ snapshots:
 
   '@types/jsdom@27.0.0':
     dependencies:
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       '@types/tough-cookie': 4.0.5
       parse5: 7.3.0
 
   '@types/json-schema@7.0.15': {}
 
-  '@types/node@24.8.1':
+  '@types/node@24.9.1':
     dependencies:
-      undici-types: 7.14.0
+      undici-types: 7.16.0
 
   '@types/stack-utils@2.0.3': {}
 
@@ -3758,15 +3767,15 @@ snapshots:
     dependencies:
       '@types/yargs-parser': 21.0.3
 
-  '@typescript-eslint/eslint-plugin@8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3))(eslint@9.37.0)(typescript@5.9.3)':
+  '@typescript-eslint/eslint-plugin@8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0)(typescript@5.9.3))(eslint@9.38.0)(typescript@5.9.3)':
     dependencies:
       '@eslint-community/regexpp': 4.12.1
-      '@typescript-eslint/parser': 8.46.1(eslint@9.37.0)(typescript@5.9.3)
-      '@typescript-eslint/scope-manager': 8.46.1
-      '@typescript-eslint/type-utils': 8.46.1(eslint@9.37.0)(typescript@5.9.3)
-      '@typescript-eslint/utils': 8.46.1(eslint@9.37.0)(typescript@5.9.3)
-      '@typescript-eslint/visitor-keys': 8.46.1
-      eslint: 9.37.0
+      '@typescript-eslint/parser': 8.46.2(eslint@9.38.0)(typescript@5.9.3)
+      '@typescript-eslint/scope-manager': 8.46.2
+      '@typescript-eslint/type-utils': 8.46.2(eslint@9.38.0)(typescript@5.9.3)
+      '@typescript-eslint/utils': 8.46.2(eslint@9.38.0)(typescript@5.9.3)
+      '@typescript-eslint/visitor-keys': 8.46.2
+      eslint: 9.38.0
       graphemer: 1.4.0
       ignore: 7.0.5
       natural-compare: 1.4.0
@@ -3775,80 +3784,80 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
-  '@typescript-eslint/parser@8.46.1(eslint@9.37.0)(typescript@5.9.3)':
+  '@typescript-eslint/parser@8.46.2(eslint@9.38.0)(typescript@5.9.3)':
     dependencies:
-      '@typescript-eslint/scope-manager': 8.46.1
-      '@typescript-eslint/types': 8.46.1
-      '@typescript-eslint/typescript-estree': 8.46.1(typescript@5.9.3)
-      '@typescript-eslint/visitor-keys': 8.46.1
+      '@typescript-eslint/scope-manager': 8.46.2
+      '@typescript-eslint/types': 8.46.2
+      '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3)
+      '@typescript-eslint/visitor-keys': 8.46.2
       debug: 4.4.3
-      eslint: 9.37.0
+      eslint: 9.38.0
       typescript: 5.9.3
     transitivePeerDependencies:
       - supports-color
 
-  '@typescript-eslint/project-service@8.46.1(typescript@5.9.3)':
+  '@typescript-eslint/project-service@8.46.2(typescript@5.9.3)':
     dependencies:
-      '@typescript-eslint/tsconfig-utils': 8.46.1(typescript@5.9.3)
-      '@typescript-eslint/types': 8.46.1
+      '@typescript-eslint/tsconfig-utils': 8.46.2(typescript@5.9.3)
+      '@typescript-eslint/types': 8.46.2
       debug: 4.4.3
       typescript: 5.9.3
     transitivePeerDependencies:
       - supports-color
 
-  '@typescript-eslint/scope-manager@8.46.1':
+  '@typescript-eslint/scope-manager@8.46.2':
     dependencies:
-      '@typescript-eslint/types': 8.46.1
-      '@typescript-eslint/visitor-keys': 8.46.1
+      '@typescript-eslint/types': 8.46.2
+      '@typescript-eslint/visitor-keys': 8.46.2
 
-  '@typescript-eslint/tsconfig-utils@8.46.1(typescript@5.9.3)':
+  '@typescript-eslint/tsconfig-utils@8.46.2(typescript@5.9.3)':
     dependencies:
       typescript: 5.9.3
 
-  '@typescript-eslint/type-utils@8.46.1(eslint@9.37.0)(typescript@5.9.3)':
+  '@typescript-eslint/type-utils@8.46.2(eslint@9.38.0)(typescript@5.9.3)':
     dependencies:
-      '@typescript-eslint/types': 8.46.1
-      '@typescript-eslint/typescript-estree': 8.46.1(typescript@5.9.3)
-      '@typescript-eslint/utils': 8.46.1(eslint@9.37.0)(typescript@5.9.3)
+      '@typescript-eslint/types': 8.46.2
+      '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3)
+      '@typescript-eslint/utils': 8.46.2(eslint@9.38.0)(typescript@5.9.3)
       debug: 4.4.3
-      eslint: 9.37.0
+      eslint: 9.38.0
       ts-api-utils: 2.1.0(typescript@5.9.3)
       typescript: 5.9.3
     transitivePeerDependencies:
       - supports-color
 
-  '@typescript-eslint/types@8.46.1': {}
+  '@typescript-eslint/types@8.46.2': {}
 
-  '@typescript-eslint/typescript-estree@8.46.1(typescript@5.9.3)':
+  '@typescript-eslint/typescript-estree@8.46.2(typescript@5.9.3)':
     dependencies:
-      '@typescript-eslint/project-service': 8.46.1(typescript@5.9.3)
-      '@typescript-eslint/tsconfig-utils': 8.46.1(typescript@5.9.3)
-      '@typescript-eslint/types': 8.46.1
-      '@typescript-eslint/visitor-keys': 8.46.1
+      '@typescript-eslint/project-service': 8.46.2(typescript@5.9.3)
+      '@typescript-eslint/tsconfig-utils': 8.46.2(typescript@5.9.3)
+      '@typescript-eslint/types': 8.46.2
+      '@typescript-eslint/visitor-keys': 8.46.2
       debug: 4.4.3
       fast-glob: 3.3.3
       is-glob: 4.0.3
       minimatch: 9.0.5
-      semver: 7.7.2
+      semver: 7.7.3
       ts-api-utils: 2.1.0(typescript@5.9.3)
       typescript: 5.9.3
     transitivePeerDependencies:
       - supports-color
 
-  '@typescript-eslint/utils@8.46.1(eslint@9.37.0)(typescript@5.9.3)':
+  '@typescript-eslint/utils@8.46.2(eslint@9.38.0)(typescript@5.9.3)':
     dependencies:
-      '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0)
-      '@typescript-eslint/scope-manager': 8.46.1
-      '@typescript-eslint/types': 8.46.1
-      '@typescript-eslint/typescript-estree': 8.46.1(typescript@5.9.3)
-      eslint: 9.37.0
+      '@eslint-community/eslint-utils': 4.9.0(eslint@9.38.0)
+      '@typescript-eslint/scope-manager': 8.46.2
+      '@typescript-eslint/types': 8.46.2
+      '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3)
+      eslint: 9.38.0
       typescript: 5.9.3
     transitivePeerDependencies:
       - supports-color
 
-  '@typescript-eslint/visitor-keys@8.46.1':
+  '@typescript-eslint/visitor-keys@8.46.2':
     dependencies:
-      '@typescript-eslint/types': 8.46.1
+      '@typescript-eslint/types': 8.46.2
       eslint-visitor-keys: 4.2.1
 
   '@ungap/structured-clone@1.3.0': {}
@@ -3914,19 +3923,19 @@ snapshots:
 
   '@vitest/expect@3.2.4':
     dependencies:
-      '@types/chai': 5.2.2
+      '@types/chai': 5.2.3
       '@vitest/spy': 3.2.4
       '@vitest/utils': 3.2.4
       chai: 5.3.3
       tinyrainbow: 2.0.0
 
-  '@vitest/mocker@3.2.4(vite@7.1.10(@types/node@24.8.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))':
+  '@vitest/mocker@3.2.4(vite@7.1.11(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))':
     dependencies:
       '@vitest/spy': 3.2.4
       estree-walker: 3.0.3
       magic-string: 0.30.19
     optionalDependencies:
-      vite: 7.1.10(@types/node@24.8.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)
+      vite: 7.1.11(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)
 
   '@vitest/pretty-format@3.2.4':
     dependencies:
@@ -3936,7 +3945,7 @@ snapshots:
     dependencies:
       '@vitest/utils': 3.2.4
       pathe: 2.0.3
-      strip-literal: 3.0.0
+      strip-literal: 3.1.0
 
   '@vitest/snapshot@3.2.4':
     dependencies:
@@ -4006,15 +4015,15 @@ snapshots:
 
   autoprefixer@10.4.21(postcss@8.5.6):
     dependencies:
-      browserslist: 4.26.2
-      caniuse-lite: 1.0.30001743
+      browserslist: 4.26.3
+      caniuse-lite: 1.0.30001751
       fraction.js: 4.3.7
       normalize-range: 0.1.2
       picocolors: 1.1.1
       postcss: 8.5.6
       postcss-value-parser: 4.2.0
 
-  b4a@1.7.2: {}
+  b4a@1.7.3: {}
 
   babel-jest@30.2.0(@babel/core@7.28.4):
     dependencies:
@@ -4070,9 +4079,9 @@ snapshots:
 
   balanced-match@1.0.2: {}
 
-  bare-events@2.7.0: {}
+  bare-events@2.8.0: {}
 
-  baseline-browser-mapping@2.8.6: {}
+  baseline-browser-mapping@2.8.19: {}
 
   benchmark@2.1.4:
     dependencies:
@@ -4096,13 +4105,13 @@ snapshots:
     dependencies:
       fill-range: 7.1.1
 
-  browserslist@4.26.2:
+  browserslist@4.26.3:
     dependencies:
-      baseline-browser-mapping: 2.8.6
-      caniuse-lite: 1.0.30001743
-      electron-to-chromium: 1.5.223
-      node-releases: 2.0.21
-      update-browserslist-db: 1.1.3(browserslist@4.26.2)
+      baseline-browser-mapping: 2.8.19
+      caniuse-lite: 1.0.30001751
+      electron-to-chromium: 1.5.237
+      node-releases: 2.0.26
+      update-browserslist-db: 1.1.3(browserslist@4.26.3)
 
   bser@2.1.1:
     dependencies:
@@ -4118,7 +4127,7 @@ snapshots:
 
   camelcase@6.3.0: {}
 
-  caniuse-lite@1.0.30001743: {}
+  caniuse-lite@1.0.30001751: {}
 
   chai@5.3.3:
     dependencies:
@@ -4143,7 +4152,7 @@ snapshots:
     dependencies:
       readdirp: 4.1.2
 
-  ci-info@4.3.0: {}
+  ci-info@4.3.1: {}
 
   cjs-module-lexer@2.1.0: {}
 
@@ -4157,7 +4166,7 @@ snapshots:
 
   co@4.6.0: {}
 
-  collect-v8-coverage@1.0.2: {}
+  collect-v8-coverage@1.0.3: {}
 
   color-convert@2.0.1:
     dependencies:
@@ -4229,7 +4238,7 @@ snapshots:
 
   eastasianwidth@0.2.0: {}
 
-  electron-to-chromium@1.5.223: {}
+  electron-to-chromium@1.5.237: {}
 
   emittery@0.13.1: {}
 
@@ -4280,18 +4289,18 @@ snapshots:
 
   escape-string-regexp@4.0.0: {}
 
-  eslint-config-prettier@10.1.8(eslint@9.37.0):
+  eslint-config-prettier@10.1.8(eslint@9.38.0):
     dependencies:
-      eslint: 9.37.0
+      eslint: 9.38.0
 
-  eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.37.0))(eslint@9.37.0)(prettier@3.6.2):
+  eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.38.0))(eslint@9.38.0)(prettier@3.6.2):
     dependencies:
-      eslint: 9.37.0
+      eslint: 9.38.0
       prettier: 3.6.2
       prettier-linter-helpers: 1.0.0
       synckit: 0.11.11
     optionalDependencies:
-      eslint-config-prettier: 10.1.8(eslint@9.37.0)
+      eslint-config-prettier: 10.1.8(eslint@9.38.0)
 
   eslint-scope@8.4.0:
     dependencies:
@@ -4302,21 +4311,20 @@ snapshots:
 
   eslint-visitor-keys@4.2.1: {}
 
-  eslint@9.37.0:
+  eslint@9.38.0:
     dependencies:
-      '@eslint-community/eslint-utils': 4.9.0(eslint@9.37.0)
+      '@eslint-community/eslint-utils': 4.9.0(eslint@9.38.0)
       '@eslint-community/regexpp': 4.12.1
-      '@eslint/config-array': 0.21.0
-      '@eslint/config-helpers': 0.4.0
+      '@eslint/config-array': 0.21.1
+      '@eslint/config-helpers': 0.4.1
       '@eslint/core': 0.16.0
       '@eslint/eslintrc': 3.3.1
-      '@eslint/js': 9.37.0
+      '@eslint/js': 9.38.0
       '@eslint/plugin-kit': 0.4.0
       '@humanfs/node': 0.16.7
       '@humanwhocodes/module-importer': 1.0.1
       '@humanwhocodes/retry': 0.4.3
       '@types/estree': 1.0.8
-      '@types/json-schema': 7.0.15
       ajv: 6.12.6
       chalk: 4.1.2
       cross-spawn: 7.0.6
@@ -4372,7 +4380,9 @@ snapshots:
 
   events-universal@1.0.1:
     dependencies:
-      bare-events: 2.7.0
+      bare-events: 2.8.0
+    transitivePeerDependencies:
+      - bare-abort-controller
 
   execa@5.1.1:
     dependencies:
@@ -4479,7 +4489,7 @@ snapshots:
 
   get-stream@6.0.1: {}
 
-  get-tsconfig@4.10.1:
+  get-tsconfig@4.12.0:
     dependencies:
       resolve-pkg-maps: 1.0.0
 
@@ -4522,33 +4532,34 @@ snapshots:
 
   globals@16.4.0: {}
 
-  google-closure-compiler-java@20251013.0.0: {}
+  google-closure-compiler-java@20251019.0.0: {}
 
-  google-closure-compiler-linux-arm64@20251013.0.0:
+  google-closure-compiler-linux-arm64@20251019.0.0:
     optional: true
 
-  google-closure-compiler-linux@20251013.0.0:
+  google-closure-compiler-linux@20251019.0.0:
     optional: true
 
-  google-closure-compiler-macos@20251013.0.0:
+  google-closure-compiler-macos@20251019.0.0:
     optional: true
 
-  google-closure-compiler-windows@20251013.0.0:
+  google-closure-compiler-windows@20251019.0.0:
     optional: true
 
-  google-closure-compiler@20251013.0.0:
+  google-closure-compiler@20251019.0.0:
     dependencies:
       chalk: 5.6.2
-      google-closure-compiler-java: 20251013.0.0
+      google-closure-compiler-java: 20251019.0.0
       minimist: 1.2.8
       vinyl: 3.0.1
       vinyl-sourcemaps-apply: 0.2.1
     optionalDependencies:
-      google-closure-compiler-linux: 20251013.0.0
-      google-closure-compiler-linux-arm64: 20251013.0.0
-      google-closure-compiler-macos: 20251013.0.0
-      google-closure-compiler-windows: 20251013.0.0
+      google-closure-compiler-linux: 20251019.0.0
+      google-closure-compiler-linux-arm64: 20251019.0.0
+      google-closure-compiler-macos: 20251019.0.0
+      google-closure-compiler-windows: 20251019.0.0
     transitivePeerDependencies:
+      - bare-abort-controller
       - react-native-b4a
 
   graceful-fs@4.2.11: {}
@@ -4593,7 +4604,7 @@ snapshots:
 
   ignore@7.0.5: {}
 
-  immutable@5.1.3: {}
+  immutable@5.1.4: {}
 
   import-fresh@3.3.1:
     dependencies:
@@ -4648,7 +4659,7 @@ snapshots:
       '@babel/parser': 7.28.4
       '@istanbuljs/schema': 0.1.3
       istanbul-lib-coverage: 3.2.2
-      semver: 7.7.2
+      semver: 7.7.3
     transitivePeerDependencies:
       - supports-color
 
@@ -4693,7 +4704,7 @@ snapshots:
       '@jest/expect': 30.2.0
       '@jest/test-result': 30.2.0
       '@jest/types': 30.2.0
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       chalk: 4.1.2
       co: 4.6.0
       dedent: 1.7.0
@@ -4713,7 +4724,7 @@ snapshots:
       - babel-plugin-macros
       - supports-color
 
-  jest-cli@30.2.0(@types/node@24.8.1):
+  jest-cli@30.2.0(@types/node@24.9.1):
     dependencies:
       '@jest/core': 30.2.0
       '@jest/test-result': 30.2.0
@@ -4721,7 +4732,7 @@ snapshots:
       chalk: 4.1.2
       exit-x: 0.2.2
       import-local: 3.2.0
-      jest-config: 30.2.0(@types/node@24.8.1)
+      jest-config: 30.2.0(@types/node@24.9.1)
       jest-util: 30.2.0
       jest-validate: 30.2.0
       yargs: 17.7.2
@@ -4732,7 +4743,7 @@ snapshots:
       - supports-color
       - ts-node
 
-  jest-config@30.2.0(@types/node@24.8.1):
+  jest-config@30.2.0(@types/node@24.9.1):
     dependencies:
       '@babel/core': 7.28.4
       '@jest/get-type': 30.1.0
@@ -4741,7 +4752,7 @@ snapshots:
       '@jest/types': 30.2.0
       babel-jest: 30.2.0(@babel/core@7.28.4)
       chalk: 4.1.2
-      ci-info: 4.3.0
+      ci-info: 4.3.1
       deepmerge: 4.3.1
       glob: 10.4.5
       graceful-fs: 4.2.11
@@ -4759,7 +4770,7 @@ snapshots:
       slash: 3.0.0
       strip-json-comments: 3.1.1
     optionalDependencies:
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
     transitivePeerDependencies:
       - babel-plugin-macros
       - supports-color
@@ -4788,7 +4799,7 @@ snapshots:
       '@jest/environment': 30.2.0
       '@jest/fake-timers': 30.2.0
       '@jest/types': 30.2.0
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       jest-mock: 30.2.0
       jest-util: 30.2.0
       jest-validate: 30.2.0
@@ -4796,7 +4807,7 @@ snapshots:
   jest-haste-map@30.2.0:
     dependencies:
       '@jest/types': 30.2.0
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       anymatch: 3.1.3
       fb-watchman: 2.0.2
       graceful-fs: 4.2.11
@@ -4835,7 +4846,7 @@ snapshots:
   jest-mock@30.2.0:
     dependencies:
       '@jest/types': 30.2.0
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       jest-util: 30.2.0
 
   jest-pnp-resolver@1.2.3(jest-resolve@30.2.0):
@@ -4869,7 +4880,7 @@ snapshots:
       '@jest/test-result': 30.2.0
       '@jest/transform': 30.2.0
       '@jest/types': 30.2.0
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       chalk: 4.1.2
       emittery: 0.13.1
       exit-x: 0.2.2
@@ -4898,10 +4909,10 @@ snapshots:
       '@jest/test-result': 30.2.0
       '@jest/transform': 30.2.0
       '@jest/types': 30.2.0
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       chalk: 4.1.2
       cjs-module-lexer: 2.1.0
-      collect-v8-coverage: 1.0.2
+      collect-v8-coverage: 1.0.3
       glob: 10.4.5
       graceful-fs: 4.2.11
       jest-haste-map: 30.2.0
@@ -4937,7 +4948,7 @@ snapshots:
       jest-message-util: 30.2.0
       jest-util: 30.2.0
       pretty-format: 30.2.0
-      semver: 7.7.2
+      semver: 7.7.3
       synckit: 0.11.11
     transitivePeerDependencies:
       - supports-color
@@ -4945,9 +4956,9 @@ snapshots:
   jest-util@30.2.0:
     dependencies:
       '@jest/types': 30.2.0
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       chalk: 4.1.2
-      ci-info: 4.3.0
+      ci-info: 4.3.1
       graceful-fs: 4.2.11
       picomatch: 4.0.3
 
@@ -4964,7 +4975,7 @@ snapshots:
     dependencies:
       '@jest/test-result': 30.2.0
       '@jest/types': 30.2.0
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       ansi-escapes: 4.3.2
       chalk: 4.1.2
       emittery: 0.13.1
@@ -4973,18 +4984,18 @@ snapshots:
 
   jest-worker@30.2.0:
     dependencies:
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       '@ungap/structured-clone': 1.3.0
       jest-util: 30.2.0
       merge-stream: 2.0.0
       supports-color: 8.1.1
 
-  jest@30.2.0(@types/node@24.8.1):
+  jest@30.2.0(@types/node@24.9.1):
     dependencies:
       '@jest/core': 30.2.0
       '@jest/types': 30.2.0
       import-local: 3.2.0
-      jest-cli: 30.2.0(@types/node@24.8.1)
+      jest-cli: 30.2.0(@types/node@24.9.1)
     transitivePeerDependencies:
       - '@types/node'
       - babel-plugin-macros
@@ -5005,9 +5016,9 @@ snapshots:
     dependencies:
       argparse: 2.0.1
 
-  jsdom@27.0.0(postcss@8.5.6):
+  jsdom@27.0.1(postcss@8.5.6):
     dependencies:
-      '@asamuzakjp/dom-selector': 6.5.6
+      '@asamuzakjp/dom-selector': 6.7.2
       cssstyle: 5.3.1(postcss@8.5.6)
       data-urls: 6.0.0
       decimal.js: 10.6.0
@@ -5015,7 +5026,7 @@ snapshots:
       http-proxy-agent: 7.0.2
       https-proxy-agent: 7.0.6
       is-potential-custom-element-name: 1.0.1
-      parse5: 7.3.0
+      parse5: 8.0.0
       rrweb-cssom: 0.8.0
       saxes: 6.0.0
       symbol-tree: 3.2.4
@@ -5088,7 +5099,7 @@ snapshots:
 
   make-dir@4.0.0:
     dependencies:
-      semver: 7.7.2
+      semver: 7.7.3
 
   makeerror@1.0.12:
     dependencies:
@@ -5129,7 +5140,7 @@ snapshots:
 
   nanoid@3.3.11: {}
 
-  napi-postinstall@0.3.3: {}
+  napi-postinstall@0.3.4: {}
 
   natural-compare@1.4.0: {}
 
@@ -5138,7 +5149,7 @@ snapshots:
 
   node-int64@0.4.0: {}
 
-  node-releases@2.0.21: {}
+  node-releases@2.0.26: {}
 
   normalize-path@3.0.0: {}
 
@@ -5200,6 +5211,10 @@ snapshots:
     dependencies:
       entities: 6.0.1
 
+  parse5@8.0.0:
+    dependencies:
+      entities: 6.0.1
+
   path-exists@4.0.0: {}
 
   path-is-absolute@1.0.1: {}
@@ -5311,7 +5326,7 @@ snapshots:
 
   resolve-pkg-maps@1.0.0: {}
 
-  resolve@1.22.10:
+  resolve@1.22.11:
     dependencies:
       is-core-module: 2.16.1
       path-parse: 1.0.7
@@ -5332,32 +5347,32 @@ snapshots:
     dependencies:
       estree-walker: 0.6.1
 
-  rollup@4.52.4:
+  rollup@4.52.5:
     dependencies:
       '@types/estree': 1.0.8
     optionalDependencies:
-      '@rollup/rollup-android-arm-eabi': 4.52.4
-      '@rollup/rollup-android-arm64': 4.52.4
-      '@rollup/rollup-darwin-arm64': 4.52.4
-      '@rollup/rollup-darwin-x64': 4.52.4
-      '@rollup/rollup-freebsd-arm64': 4.52.4
-      '@rollup/rollup-freebsd-x64': 4.52.4
-      '@rollup/rollup-linux-arm-gnueabihf': 4.52.4
-      '@rollup/rollup-linux-arm-musleabihf': 4.52.4
-      '@rollup/rollup-linux-arm64-gnu': 4.52.4
-      '@rollup/rollup-linux-arm64-musl': 4.52.4
-      '@rollup/rollup-linux-loong64-gnu': 4.52.4
-      '@rollup/rollup-linux-ppc64-gnu': 4.52.4
-      '@rollup/rollup-linux-riscv64-gnu': 4.52.4
-      '@rollup/rollup-linux-riscv64-musl': 4.52.4
-      '@rollup/rollup-linux-s390x-gnu': 4.52.4
-      '@rollup/rollup-linux-x64-gnu': 4.52.4
-      '@rollup/rollup-linux-x64-musl': 4.52.4
-      '@rollup/rollup-openharmony-arm64': 4.52.4
-      '@rollup/rollup-win32-arm64-msvc': 4.52.4
-      '@rollup/rollup-win32-ia32-msvc': 4.52.4
-      '@rollup/rollup-win32-x64-gnu': 4.52.4
-      '@rollup/rollup-win32-x64-msvc': 4.52.4
+      '@rollup/rollup-android-arm-eabi': 4.52.5
+      '@rollup/rollup-android-arm64': 4.52.5
+      '@rollup/rollup-darwin-arm64': 4.52.5
+      '@rollup/rollup-darwin-x64': 4.52.5
+      '@rollup/rollup-freebsd-arm64': 4.52.5
+      '@rollup/rollup-freebsd-x64': 4.52.5
+      '@rollup/rollup-linux-arm-gnueabihf': 4.52.5
+      '@rollup/rollup-linux-arm-musleabihf': 4.52.5
+      '@rollup/rollup-linux-arm64-gnu': 4.52.5
+      '@rollup/rollup-linux-arm64-musl': 4.52.5
+      '@rollup/rollup-linux-loong64-gnu': 4.52.5
+      '@rollup/rollup-linux-ppc64-gnu': 4.52.5
+      '@rollup/rollup-linux-riscv64-gnu': 4.52.5
+      '@rollup/rollup-linux-riscv64-musl': 4.52.5
+      '@rollup/rollup-linux-s390x-gnu': 4.52.5
+      '@rollup/rollup-linux-x64-gnu': 4.52.5
+      '@rollup/rollup-linux-x64-musl': 4.52.5
+      '@rollup/rollup-openharmony-arm64': 4.52.5
+      '@rollup/rollup-win32-arm64-msvc': 4.52.5
+      '@rollup/rollup-win32-ia32-msvc': 4.52.5
+      '@rollup/rollup-win32-x64-gnu': 4.52.5
+      '@rollup/rollup-win32-x64-msvc': 4.52.5
       fsevents: 2.3.3
 
   rrweb-cssom@0.8.0: {}
@@ -5373,7 +5388,7 @@ snapshots:
   sass@1.93.2:
     dependencies:
       chokidar: 4.0.3
-      immutable: 5.1.3
+      immutable: 5.1.4
       source-map-js: 1.2.1
     optionalDependencies:
       '@parcel/watcher': 2.5.1
@@ -5384,7 +5399,7 @@ snapshots:
 
   semver@6.3.1: {}
 
-  semver@7.7.2: {}
+  semver@7.7.3: {}
 
   serialize-javascript@6.0.2:
     dependencies:
@@ -5430,7 +5445,7 @@ snapshots:
 
   stackback@0.0.2: {}
 
-  std-env@3.9.0: {}
+  std-env@3.10.0: {}
 
   streamx@2.23.0:
     dependencies:
@@ -5438,6 +5453,7 @@ snapshots:
       fast-fifo: 1.3.2
       text-decoder: 1.2.3
     transitivePeerDependencies:
+      - bare-abort-controller
       - react-native-b4a
 
   string-length@4.0.2:
@@ -5475,7 +5491,7 @@ snapshots:
 
   strip-json-comments@3.1.1: {}
 
-  strip-literal@3.0.0:
+  strip-literal@3.1.0:
     dependencies:
       js-tokens: 9.0.1
 
@@ -5499,6 +5515,7 @@ snapshots:
     dependencies:
       streamx: 2.23.0
     transitivePeerDependencies:
+      - bare-abort-controller
       - react-native-b4a
 
   terser@5.44.0:
@@ -5516,7 +5533,7 @@ snapshots:
 
   text-decoder@1.2.3:
     dependencies:
-      b4a: 1.7.2
+      b4a: 1.7.3
     transitivePeerDependencies:
       - react-native-b4a
 
@@ -5535,11 +5552,11 @@ snapshots:
 
   tinyspy@4.0.4: {}
 
-  tldts-core@7.0.16: {}
+  tldts-core@7.0.17: {}
 
-  tldts@7.0.16:
+  tldts@7.0.17:
     dependencies:
-      tldts-core: 7.0.16
+      tldts-core: 7.0.17
 
   tmpl@1.0.5: {}
 
@@ -5549,7 +5566,7 @@ snapshots:
 
   tough-cookie@6.0.0:
     dependencies:
-      tldts: 7.0.16
+      tldts: 7.0.17
 
   tr46@6.0.0:
     dependencies:
@@ -5564,7 +5581,7 @@ snapshots:
   tsx@4.20.6:
     dependencies:
       esbuild: 0.25.11
-      get-tsconfig: 4.10.1
+      get-tsconfig: 4.12.0
     optionalDependencies:
       fsevents: 2.3.3
 
@@ -5578,11 +5595,11 @@ snapshots:
 
   typescript@5.9.3: {}
 
-  undici-types@7.14.0: {}
+  undici-types@7.16.0: {}
 
   unrs-resolver@1.11.1:
     dependencies:
-      napi-postinstall: 0.3.3
+      napi-postinstall: 0.3.4
     optionalDependencies:
       '@unrs/resolver-binding-android-arm-eabi': 1.11.1
       '@unrs/resolver-binding-android-arm64': 1.11.1
@@ -5604,9 +5621,9 @@ snapshots:
       '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1
       '@unrs/resolver-binding-win32-x64-msvc': 1.11.1
 
-  update-browserslist-db@1.1.3(browserslist@4.26.2):
+  update-browserslist-db@1.1.3(browserslist@4.26.3):
     dependencies:
-      browserslist: 4.26.2
+      browserslist: 4.26.3
       escalade: 3.2.0
       picocolors: 1.1.1
 
@@ -5631,15 +5648,16 @@ snapshots:
       replace-ext: 2.0.0
       teex: 1.0.1
     transitivePeerDependencies:
+      - bare-abort-controller
       - react-native-b4a
 
-  vite-node@3.2.4(@types/node@24.8.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6):
+  vite-node@3.2.4(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6):
     dependencies:
       cac: 6.7.14
       debug: 4.4.3
       es-module-lexer: 1.7.0
       pathe: 2.0.3
-      vite: 7.1.10(@types/node@24.8.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)
+      vite: 7.1.11(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)
     transitivePeerDependencies:
       - '@types/node'
       - jiti
@@ -5654,26 +5672,26 @@ snapshots:
       - tsx
       - yaml
 
-  vite@7.1.10(@types/node@24.8.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6):
+  vite@7.1.11(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6):
     dependencies:
       esbuild: 0.25.11
       fdir: 6.5.0(picomatch@4.0.3)
       picomatch: 4.0.3
       postcss: 8.5.6
-      rollup: 4.52.4
+      rollup: 4.52.5
       tinyglobby: 0.2.15
     optionalDependencies:
-      '@types/node': 24.8.1
+      '@types/node': 24.9.1
       fsevents: 2.3.3
       sass: 1.93.2
       terser: 5.44.0
       tsx: 4.20.6
 
-  vitest@3.2.4(@types/node@24.8.1)(jsdom@27.0.0(postcss@8.5.6))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6):
+  vitest@3.2.4(@types/node@24.9.1)(jsdom@27.0.1(postcss@8.5.6))(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6):
     dependencies:
-      '@types/chai': 5.2.2
+      '@types/chai': 5.2.3
       '@vitest/expect': 3.2.4
-      '@vitest/mocker': 3.2.4(vite@7.1.10(@types/node@24.8.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))
+      '@vitest/mocker': 3.2.4(vite@7.1.11(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6))
       '@vitest/pretty-format': 3.2.4
       '@vitest/runner': 3.2.4
       '@vitest/snapshot': 3.2.4
@@ -5685,18 +5703,18 @@ snapshots:
       magic-string: 0.30.19
       pathe: 2.0.3
       picomatch: 4.0.3
-      std-env: 3.9.0
+      std-env: 3.10.0
       tinybench: 2.9.0
       tinyexec: 0.3.2
       tinyglobby: 0.2.15
       tinypool: 1.1.1
       tinyrainbow: 2.0.0
-      vite: 7.1.10(@types/node@24.8.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)
-      vite-node: 3.2.4(@types/node@24.8.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)
+      vite: 7.1.11(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)
+      vite-node: 3.2.4(@types/node@24.9.1)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)
       why-is-node-running: 2.3.0
     optionalDependencies:
-      '@types/node': 24.8.1
-      jsdom: 27.0.0(postcss@8.5.6)
+      '@types/node': 24.9.1
+      jsdom: 27.0.1(postcss@8.5.6)
     transitivePeerDependencies:
       - jiti
       - less
diff --git a/src/enhanceSortableAccessibility.ts b/src/a11y/enhanceSortableAccessibility.ts
similarity index 65%
rename from src/enhanceSortableAccessibility.ts
rename to src/a11y/enhanceSortableAccessibility.ts
index 79b4858..7f5b7d4 100644
--- a/src/enhanceSortableAccessibility.ts
+++ b/src/a11y/enhanceSortableAccessibility.ts
@@ -1,4 +1,7 @@
 // src/enhanceSortableAccessibility.ts
+
+import { updateSortableAriaLabel } from './updateSortableAriaLabel'
+
 /**
  * This is a "plugin" for the sortable package:
  * https://www.npmjs.com/package/sortable-tablesort
@@ -8,30 +11,6 @@
  * @param tables - A list of HTML table elements to enhance.
  */
 export function 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.
-   * @param default_direction - The default sort direction for the table.
-   */
-  function updateAriaLabel(element: HTMLTableCellElement, default_direction = '') {
-    // Generate aria-label based on header content
-    const header_text = element.textContent || 'element'
-
-    const current_direction = element.getAttribute('aria-sort') ?? ''
-    let new_direction = 'descending'
-
-    if (current_direction === 'descending' || (default_direction && current_direction !== 'ascending')) {
-      new_direction = 'ascending'
-    }
-
-    const aria_label = `Click to sort table by ${header_text} in ${new_direction} order`
-
-    element.setAttribute('aria-label', aria_label)
-
-    // REMEMBER TO COMMENT OUT WHEN NOT TESTING!!
-    // element.setAttribute('title', aria_label)
-  }
-
   /**
    * 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.
@@ -45,7 +24,7 @@ export function enhanceSortableAccessibility(tables: NodeListOf {
-    const default_direction = table.classList.contains('asc') ? 'ascending' : ''
+    const default_direction = table.classList.contains('asc') ? 'ascending' : 'descending'
     const headers = table.querySelectorAll('th')
 
     // Iterate over each header cell in the table
@@ -55,12 +34,18 @@ export function enhanceSortableAccessibility(tables: NodeListOf {
-        updateAriaLabel(element, default_direction)
+      if (element.classList.contains('no-sort')) {
+        updateSortableAriaLabel(element, 'no-sort')
+        return
       }
 
       // Add tabindex attribute and generate initial aria-label attribute
       element.setAttribute('tabindex', '0')
+
+      const update = () => {
+        updateSortableAriaLabel(element, default_direction)
+      }
+
       update()
 
       // Attach click event listener to update aria-label attribute
diff --git a/src/a11y/updateSortableAriaLabel.ts b/src/a11y/updateSortableAriaLabel.ts
new file mode 100644
index 0000000..887f44b
--- /dev/null
+++ b/src/a11y/updateSortableAriaLabel.ts
@@ -0,0 +1,30 @@
+/**
+ * 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.
+ */
+
+type Direction = 'ascending' | 'descending' | 'no-sort'
+export function updateSortableAriaLabel(element: HTMLTableCellElement, default_direction: Direction) {
+  // Generate aria-label based on header content
+  const header_text = element.textContent || 'element'
+
+  let aria_label = `Column ${header_text} is not sortable`
+
+  if (default_direction !== 'no-sort') {
+    const current_direction = element.getAttribute('aria-sort')
+    let new_direction = default_direction
+
+    if (current_direction) {
+      new_direction = current_direction === 'descending' ? 'ascending' : 'descending'
+    }
+
+    aria_label = `Click to sort table by ${header_text} in ${new_direction} order`
+  }
+
+  element.setAttribute('aria-label', aria_label)
+
+  // REMEMBER TO COMMENT OUT WHEN NOT TESTING!!
+  element.setAttribute('title', aria_label)
+  console.log('🚀 comment me out')
+}
diff --git a/src/observeSortable.ts b/src/observeSortable.ts
index f939a4d..acb77fd 100644
--- a/src/observeSortable.ts
+++ b/src/observeSortable.ts
@@ -1,5 +1,5 @@
 // src/observeSortable.ts
-import { enhanceSortableAccessibility } from './enhanceSortableAccessibility'
+import { enhanceSortableAccessibility } from './a11y/enhanceSortableAccessibility'
 import { sortSortable } from './sortSortable'
 
 export function observeSortable() {
diff --git a/src/sortable.a11y.ts b/src/sortable.a11y.ts
index a4412a8..902bb07 100644
--- a/src/sortable.a11y.ts
+++ b/src/sortable.a11y.ts
@@ -1,5 +1,5 @@
 // src/sortable.a11y.ts
-import { enhanceSortableAccessibility } from './enhanceSortableAccessibility'
+import { enhanceSortableAccessibility } from './a11y/enhanceSortableAccessibility'
 
 // Attach function to DOMContentLoaded event to execute when page is loaded
 document.addEventListener('DOMContentLoaded', () => {
diff --git a/src/sortable.auto.ts b/src/sortable.auto.ts
index 9827e82..c11a31f 100644
--- a/src/sortable.auto.ts
+++ b/src/sortable.auto.ts
@@ -1,6 +1,6 @@
 // src/sortable.auto.ts
 /**
- * sortable v4.1.5
+ * sortable v4.1.6
  *
  * https://www.npmjs.com/package/sortable-tablesort
  * https://github.com/tofsjonas/sortable
diff --git a/src/sortable.ts b/src/sortable.ts
index 972ad9c..15f5c6d 100644
--- a/src/sortable.ts
+++ b/src/sortable.ts
@@ -1,6 +1,6 @@
 // src/sortable.ts
 /**
- * sortable v4.1.5
+ * sortable v4.1.6
  *
  * https://www.npmjs.com/package/sortable-tablesort
  * https://github.com/tofsjonas/sortable
diff --git a/vite.config.js b/vite.config.js
index 8a61b55..21f34b4 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -26,7 +26,7 @@ const modularConfig = defineConfig({
         sortableEventListener: resolve(__dirname, 'src/sortableEventListener.ts'),
         sortable: resolve(__dirname, 'src/sortable.ts'),
         observeSortable: resolve(__dirname, 'src/observeSortable.ts'),
-        enhanceSortableAccessibility: resolve(__dirname, 'src/enhanceSortableAccessibility.ts'),
+        enhanceSortableAccessibility: resolve(__dirname, 'src/a11y/enhanceSortableAccessibility.ts'),
       },
       formats: ['es'],
     },