bruh 1.13.1 → 2.0.0-beta.1
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/browser/jsx-runtime.mjs +2 -0
- package/dist/browser/jsx-runtime.mjs.map +1 -0
- package/dist/browser.mjs +174 -0
- package/dist/browser.mjs.map +1 -0
- package/dist/cli/node.mjs +16 -0
- package/dist/cli/node.mjs.map +1 -0
- package/dist/components/aside-toc.mjs +162 -0
- package/dist/components/aside-toc.mjs.map +1 -0
- package/dist/components/custom-elements.mjs +52 -0
- package/dist/components/custom-elements.mjs.map +1 -0
- package/dist/components/intl/date-time.mjs +219 -0
- package/dist/components/intl/date-time.mjs.map +1 -0
- package/dist/components/intl/display-name.mjs +71 -0
- package/dist/components/intl/display-name.mjs.map +1 -0
- package/dist/components/intl/language-picker.mjs +102 -0
- package/dist/components/intl/language-picker.mjs.map +1 -0
- package/dist/components/intl/list.mjs +80 -0
- package/dist/components/intl/list.mjs.map +1 -0
- package/dist/components/intl/number.mjs +118 -0
- package/dist/components/intl/number.mjs.map +1 -0
- package/dist/components/intl/plural.mjs +82 -0
- package/dist/components/intl/plural.mjs.map +1 -0
- package/dist/components/intl/utils.mjs +197 -0
- package/dist/components/intl/utils.mjs.map +1 -0
- package/dist/components/optimized-picture/hydrate.mjs +10 -0
- package/dist/components/optimized-picture/hydrate.mjs.map +1 -0
- package/dist/components/optimized-picture/server.mjs +28 -0
- package/dist/components/optimized-picture/server.mjs.map +1 -0
- package/dist/components/utils.mjs +4 -0
- package/dist/components/utils.mjs.map +1 -0
- package/dist/media/images/node.mjs +41 -0
- package/dist/media/images/node.mjs.map +1 -0
- package/dist/polyfills/weakref.mjs +16 -0
- package/dist/polyfills/weakref.mjs.map +1 -0
- package/dist/reactive/sync/transport/websocket/browser.mjs +52 -0
- package/dist/reactive/sync/transport/websocket/browser.mjs.map +1 -0
- package/dist/reactive.mjs +160 -0
- package/dist/reactive.mjs.map +1 -0
- package/dist/server/jsx-runtime.mjs +2 -0
- package/dist/server/jsx-runtime.mjs.map +1 -0
- package/dist/server.mjs +346 -0
- package/dist/server.mjs.map +1 -0
- package/dist/types/cli/index.d.mts +2 -0
- package/dist/types/components/aside-toc/index.d.ts +45 -0
- package/dist/types/components/custom-elements.d.mts +83 -0
- package/dist/types/components/intl/date-time.d.ts +138 -0
- package/dist/types/components/intl/display-name.d.ts +45 -0
- package/dist/types/components/intl/language-picker.d.ts +35 -0
- package/dist/types/components/intl/list.d.ts +41 -0
- package/dist/types/components/intl/number.d.ts +81 -0
- package/dist/types/components/intl/plural.d.ts +60 -0
- package/dist/types/components/intl/utils.d.mts +30 -0
- package/dist/types/components/optimized-picture/hydrate.d.mts +2 -0
- package/dist/types/components/optimized-picture/server.d.ts +8 -0
- package/dist/types/components/utils.d.mts +5 -0
- package/dist/types/dom/browser/jsx-runtime.d.mts +3 -0
- package/dist/types/dom/index.browser.d.mts +127 -0
- package/dist/types/dom/index.server.d.mts +174 -0
- package/dist/types/dom/server/jsx-runtime.d.mts +3 -0
- package/dist/types/dom/types.d.mts +9 -0
- package/dist/types/media/images.node.d.mts +1 -0
- package/dist/types/polyfills/weakref.d.mts +4 -0
- package/dist/types/reactive/index.d.mts +91 -0
- package/dist/types/reactive/sync/transport/websocket/browser.d.mts +11 -0
- package/dist/types/utils/browser.d.mts +2 -0
- package/dist/types/utils/index.d.mts +122 -0
- package/dist/utils/browser.mjs +27 -0
- package/dist/utils/browser.mjs.map +1 -0
- package/dist/utils.mjs +287 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +122 -19
- package/dist/bruh.es.js +0 -226
- package/dist/bruh.es.js.map +0 -1
- package/dist/bruh.umd.js +0 -2
- package/dist/bruh.umd.js.map +0 -1
- package/src/cli/index.mjs +0 -19
- package/src/components/optimized-picture/hydrate.mjs +0 -10
- package/src/components/optimized-picture/render.mjs +0 -26
- package/src/dom/index.browser.mjs +0 -270
- package/src/dom/index.server.mjs +0 -280
- package/src/index.browser.mjs +0 -3
- package/src/media/images.node.mjs +0 -70
- package/src/reactive/index.mjs +0 -160
- package/src/util/index.mjs +0 -42
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { jsx, bruhChildrenToNodes, Fragment } from '../../browser.mjs';
|
|
2
|
+
import { r } from '../../reactive.mjs';
|
|
3
|
+
import { mapObject, attempt } from '../../utils.mjs';
|
|
4
|
+
import { spaceSeparated } from '../utils.mjs';
|
|
5
|
+
import { BruhCustomElementBase } from '../custom-elements.mjs';
|
|
6
|
+
import { parseLocales, userLanguages, inferDirection } from './utils.mjs';
|
|
7
|
+
|
|
8
|
+
const optionToAttribute = {
|
|
9
|
+
// locale options
|
|
10
|
+
localeMatcher: "locale-matcher",
|
|
11
|
+
numberingSystem: "numbering-system",
|
|
12
|
+
// style options
|
|
13
|
+
style: "format-style",
|
|
14
|
+
currency: "currency",
|
|
15
|
+
currencyDisplay: "currency-display",
|
|
16
|
+
currencySign: "currency-sign",
|
|
17
|
+
unit: "unit",
|
|
18
|
+
unitDisplay: "unit-display",
|
|
19
|
+
// digit options
|
|
20
|
+
minimumIntegerDigits: "minimum-integer-digits",
|
|
21
|
+
minimumFractionDigits: "minimum-fraction-digits",
|
|
22
|
+
maximumFractionDigits: "maximum-fraction-digits",
|
|
23
|
+
minimumSignificantDigits: "minimum-significant-digits",
|
|
24
|
+
maximumSignificantDigits: "maximum-significant-digits",
|
|
25
|
+
roundingPriority: "rounding-priority",
|
|
26
|
+
roundingIncrement: "rounding-increment",
|
|
27
|
+
roundingMode: "rounding-mode",
|
|
28
|
+
trailingZeroDisplay: "trailing-zero-display",
|
|
29
|
+
// other options
|
|
30
|
+
notation: "notation",
|
|
31
|
+
compactDisplay: "compact-display",
|
|
32
|
+
useGrouping: "use-grouping",
|
|
33
|
+
signDisplay: "sign-display"
|
|
34
|
+
};
|
|
35
|
+
const isParseable = (s) => new Intl.NumberFormat().formatToParts(s).every((part) => part.type !== "nan");
|
|
36
|
+
class BruhNumber extends BruhCustomElementBase {
|
|
37
|
+
static observedAttributes = [
|
|
38
|
+
"number",
|
|
39
|
+
"end-number",
|
|
40
|
+
"locales",
|
|
41
|
+
...Object.values(optionToAttribute)
|
|
42
|
+
];
|
|
43
|
+
static bruh = {
|
|
44
|
+
parseAttributes: {
|
|
45
|
+
locales: spaceSeparated
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
#locales;
|
|
49
|
+
#options;
|
|
50
|
+
#formatter;
|
|
51
|
+
#formatted;
|
|
52
|
+
constructor() {
|
|
53
|
+
super();
|
|
54
|
+
this.#locales = r(
|
|
55
|
+
[this.bruh.attributes.locales, userLanguages],
|
|
56
|
+
() => parseLocales([
|
|
57
|
+
...this.bruh.attributes.locales.value ?? [],
|
|
58
|
+
...userLanguages.value
|
|
59
|
+
])
|
|
60
|
+
);
|
|
61
|
+
const optionToReactiveAttribute = mapObject(
|
|
62
|
+
optionToAttribute,
|
|
63
|
+
([option, attribute]) => [option, this.bruh.attributes[attribute]]
|
|
64
|
+
);
|
|
65
|
+
this.#options = r(
|
|
66
|
+
Object.values(optionToReactiveAttribute),
|
|
67
|
+
() => mapObject(optionToReactiveAttribute, ([option, attribute]) => [option, attribute.value || void 0])
|
|
68
|
+
);
|
|
69
|
+
this.#formatter = r(
|
|
70
|
+
[this.#locales, this.#options],
|
|
71
|
+
() => attempt(() => new Intl.NumberFormat(this.#locales.value, this.#options.value)) ?? new Intl.NumberFormat(this.#locales.value)
|
|
72
|
+
);
|
|
73
|
+
const numberToFormat = this.bruh.attributes.number;
|
|
74
|
+
const rangeEndNumberToFormat = this.bruh.attributes["end-number"];
|
|
75
|
+
const renderParts = (parts, fallback) => parts.map((part) => {
|
|
76
|
+
const value = part.type !== "nan" || !fallback ? part.value : /* @__PURE__ */ jsx("bdi", { children: fallback });
|
|
77
|
+
return /* @__PURE__ */ jsx("span", { class: `bruh-number-part bruh-number-part--${part.type}`, children: value });
|
|
78
|
+
});
|
|
79
|
+
const renderSingle = (number) => renderParts(this.#formatter.value.formatToParts(number), number);
|
|
80
|
+
const renderRange = (start, end) => {
|
|
81
|
+
const formatter = this.#formatter.value;
|
|
82
|
+
const canRenderRangeDirectly = "formatRangeToParts" in formatter && isParseable(start) && isParseable(end);
|
|
83
|
+
if (!canRenderRangeDirectly)
|
|
84
|
+
return /* @__PURE__ */ jsx(Fragment, { children: [
|
|
85
|
+
renderSingle(start),
|
|
86
|
+
"–",
|
|
87
|
+
renderSingle(end)
|
|
88
|
+
] });
|
|
89
|
+
const parts = formatter.formatRangeToParts(start, end);
|
|
90
|
+
const bySource = parts.reduce((bySource2, part, i) => {
|
|
91
|
+
if (!i || parts[i - 1].source !== part.source)
|
|
92
|
+
bySource2.push([]);
|
|
93
|
+
bySource2[bySource2.length - 1].push(part);
|
|
94
|
+
return bySource2;
|
|
95
|
+
}, []);
|
|
96
|
+
return bySource.map(
|
|
97
|
+
(parts2) => /* @__PURE__ */ jsx("span", { class: `bruh-number-source bruh-number-source--${parts2[0].source}`, children: renderParts(parts2) })
|
|
98
|
+
);
|
|
99
|
+
};
|
|
100
|
+
this.#formatted = r([this.#formatter, numberToFormat, rangeEndNumberToFormat], () => {
|
|
101
|
+
if (!numberToFormat.value)
|
|
102
|
+
return;
|
|
103
|
+
const formatter = this.#formatter.value;
|
|
104
|
+
const { locale } = formatter.resolvedOptions();
|
|
105
|
+
const direction = inferDirection(locale);
|
|
106
|
+
const result = rangeEndNumberToFormat.value ? renderRange(numberToFormat.value, rangeEndNumberToFormat.value) : renderSingle(numberToFormat.value);
|
|
107
|
+
return /* @__PURE__ */ jsx("bdi", { lang: locale, dir: direction, children: result });
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
mountedCallback() {
|
|
111
|
+
const children = bruhChildrenToNodes([this.#formatted]);
|
|
112
|
+
this.replaceChildren(...children);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
customElements.define("bruh-number", BruhNumber);
|
|
116
|
+
|
|
117
|
+
export { BruhNumber };
|
|
118
|
+
//# sourceMappingURL=number.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"number.mjs","sources":["../../../src/components/intl/number.tsx"],"sourcesContent":["/** @jsxImportSource bruh/browser */\nimport { bruhChildrenToNodes, type BruhChild } from \"bruh/browser\"\nimport { r } from \"../../reactive/index.mts\"\nimport { attempt, mapObject } from \"../../utils/index.mts\"\nimport { spaceSeparated } from \"../utils.mts\"\nimport { BruhCustomElementBase } from \"../custom-elements.mts\"\nimport { inferDirection, parseLocales, userLanguages } from \"./utils.mts\"\n\nconst optionToAttribute = {\n // locale options\n localeMatcher: \"locale-matcher\",\n numberingSystem: \"numbering-system\",\n // style options\n style: \"format-style\",\n currency: \"currency\",\n currencyDisplay: \"currency-display\",\n currencySign: \"currency-sign\",\n unit: \"unit\",\n unitDisplay: \"unit-display\",\n // digit options\n minimumIntegerDigits: \"minimum-integer-digits\",\n minimumFractionDigits: \"minimum-fraction-digits\",\n maximumFractionDigits: \"maximum-fraction-digits\",\n minimumSignificantDigits: \"minimum-significant-digits\",\n maximumSignificantDigits: \"maximum-significant-digits\",\n roundingPriority: \"rounding-priority\",\n roundingIncrement: \"rounding-increment\",\n roundingMode: \"rounding-mode\",\n trailingZeroDisplay: \"trailing-zero-display\",\n // other options\n notation: \"notation\",\n compactDisplay: \"compact-display\",\n useGrouping: \"use-grouping\",\n signDisplay: \"sign-display\"\n} as const\n\ntype BruhNumberAttributes = {\n \"number\"?: Intl.StringNumericLiteral | string,\n \"end-number\"?: Intl.StringNumericLiteral | string,\n \"locales\"?: ReadonlyArray<Intl.UnicodeBCP47LocaleIdentifier>,\n \"locale-matcher\"?: Intl.NumberFormatOptions[\"localeMatcher\"],\n \"numbering-system\"?: Intl.NumberFormatOptions[\"numberingSystem\"],\n \"format-style\"?: Intl.NumberFormatOptions[\"style\"],\n \"currency\"?: Intl.NumberFormatOptions[\"currency\"],\n \"currency-display\"?: Intl.NumberFormatOptions[\"currencyDisplay\"],\n \"currency-sign\"?: Intl.NumberFormatOptions[\"currencySign\"],\n \"unit\"?: Intl.NumberFormatOptions[\"unit\"],\n \"unit-display\"?: Intl.NumberFormatOptions[\"unitDisplay\"],\n \"minimum-integer-digits\"?: Intl.NumberFormatOptions[\"minimumIntegerDigits\"],\n \"minimum-fraction-digits\"?: Intl.NumberFormatOptions[\"minimumFractionDigits\"],\n \"maximum-fraction-digits\"?: Intl.NumberFormatOptions[\"maximumFractionDigits\"],\n \"minimum-significant-digits\"?: Intl.NumberFormatOptions[\"minimumSignificantDigits\"],\n \"maximum-significant-digits\"?: Intl.NumberFormatOptions[\"maximumSignificantDigits\"],\n \"rounding-priority\"?: Intl.NumberFormatOptions[\"roundingPriority\"],\n \"rounding-increment\"?: Intl.NumberFormatOptions[\"roundingIncrement\"],\n \"rounding-mode\"?: Intl.NumberFormatOptions[\"roundingMode\"],\n \"trailing-zero-display\"?: Intl.NumberFormatOptions[\"trailingZeroDisplay\"],\n \"notation\"?: Intl.NumberFormatOptions[\"notation\"],\n \"compact-display\"?: Intl.NumberFormatOptions[\"compactDisplay\"],\n \"use-grouping\"?: Intl.NumberFormatOptions[\"useGrouping\"],\n \"sign-display\"?: Intl.NumberFormatOptions[\"signDisplay\"]\n}\n\nconst isParseable = (s: string | number | bigint): s is Intl.StringNumericLiteral | number | bigint =>\n new Intl.NumberFormat()\n .formatToParts(s as any as number)\n .every(part => part.type !== \"nan\")\n\nexport class BruhNumber extends BruhCustomElementBase<BruhNumberAttributes> {\n static observedAttributes = [\n \"number\",\n \"end-number\",\n \"locales\",\n ...Object.values(optionToAttribute)\n ]\n\n static bruh = {\n parseAttributes: {\n locales: spaceSeparated\n }\n }\n\n #locales\n #options\n #formatter\n #formatted\n\n constructor() {\n super()\n\n this.#locales = r([this.bruh.attributes.locales, userLanguages], () =>\n parseLocales([\n ...this.bruh.attributes.locales.value ?? [],\n ...userLanguages.value\n ])\n )\n\n const optionToReactiveAttribute = mapObject(optionToAttribute,\n ([option, attribute]) => [option, this.bruh.attributes[attribute]]\n )\n this.#options = r(Object.values(optionToReactiveAttribute), () =>\n mapObject(optionToReactiveAttribute, ([option, attribute]) => [option, attribute.value || undefined]) as Partial<Intl.NumberFormatOptions>\n )\n\n this.#formatter = r([this.#locales, this.#options], () =>\n attempt(() => new Intl.NumberFormat(this.#locales.value, this.#options.value))\n ?? new Intl.NumberFormat(this.#locales.value)\n )\n\n const numberToFormat = this.bruh.attributes.number\n const rangeEndNumberToFormat = this.bruh.attributes[\"end-number\"]\n\n const renderParts = (parts: ReadonlyArray<Intl.NumberFormatPart>, fallback?: BruhChild) =>\n parts.map(part => {\n const value =\n part.type !== \"nan\" || !fallback\n ? part.value\n : <bdi>{fallback}</bdi> as HTMLElement\n\n return <span class={`bruh-number-part bruh-number-part--${part.type}`}>{value}</span> as HTMLSpanElement\n })\n\n const renderSingle = (number: string | number | bigint) =>\n renderParts(this.#formatter.value.formatToParts(number as number), number)\n\n const renderRange = (\n start: string | number | bigint,\n end: string | number | bigint\n ) => {\n const formatter = this.#formatter.value\n\n const canRenderRangeDirectly =\n \"formatRangeToParts\" in formatter\n && isParseable(start)\n && isParseable(end)\n if (!canRenderRangeDirectly)\n return <>{renderSingle(start)}–{renderSingle(end)}</> as BruhChild\n\n const parts = formatter.formatRangeToParts(start, end)\n const bySource = parts.reduce<Intl.NumberRangeFormatPart[][]>((bySource, part, i) => {\n if (!i || parts[i - 1].source !== part.source)\n bySource.push([])\n bySource[bySource.length - 1].push(part)\n return bySource\n }, [])\n return bySource.map(parts =>\n <span class={`bruh-number-source bruh-number-source--${parts[0].source}`}>{renderParts(parts)}</span>\n )\n }\n\n this.#formatted = r([this.#formatter, numberToFormat, rangeEndNumberToFormat], () => {\n if (!numberToFormat.value)\n return\n\n const formatter = this.#formatter.value\n const { locale } = formatter.resolvedOptions()\n const direction = inferDirection(locale)\n\n const result =\n rangeEndNumberToFormat.value\n ? renderRange(numberToFormat.value, rangeEndNumberToFormat.value)\n : renderSingle(numberToFormat.value)\n\n return <bdi lang={locale} dir={direction}>{result}</bdi>\n })\n }\n\n mountedCallback() {\n const children = bruhChildrenToNodes([this.#formatted])\n this.replaceChildren(...children)\n }\n}\n\ncustomElements.define(\"bruh-number\", BruhNumber)\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"bruh-number\": BruhNumber\n }\n}\ndeclare module \"html-info\" {\n interface HTMLTagToAttributes {\n \"bruh-number\": {\n \"number\": Intl.StringNumericLiteral | string,\n \"end-number\"?: Intl.StringNumericLiteral | string,\n /**\n * Space separated list of locales\n */\n \"locales\"?: string,\n \"locale-matcher\"?: Intl.NumberFormatOptions[\"localeMatcher\"],\n \"numbering-system\"?: Intl.NumberFormatOptions[\"numberingSystem\"],\n \"format-style\"?: Intl.NumberFormatOptions[\"style\"],\n \"currency\"?: Intl.NumberFormatOptions[\"currency\"],\n \"currency-display\"?: Intl.NumberFormatOptions[\"currencyDisplay\"],\n \"currency-sign\"?: Intl.NumberFormatOptions[\"currencySign\"],\n \"unit\"?: Intl.NumberFormatOptions[\"unit\"],\n \"unit-display\"?: Intl.NumberFormatOptions[\"unitDisplay\"],\n \"minimum-integer-digits\"?: Intl.NumberFormatOptions[\"minimumIntegerDigits\"] | `${number}`,\n \"minimum-fraction-digits\"?: Intl.NumberFormatOptions[\"minimumFractionDigits\"] | `${number}`,\n \"maximum-fraction-digits\"?: Intl.NumberFormatOptions[\"maximumFractionDigits\"] | `${number}`,\n \"minimum-significant-digits\"?: Intl.NumberFormatOptions[\"minimumSignificantDigits\"] | `${number}`,\n \"maximum-significant-digits\"?: Intl.NumberFormatOptions[\"maximumSignificantDigits\"] | `${number}`,\n \"rounding-priority\"?: Intl.NumberFormatOptions[\"roundingPriority\"],\n \"rounding-increment\"?: Intl.NumberFormatOptions[\"roundingIncrement\"] | `${Intl.NumberFormatOptions[\"roundingIncrement\"]}`,\n \"rounding-mode\"?: Intl.NumberFormatOptions[\"roundingMode\"],\n \"trailing-zero-display\"?: Intl.NumberFormatOptions[\"trailingZeroDisplay\"],\n \"notation\"?: Intl.NumberFormatOptions[\"notation\"],\n \"compact-display\"?: Intl.NumberFormatOptions[\"compactDisplay\"],\n \"use-grouping\"?: Intl.NumberFormatOptions[\"useGrouping\"],\n \"sign-display\"?: Intl.NumberFormatOptions[\"signDisplay\"]\n }\n }\n}\n"],"names":["jsxs","bySource","parts"],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { jsx, bruhChildrenToNodes } from '../../browser.mjs';
|
|
2
|
+
import { r } from '../../reactive.mjs';
|
|
3
|
+
import { mapObject, attempt } from '../../utils.mjs';
|
|
4
|
+
import { spaceSeparated } from '../utils.mjs';
|
|
5
|
+
import { BruhCustomElementBase } from '../custom-elements.mjs';
|
|
6
|
+
import { parseLocales, userLanguages } from './utils.mjs';
|
|
7
|
+
|
|
8
|
+
const optionToAttribute = {
|
|
9
|
+
localeMatcher: "locale-matcher",
|
|
10
|
+
type: "type",
|
|
11
|
+
// digit options
|
|
12
|
+
minimumIntegerDigits: "minimum-integer-digits",
|
|
13
|
+
minimumFractionDigits: "minimum-fraction-digits",
|
|
14
|
+
maximumFractionDigits: "maximum-fraction-digits",
|
|
15
|
+
minimumSignificantDigits: "minimum-significant-digits",
|
|
16
|
+
maximumSignificantDigits: "maximum-significant-digits",
|
|
17
|
+
roundingPriority: "rounding-priority",
|
|
18
|
+
roundingIncrement: "rounding-increment",
|
|
19
|
+
roundingMode: "rounding-mode",
|
|
20
|
+
trailingZeroDisplay: "trailing-zero-display"
|
|
21
|
+
};
|
|
22
|
+
const categories = ["zero", "one", "two", "few", "many", "other"];
|
|
23
|
+
class BruhPlural extends BruhCustomElementBase {
|
|
24
|
+
static observedAttributes = [
|
|
25
|
+
"number",
|
|
26
|
+
"end-number",
|
|
27
|
+
"locales",
|
|
28
|
+
...Object.values(optionToAttribute)
|
|
29
|
+
];
|
|
30
|
+
static bruh = {
|
|
31
|
+
parseAttributes: {
|
|
32
|
+
locales: spaceSeparated
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
#locales;
|
|
36
|
+
#options;
|
|
37
|
+
#pluralRules;
|
|
38
|
+
#selected;
|
|
39
|
+
constructor() {
|
|
40
|
+
super();
|
|
41
|
+
this.#locales = r(
|
|
42
|
+
[this.bruh.attributes.locales, userLanguages],
|
|
43
|
+
() => parseLocales([
|
|
44
|
+
...this.bruh.attributes.locales.value ?? [],
|
|
45
|
+
...userLanguages.value
|
|
46
|
+
])
|
|
47
|
+
);
|
|
48
|
+
const optionToReactiveAttribute = mapObject(
|
|
49
|
+
optionToAttribute,
|
|
50
|
+
([option, attribute]) => [option, this.bruh.attributes[attribute]]
|
|
51
|
+
);
|
|
52
|
+
this.#options = r(
|
|
53
|
+
Object.values(optionToReactiveAttribute),
|
|
54
|
+
() => mapObject(optionToReactiveAttribute, ([option, attribute]) => [option, attribute.value || void 0])
|
|
55
|
+
);
|
|
56
|
+
this.#pluralRules = r(
|
|
57
|
+
[this.#locales, this.#options],
|
|
58
|
+
() => attempt(() => new Intl.PluralRules(this.#locales.value, this.#options.value)) ?? new Intl.PluralRules(this.#locales.value)
|
|
59
|
+
);
|
|
60
|
+
const numberToSelect = this.bruh.attributes.number;
|
|
61
|
+
const rangeEndNumberToSelect = this.bruh.attributes["end-number"];
|
|
62
|
+
this.#selected = r([this.#pluralRules, numberToSelect, rangeEndNumberToSelect], () => {
|
|
63
|
+
if (!numberToSelect.value)
|
|
64
|
+
return;
|
|
65
|
+
const pluralRules = this.#pluralRules.value;
|
|
66
|
+
const { locale } = pluralRules.resolvedOptions();
|
|
67
|
+
if (!this.#locales.value.some((preferred) => locale === preferred + ""))
|
|
68
|
+
console.warn(`Resolved locale (${locale}) does not match`);
|
|
69
|
+
const category = rangeEndNumberToSelect.value ? pluralRules.selectRange(numberToSelect.value, rangeEndNumberToSelect.value) : pluralRules.select(numberToSelect.value);
|
|
70
|
+
return [.../* @__PURE__ */ new Set([category, ...categories])].reduceRight(
|
|
71
|
+
(fallback, category2) => /* @__PURE__ */ jsx("slot", { name: category2, children: fallback }),
|
|
72
|
+
void 0
|
|
73
|
+
);
|
|
74
|
+
});
|
|
75
|
+
const shadowContent = bruhChildrenToNodes([this.#selected]);
|
|
76
|
+
this.attachShadow({ mode: "open" }).append(...shadowContent);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
customElements.define("bruh-plural", BruhPlural);
|
|
80
|
+
|
|
81
|
+
export { BruhPlural };
|
|
82
|
+
//# sourceMappingURL=plural.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plural.mjs","sources":["../../../src/components/intl/plural.tsx"],"sourcesContent":["/** @jsxImportSource bruh/browser */\nimport { bruhChildrenToNodes } from \"bruh/browser\"\nimport { r } from \"../../reactive/index.mts\"\nimport { attempt, mapObject } from \"../../utils/index.mts\"\nimport { spaceSeparated } from \"../utils.mts\"\nimport { BruhCustomElementBase } from \"../custom-elements.mts\"\nimport { parseLocales, userLanguages } from \"./utils.mts\"\n\nconst optionToAttribute = {\n localeMatcher: \"locale-matcher\",\n type: \"type\",\n // digit options\n minimumIntegerDigits: \"minimum-integer-digits\",\n minimumFractionDigits: \"minimum-fraction-digits\",\n maximumFractionDigits: \"maximum-fraction-digits\",\n minimumSignificantDigits: \"minimum-significant-digits\",\n maximumSignificantDigits: \"maximum-significant-digits\",\n roundingPriority: \"rounding-priority\",\n roundingIncrement: \"rounding-increment\",\n roundingMode: \"rounding-mode\",\n trailingZeroDisplay: \"trailing-zero-display\"\n} as const\n\ntype BruhPluralAttributes = {\n \"number\"?: Intl.StringNumericLiteral | string,\n \"end-number\"?: Intl.StringNumericLiteral | string,\n \"locales\"?: ReadonlyArray<Intl.UnicodeBCP47LocaleIdentifier>,\n \"locale-matcher\"?: Intl.PluralRulesOptions[\"localeMatcher\"],\n \"type\"?: Intl.PluralRulesOptions[\"type\"],\n \"minimum-integer-digits\"?: Intl.PluralRulesOptions[\"minimumIntegerDigits\"],\n \"minimum-fraction-digits\"?: Intl.PluralRulesOptions[\"minimumFractionDigits\"],\n \"maximum-fraction-digits\"?: Intl.PluralRulesOptions[\"maximumFractionDigits\"],\n \"minimum-significant-digits\"?: Intl.PluralRulesOptions[\"minimumSignificantDigits\"],\n \"maximum-significant-digits\"?: Intl.PluralRulesOptions[\"maximumSignificantDigits\"],\n \"rounding-priority\"?: Intl.PluralRulesOptions[\"roundingPriority\"],\n \"rounding-increment\"?: Intl.PluralRulesOptions[\"roundingIncrement\"],\n \"rounding-mode\"?: Intl.PluralRulesOptions[\"roundingMode\"],\n \"trailing-zero-display\"?: Intl.PluralRulesOptions[\"trailingZeroDisplay\"]\n}\n\nconst categories = [\"zero\", \"one\", \"two\", \"few\", \"many\", \"other\"] as const satisfies Intl.LDMLPluralRule[]\n\nexport class BruhPlural extends BruhCustomElementBase<BruhPluralAttributes> {\n static observedAttributes = [\n \"number\",\n \"end-number\",\n \"locales\",\n ...Object.values(optionToAttribute)\n ]\n\n static bruh = {\n parseAttributes: {\n locales: spaceSeparated\n }\n }\n\n #locales\n #options\n #pluralRules\n #selected\n\n constructor() {\n super()\n\n this.#locales = r([this.bruh.attributes.locales, userLanguages], () =>\n parseLocales([\n ...this.bruh.attributes.locales.value ?? [],\n ...userLanguages.value\n ])\n )\n\n const optionToReactiveAttribute = mapObject(optionToAttribute,\n ([option, attribute]) => [option, this.bruh.attributes[attribute]]\n )\n this.#options = r(Object.values(optionToReactiveAttribute), () =>\n mapObject(optionToReactiveAttribute, ([option, attribute]) => [option, attribute.value || undefined]) as Partial<Intl.PluralRulesOptions>\n )\n\n this.#pluralRules = r([this.#locales, this.#options], () =>\n attempt(() => new Intl.PluralRules(this.#locales.value, this.#options.value))\n ?? new Intl.PluralRules(this.#locales.value)\n )\n\n const numberToSelect = this.bruh.attributes.number\n const rangeEndNumberToSelect = this.bruh.attributes[\"end-number\"]\n\n this.#selected = r([this.#pluralRules, numberToSelect, rangeEndNumberToSelect], () => {\n if (!numberToSelect.value)\n return\n\n const pluralRules = this.#pluralRules.value\n const { locale } = pluralRules.resolvedOptions()\n if (!this.#locales.value.some(preferred => locale === preferred + \"\"))\n console.warn(`Resolved locale (${locale}) does not match`)\n\n const category =\n rangeEndNumberToSelect.value\n ? pluralRules.selectRange(numberToSelect.value as any as number, rangeEndNumberToSelect.value as any as number)\n : pluralRules.select(numberToSelect.value as any as number)\n\n // Render nested slots for fallback (no correct fallback order)\n return [...new Set([category, ...categories])]\n .reduceRight<HTMLSlotElement>((fallback, category) =>\n <slot name={category}>{fallback}</slot>\n , undefined as any)\n })\n\n const shadowContent = bruhChildrenToNodes([this.#selected])\n this\n .attachShadow({ mode: \"open\" })\n .append(...shadowContent)\n }\n}\n\ncustomElements.define(\"bruh-plural\", BruhPlural)\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"bruh-plural\": BruhPlural\n }\n}\ndeclare module \"html-info\" {\n interface HTMLTagToAttributes {\n \"bruh-plural\": {\n \"number\": Intl.StringNumericLiteral | string,\n \"end-number\"?: Intl.StringNumericLiteral | string,\n /**\n * Space separated list of locales\n */\n \"locales\"?: string,\n \"locale-matcher\"?: Intl.PluralRulesOptions[\"localeMatcher\"],\n \"type\"?: Intl.PluralRulesOptions[\"type\"],\n \"minimum-integer-digits\"?: Intl.NumberFormatOptions[\"minimumIntegerDigits\"] | `${number}`,\n \"minimum-fraction-digits\"?: Intl.NumberFormatOptions[\"minimumFractionDigits\"] | `${number}`,\n \"maximum-fraction-digits\"?: Intl.NumberFormatOptions[\"maximumFractionDigits\"] | `${number}`,\n \"minimum-significant-digits\"?: Intl.NumberFormatOptions[\"minimumSignificantDigits\"] | `${number}`,\n \"maximum-significant-digits\"?: Intl.NumberFormatOptions[\"maximumSignificantDigits\"] | `${number}`,\n \"rounding-priority\"?: Intl.PluralRulesOptions[\"roundingPriority\"],\n \"rounding-increment\"?: Intl.PluralRulesOptions[\"roundingIncrement\"] | `${Intl.PluralRulesOptions[\"roundingIncrement\"]}`,\n \"rounding-mode\"?: Intl.PluralRulesOptions[\"roundingMode\"],\n \"trailing-zero-display\"?: Intl.PluralRulesOptions[\"trailingZeroDisplay\"]\n }\n }\n}\n"],"names":["category"],"mappings":"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"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { r } from '../../reactive.mjs';
|
|
2
|
+
import { unique, attempt } from '../../utils.mjs';
|
|
3
|
+
import { currentUrl } from '../../utils/browser.mjs';
|
|
4
|
+
|
|
5
|
+
const parseLocale = (locale) => {
|
|
6
|
+
if (locale)
|
|
7
|
+
return attempt(() => new Intl.Locale(locale));
|
|
8
|
+
};
|
|
9
|
+
const parseLocales = (locales) => {
|
|
10
|
+
if (Array.isArray(locales))
|
|
11
|
+
return unique(
|
|
12
|
+
locales.map(parseLocale).filter((locale) => !!locale),
|
|
13
|
+
(locale) => locale + ""
|
|
14
|
+
);
|
|
15
|
+
const parsed = parseLocale(locales);
|
|
16
|
+
if (parsed)
|
|
17
|
+
return [parsed];
|
|
18
|
+
return [];
|
|
19
|
+
};
|
|
20
|
+
const parseRegion = (region) => {
|
|
21
|
+
if (region)
|
|
22
|
+
return attempt(() => new Intl.Locale("xx", { region }).region);
|
|
23
|
+
};
|
|
24
|
+
const inferRegion = (locale) => parseLocale(locale)?.maximize().region;
|
|
25
|
+
const rtlScripts = /* @__PURE__ */ new Set([
|
|
26
|
+
"Arab",
|
|
27
|
+
"Hebr",
|
|
28
|
+
"Thaa",
|
|
29
|
+
"Adlm",
|
|
30
|
+
"Armi",
|
|
31
|
+
"Avst",
|
|
32
|
+
"Chrs",
|
|
33
|
+
"Cprt",
|
|
34
|
+
"Elym",
|
|
35
|
+
"Hatr",
|
|
36
|
+
"Hung",
|
|
37
|
+
"Khar",
|
|
38
|
+
"Lydi",
|
|
39
|
+
"Mand",
|
|
40
|
+
"Mani",
|
|
41
|
+
"Mend",
|
|
42
|
+
"Merc",
|
|
43
|
+
"Mero",
|
|
44
|
+
"Narb",
|
|
45
|
+
"Nbat",
|
|
46
|
+
"Nkoo",
|
|
47
|
+
"Orkh",
|
|
48
|
+
"Ougr",
|
|
49
|
+
"Palm",
|
|
50
|
+
"Phli",
|
|
51
|
+
"Phlp",
|
|
52
|
+
"Phnx",
|
|
53
|
+
"Prti",
|
|
54
|
+
"Rohg",
|
|
55
|
+
"Samr",
|
|
56
|
+
"Sarb",
|
|
57
|
+
"Sogd",
|
|
58
|
+
"Sogo",
|
|
59
|
+
"Syrc",
|
|
60
|
+
"Yezi"
|
|
61
|
+
]);
|
|
62
|
+
const inferDirection = (locale) => {
|
|
63
|
+
const parsed = parseLocale(locale);
|
|
64
|
+
if (!parsed)
|
|
65
|
+
return parsed;
|
|
66
|
+
const textInfo = parsed.getTextInfo?.() ?? parsed.textInfo;
|
|
67
|
+
if (textInfo?.direction)
|
|
68
|
+
return textInfo.direction;
|
|
69
|
+
const { script } = parsed.maximize();
|
|
70
|
+
if (script)
|
|
71
|
+
return rtlScripts.has(script) ? "rtl" : "ltr";
|
|
72
|
+
};
|
|
73
|
+
const languageDisplayName = (displayNames, language) => {
|
|
74
|
+
const parsed = parseLocale(language);
|
|
75
|
+
if (!parsed)
|
|
76
|
+
return language + "";
|
|
77
|
+
for (const code of [parsed + "", parsed.baseName, parsed.language]) {
|
|
78
|
+
const display = attempt(() => displayNames.of(code));
|
|
79
|
+
if (display && display !== code)
|
|
80
|
+
return display;
|
|
81
|
+
}
|
|
82
|
+
return parsed + "";
|
|
83
|
+
};
|
|
84
|
+
const generalizedLocales = (locale) => {
|
|
85
|
+
const result = [];
|
|
86
|
+
let generalized = locale + "";
|
|
87
|
+
do {
|
|
88
|
+
result.push(generalized);
|
|
89
|
+
let lastDashIndex = generalized.lastIndexOf("-");
|
|
90
|
+
if (lastDashIndex === -1)
|
|
91
|
+
break;
|
|
92
|
+
if (lastDashIndex >= 2 && generalized[lastDashIndex - 2] === "-")
|
|
93
|
+
lastDashIndex -= 2;
|
|
94
|
+
generalized = generalized.slice(0, lastDashIndex);
|
|
95
|
+
} while (true);
|
|
96
|
+
return parseLocales(result);
|
|
97
|
+
};
|
|
98
|
+
const bestAvailableLocales = (available, preferred) => {
|
|
99
|
+
const canonicalAvailable = parseLocales(available).map((locale) => locale + "");
|
|
100
|
+
const generalizedAvailable = /* @__PURE__ */ new Map();
|
|
101
|
+
for (const full of canonicalAvailable) {
|
|
102
|
+
const canonicalGeneralized = generalizedLocales(full).map((locale) => locale + "");
|
|
103
|
+
for (const generalized of canonicalGeneralized) {
|
|
104
|
+
if (!generalizedAvailable.has(generalized) || generalized === full)
|
|
105
|
+
generalizedAvailable.set(generalized, full);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const canonicalPreferred = parseLocales(preferred).map((locale) => locale + "");
|
|
109
|
+
const generalizedPreferred = /* @__PURE__ */ new Set();
|
|
110
|
+
for (const full of canonicalPreferred) {
|
|
111
|
+
const canonicalGeneralized = generalizedLocales(full).map((locale) => locale + "");
|
|
112
|
+
for (const generalized of canonicalGeneralized) {
|
|
113
|
+
if (generalizedPreferred.has(generalized))
|
|
114
|
+
generalizedPreferred.delete(generalized);
|
|
115
|
+
generalizedPreferred.add(generalized);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const matches = new Set([...generalizedPreferred].map((gp) => generalizedAvailable.get(gp)));
|
|
119
|
+
const alsoAvailable = canonicalAvailable.filter((other) => !matches.has(other));
|
|
120
|
+
return {
|
|
121
|
+
matches: parseLocales([...matches]),
|
|
122
|
+
alsoAvailable: parseLocales(alsoAvailable)
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
const browserLanguages = r();
|
|
126
|
+
const reflectLanguages = () => {
|
|
127
|
+
browserLanguages.value = parseLocales(navigator.languages);
|
|
128
|
+
};
|
|
129
|
+
reflectLanguages();
|
|
130
|
+
addEventListener("languagechange", reflectLanguages);
|
|
131
|
+
const languagePickerLanguages = r();
|
|
132
|
+
const reflectLanguagePickerLanguages = () => {
|
|
133
|
+
languagePickerLanguages.value = parseLocales(
|
|
134
|
+
attempt(
|
|
135
|
+
() => JSON.parse(
|
|
136
|
+
localStorage.getItem("bruh-language-picker-languages")
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
);
|
|
140
|
+
};
|
|
141
|
+
reflectLanguagePickerLanguages();
|
|
142
|
+
addEventListener("storage", reflectLanguagePickerLanguages);
|
|
143
|
+
const urlLocales = r([currentUrl], () => parseLocales(currentUrl.value.searchParams.getAll("locale")));
|
|
144
|
+
const urlLanguages = r([currentUrl], () => parseLocales(currentUrl.value.searchParams.getAll("language")));
|
|
145
|
+
const urlRegions = r([currentUrl], () => {
|
|
146
|
+
const regions = /* @__PURE__ */ new Set();
|
|
147
|
+
for (const region of currentUrl.value.searchParams.getAll("region")) {
|
|
148
|
+
const parsed = parseRegion(region);
|
|
149
|
+
if (parsed)
|
|
150
|
+
regions.add(parsed);
|
|
151
|
+
}
|
|
152
|
+
return [...regions];
|
|
153
|
+
});
|
|
154
|
+
const userLanguages = r([urlLanguages, urlLocales, languagePickerLanguages, browserLanguages], () => [
|
|
155
|
+
...urlLanguages.value,
|
|
156
|
+
...urlLocales.value,
|
|
157
|
+
...languagePickerLanguages.value,
|
|
158
|
+
...browserLanguages.value
|
|
159
|
+
]);
|
|
160
|
+
const userRegions = r([currentUrl, urlRegions, urlLocales, urlLanguages], () => {
|
|
161
|
+
const regions = new Set(urlRegions.value);
|
|
162
|
+
const guessedRegions = /* @__PURE__ */ new Set();
|
|
163
|
+
const locales = [
|
|
164
|
+
...urlLocales.value,
|
|
165
|
+
...urlLanguages.value,
|
|
166
|
+
...languagePickerLanguages.value,
|
|
167
|
+
...browserLanguages.value
|
|
168
|
+
];
|
|
169
|
+
for (const locale of locales) {
|
|
170
|
+
if (locale.region)
|
|
171
|
+
regions.add(locale.region);
|
|
172
|
+
else
|
|
173
|
+
guessedRegions.add(locale.maximize().region);
|
|
174
|
+
}
|
|
175
|
+
return unique([...regions, ...guessedRegions]);
|
|
176
|
+
});
|
|
177
|
+
const segment = (content, locales, options) => [...new Intl.Segmenter(locales, options).segment(content)];
|
|
178
|
+
const segmentTree = (locales, content) => segment(content, locales, { granularity: "sentence" }).map(
|
|
179
|
+
(sentence) => ({
|
|
180
|
+
type: "sentence",
|
|
181
|
+
content: segment(sentence.segment, locales, { granularity: "word" }).map((word) => {
|
|
182
|
+
const graphemes = segment(word.segment, locales, { granularity: "grapheme" }).map(
|
|
183
|
+
(grapheme) => ({
|
|
184
|
+
type: "grapheme",
|
|
185
|
+
content: grapheme.segment
|
|
186
|
+
})
|
|
187
|
+
);
|
|
188
|
+
return word.isWordLike ? {
|
|
189
|
+
type: "word",
|
|
190
|
+
content: graphemes
|
|
191
|
+
} : graphemes;
|
|
192
|
+
})
|
|
193
|
+
})
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
export { bestAvailableLocales, browserLanguages, generalizedLocales, inferDirection, inferRegion, languageDisplayName, languagePickerLanguages, parseLocale, parseLocales, parseRegion, segmentTree, userLanguages, userRegions };
|
|
197
|
+
//# sourceMappingURL=utils.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.mjs","sources":["../../../src/components/intl/utils.mts"],"sourcesContent":["import { r, type SourceNode } from \"../../reactive/index.mts\"\nimport { attempt, unique } from \"../../utils/index.mts\"\nimport { currentUrl } from \"../../utils/browser.mts\"\n\nexport type InputLocale = Intl.UnicodeBCP47LocaleIdentifier | Intl.Locale | null | undefined\n\nexport const parseLocale = (locale: InputLocale) => {\n if (locale)\n return attempt(() => new Intl.Locale(locale))\n}\n\nexport const parseLocales = (locales: ReadonlyArray<InputLocale> | InputLocale) => {\n if (Array.isArray(locales))\n return unique(\n locales.map(parseLocale).filter((locale): locale is Intl.Locale => !!locale),\n locale => locale + \"\"\n )\n\n const parsed = parseLocale(locales as InputLocale)\n if (parsed)\n return [parsed]\n\n return []\n}\n\nexport const parseRegion = (region?: string | null) => {\n if (region)\n return attempt(() => new Intl.Locale(\"xx\", { region }).region)\n}\n\nexport const inferRegion = (locale: InputLocale) =>\n parseLocale(locale)?.maximize().region\n\n// https://raw.githubusercontent.com/unicode-org/cldr/main/common/properties/scriptMetadata.txt\n// document.body.textContent.split(\"\\n\")\n// .map(line => line.trim())\n// .filter(line => line && !line.startsWith(\"#\"))\n// .reduce((scripts, line) => {\n// const columns = line.split(\";\")\n// .map(column => column.trim())\n// const script = columns[0]\n// const rtl = columns[6]\n// if (rtl === \"YES\")\n// scripts.push(script)\n// return scripts\n// }, [])\nconst rtlScripts = new Set([\n \"Arab\", \"Hebr\", \"Thaa\", \"Adlm\", \"Armi\", \"Avst\", \"Chrs\",\n \"Cprt\", \"Elym\", \"Hatr\", \"Hung\", \"Khar\", \"Lydi\", \"Mand\",\n \"Mani\", \"Mend\", \"Merc\", \"Mero\", \"Narb\", \"Nbat\", \"Nkoo\",\n \"Orkh\", \"Ougr\", \"Palm\", \"Phli\", \"Phlp\", \"Phnx\", \"Prti\",\n \"Rohg\", \"Samr\", \"Sarb\", \"Sogd\", \"Sogo\", \"Syrc\", \"Yezi\"\n])\nexport const inferDirection = (locale: InputLocale) => {\n const parsed = parseLocale(locale)\n if (!parsed)\n return parsed\n\n const textInfo: { direction: \"ltr\" | \"rtl\" } | undefined = (parsed as any).getTextInfo?.() ?? (parsed as any).textInfo\n if (textInfo?.direction)\n return textInfo.direction\n\n const { script } = parsed.maximize()\n if (script)\n return rtlScripts.has(script)\n ? \"rtl\"\n : \"ltr\"\n}\n\nexport const languageDisplayName = (displayNames: Intl.DisplayNames, language: InputLocale) => {\n const parsed = parseLocale(language)\n if (!parsed)\n return language + \"\"\n\n for (const code of [parsed + \"\", parsed.baseName, parsed.language]) {\n const display = attempt(() => displayNames.of(code))\n if (display && display !== code)\n return display\n }\n\n return parsed + \"\"\n}\n\n// Returns an array of progressively generalized locales\n// Based on https://tc39.es/ecma402/#sec-bestavailablelocale (RFC 4647, section 3.4)\nexport const generalizedLocales = (locale: InputLocale) => {\n const result = []\n\n let generalized = locale + \"\"\n do {\n result.push(generalized)\n\n let lastDashIndex = generalized.lastIndexOf(\"-\")\n if (lastDashIndex === -1)\n break\n\n if (lastDashIndex >= 2 && generalized[lastDashIndex - 2] === \"-\")\n lastDashIndex -= 2\n\n generalized = generalized.slice(0, lastDashIndex)\n } while (true)\n\n return parseLocales(result)\n}\n\nexport const bestAvailableLocales = (available: ReadonlyArray<InputLocale>, preferred: ReadonlyArray<InputLocale>) => {\n const canonicalAvailable = parseLocales(available).map(locale => locale + \"\")\n const generalizedAvailable = new Map<string, string>()\n for (const full of canonicalAvailable) {\n const canonicalGeneralized = generalizedLocales(full).map(locale => locale + \"\")\n for (const generalized of canonicalGeneralized) {\n if (!generalizedAvailable.has(generalized) || generalized === full)\n generalizedAvailable.set(generalized, full)\n }\n }\n\n const canonicalPreferred = parseLocales(preferred).map(locale => locale + \"\")\n const generalizedPreferred = new Set<string>()\n for (const full of canonicalPreferred) {\n const canonicalGeneralized = generalizedLocales(full).map(locale => locale + \"\")\n for (const generalized of canonicalGeneralized) {\n // last write wins set\n if (generalizedPreferred.has(generalized))\n generalizedPreferred.delete(generalized)\n\n generalizedPreferred.add(generalized)\n }\n }\n\n const matches = new Set([...generalizedPreferred].map(gp => generalizedAvailable.get(gp)!))\n const alsoAvailable = canonicalAvailable.filter(other => !matches.has(other))\n\n return {\n matches: parseLocales([...matches]),\n alsoAvailable: parseLocales(alsoAvailable)\n }\n}\n\nexport const browserLanguages = r() as SourceNode<ReadonlyArray<Intl.Locale>>\nconst reflectLanguages = () => {\n browserLanguages.value = parseLocales(navigator.languages)\n}\nreflectLanguages()\naddEventListener(\"languagechange\", reflectLanguages)\n\nexport const languagePickerLanguages = r() as SourceNode<ReadonlyArray<Intl.Locale>>\nconst reflectLanguagePickerLanguages = () => {\n languagePickerLanguages.value = parseLocales(\n attempt(() =>\n JSON.parse(\n localStorage.getItem(\"bruh-language-picker-languages\") as any\n )\n )\n )\n}\nreflectLanguagePickerLanguages()\naddEventListener(\"storage\", reflectLanguagePickerLanguages) // only accounts for changes on different windows\n\nconst urlLocales = r([currentUrl], () => parseLocales(currentUrl.value.searchParams.getAll(\"locale\")))\nconst urlLanguages = r([currentUrl], () => parseLocales(currentUrl.value.searchParams.getAll(\"language\")))\nconst urlRegions = r([currentUrl], () => {\n const regions = new Set<string>()\n\n for (const region of currentUrl.value.searchParams.getAll(\"region\")) {\n const parsed = parseRegion(region)\n if (parsed)\n regions.add(parsed)\n }\n\n return [...regions]\n})\n\nexport const userLanguages = r([urlLanguages, urlLocales, languagePickerLanguages, browserLanguages], () => [\n ...urlLanguages.value,\n ...urlLocales.value,\n ...languagePickerLanguages.value,\n ...browserLanguages.value\n] as const)\n\nexport const userRegions = r([currentUrl, urlRegions, urlLocales, urlLanguages], () => {\n const regions = new Set<string>(urlRegions.value)\n const guessedRegions = new Set<string>()\n\n const locales = [\n ...urlLocales.value,\n ...urlLanguages.value,\n ...languagePickerLanguages.value,\n ...browserLanguages.value\n ]\n\n for (const locale of locales) {\n if (locale.region)\n regions.add(locale.region)\n else\n guessedRegions.add(locale.maximize().region!)\n }\n\n return unique([...regions, ...guessedRegions]) as ReadonlyArray<string>\n})\n\n\nconst segment = (content: string, locales: Intl.LocalesArgument, options: Intl.SegmenterOptions) =>\n [...new Intl.Segmenter(locales, options).segment(content)]\n\nexport const segmentTree = (locales: Intl.LocalesArgument, content: string) =>\n segment(content, locales, { granularity: \"sentence\" }).map(sentence =>\n ({\n type: \"sentence\",\n content: segment(sentence.segment, locales, { granularity: \"word\" }).map(word => {\n const graphemes =\n segment(word.segment, locales, { granularity: \"grapheme\" }).map(grapheme =>\n ({\n type: \"grapheme\",\n content: grapheme.segment\n } as const)\n )\n return word.isWordLike\n ? {\n type: \"word\",\n content: graphemes\n } as const\n : graphemes\n })\n } as const)\n )\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const hydrateOptimizedPictures = (className = "bruh-optimized-picture") => document.querySelectorAll(`.${className} > img`).forEach((img) => {
|
|
2
|
+
const removeLQIP = () => img.removeAttribute("style");
|
|
3
|
+
if (img.complete)
|
|
4
|
+
removeLQIP();
|
|
5
|
+
else
|
|
6
|
+
img.addEventListener("load", removeLQIP, { once: true });
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export { hydrateOptimizedPictures as default };
|
|
10
|
+
//# sourceMappingURL=hydrate.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydrate.mjs","sources":["../../../src/components/optimized-picture/hydrate.mts"],"sourcesContent":["const hydrateOptimizedPictures = (className = \"bruh-optimized-picture\") =>\n document.querySelectorAll<HTMLImageElement>(`.${className} > img`)\n .forEach(img => {\n const removeLQIP = () => img.removeAttribute(\"style\")\n\n if (img.complete)\n removeLQIP()\n else\n img.addEventListener(\"load\", removeLQIP, { once: true })\n })\n\nexport default hydrateOptimizedPictures\n"],"names":[],"mappings":"AAAM,MAAA,wBAAA,GAA2B,CAAC,SAAA,GAAY,wBAC5C,KAAA,QAAA,CAAS,gBAAmC,CAAA,CAAA,CAAA,EAAI,SAAS,CAAA,MAAA,CAAQ,CAC9D,CAAA,OAAA,CAAQ,CAAO,GAAA,KAAA;AACd,EAAA,MAAM,UAAa,GAAA,MAAM,GAAI,CAAA,eAAA,CAAgB,OAAO,CAAA;AAEpD,EAAA,IAAI,GAAI,CAAA,QAAA;AACN,IAAW,UAAA,EAAA;AAAA;AAEX,IAAA,GAAA,CAAI,iBAAiB,MAAQ,EAAA,UAAA,EAAY,EAAE,IAAA,EAAM,MAAM,CAAA;AAC3D,CAAC;;;;"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx } from '../../server.mjs';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
|
|
4
|
+
const OptimizedPicture = async (options) => {
|
|
5
|
+
const imagePath = options.src;
|
|
6
|
+
const { width, height, lqip } = JSON.parse(
|
|
7
|
+
await readFile(`${imagePath}.json`, "utf-8")
|
|
8
|
+
);
|
|
9
|
+
const picture = /* @__PURE__ */ jsx("picture", { class: "bruh-optimized-picture", children: [
|
|
10
|
+
/* @__PURE__ */ jsx("source", { type: "image/avif", srcset: `${imagePath}.avif` }),
|
|
11
|
+
/* @__PURE__ */ jsx("source", { type: "image/webp", srcset: `${imagePath}.webp` }),
|
|
12
|
+
/* @__PURE__ */ jsx(
|
|
13
|
+
"img",
|
|
14
|
+
{
|
|
15
|
+
src: imagePath,
|
|
16
|
+
alt: options.alt || "",
|
|
17
|
+
width: options.width || width,
|
|
18
|
+
height: options.height || height,
|
|
19
|
+
loading: options.loading || "lazy",
|
|
20
|
+
style: `background-image: url(${lqip})`
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
] });
|
|
24
|
+
return picture;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export { OptimizedPicture as default };
|
|
28
|
+
//# sourceMappingURL=server.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.mjs","sources":["../../../src/components/optimized-picture/server.tsx"],"sourcesContent":["/** @jsxImportSource bruh/server */\nimport { readFile } from \"node:fs/promises\"\n\nconst OptimizedPicture = async (\n options: {\n src: string,\n alt?: string,\n width?: number,\n height?: number,\n loading?: \"lazy\" | \"eager\"\n }\n) => {\n const imagePath = options.src\n\n const { width, height, lqip } = JSON.parse(\n await readFile(`${imagePath}.json`, \"utf-8\")\n ) as {\n width: number,\n height: number,\n lqip: string\n }\n\n const picture =\n <picture class=\"bruh-optimized-picture\">\n <source type=\"image/avif\" srcset={`${imagePath}.avif`} />\n <source type=\"image/webp\" srcset={`${imagePath}.webp`} />\n <img\n src={imagePath}\n alt={options.alt || \"\"}\n width={options.width || width}\n height={options.height || height}\n loading={options.loading || \"lazy\"}\n style={`background-image: url(${lqip})`}\n />\n </picture>\n\n return picture\n}\n\nexport default OptimizedPicture\n"],"names":["jsxs"],"mappings":";;;AAGM,MAAA,gBAAA,GAAmB,OACvB,OAOG,KAAA;AACH,EAAA,MAAM,YAAY,OAAQ,CAAA,GAAA;AAE1B,EAAA,MAAM,EAAE,KAAA,EAAO,MAAQ,EAAA,IAAA,KAAS,IAAK,CAAA,KAAA;AAAA,IACnC,MAAM,QAAA,CAAS,CAAG,EAAA,SAAS,SAAS,OAAO;AAAA,GAC7C;AAMA,EAAA,MAAM,OACJ,mBAAAA,GAAA,CAAC,SAAQ,EAAA,EAAA,KAAA,EAAM,wBACb,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,YAAO,IAAK,EAAA,YAAA,EAAa,MAAQ,EAAA,CAAA,EAAG,SAAS,CAAS,KAAA,CAAA,EAAA,CAAA;AAAA,wBACtD,QAAO,EAAA,EAAA,IAAA,EAAK,cAAa,MAAQ,EAAA,CAAA,EAAG,SAAS,CAAS,KAAA,CAAA,EAAA,CAAA;AAAA,oBACvD,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAK,EAAA,SAAA;AAAA,QACL,GAAA,EAAK,QAAQ,GAAO,IAAA,EAAA;AAAA,QACpB,KAAA,EAAO,QAAQ,KAAS,IAAA,KAAA;AAAA,QACxB,MAAA,EAAQ,QAAQ,MAAU,IAAA,MAAA;AAAA,QAC1B,OAAA,EAAS,QAAQ,OAAW,IAAA,MAAA;AAAA,QAC5B,KAAA,EAAO,yBAAyB,IAAI,CAAA,CAAA;AAAA;AAAA;AACtC,GACF,EAAA,CAAA;AAEF,EAAO,OAAA,OAAA;AACT;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.mjs","sources":["../../src/components/utils.mts"],"sourcesContent":["// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#space-separated-tokens\nexport const spaceSeparated: {\n (s: string): string[]\n (s?: null): undefined\n (s?: string | null): string[] | undefined\n} = (s?: string | null) =>\n s?.trim().split(/\\s+/) ?? undefined as any\n"],"names":[],"mappings":"AACa,MAAA,cAAA,GAIT,CAAC,CACH,KAAA,CAAA,EAAG,MAAO,CAAA,KAAA,CAAM,KAAK,CAAK,IAAA;;;;"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import sharp from 'sharp';
|
|
2
|
+
import { readdir, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { join, extname } from 'node:path';
|
|
4
|
+
|
|
5
|
+
const avif = async (filePath, sharpInstance) => sharpInstance.avif({}).toFile(`${filePath}.avif`);
|
|
6
|
+
const webp = async (filePath, sharpInstance) => sharpInstance.webp({}).toFile(`${filePath}.webp`);
|
|
7
|
+
const json = async (filePath, sharpInstance) => {
|
|
8
|
+
const imageManifest = {};
|
|
9
|
+
const metadata = await sharpInstance.metadata();
|
|
10
|
+
imageManifest.format = metadata.format;
|
|
11
|
+
imageManifest.width = metadata.width;
|
|
12
|
+
imageManifest.height = metadata.height;
|
|
13
|
+
const buffer = await sharpInstance.resize({ fit: "inside", width: 16, height: 16 }).blur().webp({ effort: 6 }).toBuffer();
|
|
14
|
+
imageManifest.lqip = `data:image/webp;base64,${buffer.toString("base64")}`;
|
|
15
|
+
return writeFile(`${filePath}.json`, JSON.stringify(imageManifest));
|
|
16
|
+
};
|
|
17
|
+
const getUnprocessedImages = async (directory) => {
|
|
18
|
+
const directoryEntries = await readdir(directory, { withFileTypes: true });
|
|
19
|
+
const promisedUnproccessedImages = directoryEntries.map(async (entry) => {
|
|
20
|
+
const entryPath = join(directory, entry.name);
|
|
21
|
+
if (entry.isDirectory())
|
|
22
|
+
return await getUnprocessedImages(entryPath);
|
|
23
|
+
if (entry.name[0] == "." || [".avif", ".webp", ".json"].includes(extname(entry.name)) || directoryEntries.some(
|
|
24
|
+
(siblingEntry) => [".avif", ".webp", ".json"].map((processedExtention) => `${entry.name}${processedExtention}`).includes(siblingEntry.name)
|
|
25
|
+
))
|
|
26
|
+
return [];
|
|
27
|
+
return [entryPath];
|
|
28
|
+
});
|
|
29
|
+
return (await Promise.all(promisedUnproccessedImages)).flat();
|
|
30
|
+
};
|
|
31
|
+
const processImages = async (directory) => {
|
|
32
|
+
const unprocessedImages = await getUnprocessedImages(directory);
|
|
33
|
+
for (const filePath of unprocessedImages) {
|
|
34
|
+
await Promise.all(
|
|
35
|
+
[avif, webp, json].map((process) => process(filePath, sharp(filePath)))
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export { processImages };
|
|
41
|
+
//# sourceMappingURL=node.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.mjs","sources":["../../../src/media/images.node.mts"],"sourcesContent":["import sharp from \"sharp\"\nimport { readdir, writeFile } from \"node:fs/promises\"\nimport { extname, join } from \"node:path\"\n\nconst avif = async (filePath: string, sharpInstance: sharp.Sharp) =>\n sharpInstance\n .avif({ })\n .toFile(`${filePath}.avif`)\n\nconst webp = async (filePath: string, sharpInstance: sharp.Sharp) =>\n sharpInstance\n .webp({ })\n .toFile(`${filePath}.webp`)\n\n// Low Quality Image Placeholder inline css for the <img> style attribute\nconst json = async (filePath: string, sharpInstance: sharp.Sharp) => {\n const imageManifest: {\n format: sharp.Metadata[\"format\"]\n width: sharp.Metadata[\"width\"]\n height: sharp.Metadata[\"height\"]\n lqip: string\n } = {} as any\n\n const metadata = await sharpInstance.metadata()\n imageManifest.format = metadata.format\n imageManifest.width = metadata.width\n imageManifest.height = metadata.height\n\n const buffer = await sharpInstance\n .resize({ fit: \"inside\", width: 16, height: 16 })\n .blur()\n .webp({ effort: 6 })\n .toBuffer()\n\n imageManifest.lqip = `data:image/webp;base64,${buffer.toString(\"base64\")}`\n return writeFile(`${filePath}.json`, JSON.stringify(imageManifest))\n}\n\nconst getUnprocessedImages = async (directory: string): Promise<string[]> => {\n const directoryEntries = await readdir(directory, { withFileTypes: true })\n\n const promisedUnproccessedImages = directoryEntries\n .map(async entry => {\n const entryPath = join(directory, entry.name)\n\n if (entry.isDirectory())\n return await getUnprocessedImages(entryPath)\n\n if (\n entry.name[0] == \".\" ||\n [\".avif\", \".webp\", \".json\"]\n .includes(extname(entry.name)) ||\n directoryEntries.some(siblingEntry =>\n [\".avif\", \".webp\", \".json\"]\n .map(processedExtention => `${entry.name}${processedExtention}`)\n .includes(siblingEntry.name)\n )\n )\n return []\n\n return [entryPath]\n })\n\n return (await Promise.all(promisedUnproccessedImages)).flat()\n}\n\nexport const processImages = async (directory: string) => {\n const unprocessedImages = await getUnprocessedImages(directory)\n for (const filePath of unprocessedImages) {\n await Promise.all(\n [avif, webp, json]\n .map(process => process(filePath, sharp(filePath)))\n )\n }\n}\n"],"names":[],"mappings":";;;;AAIA,MAAM,IAAO,GAAA,OAAO,QAAkB,EAAA,aAAA,KACpC,aACG,CAAA,IAAA,CAAK,EAAI,CACT,CAAA,MAAA,CAAO,CAAG,EAAA,QAAQ,CAAO,KAAA,CAAA,CAAA;AAE9B,MAAM,IAAO,GAAA,OAAO,QAAkB,EAAA,aAAA,KACpC,aACG,CAAA,IAAA,CAAK,EAAI,CACT,CAAA,MAAA,CAAO,CAAG,EAAA,QAAQ,CAAO,KAAA,CAAA,CAAA;AAG9B,MAAM,IAAA,GAAO,OAAO,QAAA,EAAkB,aAA+B,KAAA;AACnE,EAAA,MAAM,gBAKF,EAAC;AAEL,EAAM,MAAA,QAAA,GAAW,MAAM,aAAA,CAAc,QAAS,EAAA;AAC9C,EAAA,aAAA,CAAc,SAAS,QAAS,CAAA,MAAA;AAChC,EAAA,aAAA,CAAc,QAAS,QAAS,CAAA,KAAA;AAChC,EAAA,aAAA,CAAc,SAAS,QAAS,CAAA,MAAA;AAEhC,EAAM,MAAA,MAAA,GAAS,MAAM,aAClB,CAAA,MAAA,CAAO,EAAE,GAAK,EAAA,QAAA,EAAU,OAAO,EAAI,EAAA,MAAA,EAAQ,IAAI,CAAA,CAC/C,MACA,CAAA,IAAA,CAAK,EAAE,MAAQ,EAAA,CAAA,EAAG,CAAA,CAClB,QAAS,EAAA;AAEZ,EAAA,aAAA,CAAc,IAAO,GAAA,CAAA,uBAAA,EAA0B,MAAO,CAAA,QAAA,CAAS,QAAQ,CAAC,CAAA,CAAA;AACxE,EAAA,OAAO,UAAU,CAAG,EAAA,QAAQ,SAAS,IAAK,CAAA,SAAA,CAAU,aAAa,CAAC,CAAA;AACpE,CAAA;AAEA,MAAM,oBAAA,GAAuB,OAAO,SAAyC,KAAA;AAC3E,EAAA,MAAM,mBAAmB,MAAM,OAAA,CAAQ,WAAW,EAAE,aAAA,EAAe,MAAM,CAAA;AAEzE,EAAA,MAAM,0BAA6B,GAAA,gBAAA,CAChC,GAAI,CAAA,OAAM,KAAS,KAAA;AAClB,IAAA,MAAM,SAAY,GAAA,IAAA,CAAK,SAAW,EAAA,KAAA,CAAM,IAAI,CAAA;AAE5C,IAAA,IAAI,MAAM,WAAY,EAAA;AACpB,MAAO,OAAA,MAAM,qBAAqB,SAAS,CAAA;AAE7C,IAAA,IACE,MAAM,IAAK,CAAA,CAAC,CAAK,IAAA,GAAA,IACjB,CAAC,OAAS,EAAA,OAAA,EAAS,OAAO,CAAA,CACvB,SAAS,OAAQ,CAAA,KAAA,CAAM,IAAI,CAAC,KAC/B,gBAAiB,CAAA,IAAA;AAAA,MAAK,kBACpB,CAAC,OAAA,EAAS,OAAS,EAAA,OAAO,EACvB,GAAI,CAAA,CAAA,kBAAA,KAAsB,CAAG,EAAA,KAAA,CAAM,IAAI,CAAG,EAAA,kBAAkB,EAAE,CAC9D,CAAA,QAAA,CAAS,aAAa,IAAI;AAAA,KAC/B;AAEA,MAAA,OAAO,EAAC;AAEV,IAAA,OAAO,CAAC,SAAS,CAAA;AAAA,GAClB,CAAA;AAEH,EAAA,OAAA,CAAQ,MAAM,OAAA,CAAQ,GAAI,CAAA,0BAA0B,GAAG,IAAK,EAAA;AAC9D,CAAA;AAEa,MAAA,aAAA,GAAgB,OAAO,SAAsB,KAAA;AACxD,EAAM,MAAA,iBAAA,GAAoB,MAAM,oBAAA,CAAqB,SAAS,CAAA;AAC9D,EAAA,KAAA,MAAW,YAAY,iBAAmB,EAAA;AACxC,IAAA,MAAM,OAAQ,CAAA,GAAA;AAAA,MACZ,CAAC,IAAA,EAAM,IAAM,EAAA,IAAI,CACd,CAAA,GAAA,CAAI,CAAW,OAAA,KAAA,OAAA,CAAQ,QAAU,EAAA,KAAA,CAAM,QAAQ,CAAC,CAAC;AAAA,KACtD;AAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const weakRefPolyfill = () => {
|
|
2
|
+
if (globalThis.WeakRef) return;
|
|
3
|
+
const weakRefToObject = /* @__PURE__ */ new WeakMap();
|
|
4
|
+
class WeakRefPolyfill {
|
|
5
|
+
constructor(object) {
|
|
6
|
+
weakRefToObject.set(this, object);
|
|
7
|
+
}
|
|
8
|
+
deref() {
|
|
9
|
+
return weakRefToObject.get(this);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
globalThis.WeakRef = WeakRefPolyfill;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export { weakRefPolyfill };
|
|
16
|
+
//# sourceMappingURL=weakref.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weakref.mjs","sources":["../../src/polyfills/weakref.mts"],"sourcesContent":["/**\n * Was unsupported in safari until spring 2021\n */\nexport const weakRefPolyfill = () => {\n if (globalThis.WeakRef) return\n\n const weakRefToObject = new WeakMap<WeakRefPolyfill<object>, object>()\n\n class WeakRefPolyfill<T extends object> {\n constructor(object: T) {\n weakRefToObject.set(this, object)\n }\n\n deref(): T | undefined {\n return weakRefToObject.get(this) as T\n }\n }\n\n globalThis.WeakRef = WeakRefPolyfill as WeakRefConstructor\n}\n"],"names":[],"mappings":"AAGO,MAAM,kBAAkB,MAAM;AACnC,EAAA,IAAI,WAAW,OAAS,EAAA;AAExB,EAAM,MAAA,eAAA,uBAAsB,OAAyC,EAAA;AAAA,EAErE,MAAM,eAAkC,CAAA;AAAA,IACtC,YAAY,MAAW,EAAA;AACrB,MAAgB,eAAA,CAAA,GAAA,CAAI,MAAM,MAAM,CAAA;AAAA;AAClC,IAEA,KAAuB,GAAA;AACrB,MAAO,OAAA,eAAA,CAAgB,IAAI,IAAI,CAAA;AAAA;AACjC;AAGF,EAAA,UAAA,CAAW,OAAU,GAAA,eAAA;AACvB;;;;"}
|