@stonecrop/utilities 0.42.0 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/utilities.d.ts +55 -0
- package/dist/utilities.js +141 -11
- package/dist/utilities.js.map +1 -1
- package/package.json +3 -3
package/dist/utilities.d.ts
CHANGED
|
@@ -14,12 +14,59 @@ import { Temporal } from 'temporal-polyfill';
|
|
|
14
14
|
*/
|
|
15
15
|
export declare function compareSemver(a: string, b: string): number;
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* What a masked currency amount field may hold while it is typed in: digits and grouping marks, then at most one
|
|
19
|
+
* decimal point followed by digits.
|
|
20
|
+
* @param locale - The browser's own when omitted
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
export declare function currencyAmountEntryPattern(currencyId: string | undefined, locale?: string): RegExp;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Fraction digits for a currency in amount inputs (e.g. JPY → 0).
|
|
27
|
+
* @public
|
|
28
|
+
*/
|
|
29
|
+
export declare function currencyInputFractionDigits(currencyId: string | undefined): number;
|
|
30
|
+
|
|
31
|
+
declare type CurrencyLike = {
|
|
32
|
+
id?: string | number;
|
|
33
|
+
symbol?: string;
|
|
34
|
+
displayText?: string;
|
|
35
|
+
};
|
|
36
|
+
|
|
17
37
|
/**
|
|
18
38
|
* Default keypress handlers for keyboard navigation
|
|
19
39
|
* @public
|
|
20
40
|
*/
|
|
21
41
|
export declare const defaultKeypressHandlers: KeypressHandlers;
|
|
22
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Format a currency amount for display (forms, table cells). Uses `Intl` when `currency.id` is a
|
|
45
|
+
* valid ISO code; otherwise falls back to symbol, display text, or id.
|
|
46
|
+
* @public
|
|
47
|
+
*/
|
|
48
|
+
export declare function formatCurrencyAmount(amount: number | null | undefined, currency: CurrencyLike | undefined): string;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Format a numeric amount for display in a currency amount field (no currency symbol). The currency
|
|
52
|
+
* sets the decimals; the separators are the locale's, as in the table cell.
|
|
53
|
+
* @param locale - The browser's own when omitted
|
|
54
|
+
* @public
|
|
55
|
+
*/
|
|
56
|
+
export declare function formatCurrencyAmountInput(amount: number | null | undefined, currencyId: string | undefined, locale?: string): string;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Render a composite currency value for table cells.
|
|
60
|
+
* @public
|
|
61
|
+
*/
|
|
62
|
+
export declare function formatCurrencyCell(value: unknown): string;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Render a composite quantity value for table cells. Omits the UOM when it matches `stockUom`.
|
|
66
|
+
* @public
|
|
67
|
+
*/
|
|
68
|
+
export declare function formatQuantityCell(value: unknown): string;
|
|
69
|
+
|
|
23
70
|
/**
|
|
24
71
|
* Reads a `YYYY-MM-DD` day. Anything that is not a real day written exactly that way reads as no day.
|
|
25
72
|
*
|
|
@@ -72,6 +119,14 @@ export declare type KeypressHandlers = {
|
|
|
72
119
|
[key: string]: (ev: KeyboardEvent) => any;
|
|
73
120
|
};
|
|
74
121
|
|
|
122
|
+
/**
|
|
123
|
+
* Parse user-entered text in a currency amount field back to a number, read with the separators the
|
|
124
|
+
* field writes it with.
|
|
125
|
+
* @param locale - The browser's own when omitted
|
|
126
|
+
* @public
|
|
127
|
+
*/
|
|
128
|
+
export declare function parseCurrencyAmountInput(text: string, locale?: string): number | null;
|
|
129
|
+
|
|
75
130
|
/**
|
|
76
131
|
* Keyboard navigation composable
|
|
77
132
|
* @param options - Keyboard navigation options
|
package/dist/utilities.js
CHANGED
|
@@ -51,9 +51,16 @@ var isVisible = (element) => {
|
|
|
51
51
|
var isFocusable = (element) => {
|
|
52
52
|
return element.tabIndex >= 0;
|
|
53
53
|
};
|
|
54
|
+
/** When focus is on a control inside a cell, grid navigation still uses the owning `<td>`. */
|
|
55
|
+
var resolveNavCell = (element) => {
|
|
56
|
+
if (element instanceof HTMLTableCellElement) return element;
|
|
57
|
+
const cell = element.closest("td, th");
|
|
58
|
+
if (cell instanceof HTMLTableCellElement) return cell;
|
|
59
|
+
return element;
|
|
60
|
+
};
|
|
54
61
|
var getUpCell = (event) => {
|
|
55
62
|
if (!(event.target instanceof HTMLElement)) return void 0;
|
|
56
|
-
return getUpCellEl(event.target);
|
|
63
|
+
return getUpCellEl(resolveNavCell(event.target));
|
|
57
64
|
};
|
|
58
65
|
var getUpCellEl = (element) => {
|
|
59
66
|
let $upCell;
|
|
@@ -72,7 +79,7 @@ var getUpCellEl = (element) => {
|
|
|
72
79
|
};
|
|
73
80
|
var getTopCell = (event) => {
|
|
74
81
|
if (!(event.target instanceof HTMLElement)) return void 0;
|
|
75
|
-
const $target = event.target;
|
|
82
|
+
const $target = resolveNavCell(event.target);
|
|
76
83
|
let $topCell;
|
|
77
84
|
if ($target instanceof HTMLTableCellElement) {
|
|
78
85
|
const $table = $target.parentElement?.parentElement;
|
|
@@ -92,7 +99,7 @@ var getTopCell = (event) => {
|
|
|
92
99
|
};
|
|
93
100
|
var getDownCell = (event) => {
|
|
94
101
|
if (!(event.target instanceof HTMLElement)) return void 0;
|
|
95
|
-
return getDownCellEl(event.target);
|
|
102
|
+
return getDownCellEl(resolveNavCell(event.target));
|
|
96
103
|
};
|
|
97
104
|
var getDownCellEl = (element) => {
|
|
98
105
|
let $downCell;
|
|
@@ -111,7 +118,7 @@ var getDownCellEl = (element) => {
|
|
|
111
118
|
};
|
|
112
119
|
var getBottomCell = (event) => {
|
|
113
120
|
if (!(event.target instanceof HTMLElement)) return void 0;
|
|
114
|
-
const $target = event.target;
|
|
121
|
+
const $target = resolveNavCell(event.target);
|
|
115
122
|
let $bottomCell;
|
|
116
123
|
if ($target instanceof HTMLTableCellElement) {
|
|
117
124
|
const $table = $target.parentElement?.parentElement;
|
|
@@ -131,7 +138,7 @@ var getBottomCell = (event) => {
|
|
|
131
138
|
};
|
|
132
139
|
var getPrevCell = (event) => {
|
|
133
140
|
if (!(event.target instanceof HTMLElement)) return void 0;
|
|
134
|
-
return getPrevCellEl(event.target);
|
|
141
|
+
return getPrevCellEl(resolveNavCell(event.target));
|
|
135
142
|
};
|
|
136
143
|
var getPrevCellEl = (element) => {
|
|
137
144
|
let $prevCell;
|
|
@@ -146,7 +153,7 @@ var getPrevCellEl = (element) => {
|
|
|
146
153
|
};
|
|
147
154
|
var getNextCell = (event) => {
|
|
148
155
|
if (!(event.target instanceof HTMLElement)) return void 0;
|
|
149
|
-
return getNextCellEl(event.target);
|
|
156
|
+
return getNextCellEl(resolveNavCell(event.target));
|
|
150
157
|
};
|
|
151
158
|
var getNextCellEl = (element) => {
|
|
152
159
|
let $nextCell;
|
|
@@ -161,14 +168,14 @@ var getNextCellEl = (element) => {
|
|
|
161
168
|
};
|
|
162
169
|
var getFirstCell = (event) => {
|
|
163
170
|
if (!(event.target instanceof HTMLElement)) return void 0;
|
|
164
|
-
const $firstEl = event.target.parentElement?.firstElementChild;
|
|
171
|
+
const $firstEl = resolveNavCell(event.target).parentElement?.firstElementChild;
|
|
165
172
|
const $firstCell = $firstEl instanceof HTMLElement ? $firstEl : null;
|
|
166
173
|
if ($firstCell && (!isFocusable($firstCell) || !isVisible($firstCell))) return getNextCellEl($firstCell);
|
|
167
174
|
return $firstCell;
|
|
168
175
|
};
|
|
169
176
|
var getLastCell = (event) => {
|
|
170
177
|
if (!(event.target instanceof HTMLElement)) return void 0;
|
|
171
|
-
const $lastEl = event.target.parentElement?.lastElementChild;
|
|
178
|
+
const $lastEl = resolveNavCell(event.target).parentElement?.lastElementChild;
|
|
172
179
|
const $lastCell = $lastEl instanceof HTMLElement ? $lastEl : null;
|
|
173
180
|
if ($lastCell && (!isFocusable($lastCell) || !isVisible($lastCell))) return getPrevCellEl($lastCell);
|
|
174
181
|
return $lastCell;
|
|
@@ -260,7 +267,7 @@ var defaultKeypressHandlers = {
|
|
|
260
267
|
},
|
|
261
268
|
"keydown.enter": (event) => {
|
|
262
269
|
if (!(event.target instanceof HTMLElement)) return;
|
|
263
|
-
if (event.target instanceof HTMLTableCellElement) {
|
|
270
|
+
if (resolveNavCell(event.target) instanceof HTMLTableCellElement) {
|
|
264
271
|
event.preventDefault();
|
|
265
272
|
event.stopPropagation();
|
|
266
273
|
const $downCell = getDownCell(event);
|
|
@@ -269,7 +276,7 @@ var defaultKeypressHandlers = {
|
|
|
269
276
|
},
|
|
270
277
|
"keydown.shift.enter": (event) => {
|
|
271
278
|
if (!(event.target instanceof HTMLElement)) return;
|
|
272
|
-
if (event.target instanceof HTMLTableCellElement) {
|
|
279
|
+
if (resolveNavCell(event.target) instanceof HTMLTableCellElement) {
|
|
273
280
|
event.preventDefault();
|
|
274
281
|
event.stopPropagation();
|
|
275
282
|
const $upCell = getUpCell(event);
|
|
@@ -495,6 +502,129 @@ function compareSemver(a, b) {
|
|
|
495
502
|
return comparePrereleases(left[4], right[4]);
|
|
496
503
|
}
|
|
497
504
|
//#endregion
|
|
505
|
+
//#region src/currencyAmountFormat.ts
|
|
506
|
+
/**
|
|
507
|
+
* Fraction digits for a currency in amount inputs (e.g. JPY → 0).
|
|
508
|
+
* @public
|
|
509
|
+
*/
|
|
510
|
+
function currencyInputFractionDigits(currencyId) {
|
|
511
|
+
const id = currencyId?.toUpperCase() ?? "";
|
|
512
|
+
if (!id) return 2;
|
|
513
|
+
try {
|
|
514
|
+
return new Intl.NumberFormat("en-US", {
|
|
515
|
+
style: "currency",
|
|
516
|
+
currency: id
|
|
517
|
+
}).resolvedOptions().maximumFractionDigits ?? 2;
|
|
518
|
+
} catch {
|
|
519
|
+
return 2;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
function separatorsForLocale(locale) {
|
|
523
|
+
const parts = new Intl.NumberFormat(locale).formatToParts(1234567.89);
|
|
524
|
+
return {
|
|
525
|
+
group: parts.find((part) => part.type === "group")?.value ?? ",",
|
|
526
|
+
decimal: parts.find((part) => part.type === "decimal")?.value ?? "."
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Format a numeric amount for display in a currency amount field (no currency symbol). The currency
|
|
531
|
+
* sets the decimals; the separators are the locale's, as in the table cell.
|
|
532
|
+
* @param locale - The browser's own when omitted
|
|
533
|
+
* @public
|
|
534
|
+
*/
|
|
535
|
+
function formatCurrencyAmountInput(amount, currencyId, locale) {
|
|
536
|
+
if (amount === null || amount === void 0) return "";
|
|
537
|
+
const id = currencyId?.toUpperCase() ?? "";
|
|
538
|
+
const fractionDigits = currencyInputFractionDigits(id);
|
|
539
|
+
return new Intl.NumberFormat(locale, {
|
|
540
|
+
minimumFractionDigits: fractionDigits,
|
|
541
|
+
maximumFractionDigits: fractionDigits,
|
|
542
|
+
useGrouping: id !== "JPY"
|
|
543
|
+
}).format(amount);
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Parse user-entered text in a currency amount field back to a number, read with the separators the
|
|
547
|
+
* field writes it with.
|
|
548
|
+
* @param locale - The browser's own when omitted
|
|
549
|
+
* @public
|
|
550
|
+
*/
|
|
551
|
+
function parseCurrencyAmountInput(text, locale) {
|
|
552
|
+
const { group, decimal } = separatorsForLocale(locale);
|
|
553
|
+
const normalized = text.replace(/\s/g, "").replace(/[^\d.,\-+]/g, "").replaceAll(group, "").replace(decimal, ".");
|
|
554
|
+
if (!/\d/.test(normalized)) return null;
|
|
555
|
+
const value = Number(normalized);
|
|
556
|
+
return Number.isFinite(value) ? value : null;
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* What a masked currency amount field may hold while it is typed in: digits and grouping marks, then at most one
|
|
560
|
+
* decimal point followed by digits.
|
|
561
|
+
* @param locale - The browser's own when omitted
|
|
562
|
+
* @public
|
|
563
|
+
*/
|
|
564
|
+
function currencyAmountEntryPattern(currencyId, locale) {
|
|
565
|
+
const { group, decimal } = separatorsForLocale(locale);
|
|
566
|
+
const escape = (mark) => mark.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
567
|
+
const whole = `-?[\\d${escape(group)}]*`;
|
|
568
|
+
if (currencyInputFractionDigits(currencyId) === 0) return new RegExp(`^${whole}$`);
|
|
569
|
+
const point = decimal === "." ? "\\." : `[${escape(decimal)}.]`;
|
|
570
|
+
return new RegExp(`^${whole}(?:${point}\\d*)?$`);
|
|
571
|
+
}
|
|
572
|
+
//#endregion
|
|
573
|
+
//#region src/denominatedFormat.ts
|
|
574
|
+
function displayScalar(value) {
|
|
575
|
+
if (typeof value === "string") return value;
|
|
576
|
+
if (typeof value === "number" || typeof value === "bigint") return String(value);
|
|
577
|
+
if (typeof value === "boolean") return String(value);
|
|
578
|
+
return "";
|
|
579
|
+
}
|
|
580
|
+
function displayQty(qty) {
|
|
581
|
+
if (qty === null || qty === void 0 || qty === "") return "";
|
|
582
|
+
return displayScalar(qty);
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Format a currency amount for display (forms, table cells). Uses `Intl` when `currency.id` is a
|
|
586
|
+
* valid ISO code; otherwise falls back to symbol, display text, or id.
|
|
587
|
+
* @public
|
|
588
|
+
*/
|
|
589
|
+
function formatCurrencyAmount(amount, currency) {
|
|
590
|
+
if (amount === null || amount === void 0) return "";
|
|
591
|
+
const id = currency?.id != null ? String(currency.id) : "";
|
|
592
|
+
if (id) try {
|
|
593
|
+
return new Intl.NumberFormat(void 0, {
|
|
594
|
+
style: "currency",
|
|
595
|
+
currency: id,
|
|
596
|
+
currencyDisplay: "symbol"
|
|
597
|
+
}).format(amount);
|
|
598
|
+
} catch {}
|
|
599
|
+
const suffix = currency?.symbol ?? currency?.displayText ?? id;
|
|
600
|
+
return suffix ? `${amount} ${suffix}`.trim() : String(amount);
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Render a composite quantity value for table cells. Omits the UOM when it matches `stockUom`.
|
|
604
|
+
* @public
|
|
605
|
+
*/
|
|
606
|
+
function formatQuantityCell(value) {
|
|
607
|
+
if (value === null || value === void 0) return "";
|
|
608
|
+
if (typeof value !== "object") return displayScalar(value);
|
|
609
|
+
const record = value;
|
|
610
|
+
const qtyText = displayQty(record.qty);
|
|
611
|
+
const uom = record.uom ?? "";
|
|
612
|
+
const stockUom = record.stockUom ?? "";
|
|
613
|
+
if (!uom) return qtyText;
|
|
614
|
+
if (stockUom && uom === stockUom) return qtyText;
|
|
615
|
+
return `${qtyText} ${uom}`.trim();
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Render a composite currency value for table cells.
|
|
619
|
+
* @public
|
|
620
|
+
*/
|
|
621
|
+
function formatCurrencyCell(value) {
|
|
622
|
+
if (value === null || value === void 0) return "";
|
|
623
|
+
if (typeof value !== "object") return displayScalar(value);
|
|
624
|
+
const record = value;
|
|
625
|
+
return formatCurrencyAmount(record.amount, record.currency);
|
|
626
|
+
}
|
|
627
|
+
//#endregion
|
|
498
628
|
//#region src/index.ts
|
|
499
629
|
/**
|
|
500
630
|
* Install all utility components
|
|
@@ -503,6 +633,6 @@ function compareSemver(a, b) {
|
|
|
503
633
|
*/
|
|
504
634
|
function install(_app) {}
|
|
505
635
|
//#endregion
|
|
506
|
-
export { compareSemver, defaultKeypressHandlers, fromISODate, install, isSemver, isSemverPrefix, useKeyboardNav };
|
|
636
|
+
export { compareSemver, currencyAmountEntryPattern, currencyInputFractionDigits, defaultKeypressHandlers, formatCurrencyAmount, formatCurrencyAmountInput, formatCurrencyCell, formatQuantityCell, fromISODate, install, isSemver, isSemverPrefix, parseCurrencyAmountInput, useKeyboardNav };
|
|
507
637
|
|
|
508
638
|
//# sourceMappingURL=utilities.js.map
|
package/dist/utilities.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utilities.js","names":[],"sources":["../src/composables/visibility/index.ts","../src/composables/keyboard.ts","../src/dates.ts","../src/semver.ts","../src/index.ts"],"sourcesContent":["import {\n\ttype ConfigurableWindow,\n\ttype MaybeComputedElementRef,\n\tdefaultWindow,\n\tunrefElement,\n\tuseEventListener,\n} from '@vueuse/core'\nimport { ref, watch, type MaybeRefOrGetter } from 'vue'\n\nexport interface UseElementVisibilityOptions extends ConfigurableWindow {\n\tscrollTarget?: MaybeRefOrGetter<HTMLElement | undefined | null>\n}\n\n/**\n * Tracks the visibility of an element within the viewport.\n *\n * Compatibility version to get Stonecrop keyboard navigation to work. This function is a copy of the\n * `useElementVisibility` function from VueUse v9.13.0, with the `IntersectionObserver` API removed.\n *\n * This version uses the `getBoundingClientRect` method to determine if an element is visible\n * in the viewport. This is less performant than the `IntersectionObserver` API, but it is\n * more compatible.\n *\n * Note: the newer versions of the VueUse dependencies imported here are sufficient for this composable.\n * (Last verified: v10.9.0 on May 2, 2024)\n *\n * @see https://v9-13-0.vueuse.org/core/useElementVisibility\n * @param element - Element to track visibility for\n * @param options - Configuration options (window, scrollTarget)\n */\nexport function useElementVisibility(\n\telement: MaybeComputedElementRef,\n\t{ window = defaultWindow, scrollTarget }: UseElementVisibilityOptions = {}\n) {\n\tconst elementIsVisible = ref(false)\n\n\tconst testBounding = () => {\n\t\tif (!window) return\n\n\t\tconst document = window.document\n\t\tconst el = unrefElement(element)\n\t\tif (!el) {\n\t\t\telementIsVisible.value = false\n\t\t} else {\n\t\t\tconst rect = el.getBoundingClientRect()\n\t\t\telementIsVisible.value =\n\t\t\t\trect.top <= (window.innerHeight || document.documentElement.clientHeight) &&\n\t\t\t\trect.left <= (window.innerWidth || document.documentElement.clientWidth) &&\n\t\t\t\trect.bottom >= 0 &&\n\t\t\t\trect.right >= 0\n\t\t}\n\t}\n\n\twatch(\n\t\t() => unrefElement(element),\n\t\t() => testBounding(),\n\t\t{ immediate: true, flush: 'post' }\n\t)\n\n\tif (window) {\n\t\tuseEventListener(scrollTarget || window, 'scroll', testBounding, {\n\t\t\tcapture: false,\n\t\t\tpassive: true,\n\t\t})\n\t}\n\n\treturn elementIsVisible\n}\n","import { type WatchStopHandle, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { useFocusWithin } from '@vueuse/core'\n\nimport { useElementVisibility } from './visibility'\nimport type { KeyboardNavigationOptions, KeypressHandlers } from '../types'\n\n// helper functions\nconst isVisible = (element: HTMLElement) => {\n\tlet visible = useElementVisibility(element).value\n\tvisible = visible && element.offsetHeight > 0\n\treturn visible\n}\n\nconst isFocusable = (element: HTMLElement) => {\n\treturn element.tabIndex >= 0\n}\n\n// navigation functions\nconst getUpCell = (event: KeyboardEvent) => {\n\tif (!(event.target instanceof HTMLElement)) return undefined\n\treturn getUpCellEl(event.target)\n}\n\nconst getUpCellEl = (element: HTMLElement): HTMLElement | undefined => {\n\tlet $upCell: HTMLElement | undefined\n\tif (element instanceof HTMLTableCellElement) {\n\t\tconst $prevSibling = element.parentElement?.previousElementSibling\n\t\tif ($prevSibling instanceof HTMLTableRowElement) {\n\t\t\tconst $prevRowCells = Array.from($prevSibling.children)\n\t\t\tconst $cellEl = $prevRowCells[element.cellIndex]\n\t\t\tif ($cellEl instanceof HTMLElement) {\n\t\t\t\t$upCell = $cellEl\n\t\t\t}\n\t\t}\n\t} else if (element instanceof HTMLTableRowElement) {\n\t\tconst $prevSibling = element.previousElementSibling\n\t\tif ($prevSibling instanceof HTMLTableRowElement) {\n\t\t\t$upCell = $prevSibling\n\t\t}\n\t} else {\n\t\t// handle other contexts\n\t}\n\tif ($upCell && (!isFocusable($upCell) || !isVisible($upCell))) {\n\t\treturn getUpCellEl($upCell)\n\t}\n\treturn $upCell\n}\n\nconst getTopCell = (event: KeyboardEvent) => {\n\tif (!(event.target instanceof HTMLElement)) return undefined\n\tconst $target = event.target\n\tlet $topCell: HTMLElement | undefined\n\tif ($target instanceof HTMLTableCellElement) {\n\t\tconst $table = $target.parentElement?.parentElement\n\t\tif ($table) {\n\t\t\tconst $firstRow = $table.firstElementChild\n\t\t\tconst $navEl = $firstRow?.children[$target.cellIndex]\n\t\t\tif ($navEl instanceof HTMLElement) {\n\t\t\t\t$topCell = $navEl\n\t\t\t}\n\t\t}\n\t} else if ($target instanceof HTMLTableRowElement) {\n\t\tconst $parent = $target.parentElement\n\t\tif ($parent) {\n\t\t\tconst $firstEl = $parent.firstElementChild\n\t\t\tif ($firstEl instanceof HTMLTableRowElement) {\n\t\t\t\t$topCell = $firstEl\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// handle other contexts\n\t}\n\tif ($topCell && (!isFocusable($topCell) || !isVisible($topCell))) {\n\t\treturn getDownCellEl($topCell)\n\t}\n\treturn $topCell\n}\n\nconst getDownCell = (event: KeyboardEvent) => {\n\tif (!(event.target instanceof HTMLElement)) return undefined\n\treturn getDownCellEl(event.target)\n}\n\nconst getDownCellEl = (element: HTMLElement): HTMLElement | undefined => {\n\tlet $downCell: HTMLElement | undefined\n\tif (element instanceof HTMLTableCellElement) {\n\t\tconst $nextSibling = element.parentElement?.nextElementSibling\n\t\tif ($nextSibling) {\n\t\t\tconst $nextRowCells = Array.from($nextSibling.children)\n\t\t\tconst $cellEl = $nextRowCells[element.cellIndex]\n\t\t\tif ($cellEl instanceof HTMLElement) {\n\t\t\t\t$downCell = $cellEl\n\t\t\t}\n\t\t}\n\t} else if (element instanceof HTMLTableRowElement) {\n\t\tconst $nextSibling = element.nextElementSibling\n\t\tif ($nextSibling instanceof HTMLTableRowElement) {\n\t\t\t$downCell = $nextSibling\n\t\t}\n\t} else {\n\t\t// handle other contexts\n\t}\n\tif ($downCell && (!isFocusable($downCell) || !isVisible($downCell))) {\n\t\treturn getDownCellEl($downCell)\n\t}\n\treturn $downCell\n}\n\nconst getBottomCell = (event: KeyboardEvent) => {\n\tif (!(event.target instanceof HTMLElement)) return undefined\n\tconst $target = event.target\n\tlet $bottomCell: HTMLElement | undefined\n\tif ($target instanceof HTMLTableCellElement) {\n\t\tconst $table = $target.parentElement?.parentElement\n\t\tif ($table) {\n\t\t\tconst $lastRow = $table.lastElementChild\n\t\t\tconst $navEl = $lastRow?.children[$target.cellIndex]\n\t\t\tif ($navEl instanceof HTMLElement) {\n\t\t\t\t$bottomCell = $navEl\n\t\t\t}\n\t\t}\n\t} else if ($target instanceof HTMLTableRowElement) {\n\t\tconst $parent = $target.parentElement\n\t\tif ($parent) {\n\t\t\tconst $lastEl = $parent.lastElementChild\n\t\t\tif ($lastEl instanceof HTMLTableRowElement) {\n\t\t\t\t$bottomCell = $lastEl\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// handle other contexts\n\t}\n\tif ($bottomCell && (!isFocusable($bottomCell) || !isVisible($bottomCell))) {\n\t\treturn getUpCellEl($bottomCell)\n\t}\n\treturn $bottomCell\n}\n\nconst getPrevCell = (event: KeyboardEvent) => {\n\tif (!(event.target instanceof HTMLElement)) return undefined\n\treturn getPrevCellEl(event.target)\n}\n\nconst getPrevCellEl = (element: HTMLElement): HTMLElement | undefined => {\n\tlet $prevCell: HTMLElement | undefined\n\tconst $prevSibling = element.previousElementSibling\n\tif ($prevSibling instanceof HTMLElement) {\n\t\t$prevCell = $prevSibling\n\t} else {\n\t\tconst $prevRow = element.parentElement?.previousElementSibling\n\t\tconst $lastEl = $prevRow?.lastElementChild\n\t\tif ($lastEl instanceof HTMLElement) {\n\t\t\t$prevCell = $lastEl\n\t\t}\n\t}\n\tif ($prevCell && (!isFocusable($prevCell) || !isVisible($prevCell))) {\n\t\treturn getPrevCellEl($prevCell)\n\t}\n\treturn $prevCell\n}\n\nconst getNextCell = (event: KeyboardEvent) => {\n\tif (!(event.target instanceof HTMLElement)) return undefined\n\treturn getNextCellEl(event.target)\n}\n\nconst getNextCellEl = (element: HTMLElement): HTMLElement | undefined => {\n\tlet $nextCell: HTMLElement | undefined\n\tconst $nextSibling = element.nextElementSibling\n\tif ($nextSibling instanceof HTMLElement) {\n\t\t$nextCell = $nextSibling\n\t} else {\n\t\tconst $nextRow = element.parentElement?.nextElementSibling\n\t\tconst $firstEl = $nextRow?.firstElementChild\n\t\tif ($firstEl instanceof HTMLElement) {\n\t\t\t$nextCell = $firstEl\n\t\t}\n\t}\n\tif ($nextCell && (!isFocusable($nextCell) || !isVisible($nextCell))) {\n\t\treturn getNextCellEl($nextCell)\n\t}\n\treturn $nextCell\n}\n\nconst getFirstCell = (event: KeyboardEvent) => {\n\tif (!(event.target instanceof HTMLElement)) return undefined\n\tconst $parent = event.target.parentElement\n\tconst $firstEl = $parent?.firstElementChild\n\tconst $firstCell = $firstEl instanceof HTMLElement ? $firstEl : null\n\tif ($firstCell && (!isFocusable($firstCell) || !isVisible($firstCell))) {\n\t\treturn getNextCellEl($firstCell)\n\t}\n\treturn $firstCell\n}\n\nconst getLastCell = (event: KeyboardEvent) => {\n\tif (!(event.target instanceof HTMLElement)) return undefined\n\tconst $parent = event.target.parentElement\n\tconst $lastEl = $parent?.lastElementChild\n\tconst $lastCell = $lastEl instanceof HTMLElement ? $lastEl : null\n\tif ($lastCell && (!isFocusable($lastCell) || !isVisible($lastCell))) {\n\t\treturn getPrevCellEl($lastCell)\n\t}\n\treturn $lastCell\n}\n\nconst modifierKeys = ['alt', 'control', 'shift', 'meta']\n\nconst eventKeyMap: Record<string, string> = {\n\tArrowUp: 'up',\n\tArrowDown: 'down',\n\tArrowLeft: 'left',\n\tArrowRight: 'right',\n}\n\n/**\n * Default keypress handlers for keyboard navigation\n * @public\n */\nexport const defaultKeypressHandlers: KeypressHandlers = {\n\t'keydown.up': (event: KeyboardEvent) => {\n\t\tconst $upCell = getUpCell(event)\n\t\tif ($upCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$upCell.focus()\n\t\t}\n\t},\n\t'keydown.down': (event: KeyboardEvent) => {\n\t\tconst $downCell = getDownCell(event)\n\t\tif ($downCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$downCell.focus()\n\t\t}\n\t},\n\t'keydown.left': (event: KeyboardEvent) => {\n\t\tconst $prevCell = getPrevCell(event)\n\t\t// prevent default edit-cell behaviour on first cell\n\t\tevent.preventDefault()\n\t\tevent.stopPropagation()\n\t\tif ($prevCell) {\n\t\t\t$prevCell.focus()\n\t\t}\n\t},\n\t'keydown.right': (event: KeyboardEvent) => {\n\t\tconst $nextCell = getNextCell(event)\n\t\t// prevent default edit-cell behaviour on last cell\n\t\tevent.preventDefault()\n\t\tevent.stopPropagation()\n\t\tif ($nextCell) {\n\t\t\t$nextCell.focus()\n\t\t}\n\t},\n\t'keydown.control.up': (event: KeyboardEvent) => {\n\t\tconst $topCell = getTopCell(event)\n\t\tif ($topCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$topCell.focus()\n\t\t}\n\t},\n\t'keydown.control.down': (event: KeyboardEvent) => {\n\t\tconst $bottomCell = getBottomCell(event)\n\t\tif ($bottomCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$bottomCell.focus()\n\t\t}\n\t},\n\t'keydown.control.left': (event: KeyboardEvent) => {\n\t\tconst $firstCell = getFirstCell(event)\n\t\tif ($firstCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$firstCell.focus()\n\t\t}\n\t},\n\t'keydown.control.right': (event: KeyboardEvent) => {\n\t\tconst $lastCell = getLastCell(event)\n\t\tif ($lastCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$lastCell.focus()\n\t\t}\n\t},\n\t'keydown.end': (event: KeyboardEvent) => {\n\t\tconst $lastCell = getLastCell(event)\n\t\tif ($lastCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$lastCell.focus()\n\t\t}\n\t},\n\t'keydown.enter': (event: KeyboardEvent) => {\n\t\tif (!(event.target instanceof HTMLElement)) return\n\t\tconst $target = event.target\n\t\tif ($target instanceof HTMLTableCellElement) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\tconst $downCell = getDownCell(event)\n\t\t\tif ($downCell) {\n\t\t\t\t$downCell.focus()\n\t\t\t}\n\t\t} else {\n\t\t\t// handle other contexts\n\t\t}\n\t},\n\t'keydown.shift.enter': (event: KeyboardEvent) => {\n\t\tif (!(event.target instanceof HTMLElement)) return\n\t\tconst $target = event.target\n\t\tif ($target instanceof HTMLTableCellElement) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\tconst $upCell = getUpCell(event)\n\t\t\tif ($upCell) {\n\t\t\t\t$upCell.focus()\n\t\t\t}\n\t\t} else {\n\t\t\t// handle other contexts\n\t\t}\n\t},\n\t'keydown.home': (event: KeyboardEvent) => {\n\t\tconst $firstCell = getFirstCell(event)\n\t\tif ($firstCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$firstCell.focus()\n\t\t}\n\t},\n\t'keydown.tab': (event: KeyboardEvent) => {\n\t\tconst $nextCell = getNextCell(event)\n\t\tif ($nextCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$nextCell.focus()\n\t\t}\n\t},\n\t'keydown.shift.tab': (event: KeyboardEvent) => {\n\t\tconst $prevCell = getPrevCell(event)\n\t\tif ($prevCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$prevCell.focus()\n\t\t}\n\t},\n}\n\n/**\n * Gets the parent element from a keyboard navigation option.\n * @internal\n */\nfunction getParentElement(option: KeyboardNavigationOptions): HTMLElement | null {\n\tlet $parent: HTMLElement | null = null\n\tif (option.parent) {\n\t\tif (typeof option.parent === 'string') {\n\t\t\t$parent = document.querySelector(option.parent)\n\t\t} else if (option.parent instanceof HTMLElement) {\n\t\t\t$parent = option.parent\n\t\t} else {\n\t\t\t$parent = option.parent.value\n\t\t}\n\t}\n\treturn $parent\n}\n\n/**\n * Keyboard navigation composable\n * @param options - Keyboard navigation options\n * @public\n */\nexport function useKeyboardNav(options: KeyboardNavigationOptions[]) {\n\tconst getSelectorsFromOption = (option: KeyboardNavigationOptions) => {\n\t\t// assumes that option.selectors is provided\n\t\tconst $parent = getParentElement(option)\n\t\tlet selectors: HTMLElement[] = []\n\t\tif (typeof option.selectors === 'string') {\n\t\t\tselectors = $parent\n\t\t\t\t? Array.from($parent.querySelectorAll(option.selectors))\n\t\t\t\t: Array.from(document.querySelectorAll(option.selectors))\n\t\t} else if (Array.isArray(option.selectors)) {\n\t\t\tfor (const element of option.selectors) {\n\t\t\t\tif (element instanceof HTMLElement) {\n\t\t\t\t\tselectors.push(element)\n\t\t\t\t} else {\n\t\t\t\t\t// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Vue component $el is typed as any; shape guaranteed by VNode contract\n\t\t\t\t\tselectors.push(element.$el as HTMLElement)\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (option.selectors instanceof HTMLElement) {\n\t\t\tselectors.push(option.selectors)\n\t\t} else if (option.selectors?.value) {\n\t\t\tif (Array.isArray(option.selectors.value)) {\n\t\t\t\tfor (const element of option.selectors.value) {\n\t\t\t\t\tif (element instanceof HTMLElement) {\n\t\t\t\t\t\tselectors.push(element)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Vue component $el is typed as any; shape guaranteed by VNode contract\n\t\t\t\t\t\tselectors.push(element.$el as HTMLElement)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tselectors.push(option.selectors.value)\n\t\t\t}\n\t\t}\n\t\treturn selectors\n\t}\n\n\tconst getSelectors = (option: KeyboardNavigationOptions) => {\n\t\tconst $parent = getParentElement(option)\n\t\tlet selectors: HTMLElement[] = []\n\t\tif (option.selectors) {\n\t\t\tselectors = getSelectorsFromOption(option)\n\t\t} else if ($parent) {\n\t\t\t// TODO: what should happen if no parent or selectors are provided?\n\t\t\tconst $children = Array.from($parent.children).filter((el): el is HTMLElement => el instanceof HTMLElement)\n\t\t\tselectors = $children.filter(selector => {\n\t\t\t\t// ignore elements not in the tab order or are not visible\n\t\t\t\treturn isFocusable(selector) && isVisible(selector)\n\t\t\t})\n\t\t}\n\t\treturn selectors\n\t}\n\n\tconst getEventListener = (option: KeyboardNavigationOptions) => {\n\t\treturn (event: KeyboardEvent) => {\n\t\t\tconst activeKey = eventKeyMap[event.key] || event.key.toLowerCase()\n\t\t\tif (modifierKeys.includes(activeKey)) return // ignore modifier key presses\n\n\t\t\tconst handlers = option.handlers || defaultKeypressHandlers\n\t\t\tfor (const key of Object.keys(handlers)) {\n\t\t\t\tconst [eventType, ...keys] = key.split('.')\n\t\t\t\tif (eventType !== 'keydown') {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif (keys.includes(activeKey)) {\n\t\t\t\t\tconst listener = handlers[key]\n\n\t\t\t\t\t// check if the handler has modifiers, and if the modifier is active;\n\t\t\t\t\t// this is to ensure exact key-press matches\n\t\t\t\t\tconst hasModifier = keys.filter(k => modifierKeys.includes(k))\n\t\t\t\t\tconst isModifierActive = modifierKeys.some(mk => {\n\t\t\t\t\t\tconst modifierKey = mk.charAt(0).toUpperCase() + mk.slice(1)\n\t\t\t\t\t\treturn event.getModifierState(modifierKey)\n\t\t\t\t\t})\n\n\t\t\t\t\tif (hasModifier.length > 0) {\n\t\t\t\t\t\tif (isModifierActive) {\n\t\t\t\t\t\t\tfor (const modifier of modifierKeys) {\n\t\t\t\t\t\t\t\tif (keys.includes(modifier)) {\n\t\t\t\t\t\t\t\t\t// docs: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/getModifierState\n\t\t\t\t\t\t\t\t\tconst modifierKey = modifier.charAt(0).toUpperCase() + modifier.slice(1)\n\t\t\t\t\t\t\t\t\tif (event.getModifierState(modifierKey)) {\n\t\t\t\t\t\t\t\t\t\tlistener(event)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (!isModifierActive) {\n\t\t\t\t\t\t\tlistener(event)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconst watchStopHandlers: WatchStopHandle[] = []\n\tonMounted(() => {\n\t\tfor (const option of options) {\n\t\t\tconst $parent = getParentElement(option)\n\t\t\tconst selectors = getSelectors(option)\n\t\t\tconst listener = getEventListener(option)\n\t\t\tconst listenerElements = $parent\n\t\t\t\t? [$parent] // watch for focus recursively within the parent element\n\t\t\t\t: selectors // watch for focus on each selector element TODO: too much JS?\n\n\t\t\tfor (const element of listenerElements) {\n\t\t\t\tconst { focused } = useFocusWithin(ref(element))\n\t\t\t\tconst stopHandler = watch(focused, value => {\n\t\t\t\t\tif (value) {\n\t\t\t\t\t\telement.addEventListener('keydown', listener)\n\t\t\t\t\t} else {\n\t\t\t\t\t\telement.removeEventListener('keydown', listener)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\twatchStopHandlers.push(stopHandler)\n\t\t\t}\n\t\t}\n\t})\n\n\tonBeforeUnmount(() => {\n\t\tfor (const stopHandler of watchStopHandlers) {\n\t\t\tstopHandler()\n\t\t}\n\t})\n}\n","import { Temporal } from 'temporal-polyfill'\n\n/**\n * Reads a `YYYY-MM-DD` day. Anything that is not a real day written exactly that way reads as no day.\n *\n * Not `Temporal.PlainDate.from` alone: it also takes the day out of a date-time, which would show a day\n * field over a date-time column as a day instead of as the mismatch it is.\n * @param day - The day, as `YYYY-MM-DD`\n * @public\n */\nexport function fromISODate(day: string): Temporal.PlainDate | undefined {\n\tif (!/^\\d{4}-\\d{2}-\\d{2}$/.test(day)) return undefined\n\n\ttry {\n\t\treturn Temporal.PlainDate.from(day)\n\t} catch {\n\t\treturn undefined\n\t}\n}\n","// SemVer 2.0.0, strictly: https://semver.org. The same grammar the `semver` Postgres extension stores,\n// so a version the form accepts is one the column takes, and the two order versions alike.\nconst SEMVER =\n\t/^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/\n\nconst NUMBER = /^(0|[1-9]\\d*)$/\nconst NUMBER_SO_FAR = /^(0|[1-9]\\d*)?$/\nconst PRERELEASE_IDENTIFIER = /^(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)$/\nconst BUILD_IDENTIFIER = /^[0-9a-zA-Z-]+$/\n// Any run of identifier characters can still become an identifier: `01` is not one, but `01a` is.\nconst IDENTIFIER_SO_FAR = /^[0-9a-zA-Z-]*$/\n\n/**\n * Whether the text is a version under SemVer 2.0.0: `1.4.0`, `1.4.0-beta.2`, `1.4.0+build.5`. A `v`\n * prefix, a missing part (`1.4`) and a leading zero (`01.4.0`) are not.\n * @param text - The text to check\n * @public\n */\nexport function isSemver(text: string): boolean {\n\treturn SEMVER.test(text)\n}\n\nconst splitOnce = (text: string, separator: string): [string, string | undefined] => {\n\tconst index = text.indexOf(separator)\n\treturn index === -1 ? [text, undefined] : [text.slice(0, index), text.slice(index + 1)]\n}\n\n/** Whether each dot-separated part before the last matches `whole`, and the last matches `last`. */\nconst partsMatch = (text: string, whole: RegExp, last: RegExp): boolean => {\n\tconst parts = text.split('.')\n\tconst typing = parts.pop() ?? ''\n\treturn parts.every(part => whole.test(part)) && last.test(typing)\n}\n\n/**\n * Whether typing more could still make the text a version: `1.`, `1.4.0-` and the empty text can,\n * while `v1`, `01` and `1.4-beta` cannot. Every version passes, so a box that refuses any edit failing\n * this one never stops someone typing a version.\n * @param text - The text so far\n * @public\n */\nexport function isSemverPrefix(text: string): boolean {\n\t// Neither `+` nor `-` can appear in the numbers, so the first of each ends the part before it.\n\tconst [head, build] = splitOnce(text, '+')\n\tconst [core, prerelease] = splitOnce(head, '-')\n\n\tconst coreDone = prerelease !== undefined || build !== undefined\n\tconst numbers = core.split('.').length\n\tif (numbers > 3 || (coreDone && numbers < 3)) return false\n\tif (!partsMatch(core, NUMBER, coreDone ? NUMBER : NUMBER_SO_FAR)) return false\n\n\tif (prerelease !== undefined) {\n\t\tconst last = build === undefined ? IDENTIFIER_SO_FAR : PRERELEASE_IDENTIFIER\n\t\tif (!partsMatch(prerelease, PRERELEASE_IDENTIFIER, last)) return false\n\t}\n\n\treturn build === undefined || partsMatch(build, BUILD_IDENTIFIER, IDENTIFIER_SO_FAR)\n}\n\n// Digits without leading zeros, compared without converting, so no version is too big to order.\nconst compareDigits = (a: string, b: string): number => a.length - b.length || (a < b ? -1 : a > b ? 1 : 0)\n\nconst compareIdentifiers = (a: string, b: string): number => {\n\tconst aNumeric = /^\\d+$/.test(a)\n\tconst bNumeric = /^\\d+$/.test(b)\n\tif (aNumeric && bNumeric) return compareDigits(a, b)\n\tif (aNumeric !== bNumeric) return aNumeric ? -1 : 1\n\treturn a < b ? -1 : a > b ? 1 : 0\n}\n\nconst comparePrereleases = (a: string | undefined, b: string | undefined): number => {\n\tif (a === b) return 0\n\t// A prerelease comes before its release.\n\tif (a === undefined) return 1\n\tif (b === undefined) return -1\n\n\tconst left = a.split('.')\n\tconst right = b.split('.')\n\tfor (let i = 0; i < Math.min(left.length, right.length); i++) {\n\t\tconst order = compareIdentifiers(left[i], right[i])\n\t\tif (order) return order\n\t}\n\treturn left.length - right.length\n}\n\n/**\n * Orders two versions by SemVer 2.0.0 precedence: major, minor and patch as numbers, a prerelease\n * before its release, and prerelease identifiers one by one. Build metadata does not count, so\n * `1.4.0+a` and `1.4.0+b` compare equal. Text that is not a version comes after every version.\n * @param a - The first version\n * @param b - The second version\n * @returns Negative when `a` comes first, positive when `b` does, zero when neither\n * @public\n */\nexport function compareSemver(a: string, b: string): number {\n\tconst left = SEMVER.exec(a)\n\tconst right = SEMVER.exec(b)\n\tif (!left || !right) return Number(!left) - Number(!right)\n\n\tfor (let part = 1; part <= 3; part++) {\n\t\tconst order = compareDigits(left[part], right[part])\n\t\tif (order) return order\n\t}\n\treturn comparePrereleases(left[4], right[4])\n}\n","import { App } from 'vue'\n\nimport { defaultKeypressHandlers, useKeyboardNav } from './composables/keyboard'\nimport { fromISODate } from './dates'\nimport { compareSemver, isSemver, isSemverPrefix } from './semver'\nexport type * from './types'\n\n/**\n * Install all utility components\n * @param _app - Vue app instance\n * @public\n */\nfunction install(_app: App /* options */) {}\n\nexport { compareSemver, defaultKeypressHandlers, fromISODate, install, isSemver, isSemverPrefix, useKeyboardNav }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA8BA,SAAgB,qBACf,SACA,EAAE,SAAS,eAAe,iBAA8C,CAAC,GACxE;CACD,MAAM,mBAAmB,IAAI,KAAK;CAElC,MAAM,qBAAqB;EAC1B,IAAI,CAAC,QAAQ;EAEb,MAAM,WAAW,OAAO;EACxB,MAAM,KAAK,aAAa,OAAO;EAC/B,IAAI,CAAC,IACJ,iBAAiB,QAAQ;OACnB;GACN,MAAM,OAAO,GAAG,sBAAsB;GACtC,iBAAiB,QAChB,KAAK,QAAQ,OAAO,eAAe,SAAS,gBAAgB,iBAC5D,KAAK,SAAS,OAAO,cAAc,SAAS,gBAAgB,gBAC5D,KAAK,UAAU,KACf,KAAK,SAAS;EAChB;CACD;CAEA,YACO,aAAa,OAAO,SACpB,aAAa,GACnB;EAAE,WAAW;EAAM,OAAO;CAAO,CAClC;CAEA,IAAI,QACH,iBAAiB,gBAAgB,QAAQ,UAAU,cAAc;EAChE,SAAS;EACT,SAAS;CACV,CAAC;CAGF,OAAO;AACR;;;AC5DA,IAAM,aAAa,YAAyB;CAC3C,IAAI,UAAU,qBAAqB,OAAO,CAAC,CAAC;CAC5C,UAAU,WAAW,QAAQ,eAAe;CAC5C,OAAO;AACR;AAEA,IAAM,eAAe,YAAyB;CAC7C,OAAO,QAAQ,YAAY;AAC5B;AAGA,IAAM,aAAa,UAAyB;CAC3C,IAAI,EAAE,MAAM,kBAAkB,cAAc,OAAO,KAAA;CACnD,OAAO,YAAY,MAAM,MAAM;AAChC;AAEA,IAAM,eAAe,YAAkD;CACtE,IAAI;CACJ,IAAI,mBAAmB,sBAAsB;EAC5C,MAAM,eAAe,QAAQ,eAAe;EAC5C,IAAI,wBAAwB,qBAAqB;GAEhD,MAAM,UADgB,MAAM,KAAK,aAAa,QAC9B,CAAA,CAAc,QAAQ;GACtC,IAAI,mBAAmB,aACtB,UAAU;EAEZ;CACD,OAAO,IAAI,mBAAmB,qBAAqB;EAClD,MAAM,eAAe,QAAQ;EAC7B,IAAI,wBAAwB,qBAC3B,UAAU;CAEZ;CAGA,IAAI,YAAY,CAAC,YAAY,OAAO,KAAK,CAAC,UAAU,OAAO,IAC1D,OAAO,YAAY,OAAO;CAE3B,OAAO;AACR;AAEA,IAAM,cAAc,UAAyB;CAC5C,IAAI,EAAE,MAAM,kBAAkB,cAAc,OAAO,KAAA;CACnD,MAAM,UAAU,MAAM;CACtB,IAAI;CACJ,IAAI,mBAAmB,sBAAsB;EAC5C,MAAM,SAAS,QAAQ,eAAe;EACtC,IAAI,QAAQ;GAEX,MAAM,SADY,OAAO,mBACC,SAAS,QAAQ;GAC3C,IAAI,kBAAkB,aACrB,WAAW;EAEb;CACD,OAAO,IAAI,mBAAmB,qBAAqB;EAClD,MAAM,UAAU,QAAQ;EACxB,IAAI,SAAS;GACZ,MAAM,WAAW,QAAQ;GACzB,IAAI,oBAAoB,qBACvB,WAAW;EAEb;CACD;CAGA,IAAI,aAAa,CAAC,YAAY,QAAQ,KAAK,CAAC,UAAU,QAAQ,IAC7D,OAAO,cAAc,QAAQ;CAE9B,OAAO;AACR;AAEA,IAAM,eAAe,UAAyB;CAC7C,IAAI,EAAE,MAAM,kBAAkB,cAAc,OAAO,KAAA;CACnD,OAAO,cAAc,MAAM,MAAM;AAClC;AAEA,IAAM,iBAAiB,YAAkD;CACxE,IAAI;CACJ,IAAI,mBAAmB,sBAAsB;EAC5C,MAAM,eAAe,QAAQ,eAAe;EAC5C,IAAI,cAAc;GAEjB,MAAM,UADgB,MAAM,KAAK,aAAa,QAC9B,CAAA,CAAc,QAAQ;GACtC,IAAI,mBAAmB,aACtB,YAAY;EAEd;CACD,OAAO,IAAI,mBAAmB,qBAAqB;EAClD,MAAM,eAAe,QAAQ;EAC7B,IAAI,wBAAwB,qBAC3B,YAAY;CAEd;CAGA,IAAI,cAAc,CAAC,YAAY,SAAS,KAAK,CAAC,UAAU,SAAS,IAChE,OAAO,cAAc,SAAS;CAE/B,OAAO;AACR;AAEA,IAAM,iBAAiB,UAAyB;CAC/C,IAAI,EAAE,MAAM,kBAAkB,cAAc,OAAO,KAAA;CACnD,MAAM,UAAU,MAAM;CACtB,IAAI;CACJ,IAAI,mBAAmB,sBAAsB;EAC5C,MAAM,SAAS,QAAQ,eAAe;EACtC,IAAI,QAAQ;GAEX,MAAM,SADW,OAAO,kBACC,SAAS,QAAQ;GAC1C,IAAI,kBAAkB,aACrB,cAAc;EAEhB;CACD,OAAO,IAAI,mBAAmB,qBAAqB;EAClD,MAAM,UAAU,QAAQ;EACxB,IAAI,SAAS;GACZ,MAAM,UAAU,QAAQ;GACxB,IAAI,mBAAmB,qBACtB,cAAc;EAEhB;CACD;CAGA,IAAI,gBAAgB,CAAC,YAAY,WAAW,KAAK,CAAC,UAAU,WAAW,IACtE,OAAO,YAAY,WAAW;CAE/B,OAAO;AACR;AAEA,IAAM,eAAe,UAAyB;CAC7C,IAAI,EAAE,MAAM,kBAAkB,cAAc,OAAO,KAAA;CACnD,OAAO,cAAc,MAAM,MAAM;AAClC;AAEA,IAAM,iBAAiB,YAAkD;CACxE,IAAI;CACJ,MAAM,eAAe,QAAQ;CAC7B,IAAI,wBAAwB,aAC3B,YAAY;MACN;EAEN,MAAM,WADW,QAAQ,eAAe,uBAAA,EACd;EAC1B,IAAI,mBAAmB,aACtB,YAAY;CAEd;CACA,IAAI,cAAc,CAAC,YAAY,SAAS,KAAK,CAAC,UAAU,SAAS,IAChE,OAAO,cAAc,SAAS;CAE/B,OAAO;AACR;AAEA,IAAM,eAAe,UAAyB;CAC7C,IAAI,EAAE,MAAM,kBAAkB,cAAc,OAAO,KAAA;CACnD,OAAO,cAAc,MAAM,MAAM;AAClC;AAEA,IAAM,iBAAiB,YAAkD;CACxE,IAAI;CACJ,MAAM,eAAe,QAAQ;CAC7B,IAAI,wBAAwB,aAC3B,YAAY;MACN;EAEN,MAAM,YADW,QAAQ,eAAe,mBAAA,EACb;EAC3B,IAAI,oBAAoB,aACvB,YAAY;CAEd;CACA,IAAI,cAAc,CAAC,YAAY,SAAS,KAAK,CAAC,UAAU,SAAS,IAChE,OAAO,cAAc,SAAS;CAE/B,OAAO;AACR;AAEA,IAAM,gBAAgB,UAAyB;CAC9C,IAAI,EAAE,MAAM,kBAAkB,cAAc,OAAO,KAAA;CAEnD,MAAM,WADU,MAAM,OAAO,eACH;CAC1B,MAAM,aAAa,oBAAoB,cAAc,WAAW;CAChE,IAAI,eAAe,CAAC,YAAY,UAAU,KAAK,CAAC,UAAU,UAAU,IACnE,OAAO,cAAc,UAAU;CAEhC,OAAO;AACR;AAEA,IAAM,eAAe,UAAyB;CAC7C,IAAI,EAAE,MAAM,kBAAkB,cAAc,OAAO,KAAA;CAEnD,MAAM,UADU,MAAM,OAAO,eACJ;CACzB,MAAM,YAAY,mBAAmB,cAAc,UAAU;CAC7D,IAAI,cAAc,CAAC,YAAY,SAAS,KAAK,CAAC,UAAU,SAAS,IAChE,OAAO,cAAc,SAAS;CAE/B,OAAO;AACR;AAEA,IAAM,eAAe;CAAC;CAAO;CAAW;CAAS;AAAM;AAEvD,IAAM,cAAsC;CAC3C,SAAS;CACT,WAAW;CACX,WAAW;CACX,YAAY;AACb;;;;;AAMA,IAAa,0BAA4C;CACxD,eAAe,UAAyB;EACvC,MAAM,UAAU,UAAU,KAAK;EAC/B,IAAI,SAAS;GACZ,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,QAAQ,MAAM;EACf;CACD;CACA,iBAAiB,UAAyB;EACzC,MAAM,YAAY,YAAY,KAAK;EACnC,IAAI,WAAW;GACd,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,UAAU,MAAM;EACjB;CACD;CACA,iBAAiB,UAAyB;EACzC,MAAM,YAAY,YAAY,KAAK;EAEnC,MAAM,eAAe;EACrB,MAAM,gBAAgB;EACtB,IAAI,WACH,UAAU,MAAM;CAElB;CACA,kBAAkB,UAAyB;EAC1C,MAAM,YAAY,YAAY,KAAK;EAEnC,MAAM,eAAe;EACrB,MAAM,gBAAgB;EACtB,IAAI,WACH,UAAU,MAAM;CAElB;CACA,uBAAuB,UAAyB;EAC/C,MAAM,WAAW,WAAW,KAAK;EACjC,IAAI,UAAU;GACb,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,SAAS,MAAM;EAChB;CACD;CACA,yBAAyB,UAAyB;EACjD,MAAM,cAAc,cAAc,KAAK;EACvC,IAAI,aAAa;GAChB,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,YAAY,MAAM;EACnB;CACD;CACA,yBAAyB,UAAyB;EACjD,MAAM,aAAa,aAAa,KAAK;EACrC,IAAI,YAAY;GACf,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,WAAW,MAAM;EAClB;CACD;CACA,0BAA0B,UAAyB;EAClD,MAAM,YAAY,YAAY,KAAK;EACnC,IAAI,WAAW;GACd,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,UAAU,MAAM;EACjB;CACD;CACA,gBAAgB,UAAyB;EACxC,MAAM,YAAY,YAAY,KAAK;EACnC,IAAI,WAAW;GACd,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,UAAU,MAAM;EACjB;CACD;CACA,kBAAkB,UAAyB;EAC1C,IAAI,EAAE,MAAM,kBAAkB,cAAc;EAE5C,IADgB,MAAM,kBACC,sBAAsB;GAC5C,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,MAAM,YAAY,YAAY,KAAK;GACnC,IAAI,WACH,UAAU,MAAM;EAElB;CAGD;CACA,wBAAwB,UAAyB;EAChD,IAAI,EAAE,MAAM,kBAAkB,cAAc;EAE5C,IADgB,MAAM,kBACC,sBAAsB;GAC5C,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,MAAM,UAAU,UAAU,KAAK;GAC/B,IAAI,SACH,QAAQ,MAAM;EAEhB;CAGD;CACA,iBAAiB,UAAyB;EACzC,MAAM,aAAa,aAAa,KAAK;EACrC,IAAI,YAAY;GACf,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,WAAW,MAAM;EAClB;CACD;CACA,gBAAgB,UAAyB;EACxC,MAAM,YAAY,YAAY,KAAK;EACnC,IAAI,WAAW;GACd,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,UAAU,MAAM;EACjB;CACD;CACA,sBAAsB,UAAyB;EAC9C,MAAM,YAAY,YAAY,KAAK;EACnC,IAAI,WAAW;GACd,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,UAAU,MAAM;EACjB;CACD;AACD;;;;;AAMA,SAAS,iBAAiB,QAAuD;CAChF,IAAI,UAA8B;CAClC,IAAI,OAAO,QAAQ;EAClB,IAAI,OAAO,OAAO,WAAW,UAC5B,UAAU,SAAS,cAAc,OAAO,MAAM;OACxC,IAAI,OAAO,kBAAkB,aACnC,UAAU,OAAO;OAEjB,UAAU,OAAO,OAAO;CAE1B;CACA,OAAO;AACR;;;;;;AAOA,SAAgB,eAAe,SAAsC;CACpE,MAAM,0BAA0B,WAAsC;EAErE,MAAM,UAAU,iBAAiB,MAAM;EACvC,IAAI,YAA2B,CAAC;EAChC,IAAI,OAAO,OAAO,cAAc,UAC/B,YAAY,UACT,MAAM,KAAK,QAAQ,iBAAiB,OAAO,SAAS,CAAC,IACrD,MAAM,KAAK,SAAS,iBAAiB,OAAO,SAAS,CAAC;OACnD,IAAI,MAAM,QAAQ,OAAO,SAAS,GACxC,KAAK,MAAM,WAAW,OAAO,WAC5B,IAAI,mBAAmB,aACtB,UAAU,KAAK,OAAO;OAGtB,UAAU,KAAK,QAAQ,GAAkB;OAGrC,IAAI,OAAO,qBAAqB,aACtC,UAAU,KAAK,OAAO,SAAS;OACzB,IAAI,OAAO,WAAW,OAAO;GACnC,IAAI,MAAM,QAAQ,OAAO,UAAU,KAAK,GACvC,KAAK,MAAM,WAAW,OAAO,UAAU,OACtC,IAAI,mBAAmB,aACtB,UAAU,KAAK,OAAO;QAGtB,UAAU,KAAK,QAAQ,GAAkB;QAI3C,UAAU,KAAK,OAAO,UAAU,KAAK;EAEvC;EACA,OAAO;CACR;CAEA,MAAM,gBAAgB,WAAsC;EAC3D,MAAM,UAAU,iBAAiB,MAAM;EACvC,IAAI,YAA2B,CAAC;EAChC,IAAI,OAAO,WACV,YAAY,uBAAuB,MAAM;OACnC,IAAI,SAGV,YADkB,MAAM,KAAK,QAAQ,QAAQ,CAAC,CAAC,QAAQ,OAA0B,cAAc,WACnF,CAAA,CAAU,QAAO,aAAY;GAExC,OAAO,YAAY,QAAQ,KAAK,UAAU,QAAQ;EACnD,CAAC;EAEF,OAAO;CACR;CAEA,MAAM,oBAAoB,WAAsC;EAC/D,QAAQ,UAAyB;GAChC,MAAM,YAAY,YAAY,MAAM,QAAQ,MAAM,IAAI,YAAY;GAClE,IAAI,aAAa,SAAS,SAAS,GAAG;GAEtC,MAAM,WAAW,OAAO,YAAY;GACpC,KAAK,MAAM,OAAO,OAAO,KAAK,QAAQ,GAAG;IACxC,MAAM,CAAC,WAAW,GAAG,QAAQ,IAAI,MAAM,GAAG;IAC1C,IAAI,cAAc,WACjB;IAGD,IAAI,KAAK,SAAS,SAAS,GAAG;KAC7B,MAAM,WAAW,SAAS;KAI1B,MAAM,cAAc,KAAK,QAAO,MAAK,aAAa,SAAS,CAAC,CAAC;KAC7D,MAAM,mBAAmB,aAAa,MAAK,OAAM;MAChD,MAAM,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,GAAG,MAAM,CAAC;MAC3D,OAAO,MAAM,iBAAiB,WAAW;KAC1C,CAAC;KAED,IAAI,YAAY,SAAS,GACpB;UAAA,kBACE;YAAA,MAAM,YAAY,cACtB,IAAI,KAAK,SAAS,QAAQ,GAAG;QAE5B,MAAM,cAAc,SAAS,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,SAAS,MAAM,CAAC;QACvE,IAAI,MAAM,iBAAiB,WAAW,GACrC,SAAS,KAAK;OAEhB;;KACD,OAGD,IAAI,CAAC,kBACJ,SAAS,KAAK;IAGjB;GACD;EACD;CACD;CAEA,MAAM,oBAAuC,CAAC;CAC9C,gBAAgB;EACf,KAAK,MAAM,UAAU,SAAS;GAC7B,MAAM,UAAU,iBAAiB,MAAM;GACvC,MAAM,YAAY,aAAa,MAAM;GACrC,MAAM,WAAW,iBAAiB,MAAM;GACxC,MAAM,mBAAmB,UACtB,CAAC,OAAO,IACR;GAEH,KAAK,MAAM,WAAW,kBAAkB;IACvC,MAAM,EAAE,YAAY,eAAe,IAAI,OAAO,CAAC;IAC/C,MAAM,cAAc,MAAM,UAAS,UAAS;KAC3C,IAAI,OACH,QAAQ,iBAAiB,WAAW,QAAQ;UAE5C,QAAQ,oBAAoB,WAAW,QAAQ;IAEjD,CAAC;IACD,kBAAkB,KAAK,WAAW;GACnC;EACD;CACD,CAAC;CAED,sBAAsB;EACrB,KAAK,MAAM,eAAe,mBACzB,YAAY;CAEd,CAAC;AACF;;;;;;;;;;;ACxeA,SAAgB,YAAY,KAA6C;CACxE,IAAI,CAAC,sBAAsB,KAAK,GAAG,GAAG,OAAO,KAAA;CAE7C,IAAI;EACH,OAAO,SAAS,UAAU,KAAK,GAAG;CACnC,QAAQ;EACP;CACD;AACD;;;AChBA,IAAM,SACL;AAED,IAAM,SAAS;AACf,IAAM,gBAAgB;AACtB,IAAM,wBAAwB;AAC9B,IAAM,mBAAmB;AAEzB,IAAM,oBAAoB;;;;;;;AAQ1B,SAAgB,SAAS,MAAuB;CAC/C,OAAO,OAAO,KAAK,IAAI;AACxB;AAEA,IAAM,aAAa,MAAc,cAAoD;CACpF,MAAM,QAAQ,KAAK,QAAQ,SAAS;CACpC,OAAO,UAAU,KAAK,CAAC,MAAM,KAAA,CAAS,IAAI,CAAC,KAAK,MAAM,GAAG,KAAK,GAAG,KAAK,MAAM,QAAQ,CAAC,CAAC;AACvF;;AAGA,IAAM,cAAc,MAAc,OAAe,SAA0B;CAC1E,MAAM,QAAQ,KAAK,MAAM,GAAG;CAC5B,MAAM,SAAS,MAAM,IAAI,KAAK;CAC9B,OAAO,MAAM,OAAM,SAAQ,MAAM,KAAK,IAAI,CAAC,KAAK,KAAK,KAAK,MAAM;AACjE;;;;;;;;AASA,SAAgB,eAAe,MAAuB;CAErD,MAAM,CAAC,MAAM,SAAS,UAAU,MAAM,GAAG;CACzC,MAAM,CAAC,MAAM,cAAc,UAAU,MAAM,GAAG;CAE9C,MAAM,WAAW,eAAe,KAAA,KAAa,UAAU,KAAA;CACvD,MAAM,UAAU,KAAK,MAAM,GAAG,CAAC,CAAC;CAChC,IAAI,UAAU,KAAM,YAAY,UAAU,GAAI,OAAO;CACrD,IAAI,CAAC,WAAW,MAAM,QAAQ,WAAW,SAAS,aAAa,GAAG,OAAO;CAEzE,IAAI,eAAe,KAAA,GAEd;MAAA,CAAC,WAAW,YAAY,uBADf,UAAU,KAAA,IAAY,oBAAoB,qBACA,GAAG,OAAO;CAAA;CAGlE,OAAO,UAAU,KAAA,KAAa,WAAW,OAAO,kBAAkB,iBAAiB;AACpF;AAGA,IAAM,iBAAiB,GAAW,MAAsB,EAAE,SAAS,EAAE,WAAW,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AAEzG,IAAM,sBAAsB,GAAW,MAAsB;CAC5D,MAAM,WAAW,QAAQ,KAAK,CAAC;CAC/B,MAAM,WAAW,QAAQ,KAAK,CAAC;CAC/B,IAAI,YAAY,UAAU,OAAO,cAAc,GAAG,CAAC;CACnD,IAAI,aAAa,UAAU,OAAO,WAAW,KAAK;CAClD,OAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AACjC;AAEA,IAAM,sBAAsB,GAAuB,MAAkC;CACpF,IAAI,MAAM,GAAG,OAAO;CAEpB,IAAI,MAAM,KAAA,GAAW,OAAO;CAC5B,IAAI,MAAM,KAAA,GAAW,OAAO;CAE5B,MAAM,OAAO,EAAE,MAAM,GAAG;CACxB,MAAM,QAAQ,EAAE,MAAM,GAAG;CACzB,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,IAAI,KAAK,QAAQ,MAAM,MAAM,GAAG,KAAK;EAC7D,MAAM,QAAQ,mBAAmB,KAAK,IAAI,MAAM,EAAE;EAClD,IAAI,OAAO,OAAO;CACnB;CACA,OAAO,KAAK,SAAS,MAAM;AAC5B;;;;;;;;;;AAWA,SAAgB,cAAc,GAAW,GAAmB;CAC3D,MAAM,OAAO,OAAO,KAAK,CAAC;CAC1B,MAAM,QAAQ,OAAO,KAAK,CAAC;CAC3B,IAAI,CAAC,QAAQ,CAAC,OAAO,OAAO,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,KAAK;CAEzD,KAAK,IAAI,OAAO,GAAG,QAAQ,GAAG,QAAQ;EACrC,MAAM,QAAQ,cAAc,KAAK,OAAO,MAAM,KAAK;EACnD,IAAI,OAAO,OAAO;CACnB;CACA,OAAO,mBAAmB,KAAK,IAAI,MAAM,EAAE;AAC5C;;;;;;;;AC5FA,SAAS,QAAQ,MAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"utilities.js","names":[],"sources":["../src/composables/visibility/index.ts","../src/composables/keyboard.ts","../src/dates.ts","../src/semver.ts","../src/currencyAmountFormat.ts","../src/denominatedFormat.ts","../src/index.ts"],"sourcesContent":["import {\n\ttype ConfigurableWindow,\n\ttype MaybeComputedElementRef,\n\tdefaultWindow,\n\tunrefElement,\n\tuseEventListener,\n} from '@vueuse/core'\nimport { ref, watch, type MaybeRefOrGetter } from 'vue'\n\nexport interface UseElementVisibilityOptions extends ConfigurableWindow {\n\tscrollTarget?: MaybeRefOrGetter<HTMLElement | undefined | null>\n}\n\n/**\n * Tracks the visibility of an element within the viewport.\n *\n * Compatibility version to get Stonecrop keyboard navigation to work. This function is a copy of the\n * `useElementVisibility` function from VueUse v9.13.0, with the `IntersectionObserver` API removed.\n *\n * This version uses the `getBoundingClientRect` method to determine if an element is visible\n * in the viewport. This is less performant than the `IntersectionObserver` API, but it is\n * more compatible.\n *\n * Note: the newer versions of the VueUse dependencies imported here are sufficient for this composable.\n * (Last verified: v10.9.0 on May 2, 2024)\n *\n * @see https://v9-13-0.vueuse.org/core/useElementVisibility\n * @param element - Element to track visibility for\n * @param options - Configuration options (window, scrollTarget)\n */\nexport function useElementVisibility(\n\telement: MaybeComputedElementRef,\n\t{ window = defaultWindow, scrollTarget }: UseElementVisibilityOptions = {}\n) {\n\tconst elementIsVisible = ref(false)\n\n\tconst testBounding = () => {\n\t\tif (!window) return\n\n\t\tconst document = window.document\n\t\tconst el = unrefElement(element)\n\t\tif (!el) {\n\t\t\telementIsVisible.value = false\n\t\t} else {\n\t\t\tconst rect = el.getBoundingClientRect()\n\t\t\telementIsVisible.value =\n\t\t\t\trect.top <= (window.innerHeight || document.documentElement.clientHeight) &&\n\t\t\t\trect.left <= (window.innerWidth || document.documentElement.clientWidth) &&\n\t\t\t\trect.bottom >= 0 &&\n\t\t\t\trect.right >= 0\n\t\t}\n\t}\n\n\twatch(\n\t\t() => unrefElement(element),\n\t\t() => testBounding(),\n\t\t{ immediate: true, flush: 'post' }\n\t)\n\n\tif (window) {\n\t\tuseEventListener(scrollTarget || window, 'scroll', testBounding, {\n\t\t\tcapture: false,\n\t\t\tpassive: true,\n\t\t})\n\t}\n\n\treturn elementIsVisible\n}\n","import { type WatchStopHandle, onBeforeUnmount, onMounted, ref, watch } from 'vue'\nimport { useFocusWithin } from '@vueuse/core'\n\nimport { useElementVisibility } from './visibility'\nimport type { KeyboardNavigationOptions, KeypressHandlers } from '../types'\n\n// helper functions\nconst isVisible = (element: HTMLElement) => {\n\tlet visible = useElementVisibility(element).value\n\tvisible = visible && element.offsetHeight > 0\n\treturn visible\n}\n\nconst isFocusable = (element: HTMLElement) => {\n\treturn element.tabIndex >= 0\n}\n\n/** When focus is on a control inside a cell, grid navigation still uses the owning `<td>`. */\nconst resolveNavCell = (element: HTMLElement): HTMLElement => {\n\tif (element instanceof HTMLTableCellElement) {\n\t\treturn element\n\t}\n\tconst cell = element.closest('td, th')\n\tif (cell instanceof HTMLTableCellElement) {\n\t\treturn cell\n\t}\n\treturn element\n}\n\n// navigation functions\nconst getUpCell = (event: KeyboardEvent) => {\n\tif (!(event.target instanceof HTMLElement)) return undefined\n\treturn getUpCellEl(resolveNavCell(event.target))\n}\n\nconst getUpCellEl = (element: HTMLElement): HTMLElement | undefined => {\n\tlet $upCell: HTMLElement | undefined\n\tif (element instanceof HTMLTableCellElement) {\n\t\tconst $prevSibling = element.parentElement?.previousElementSibling\n\t\tif ($prevSibling instanceof HTMLTableRowElement) {\n\t\t\tconst $prevRowCells = Array.from($prevSibling.children)\n\t\t\tconst $cellEl = $prevRowCells[element.cellIndex]\n\t\t\tif ($cellEl instanceof HTMLElement) {\n\t\t\t\t$upCell = $cellEl\n\t\t\t}\n\t\t}\n\t} else if (element instanceof HTMLTableRowElement) {\n\t\tconst $prevSibling = element.previousElementSibling\n\t\tif ($prevSibling instanceof HTMLTableRowElement) {\n\t\t\t$upCell = $prevSibling\n\t\t}\n\t} else {\n\t\t// handle other contexts\n\t}\n\tif ($upCell && (!isFocusable($upCell) || !isVisible($upCell))) {\n\t\treturn getUpCellEl($upCell)\n\t}\n\treturn $upCell\n}\n\nconst getTopCell = (event: KeyboardEvent) => {\n\tif (!(event.target instanceof HTMLElement)) return undefined\n\tconst $target = resolveNavCell(event.target)\n\tlet $topCell: HTMLElement | undefined\n\tif ($target instanceof HTMLTableCellElement) {\n\t\tconst $table = $target.parentElement?.parentElement\n\t\tif ($table) {\n\t\t\tconst $firstRow = $table.firstElementChild\n\t\t\tconst $navEl = $firstRow?.children[$target.cellIndex]\n\t\t\tif ($navEl instanceof HTMLElement) {\n\t\t\t\t$topCell = $navEl\n\t\t\t}\n\t\t}\n\t} else if ($target instanceof HTMLTableRowElement) {\n\t\tconst $parent = $target.parentElement\n\t\tif ($parent) {\n\t\t\tconst $firstEl = $parent.firstElementChild\n\t\t\tif ($firstEl instanceof HTMLTableRowElement) {\n\t\t\t\t$topCell = $firstEl\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// handle other contexts\n\t}\n\tif ($topCell && (!isFocusable($topCell) || !isVisible($topCell))) {\n\t\treturn getDownCellEl($topCell)\n\t}\n\treturn $topCell\n}\n\nconst getDownCell = (event: KeyboardEvent) => {\n\tif (!(event.target instanceof HTMLElement)) return undefined\n\treturn getDownCellEl(resolveNavCell(event.target))\n}\n\nconst getDownCellEl = (element: HTMLElement): HTMLElement | undefined => {\n\tlet $downCell: HTMLElement | undefined\n\tif (element instanceof HTMLTableCellElement) {\n\t\tconst $nextSibling = element.parentElement?.nextElementSibling\n\t\tif ($nextSibling) {\n\t\t\tconst $nextRowCells = Array.from($nextSibling.children)\n\t\t\tconst $cellEl = $nextRowCells[element.cellIndex]\n\t\t\tif ($cellEl instanceof HTMLElement) {\n\t\t\t\t$downCell = $cellEl\n\t\t\t}\n\t\t}\n\t} else if (element instanceof HTMLTableRowElement) {\n\t\tconst $nextSibling = element.nextElementSibling\n\t\tif ($nextSibling instanceof HTMLTableRowElement) {\n\t\t\t$downCell = $nextSibling\n\t\t}\n\t} else {\n\t\t// handle other contexts\n\t}\n\tif ($downCell && (!isFocusable($downCell) || !isVisible($downCell))) {\n\t\treturn getDownCellEl($downCell)\n\t}\n\treturn $downCell\n}\n\nconst getBottomCell = (event: KeyboardEvent) => {\n\tif (!(event.target instanceof HTMLElement)) return undefined\n\tconst $target = resolveNavCell(event.target)\n\tlet $bottomCell: HTMLElement | undefined\n\tif ($target instanceof HTMLTableCellElement) {\n\t\tconst $table = $target.parentElement?.parentElement\n\t\tif ($table) {\n\t\t\tconst $lastRow = $table.lastElementChild\n\t\t\tconst $navEl = $lastRow?.children[$target.cellIndex]\n\t\t\tif ($navEl instanceof HTMLElement) {\n\t\t\t\t$bottomCell = $navEl\n\t\t\t}\n\t\t}\n\t} else if ($target instanceof HTMLTableRowElement) {\n\t\tconst $parent = $target.parentElement\n\t\tif ($parent) {\n\t\t\tconst $lastEl = $parent.lastElementChild\n\t\t\tif ($lastEl instanceof HTMLTableRowElement) {\n\t\t\t\t$bottomCell = $lastEl\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// handle other contexts\n\t}\n\tif ($bottomCell && (!isFocusable($bottomCell) || !isVisible($bottomCell))) {\n\t\treturn getUpCellEl($bottomCell)\n\t}\n\treturn $bottomCell\n}\n\nconst getPrevCell = (event: KeyboardEvent) => {\n\tif (!(event.target instanceof HTMLElement)) return undefined\n\treturn getPrevCellEl(resolveNavCell(event.target))\n}\n\nconst getPrevCellEl = (element: HTMLElement): HTMLElement | undefined => {\n\tlet $prevCell: HTMLElement | undefined\n\tconst $prevSibling = element.previousElementSibling\n\tif ($prevSibling instanceof HTMLElement) {\n\t\t$prevCell = $prevSibling\n\t} else {\n\t\tconst $prevRow = element.parentElement?.previousElementSibling\n\t\tconst $lastEl = $prevRow?.lastElementChild\n\t\tif ($lastEl instanceof HTMLElement) {\n\t\t\t$prevCell = $lastEl\n\t\t}\n\t}\n\tif ($prevCell && (!isFocusable($prevCell) || !isVisible($prevCell))) {\n\t\treturn getPrevCellEl($prevCell)\n\t}\n\treturn $prevCell\n}\n\nconst getNextCell = (event: KeyboardEvent) => {\n\tif (!(event.target instanceof HTMLElement)) return undefined\n\treturn getNextCellEl(resolveNavCell(event.target))\n}\n\nconst getNextCellEl = (element: HTMLElement): HTMLElement | undefined => {\n\tlet $nextCell: HTMLElement | undefined\n\tconst $nextSibling = element.nextElementSibling\n\tif ($nextSibling instanceof HTMLElement) {\n\t\t$nextCell = $nextSibling\n\t} else {\n\t\tconst $nextRow = element.parentElement?.nextElementSibling\n\t\tconst $firstEl = $nextRow?.firstElementChild\n\t\tif ($firstEl instanceof HTMLElement) {\n\t\t\t$nextCell = $firstEl\n\t\t}\n\t}\n\tif ($nextCell && (!isFocusable($nextCell) || !isVisible($nextCell))) {\n\t\treturn getNextCellEl($nextCell)\n\t}\n\treturn $nextCell\n}\n\nconst getFirstCell = (event: KeyboardEvent) => {\n\tif (!(event.target instanceof HTMLElement)) return undefined\n\tconst $parent = resolveNavCell(event.target).parentElement\n\tconst $firstEl = $parent?.firstElementChild\n\tconst $firstCell = $firstEl instanceof HTMLElement ? $firstEl : null\n\tif ($firstCell && (!isFocusable($firstCell) || !isVisible($firstCell))) {\n\t\treturn getNextCellEl($firstCell)\n\t}\n\treturn $firstCell\n}\n\nconst getLastCell = (event: KeyboardEvent) => {\n\tif (!(event.target instanceof HTMLElement)) return undefined\n\tconst $parent = resolveNavCell(event.target).parentElement\n\tconst $lastEl = $parent?.lastElementChild\n\tconst $lastCell = $lastEl instanceof HTMLElement ? $lastEl : null\n\tif ($lastCell && (!isFocusable($lastCell) || !isVisible($lastCell))) {\n\t\treturn getPrevCellEl($lastCell)\n\t}\n\treturn $lastCell\n}\n\nconst modifierKeys = ['alt', 'control', 'shift', 'meta']\n\nconst eventKeyMap: Record<string, string> = {\n\tArrowUp: 'up',\n\tArrowDown: 'down',\n\tArrowLeft: 'left',\n\tArrowRight: 'right',\n}\n\n/**\n * Default keypress handlers for keyboard navigation\n * @public\n */\nexport const defaultKeypressHandlers: KeypressHandlers = {\n\t'keydown.up': (event: KeyboardEvent) => {\n\t\tconst $upCell = getUpCell(event)\n\t\tif ($upCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$upCell.focus()\n\t\t}\n\t},\n\t'keydown.down': (event: KeyboardEvent) => {\n\t\tconst $downCell = getDownCell(event)\n\t\tif ($downCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$downCell.focus()\n\t\t}\n\t},\n\t'keydown.left': (event: KeyboardEvent) => {\n\t\tconst $prevCell = getPrevCell(event)\n\t\t// prevent default edit-cell behaviour on first cell\n\t\tevent.preventDefault()\n\t\tevent.stopPropagation()\n\t\tif ($prevCell) {\n\t\t\t$prevCell.focus()\n\t\t}\n\t},\n\t'keydown.right': (event: KeyboardEvent) => {\n\t\tconst $nextCell = getNextCell(event)\n\t\t// prevent default edit-cell behaviour on last cell\n\t\tevent.preventDefault()\n\t\tevent.stopPropagation()\n\t\tif ($nextCell) {\n\t\t\t$nextCell.focus()\n\t\t}\n\t},\n\t'keydown.control.up': (event: KeyboardEvent) => {\n\t\tconst $topCell = getTopCell(event)\n\t\tif ($topCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$topCell.focus()\n\t\t}\n\t},\n\t'keydown.control.down': (event: KeyboardEvent) => {\n\t\tconst $bottomCell = getBottomCell(event)\n\t\tif ($bottomCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$bottomCell.focus()\n\t\t}\n\t},\n\t'keydown.control.left': (event: KeyboardEvent) => {\n\t\tconst $firstCell = getFirstCell(event)\n\t\tif ($firstCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$firstCell.focus()\n\t\t}\n\t},\n\t'keydown.control.right': (event: KeyboardEvent) => {\n\t\tconst $lastCell = getLastCell(event)\n\t\tif ($lastCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$lastCell.focus()\n\t\t}\n\t},\n\t'keydown.end': (event: KeyboardEvent) => {\n\t\tconst $lastCell = getLastCell(event)\n\t\tif ($lastCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$lastCell.focus()\n\t\t}\n\t},\n\t'keydown.enter': (event: KeyboardEvent) => {\n\t\tif (!(event.target instanceof HTMLElement)) return\n\t\tconst $target = resolveNavCell(event.target)\n\t\tif ($target instanceof HTMLTableCellElement) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\tconst $downCell = getDownCell(event)\n\t\t\tif ($downCell) {\n\t\t\t\t$downCell.focus()\n\t\t\t}\n\t\t} else {\n\t\t\t// handle other contexts\n\t\t}\n\t},\n\t'keydown.shift.enter': (event: KeyboardEvent) => {\n\t\tif (!(event.target instanceof HTMLElement)) return\n\t\tconst $target = resolveNavCell(event.target)\n\t\tif ($target instanceof HTMLTableCellElement) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\tconst $upCell = getUpCell(event)\n\t\t\tif ($upCell) {\n\t\t\t\t$upCell.focus()\n\t\t\t}\n\t\t} else {\n\t\t\t// handle other contexts\n\t\t}\n\t},\n\t'keydown.home': (event: KeyboardEvent) => {\n\t\tconst $firstCell = getFirstCell(event)\n\t\tif ($firstCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$firstCell.focus()\n\t\t}\n\t},\n\t'keydown.tab': (event: KeyboardEvent) => {\n\t\tconst $nextCell = getNextCell(event)\n\t\tif ($nextCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$nextCell.focus()\n\t\t}\n\t},\n\t'keydown.shift.tab': (event: KeyboardEvent) => {\n\t\tconst $prevCell = getPrevCell(event)\n\t\tif ($prevCell) {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\t$prevCell.focus()\n\t\t}\n\t},\n}\n\n/**\n * Gets the parent element from a keyboard navigation option.\n * @internal\n */\nfunction getParentElement(option: KeyboardNavigationOptions): HTMLElement | null {\n\tlet $parent: HTMLElement | null = null\n\tif (option.parent) {\n\t\tif (typeof option.parent === 'string') {\n\t\t\t$parent = document.querySelector(option.parent)\n\t\t} else if (option.parent instanceof HTMLElement) {\n\t\t\t$parent = option.parent\n\t\t} else {\n\t\t\t$parent = option.parent.value\n\t\t}\n\t}\n\treturn $parent\n}\n\n/**\n * Keyboard navigation composable\n * @param options - Keyboard navigation options\n * @public\n */\nexport function useKeyboardNav(options: KeyboardNavigationOptions[]) {\n\tconst getSelectorsFromOption = (option: KeyboardNavigationOptions) => {\n\t\t// assumes that option.selectors is provided\n\t\tconst $parent = getParentElement(option)\n\t\tlet selectors: HTMLElement[] = []\n\t\tif (typeof option.selectors === 'string') {\n\t\t\tselectors = $parent\n\t\t\t\t? Array.from($parent.querySelectorAll(option.selectors))\n\t\t\t\t: Array.from(document.querySelectorAll(option.selectors))\n\t\t} else if (Array.isArray(option.selectors)) {\n\t\t\tfor (const element of option.selectors) {\n\t\t\t\tif (element instanceof HTMLElement) {\n\t\t\t\t\tselectors.push(element)\n\t\t\t\t} else {\n\t\t\t\t\t// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Vue component $el is typed as any; shape guaranteed by VNode contract\n\t\t\t\t\tselectors.push(element.$el as HTMLElement)\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (option.selectors instanceof HTMLElement) {\n\t\t\tselectors.push(option.selectors)\n\t\t} else if (option.selectors?.value) {\n\t\t\tif (Array.isArray(option.selectors.value)) {\n\t\t\t\tfor (const element of option.selectors.value) {\n\t\t\t\t\tif (element instanceof HTMLElement) {\n\t\t\t\t\t\tselectors.push(element)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Vue component $el is typed as any; shape guaranteed by VNode contract\n\t\t\t\t\t\tselectors.push(element.$el as HTMLElement)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tselectors.push(option.selectors.value)\n\t\t\t}\n\t\t}\n\t\treturn selectors\n\t}\n\n\tconst getSelectors = (option: KeyboardNavigationOptions) => {\n\t\tconst $parent = getParentElement(option)\n\t\tlet selectors: HTMLElement[] = []\n\t\tif (option.selectors) {\n\t\t\tselectors = getSelectorsFromOption(option)\n\t\t} else if ($parent) {\n\t\t\t// TODO: what should happen if no parent or selectors are provided?\n\t\t\tconst $children = Array.from($parent.children).filter((el): el is HTMLElement => el instanceof HTMLElement)\n\t\t\tselectors = $children.filter(selector => {\n\t\t\t\t// ignore elements not in the tab order or are not visible\n\t\t\t\treturn isFocusable(selector) && isVisible(selector)\n\t\t\t})\n\t\t}\n\t\treturn selectors\n\t}\n\n\tconst getEventListener = (option: KeyboardNavigationOptions) => {\n\t\treturn (event: KeyboardEvent) => {\n\t\t\tconst activeKey = eventKeyMap[event.key] || event.key.toLowerCase()\n\t\t\tif (modifierKeys.includes(activeKey)) return // ignore modifier key presses\n\n\t\t\tconst handlers = option.handlers || defaultKeypressHandlers\n\t\t\tfor (const key of Object.keys(handlers)) {\n\t\t\t\tconst [eventType, ...keys] = key.split('.')\n\t\t\t\tif (eventType !== 'keydown') {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif (keys.includes(activeKey)) {\n\t\t\t\t\tconst listener = handlers[key]\n\n\t\t\t\t\t// check if the handler has modifiers, and if the modifier is active;\n\t\t\t\t\t// this is to ensure exact key-press matches\n\t\t\t\t\tconst hasModifier = keys.filter(k => modifierKeys.includes(k))\n\t\t\t\t\tconst isModifierActive = modifierKeys.some(mk => {\n\t\t\t\t\t\tconst modifierKey = mk.charAt(0).toUpperCase() + mk.slice(1)\n\t\t\t\t\t\treturn event.getModifierState(modifierKey)\n\t\t\t\t\t})\n\n\t\t\t\t\tif (hasModifier.length > 0) {\n\t\t\t\t\t\tif (isModifierActive) {\n\t\t\t\t\t\t\tfor (const modifier of modifierKeys) {\n\t\t\t\t\t\t\t\tif (keys.includes(modifier)) {\n\t\t\t\t\t\t\t\t\t// docs: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/getModifierState\n\t\t\t\t\t\t\t\t\tconst modifierKey = modifier.charAt(0).toUpperCase() + modifier.slice(1)\n\t\t\t\t\t\t\t\t\tif (event.getModifierState(modifierKey)) {\n\t\t\t\t\t\t\t\t\t\tlistener(event)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (!isModifierActive) {\n\t\t\t\t\t\t\tlistener(event)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconst watchStopHandlers: WatchStopHandle[] = []\n\tonMounted(() => {\n\t\tfor (const option of options) {\n\t\t\tconst $parent = getParentElement(option)\n\t\t\tconst selectors = getSelectors(option)\n\t\t\tconst listener = getEventListener(option)\n\t\t\tconst listenerElements = $parent\n\t\t\t\t? [$parent] // watch for focus recursively within the parent element\n\t\t\t\t: selectors // watch for focus on each selector element TODO: too much JS?\n\n\t\t\tfor (const element of listenerElements) {\n\t\t\t\tconst { focused } = useFocusWithin(ref(element))\n\t\t\t\tconst stopHandler = watch(focused, value => {\n\t\t\t\t\tif (value) {\n\t\t\t\t\t\telement.addEventListener('keydown', listener)\n\t\t\t\t\t} else {\n\t\t\t\t\t\telement.removeEventListener('keydown', listener)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\twatchStopHandlers.push(stopHandler)\n\t\t\t}\n\t\t}\n\t})\n\n\tonBeforeUnmount(() => {\n\t\tfor (const stopHandler of watchStopHandlers) {\n\t\t\tstopHandler()\n\t\t}\n\t})\n}\n","import { Temporal } from 'temporal-polyfill'\n\n/**\n * Reads a `YYYY-MM-DD` day. Anything that is not a real day written exactly that way reads as no day.\n *\n * Not `Temporal.PlainDate.from` alone: it also takes the day out of a date-time, which would show a day\n * field over a date-time column as a day instead of as the mismatch it is.\n * @param day - The day, as `YYYY-MM-DD`\n * @public\n */\nexport function fromISODate(day: string): Temporal.PlainDate | undefined {\n\tif (!/^\\d{4}-\\d{2}-\\d{2}$/.test(day)) return undefined\n\n\ttry {\n\t\treturn Temporal.PlainDate.from(day)\n\t} catch {\n\t\treturn undefined\n\t}\n}\n","// SemVer 2.0.0, strictly: https://semver.org. The same grammar the `semver` Postgres extension stores,\n// so a version the form accepts is one the column takes, and the two order versions alike.\nconst SEMVER =\n\t/^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/\n\nconst NUMBER = /^(0|[1-9]\\d*)$/\nconst NUMBER_SO_FAR = /^(0|[1-9]\\d*)?$/\nconst PRERELEASE_IDENTIFIER = /^(0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)$/\nconst BUILD_IDENTIFIER = /^[0-9a-zA-Z-]+$/\n// Any run of identifier characters can still become an identifier: `01` is not one, but `01a` is.\nconst IDENTIFIER_SO_FAR = /^[0-9a-zA-Z-]*$/\n\n/**\n * Whether the text is a version under SemVer 2.0.0: `1.4.0`, `1.4.0-beta.2`, `1.4.0+build.5`. A `v`\n * prefix, a missing part (`1.4`) and a leading zero (`01.4.0`) are not.\n * @param text - The text to check\n * @public\n */\nexport function isSemver(text: string): boolean {\n\treturn SEMVER.test(text)\n}\n\nconst splitOnce = (text: string, separator: string): [string, string | undefined] => {\n\tconst index = text.indexOf(separator)\n\treturn index === -1 ? [text, undefined] : [text.slice(0, index), text.slice(index + 1)]\n}\n\n/** Whether each dot-separated part before the last matches `whole`, and the last matches `last`. */\nconst partsMatch = (text: string, whole: RegExp, last: RegExp): boolean => {\n\tconst parts = text.split('.')\n\tconst typing = parts.pop() ?? ''\n\treturn parts.every(part => whole.test(part)) && last.test(typing)\n}\n\n/**\n * Whether typing more could still make the text a version: `1.`, `1.4.0-` and the empty text can,\n * while `v1`, `01` and `1.4-beta` cannot. Every version passes, so a box that refuses any edit failing\n * this one never stops someone typing a version.\n * @param text - The text so far\n * @public\n */\nexport function isSemverPrefix(text: string): boolean {\n\t// Neither `+` nor `-` can appear in the numbers, so the first of each ends the part before it.\n\tconst [head, build] = splitOnce(text, '+')\n\tconst [core, prerelease] = splitOnce(head, '-')\n\n\tconst coreDone = prerelease !== undefined || build !== undefined\n\tconst numbers = core.split('.').length\n\tif (numbers > 3 || (coreDone && numbers < 3)) return false\n\tif (!partsMatch(core, NUMBER, coreDone ? NUMBER : NUMBER_SO_FAR)) return false\n\n\tif (prerelease !== undefined) {\n\t\tconst last = build === undefined ? IDENTIFIER_SO_FAR : PRERELEASE_IDENTIFIER\n\t\tif (!partsMatch(prerelease, PRERELEASE_IDENTIFIER, last)) return false\n\t}\n\n\treturn build === undefined || partsMatch(build, BUILD_IDENTIFIER, IDENTIFIER_SO_FAR)\n}\n\n// Digits without leading zeros, compared without converting, so no version is too big to order.\nconst compareDigits = (a: string, b: string): number => a.length - b.length || (a < b ? -1 : a > b ? 1 : 0)\n\nconst compareIdentifiers = (a: string, b: string): number => {\n\tconst aNumeric = /^\\d+$/.test(a)\n\tconst bNumeric = /^\\d+$/.test(b)\n\tif (aNumeric && bNumeric) return compareDigits(a, b)\n\tif (aNumeric !== bNumeric) return aNumeric ? -1 : 1\n\treturn a < b ? -1 : a > b ? 1 : 0\n}\n\nconst comparePrereleases = (a: string | undefined, b: string | undefined): number => {\n\tif (a === b) return 0\n\t// A prerelease comes before its release.\n\tif (a === undefined) return 1\n\tif (b === undefined) return -1\n\n\tconst left = a.split('.')\n\tconst right = b.split('.')\n\tfor (let i = 0; i < Math.min(left.length, right.length); i++) {\n\t\tconst order = compareIdentifiers(left[i], right[i])\n\t\tif (order) return order\n\t}\n\treturn left.length - right.length\n}\n\n/**\n * Orders two versions by SemVer 2.0.0 precedence: major, minor and patch as numbers, a prerelease\n * before its release, and prerelease identifiers one by one. Build metadata does not count, so\n * `1.4.0+a` and `1.4.0+b` compare equal. Text that is not a version comes after every version.\n * @param a - The first version\n * @param b - The second version\n * @returns Negative when `a` comes first, positive when `b` does, zero when neither\n * @public\n */\nexport function compareSemver(a: string, b: string): number {\n\tconst left = SEMVER.exec(a)\n\tconst right = SEMVER.exec(b)\n\tif (!left || !right) return Number(!left) - Number(!right)\n\n\tfor (let part = 1; part <= 3; part++) {\n\t\tconst order = compareDigits(left[part], right[part])\n\t\tif (order) return order\n\t}\n\treturn comparePrereleases(left[4], right[4])\n}\n","/**\n * Fraction digits for a currency in amount inputs (e.g. JPY → 0).\n * @public\n */\nexport function currencyInputFractionDigits(currencyId: string | undefined): number {\n\tconst id = currencyId?.toUpperCase() ?? ''\n\tif (!id) return 2\n\ttry {\n\t\treturn (\n\t\t\tnew Intl.NumberFormat('en-US', {\n\t\t\t\tstyle: 'currency',\n\t\t\t\tcurrency: id,\n\t\t\t}).resolvedOptions().maximumFractionDigits ?? 2\n\t\t)\n\t} catch {\n\t\treturn 2\n\t}\n}\n\nfunction separatorsForLocale(locale: string | undefined): { group: string; decimal: string } {\n\tconst parts = new Intl.NumberFormat(locale).formatToParts(1234567.89)\n\treturn {\n\t\tgroup: parts.find(part => part.type === 'group')?.value ?? ',',\n\t\tdecimal: parts.find(part => part.type === 'decimal')?.value ?? '.',\n\t}\n}\n\n/**\n * Format a numeric amount for display in a currency amount field (no currency symbol). The currency\n * sets the decimals; the separators are the locale's, as in the table cell.\n * @param locale - The browser's own when omitted\n * @public\n */\nexport function formatCurrencyAmountInput(\n\tamount: number | null | undefined,\n\tcurrencyId: string | undefined,\n\tlocale?: string\n): string {\n\tif (amount === null || amount === undefined) return ''\n\tconst id = currencyId?.toUpperCase() ?? ''\n\tconst fractionDigits = currencyInputFractionDigits(id)\n\treturn new Intl.NumberFormat(locale, {\n\t\tminimumFractionDigits: fractionDigits,\n\t\tmaximumFractionDigits: fractionDigits,\n\t\tuseGrouping: id !== 'JPY',\n\t}).format(amount)\n}\n\n/**\n * Parse user-entered text in a currency amount field back to a number, read with the separators the\n * field writes it with.\n * @param locale - The browser's own when omitted\n * @public\n */\nexport function parseCurrencyAmountInput(text: string, locale?: string): number | null {\n\tconst { group, decimal } = separatorsForLocale(locale)\n\tconst normalized = text\n\t\t.replace(/\\s/g, '')\n\t\t.replace(/[^\\d.,\\-+]/g, '')\n\t\t.replaceAll(group, '')\n\t\t.replace(decimal, '.')\n\t// No digits is no amount, though `Number('')` is 0.\n\tif (!/\\d/.test(normalized)) return null\n\tconst value = Number(normalized)\n\treturn Number.isFinite(value) ? value : null\n}\n\n/**\n * What a masked currency amount field may hold while it is typed in: digits and grouping marks, then at most one\n * decimal point followed by digits.\n * @param locale - The browser's own when omitted\n * @public\n */\nexport function currencyAmountEntryPattern(currencyId: string | undefined, locale?: string): RegExp {\n\tconst { group, decimal } = separatorsForLocale(locale)\n\tconst escape = (mark: string) => mark.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n\tconst whole = `-?[\\\\d${escape(group)}]*`\n\tif (currencyInputFractionDigits(currencyId) === 0) return new RegExp(`^${whole}$`)\n\t// US-style keyboards often paste/type '.' even when the locale decimal is ','.\n\tconst point = decimal === '.' ? '\\\\.' : `[${escape(decimal)}.]`\n\treturn new RegExp(`^${whole}(?:${point}\\\\d*)?$`)\n}\n","type CurrencyLike = {\n\tid?: string | number\n\tsymbol?: string\n\tdisplayText?: string\n}\n\nfunction displayScalar(value: unknown): string {\n\tif (typeof value === 'string') return value\n\tif (typeof value === 'number' || typeof value === 'bigint') return String(value)\n\tif (typeof value === 'boolean') return String(value)\n\treturn ''\n}\n\nfunction displayQty(qty: unknown): string {\n\tif (qty === null || qty === undefined || qty === '') return ''\n\treturn displayScalar(qty)\n}\n\n/**\n * Format a currency amount for display (forms, table cells). Uses `Intl` when `currency.id` is a\n * valid ISO code; otherwise falls back to symbol, display text, or id.\n * @public\n */\nexport function formatCurrencyAmount(amount: number | null | undefined, currency: CurrencyLike | undefined): string {\n\tif (amount === null || amount === undefined) return ''\n\tconst id = currency?.id != null ? String(currency.id) : ''\n\tif (id) {\n\t\ttry {\n\t\t\treturn new Intl.NumberFormat(undefined, {\n\t\t\t\tstyle: 'currency',\n\t\t\t\tcurrency: id,\n\t\t\t\tcurrencyDisplay: 'symbol',\n\t\t\t}).format(amount)\n\t\t} catch {\n\t\t\t// Not a valid ISO 4217 code — fall through to symbol / displayText.\n\t\t}\n\t}\n\tconst suffix = currency?.symbol ?? currency?.displayText ?? id\n\treturn suffix ? `${amount} ${suffix}`.trim() : String(amount)\n}\n\n/**\n * Render a composite quantity value for table cells. Omits the UOM when it matches `stockUom`.\n * @public\n */\nexport function formatQuantityCell(value: unknown): string {\n\tif (value === null || value === undefined) return ''\n\tif (typeof value !== 'object') return displayScalar(value)\n\tconst record = value as { qty?: unknown; uom?: string; stockUom?: string }\n\tconst qtyText = displayQty(record.qty)\n\tconst uom = record.uom ?? ''\n\tconst stockUom = record.stockUom ?? ''\n\tif (!uom) return qtyText\n\tif (stockUom && uom === stockUom) return qtyText\n\treturn `${qtyText} ${uom}`.trim()\n}\n\n/**\n * Render a composite currency value for table cells.\n * @public\n */\nexport function formatCurrencyCell(value: unknown): string {\n\tif (value === null || value === undefined) return ''\n\tif (typeof value !== 'object') return displayScalar(value)\n\tconst record = value as { amount?: number | null; currency?: CurrencyLike }\n\treturn formatCurrencyAmount(record.amount, record.currency)\n}\n","import { App } from 'vue'\n\nimport { defaultKeypressHandlers, useKeyboardNav } from './composables/keyboard'\nimport { fromISODate } from './dates'\nimport { compareSemver, isSemver, isSemverPrefix } from './semver'\nexport type * from './types'\n\n/**\n * Install all utility components\n * @param _app - Vue app instance\n * @public\n */\nfunction install(_app: App /* options */) {}\n\nexport {\n\tcurrencyAmountEntryPattern,\n\tcurrencyInputFractionDigits,\n\tformatCurrencyAmountInput,\n\tparseCurrencyAmountInput,\n} from './currencyAmountFormat'\nexport { formatCurrencyAmount, formatCurrencyCell, formatQuantityCell } from './denominatedFormat'\nexport { compareSemver, defaultKeypressHandlers, fromISODate, install, isSemver, isSemverPrefix, useKeyboardNav }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA8BA,SAAgB,qBACf,SACA,EAAE,SAAS,eAAe,iBAA8C,CAAC,GACxE;CACD,MAAM,mBAAmB,IAAI,KAAK;CAElC,MAAM,qBAAqB;EAC1B,IAAI,CAAC,QAAQ;EAEb,MAAM,WAAW,OAAO;EACxB,MAAM,KAAK,aAAa,OAAO;EAC/B,IAAI,CAAC,IACJ,iBAAiB,QAAQ;OACnB;GACN,MAAM,OAAO,GAAG,sBAAsB;GACtC,iBAAiB,QAChB,KAAK,QAAQ,OAAO,eAAe,SAAS,gBAAgB,iBAC5D,KAAK,SAAS,OAAO,cAAc,SAAS,gBAAgB,gBAC5D,KAAK,UAAU,KACf,KAAK,SAAS;EAChB;CACD;CAEA,YACO,aAAa,OAAO,SACpB,aAAa,GACnB;EAAE,WAAW;EAAM,OAAO;CAAO,CAClC;CAEA,IAAI,QACH,iBAAiB,gBAAgB,QAAQ,UAAU,cAAc;EAChE,SAAS;EACT,SAAS;CACV,CAAC;CAGF,OAAO;AACR;;;AC5DA,IAAM,aAAa,YAAyB;CAC3C,IAAI,UAAU,qBAAqB,OAAO,CAAC,CAAC;CAC5C,UAAU,WAAW,QAAQ,eAAe;CAC5C,OAAO;AACR;AAEA,IAAM,eAAe,YAAyB;CAC7C,OAAO,QAAQ,YAAY;AAC5B;;AAGA,IAAM,kBAAkB,YAAsC;CAC7D,IAAI,mBAAmB,sBACtB,OAAO;CAER,MAAM,OAAO,QAAQ,QAAQ,QAAQ;CACrC,IAAI,gBAAgB,sBACnB,OAAO;CAER,OAAO;AACR;AAGA,IAAM,aAAa,UAAyB;CAC3C,IAAI,EAAE,MAAM,kBAAkB,cAAc,OAAO,KAAA;CACnD,OAAO,YAAY,eAAe,MAAM,MAAM,CAAC;AAChD;AAEA,IAAM,eAAe,YAAkD;CACtE,IAAI;CACJ,IAAI,mBAAmB,sBAAsB;EAC5C,MAAM,eAAe,QAAQ,eAAe;EAC5C,IAAI,wBAAwB,qBAAqB;GAEhD,MAAM,UADgB,MAAM,KAAK,aAAa,QAC9B,CAAA,CAAc,QAAQ;GACtC,IAAI,mBAAmB,aACtB,UAAU;EAEZ;CACD,OAAO,IAAI,mBAAmB,qBAAqB;EAClD,MAAM,eAAe,QAAQ;EAC7B,IAAI,wBAAwB,qBAC3B,UAAU;CAEZ;CAGA,IAAI,YAAY,CAAC,YAAY,OAAO,KAAK,CAAC,UAAU,OAAO,IAC1D,OAAO,YAAY,OAAO;CAE3B,OAAO;AACR;AAEA,IAAM,cAAc,UAAyB;CAC5C,IAAI,EAAE,MAAM,kBAAkB,cAAc,OAAO,KAAA;CACnD,MAAM,UAAU,eAAe,MAAM,MAAM;CAC3C,IAAI;CACJ,IAAI,mBAAmB,sBAAsB;EAC5C,MAAM,SAAS,QAAQ,eAAe;EACtC,IAAI,QAAQ;GAEX,MAAM,SADY,OAAO,mBACC,SAAS,QAAQ;GAC3C,IAAI,kBAAkB,aACrB,WAAW;EAEb;CACD,OAAO,IAAI,mBAAmB,qBAAqB;EAClD,MAAM,UAAU,QAAQ;EACxB,IAAI,SAAS;GACZ,MAAM,WAAW,QAAQ;GACzB,IAAI,oBAAoB,qBACvB,WAAW;EAEb;CACD;CAGA,IAAI,aAAa,CAAC,YAAY,QAAQ,KAAK,CAAC,UAAU,QAAQ,IAC7D,OAAO,cAAc,QAAQ;CAE9B,OAAO;AACR;AAEA,IAAM,eAAe,UAAyB;CAC7C,IAAI,EAAE,MAAM,kBAAkB,cAAc,OAAO,KAAA;CACnD,OAAO,cAAc,eAAe,MAAM,MAAM,CAAC;AAClD;AAEA,IAAM,iBAAiB,YAAkD;CACxE,IAAI;CACJ,IAAI,mBAAmB,sBAAsB;EAC5C,MAAM,eAAe,QAAQ,eAAe;EAC5C,IAAI,cAAc;GAEjB,MAAM,UADgB,MAAM,KAAK,aAAa,QAC9B,CAAA,CAAc,QAAQ;GACtC,IAAI,mBAAmB,aACtB,YAAY;EAEd;CACD,OAAO,IAAI,mBAAmB,qBAAqB;EAClD,MAAM,eAAe,QAAQ;EAC7B,IAAI,wBAAwB,qBAC3B,YAAY;CAEd;CAGA,IAAI,cAAc,CAAC,YAAY,SAAS,KAAK,CAAC,UAAU,SAAS,IAChE,OAAO,cAAc,SAAS;CAE/B,OAAO;AACR;AAEA,IAAM,iBAAiB,UAAyB;CAC/C,IAAI,EAAE,MAAM,kBAAkB,cAAc,OAAO,KAAA;CACnD,MAAM,UAAU,eAAe,MAAM,MAAM;CAC3C,IAAI;CACJ,IAAI,mBAAmB,sBAAsB;EAC5C,MAAM,SAAS,QAAQ,eAAe;EACtC,IAAI,QAAQ;GAEX,MAAM,SADW,OAAO,kBACC,SAAS,QAAQ;GAC1C,IAAI,kBAAkB,aACrB,cAAc;EAEhB;CACD,OAAO,IAAI,mBAAmB,qBAAqB;EAClD,MAAM,UAAU,QAAQ;EACxB,IAAI,SAAS;GACZ,MAAM,UAAU,QAAQ;GACxB,IAAI,mBAAmB,qBACtB,cAAc;EAEhB;CACD;CAGA,IAAI,gBAAgB,CAAC,YAAY,WAAW,KAAK,CAAC,UAAU,WAAW,IACtE,OAAO,YAAY,WAAW;CAE/B,OAAO;AACR;AAEA,IAAM,eAAe,UAAyB;CAC7C,IAAI,EAAE,MAAM,kBAAkB,cAAc,OAAO,KAAA;CACnD,OAAO,cAAc,eAAe,MAAM,MAAM,CAAC;AAClD;AAEA,IAAM,iBAAiB,YAAkD;CACxE,IAAI;CACJ,MAAM,eAAe,QAAQ;CAC7B,IAAI,wBAAwB,aAC3B,YAAY;MACN;EAEN,MAAM,WADW,QAAQ,eAAe,uBAAA,EACd;EAC1B,IAAI,mBAAmB,aACtB,YAAY;CAEd;CACA,IAAI,cAAc,CAAC,YAAY,SAAS,KAAK,CAAC,UAAU,SAAS,IAChE,OAAO,cAAc,SAAS;CAE/B,OAAO;AACR;AAEA,IAAM,eAAe,UAAyB;CAC7C,IAAI,EAAE,MAAM,kBAAkB,cAAc,OAAO,KAAA;CACnD,OAAO,cAAc,eAAe,MAAM,MAAM,CAAC;AAClD;AAEA,IAAM,iBAAiB,YAAkD;CACxE,IAAI;CACJ,MAAM,eAAe,QAAQ;CAC7B,IAAI,wBAAwB,aAC3B,YAAY;MACN;EAEN,MAAM,YADW,QAAQ,eAAe,mBAAA,EACb;EAC3B,IAAI,oBAAoB,aACvB,YAAY;CAEd;CACA,IAAI,cAAc,CAAC,YAAY,SAAS,KAAK,CAAC,UAAU,SAAS,IAChE,OAAO,cAAc,SAAS;CAE/B,OAAO;AACR;AAEA,IAAM,gBAAgB,UAAyB;CAC9C,IAAI,EAAE,MAAM,kBAAkB,cAAc,OAAO,KAAA;CAEnD,MAAM,WADU,eAAe,MAAM,MAAM,CAAC,CAAC,eACnB;CAC1B,MAAM,aAAa,oBAAoB,cAAc,WAAW;CAChE,IAAI,eAAe,CAAC,YAAY,UAAU,KAAK,CAAC,UAAU,UAAU,IACnE,OAAO,cAAc,UAAU;CAEhC,OAAO;AACR;AAEA,IAAM,eAAe,UAAyB;CAC7C,IAAI,EAAE,MAAM,kBAAkB,cAAc,OAAO,KAAA;CAEnD,MAAM,UADU,eAAe,MAAM,MAAM,CAAC,CAAC,eACpB;CACzB,MAAM,YAAY,mBAAmB,cAAc,UAAU;CAC7D,IAAI,cAAc,CAAC,YAAY,SAAS,KAAK,CAAC,UAAU,SAAS,IAChE,OAAO,cAAc,SAAS;CAE/B,OAAO;AACR;AAEA,IAAM,eAAe;CAAC;CAAO;CAAW;CAAS;AAAM;AAEvD,IAAM,cAAsC;CAC3C,SAAS;CACT,WAAW;CACX,WAAW;CACX,YAAY;AACb;;;;;AAMA,IAAa,0BAA4C;CACxD,eAAe,UAAyB;EACvC,MAAM,UAAU,UAAU,KAAK;EAC/B,IAAI,SAAS;GACZ,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,QAAQ,MAAM;EACf;CACD;CACA,iBAAiB,UAAyB;EACzC,MAAM,YAAY,YAAY,KAAK;EACnC,IAAI,WAAW;GACd,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,UAAU,MAAM;EACjB;CACD;CACA,iBAAiB,UAAyB;EACzC,MAAM,YAAY,YAAY,KAAK;EAEnC,MAAM,eAAe;EACrB,MAAM,gBAAgB;EACtB,IAAI,WACH,UAAU,MAAM;CAElB;CACA,kBAAkB,UAAyB;EAC1C,MAAM,YAAY,YAAY,KAAK;EAEnC,MAAM,eAAe;EACrB,MAAM,gBAAgB;EACtB,IAAI,WACH,UAAU,MAAM;CAElB;CACA,uBAAuB,UAAyB;EAC/C,MAAM,WAAW,WAAW,KAAK;EACjC,IAAI,UAAU;GACb,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,SAAS,MAAM;EAChB;CACD;CACA,yBAAyB,UAAyB;EACjD,MAAM,cAAc,cAAc,KAAK;EACvC,IAAI,aAAa;GAChB,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,YAAY,MAAM;EACnB;CACD;CACA,yBAAyB,UAAyB;EACjD,MAAM,aAAa,aAAa,KAAK;EACrC,IAAI,YAAY;GACf,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,WAAW,MAAM;EAClB;CACD;CACA,0BAA0B,UAAyB;EAClD,MAAM,YAAY,YAAY,KAAK;EACnC,IAAI,WAAW;GACd,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,UAAU,MAAM;EACjB;CACD;CACA,gBAAgB,UAAyB;EACxC,MAAM,YAAY,YAAY,KAAK;EACnC,IAAI,WAAW;GACd,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,UAAU,MAAM;EACjB;CACD;CACA,kBAAkB,UAAyB;EAC1C,IAAI,EAAE,MAAM,kBAAkB,cAAc;EAE5C,IADgB,eAAe,MAAM,MACjC,aAAmB,sBAAsB;GAC5C,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,MAAM,YAAY,YAAY,KAAK;GACnC,IAAI,WACH,UAAU,MAAM;EAElB;CAGD;CACA,wBAAwB,UAAyB;EAChD,IAAI,EAAE,MAAM,kBAAkB,cAAc;EAE5C,IADgB,eAAe,MAAM,MACjC,aAAmB,sBAAsB;GAC5C,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,MAAM,UAAU,UAAU,KAAK;GAC/B,IAAI,SACH,QAAQ,MAAM;EAEhB;CAGD;CACA,iBAAiB,UAAyB;EACzC,MAAM,aAAa,aAAa,KAAK;EACrC,IAAI,YAAY;GACf,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,WAAW,MAAM;EAClB;CACD;CACA,gBAAgB,UAAyB;EACxC,MAAM,YAAY,YAAY,KAAK;EACnC,IAAI,WAAW;GACd,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,UAAU,MAAM;EACjB;CACD;CACA,sBAAsB,UAAyB;EAC9C,MAAM,YAAY,YAAY,KAAK;EACnC,IAAI,WAAW;GACd,MAAM,eAAe;GACrB,MAAM,gBAAgB;GACtB,UAAU,MAAM;EACjB;CACD;AACD;;;;;AAMA,SAAS,iBAAiB,QAAuD;CAChF,IAAI,UAA8B;CAClC,IAAI,OAAO,QAAQ;EAClB,IAAI,OAAO,OAAO,WAAW,UAC5B,UAAU,SAAS,cAAc,OAAO,MAAM;OACxC,IAAI,OAAO,kBAAkB,aACnC,UAAU,OAAO;OAEjB,UAAU,OAAO,OAAO;CAE1B;CACA,OAAO;AACR;;;;;;AAOA,SAAgB,eAAe,SAAsC;CACpE,MAAM,0BAA0B,WAAsC;EAErE,MAAM,UAAU,iBAAiB,MAAM;EACvC,IAAI,YAA2B,CAAC;EAChC,IAAI,OAAO,OAAO,cAAc,UAC/B,YAAY,UACT,MAAM,KAAK,QAAQ,iBAAiB,OAAO,SAAS,CAAC,IACrD,MAAM,KAAK,SAAS,iBAAiB,OAAO,SAAS,CAAC;OACnD,IAAI,MAAM,QAAQ,OAAO,SAAS,GACxC,KAAK,MAAM,WAAW,OAAO,WAC5B,IAAI,mBAAmB,aACtB,UAAU,KAAK,OAAO;OAGtB,UAAU,KAAK,QAAQ,GAAkB;OAGrC,IAAI,OAAO,qBAAqB,aACtC,UAAU,KAAK,OAAO,SAAS;OACzB,IAAI,OAAO,WAAW,OAAO;GACnC,IAAI,MAAM,QAAQ,OAAO,UAAU,KAAK,GACvC,KAAK,MAAM,WAAW,OAAO,UAAU,OACtC,IAAI,mBAAmB,aACtB,UAAU,KAAK,OAAO;QAGtB,UAAU,KAAK,QAAQ,GAAkB;QAI3C,UAAU,KAAK,OAAO,UAAU,KAAK;EAEvC;EACA,OAAO;CACR;CAEA,MAAM,gBAAgB,WAAsC;EAC3D,MAAM,UAAU,iBAAiB,MAAM;EACvC,IAAI,YAA2B,CAAC;EAChC,IAAI,OAAO,WACV,YAAY,uBAAuB,MAAM;OACnC,IAAI,SAGV,YADkB,MAAM,KAAK,QAAQ,QAAQ,CAAC,CAAC,QAAQ,OAA0B,cAAc,WACnF,CAAA,CAAU,QAAO,aAAY;GAExC,OAAO,YAAY,QAAQ,KAAK,UAAU,QAAQ;EACnD,CAAC;EAEF,OAAO;CACR;CAEA,MAAM,oBAAoB,WAAsC;EAC/D,QAAQ,UAAyB;GAChC,MAAM,YAAY,YAAY,MAAM,QAAQ,MAAM,IAAI,YAAY;GAClE,IAAI,aAAa,SAAS,SAAS,GAAG;GAEtC,MAAM,WAAW,OAAO,YAAY;GACpC,KAAK,MAAM,OAAO,OAAO,KAAK,QAAQ,GAAG;IACxC,MAAM,CAAC,WAAW,GAAG,QAAQ,IAAI,MAAM,GAAG;IAC1C,IAAI,cAAc,WACjB;IAGD,IAAI,KAAK,SAAS,SAAS,GAAG;KAC7B,MAAM,WAAW,SAAS;KAI1B,MAAM,cAAc,KAAK,QAAO,MAAK,aAAa,SAAS,CAAC,CAAC;KAC7D,MAAM,mBAAmB,aAAa,MAAK,OAAM;MAChD,MAAM,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,GAAG,MAAM,CAAC;MAC3D,OAAO,MAAM,iBAAiB,WAAW;KAC1C,CAAC;KAED,IAAI,YAAY,SAAS,GACpB;UAAA,kBACE;YAAA,MAAM,YAAY,cACtB,IAAI,KAAK,SAAS,QAAQ,GAAG;QAE5B,MAAM,cAAc,SAAS,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,SAAS,MAAM,CAAC;QACvE,IAAI,MAAM,iBAAiB,WAAW,GACrC,SAAS,KAAK;OAEhB;;KACD,OAGD,IAAI,CAAC,kBACJ,SAAS,KAAK;IAGjB;GACD;EACD;CACD;CAEA,MAAM,oBAAuC,CAAC;CAC9C,gBAAgB;EACf,KAAK,MAAM,UAAU,SAAS;GAC7B,MAAM,UAAU,iBAAiB,MAAM;GACvC,MAAM,YAAY,aAAa,MAAM;GACrC,MAAM,WAAW,iBAAiB,MAAM;GACxC,MAAM,mBAAmB,UACtB,CAAC,OAAO,IACR;GAEH,KAAK,MAAM,WAAW,kBAAkB;IACvC,MAAM,EAAE,YAAY,eAAe,IAAI,OAAO,CAAC;IAC/C,MAAM,cAAc,MAAM,UAAS,UAAS;KAC3C,IAAI,OACH,QAAQ,iBAAiB,WAAW,QAAQ;UAE5C,QAAQ,oBAAoB,WAAW,QAAQ;IAEjD,CAAC;IACD,kBAAkB,KAAK,WAAW;GACnC;EACD;CACD,CAAC;CAED,sBAAsB;EACrB,KAAK,MAAM,eAAe,mBACzB,YAAY;CAEd,CAAC;AACF;;;;;;;;;;;ACpfA,SAAgB,YAAY,KAA6C;CACxE,IAAI,CAAC,sBAAsB,KAAK,GAAG,GAAG,OAAO,KAAA;CAE7C,IAAI;EACH,OAAO,SAAS,UAAU,KAAK,GAAG;CACnC,QAAQ;EACP;CACD;AACD;;;AChBA,IAAM,SACL;AAED,IAAM,SAAS;AACf,IAAM,gBAAgB;AACtB,IAAM,wBAAwB;AAC9B,IAAM,mBAAmB;AAEzB,IAAM,oBAAoB;;;;;;;AAQ1B,SAAgB,SAAS,MAAuB;CAC/C,OAAO,OAAO,KAAK,IAAI;AACxB;AAEA,IAAM,aAAa,MAAc,cAAoD;CACpF,MAAM,QAAQ,KAAK,QAAQ,SAAS;CACpC,OAAO,UAAU,KAAK,CAAC,MAAM,KAAA,CAAS,IAAI,CAAC,KAAK,MAAM,GAAG,KAAK,GAAG,KAAK,MAAM,QAAQ,CAAC,CAAC;AACvF;;AAGA,IAAM,cAAc,MAAc,OAAe,SAA0B;CAC1E,MAAM,QAAQ,KAAK,MAAM,GAAG;CAC5B,MAAM,SAAS,MAAM,IAAI,KAAK;CAC9B,OAAO,MAAM,OAAM,SAAQ,MAAM,KAAK,IAAI,CAAC,KAAK,KAAK,KAAK,MAAM;AACjE;;;;;;;;AASA,SAAgB,eAAe,MAAuB;CAErD,MAAM,CAAC,MAAM,SAAS,UAAU,MAAM,GAAG;CACzC,MAAM,CAAC,MAAM,cAAc,UAAU,MAAM,GAAG;CAE9C,MAAM,WAAW,eAAe,KAAA,KAAa,UAAU,KAAA;CACvD,MAAM,UAAU,KAAK,MAAM,GAAG,CAAC,CAAC;CAChC,IAAI,UAAU,KAAM,YAAY,UAAU,GAAI,OAAO;CACrD,IAAI,CAAC,WAAW,MAAM,QAAQ,WAAW,SAAS,aAAa,GAAG,OAAO;CAEzE,IAAI,eAAe,KAAA,GAEd;MAAA,CAAC,WAAW,YAAY,uBADf,UAAU,KAAA,IAAY,oBAAoB,qBACA,GAAG,OAAO;CAAA;CAGlE,OAAO,UAAU,KAAA,KAAa,WAAW,OAAO,kBAAkB,iBAAiB;AACpF;AAGA,IAAM,iBAAiB,GAAW,MAAsB,EAAE,SAAS,EAAE,WAAW,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AAEzG,IAAM,sBAAsB,GAAW,MAAsB;CAC5D,MAAM,WAAW,QAAQ,KAAK,CAAC;CAC/B,MAAM,WAAW,QAAQ,KAAK,CAAC;CAC/B,IAAI,YAAY,UAAU,OAAO,cAAc,GAAG,CAAC;CACnD,IAAI,aAAa,UAAU,OAAO,WAAW,KAAK;CAClD,OAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI;AACjC;AAEA,IAAM,sBAAsB,GAAuB,MAAkC;CACpF,IAAI,MAAM,GAAG,OAAO;CAEpB,IAAI,MAAM,KAAA,GAAW,OAAO;CAC5B,IAAI,MAAM,KAAA,GAAW,OAAO;CAE5B,MAAM,OAAO,EAAE,MAAM,GAAG;CACxB,MAAM,QAAQ,EAAE,MAAM,GAAG;CACzB,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,IAAI,KAAK,QAAQ,MAAM,MAAM,GAAG,KAAK;EAC7D,MAAM,QAAQ,mBAAmB,KAAK,IAAI,MAAM,EAAE;EAClD,IAAI,OAAO,OAAO;CACnB;CACA,OAAO,KAAK,SAAS,MAAM;AAC5B;;;;;;;;;;AAWA,SAAgB,cAAc,GAAW,GAAmB;CAC3D,MAAM,OAAO,OAAO,KAAK,CAAC;CAC1B,MAAM,QAAQ,OAAO,KAAK,CAAC;CAC3B,IAAI,CAAC,QAAQ,CAAC,OAAO,OAAO,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,KAAK;CAEzD,KAAK,IAAI,OAAO,GAAG,QAAQ,GAAG,QAAQ;EACrC,MAAM,QAAQ,cAAc,KAAK,OAAO,MAAM,KAAK;EACnD,IAAI,OAAO,OAAO;CACnB;CACA,OAAO,mBAAmB,KAAK,IAAI,MAAM,EAAE;AAC5C;;;;;;;ACpGA,SAAgB,4BAA4B,YAAwC;CACnF,MAAM,KAAK,YAAY,YAAY,KAAK;CACxC,IAAI,CAAC,IAAI,OAAO;CAChB,IAAI;EACH,OACC,IAAI,KAAK,aAAa,SAAS;GAC9B,OAAO;GACP,UAAU;EACX,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,yBAAyB;CAEhD,QAAQ;EACP,OAAO;CACR;AACD;AAEA,SAAS,oBAAoB,QAAgE;CAC5F,MAAM,QAAQ,IAAI,KAAK,aAAa,MAAM,CAAC,CAAC,cAAc,UAAU;CACpE,OAAO;EACN,OAAO,MAAM,MAAK,SAAQ,KAAK,SAAS,OAAO,CAAC,EAAE,SAAS;EAC3D,SAAS,MAAM,MAAK,SAAQ,KAAK,SAAS,SAAS,CAAC,EAAE,SAAS;CAChE;AACD;;;;;;;AAQA,SAAgB,0BACf,QACA,YACA,QACS;CACT,IAAI,WAAW,QAAQ,WAAW,KAAA,GAAW,OAAO;CACpD,MAAM,KAAK,YAAY,YAAY,KAAK;CACxC,MAAM,iBAAiB,4BAA4B,EAAE;CACrD,OAAO,IAAI,KAAK,aAAa,QAAQ;EACpC,uBAAuB;EACvB,uBAAuB;EACvB,aAAa,OAAO;CACrB,CAAC,CAAC,CAAC,OAAO,MAAM;AACjB;;;;;;;AAQA,SAAgB,yBAAyB,MAAc,QAAgC;CACtF,MAAM,EAAE,OAAO,YAAY,oBAAoB,MAAM;CACrD,MAAM,aAAa,KACjB,QAAQ,OAAO,EAAE,CAAC,CAClB,QAAQ,eAAe,EAAE,CAAC,CAC1B,WAAW,OAAO,EAAE,CAAC,CACrB,QAAQ,SAAS,GAAG;CAEtB,IAAI,CAAC,KAAK,KAAK,UAAU,GAAG,OAAO;CACnC,MAAM,QAAQ,OAAO,UAAU;CAC/B,OAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AACzC;;;;;;;AAQA,SAAgB,2BAA2B,YAAgC,QAAyB;CACnG,MAAM,EAAE,OAAO,YAAY,oBAAoB,MAAM;CACrD,MAAM,UAAU,SAAiB,KAAK,QAAQ,uBAAuB,MAAM;CAC3E,MAAM,QAAQ,SAAS,OAAO,KAAK,EAAE;CACrC,IAAI,4BAA4B,UAAU,MAAM,GAAG,OAAO,IAAI,OAAO,IAAI,MAAM,EAAE;CAEjF,MAAM,QAAQ,YAAY,MAAM,QAAQ,IAAI,OAAO,OAAO,EAAE;CAC5D,OAAO,IAAI,OAAO,IAAI,MAAM,KAAK,MAAM,QAAQ;AAChD;;;AC3EA,SAAS,cAAc,OAAwB;CAC9C,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU,OAAO,OAAO,KAAK;CAC/E,IAAI,OAAO,UAAU,WAAW,OAAO,OAAO,KAAK;CACnD,OAAO;AACR;AAEA,SAAS,WAAW,KAAsB;CACzC,IAAI,QAAQ,QAAQ,QAAQ,KAAA,KAAa,QAAQ,IAAI,OAAO;CAC5D,OAAO,cAAc,GAAG;AACzB;;;;;;AAOA,SAAgB,qBAAqB,QAAmC,UAA4C;CACnH,IAAI,WAAW,QAAQ,WAAW,KAAA,GAAW,OAAO;CACpD,MAAM,KAAK,UAAU,MAAM,OAAO,OAAO,SAAS,EAAE,IAAI;CACxD,IAAI,IACH,IAAI;EACH,OAAO,IAAI,KAAK,aAAa,KAAA,GAAW;GACvC,OAAO;GACP,UAAU;GACV,iBAAiB;EAClB,CAAC,CAAC,CAAC,OAAO,MAAM;CACjB,QAAQ,CAER;CAED,MAAM,SAAS,UAAU,UAAU,UAAU,eAAe;CAC5D,OAAO,SAAS,GAAG,OAAO,GAAG,SAAS,KAAK,IAAI,OAAO,MAAM;AAC7D;;;;;AAMA,SAAgB,mBAAmB,OAAwB;CAC1D,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW,OAAO;CAClD,IAAI,OAAO,UAAU,UAAU,OAAO,cAAc,KAAK;CACzD,MAAM,SAAS;CACf,MAAM,UAAU,WAAW,OAAO,GAAG;CACrC,MAAM,MAAM,OAAO,OAAO;CAC1B,MAAM,WAAW,OAAO,YAAY;CACpC,IAAI,CAAC,KAAK,OAAO;CACjB,IAAI,YAAY,QAAQ,UAAU,OAAO;CACzC,OAAO,GAAG,QAAQ,GAAG,MAAM,KAAK;AACjC;;;;;AAMA,SAAgB,mBAAmB,OAAwB;CAC1D,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW,OAAO;CAClD,IAAI,OAAO,UAAU,UAAU,OAAO,cAAc,KAAK;CACzD,MAAM,SAAS;CACf,OAAO,qBAAqB,OAAO,QAAQ,OAAO,QAAQ;AAC3D;;;;;;;;ACtDA,SAAS,QAAQ,MAAyB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stonecrop/utilities",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0",
|
|
4
4
|
"description": "Shared utility functions for Stonecrop",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"helpers",
|
|
@@ -46,14 +46,14 @@
|
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@microsoft/api-extractor": "^7.58.7",
|
|
48
48
|
"@vitejs/plugin-vue": "^6.0.6",
|
|
49
|
-
"@vitest/coverage-istanbul": "
|
|
49
|
+
"@vitest/coverage-istanbul": "5.0.1",
|
|
50
50
|
"@vue/test-utils": "^2.4.10",
|
|
51
51
|
"jsdom": "^29.1.1",
|
|
52
52
|
"oxlint": "1.67.0",
|
|
53
53
|
"oxlint-tsgolint": "0.23.0",
|
|
54
54
|
"typescript": "^6.0.3",
|
|
55
55
|
"vite": "^8.2.2",
|
|
56
|
-
"vitest": "
|
|
56
|
+
"vitest": "5.0.1",
|
|
57
57
|
"vue": "^3.5.33",
|
|
58
58
|
"vue-router": "^5.0.6"
|
|
59
59
|
},
|