@edrlab/thorium-web 1.1.2 → 1.1.4

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.
Files changed (86) hide show
  1. package/README.md +2 -0
  2. package/dist/{StatefulReader-BjH7bkU1.d.mts → StatefulReader-lpxHxgKK.d.mts} +8 -6
  3. package/dist/{ThPreferencesAdapter-x_D4c7wI.d.mts → ThPreferencesAdapter-CcJgE3zC.d.mts} +78 -56
  4. package/dist/{actionsReducer-BKoeohBu.d.mts → actionsReducer-6UNIgifE.d.mts} +1 -1
  5. package/dist/{chunk-2JHEFF46.mjs → chunk-GKXS45F4.mjs} +347 -47
  6. package/dist/chunk-GKXS45F4.mjs.map +1 -0
  7. package/dist/{chunk-VETE7ULS.mjs → chunk-KKMH2EPS.mjs} +12 -4
  8. package/dist/chunk-KKMH2EPS.mjs.map +1 -0
  9. package/dist/{chunk-HE3WFPGE.mjs → chunk-KTZPAJ4S.mjs} +34 -19
  10. package/dist/chunk-KTZPAJ4S.mjs.map +1 -0
  11. package/dist/{chunk-EY4D4BZN.mjs → chunk-MW7LXDWC.mjs} +3 -3
  12. package/dist/{chunk-EY4D4BZN.mjs.map → chunk-MW7LXDWC.mjs.map} +1 -1
  13. package/dist/{chunk-IRA4ZKAX.mjs → chunk-VN44OJDD.mjs} +819 -43
  14. package/dist/chunk-VN44OJDD.mjs.map +1 -0
  15. package/dist/components/Epub/index.css +1 -0
  16. package/dist/components/Epub/index.css.map +1 -1
  17. package/dist/components/Epub/index.d.mts +8 -8
  18. package/dist/components/Epub/index.mjs +55 -18
  19. package/dist/components/Epub/index.mjs.map +1 -1
  20. package/dist/components/WebPub/index.css +1 -0
  21. package/dist/components/WebPub/index.css.map +1 -1
  22. package/dist/components/WebPub/index.d.mts +12 -12
  23. package/dist/components/WebPub/index.mjs +39 -16
  24. package/dist/components/WebPub/index.mjs.map +1 -1
  25. package/dist/core/Components/index.d.mts +2 -2
  26. package/dist/core/Helpers/index.d.mts +2 -2
  27. package/dist/core/Hooks/index.d.mts +4 -4
  28. package/dist/core/Hooks/index.mjs +1 -1
  29. package/dist/{enums-CBaXSsr9.d.mts → enums-Bhwwdfx5.d.mts} +1 -1
  30. package/dist/fonts/AccessibleDfA/AccessibleDfA-Bold.woff2 +0 -0
  31. package/dist/fonts/AccessibleDfA/AccessibleDfA-Italic.woff2 +0 -0
  32. package/dist/fonts/AccessibleDfA/AccessibleDfA-Regular.woff2 +0 -0
  33. package/dist/fonts/AccessibleDfA/LICENSE-AccessibleDfa +95 -0
  34. package/dist/fonts/AndroidPatch/sans-serif/GNU General Public License.txt +340 -0
  35. package/dist/fonts/AndroidPatch/sans-serif/NimbusSans-Bold.woff +0 -0
  36. package/dist/fonts/AndroidPatch/sans-serif/NimbusSans-BoldItalic.woff +0 -0
  37. package/dist/fonts/AndroidPatch/sans-serif/NimbusSans-Italic.woff +0 -0
  38. package/dist/fonts/AndroidPatch/sans-serif/NimbusSans.woff +0 -0
  39. package/dist/fonts/AndroidPatch/serif/GNU General Public License.txt +340 -0
  40. package/dist/fonts/AndroidPatch/serif/NimbusRoman-Bold.woff +0 -0
  41. package/dist/fonts/AndroidPatch/serif/NimbusRoman-BoldItalic.woff +0 -0
  42. package/dist/fonts/AndroidPatch/serif/NimbusRoman-Italic.woff +0 -0
  43. package/dist/fonts/AndroidPatch/serif/NimbusRoman.woff +0 -0
  44. package/dist/fonts/Luciole/Luciole-Bold.woff2 +0 -0
  45. package/dist/fonts/Luciole/Luciole-BoldItalic.woff2 +0 -0
  46. package/dist/fonts/Luciole/Luciole-Italic.woff2 +0 -0
  47. package/dist/fonts/Luciole/Luciole-Regular.woff2 +0 -0
  48. package/dist/fonts/Luciole/Read Me.txt +14 -0
  49. package/dist/fonts/OpenDyslexic/OpenDyslexic-Bold.otf +0 -0
  50. package/dist/fonts/OpenDyslexic/OpenDyslexic-BoldItalic.otf +0 -0
  51. package/dist/fonts/OpenDyslexic/OpenDyslexic-Italic.otf +0 -0
  52. package/dist/fonts/OpenDyslexic/OpenDyslexic-Regular.otf +0 -0
  53. package/dist/fonts/iAWriterDuo/README.md +13 -0
  54. package/dist/fonts/iAWriterDuo/iAWriterDuoS-Bold.woff2 +0 -0
  55. package/dist/fonts/iAWriterDuo/iAWriterDuoS-BoldItalic.woff2 +0 -0
  56. package/dist/fonts/iAWriterDuo/iAWriterDuoS-Italic.woff2 +0 -0
  57. package/dist/fonts/iAWriterDuo/iAWriterDuoS-Regular.woff2 +0 -0
  58. package/dist/i18n/index.mjs +2 -2
  59. package/dist/lib/index.d.mts +35 -18
  60. package/dist/lib/index.mjs +1 -1
  61. package/dist/locales/ar/thorium-shared.json +258 -2
  62. package/dist/locales/ar/thorium-web.json +59 -1
  63. package/dist/locales/da/thorium-shared.json +9 -3
  64. package/dist/locales/el/thorium-web.json +53 -1
  65. package/dist/locales/en/thorium-shared.json +30 -12
  66. package/dist/locales/et/thorium-shared.json +99 -7
  67. package/dist/locales/fi/thorium-shared.json +68 -15
  68. package/dist/locales/fr/thorium-shared.json +12 -6
  69. package/dist/locales/it/thorium-shared.json +82 -14
  70. package/dist/locales/lt/thorium-shared.json +80 -12
  71. package/dist/locales/pt-BR/thorium-shared.json +24 -12
  72. package/dist/locales/pt-PT/thorium-shared.json +24 -12
  73. package/dist/locales/sv/thorium-shared.json +24 -12
  74. package/dist/locales/tr/thorium-shared.json +24 -12
  75. package/dist/preferences/index.d.mts +104 -7
  76. package/dist/preferences/index.mjs +1 -1
  77. package/dist/{useBreakpoints-BtHd3571.d.mts → useBreakpoints-LTrHif3E.d.mts} +1 -1
  78. package/dist/{useEpubNavigator-DpvqVgNu.d.mts → useEpubNavigator-DQq5VlY0.d.mts} +2 -1
  79. package/dist/usePreferences-CM_Y2jpZ.d.mts +42 -0
  80. package/dist/{useWebPubNavigator-DBRj8KyC.d.mts → useWebPubNavigator-XFUVekhV.d.mts} +2 -1
  81. package/package.json +22 -20
  82. package/dist/chunk-2JHEFF46.mjs.map +0 -1
  83. package/dist/chunk-HE3WFPGE.mjs.map +0 -1
  84. package/dist/chunk-IRA4ZKAX.mjs.map +0 -1
  85. package/dist/chunk-VETE7ULS.mjs.map +0 -1
  86. package/dist/usePreferences-CRjFlZvF.d.mts +0 -16
@@ -126,8 +126,307 @@ var createPreferences = (params) => {
126
126
  }
127
127
  }
128
128
  }
129
+ if (params.settings?.keys?.fontFamily) {
130
+ const fontFamilyPref = params.settings.keys.fontFamily;
131
+ const languageMap = /* @__PURE__ */ new Map();
132
+ Object.entries(fontFamilyPref).forEach(([collectionName, collectionData]) => {
133
+ if (collectionName === "default") return;
134
+ const supportedLangs = "supportedLanguages" in collectionData ? collectionData.supportedLanguages : null;
135
+ if (supportedLangs && Array.isArray(supportedLangs)) {
136
+ supportedLangs.forEach((lang) => {
137
+ if (!languageMap.has(lang)) {
138
+ languageMap.set(lang, []);
139
+ }
140
+ languageMap.get(lang).push(collectionName);
141
+ });
142
+ }
143
+ });
144
+ languageMap.forEach((collections, language) => {
145
+ if (collections.length > 1) {
146
+ console.warn(`Language "${language}" is supported by multiple font collections: ${collections.join(", ")}. This may cause ambiguous font selection. Consider consolidating to a single collection per language.`);
147
+ }
148
+ });
149
+ }
129
150
  return params;
130
151
  };
152
+
153
+ // src/preferences/helpers/buildThemeObject.ts
154
+ var buildThemeObject = ({
155
+ theme,
156
+ themeKeys,
157
+ systemThemes,
158
+ colorScheme
159
+ }) => {
160
+ if (!theme) {
161
+ return {};
162
+ }
163
+ if (theme === "auto" && colorScheme && systemThemes) {
164
+ theme = colorScheme === "dark" /* dark */ ? systemThemes.dark : systemThemes.light;
165
+ }
166
+ let themeProps = {};
167
+ const themeToken = themeKeys[theme];
168
+ if (themeToken) {
169
+ themeProps = {
170
+ backgroundColor: themeToken.background,
171
+ textColor: themeToken.text,
172
+ linkColor: themeToken.link,
173
+ selectionBackgroundColor: themeToken.select,
174
+ selectionTextColor: themeToken.onSelect,
175
+ visitedColor: themeToken.visited
176
+ };
177
+ } else {
178
+ console.warn(`Theme key "${String(theme)}" not found in themeKeys.`);
179
+ themeProps = {
180
+ backgroundColor: null,
181
+ textColor: null,
182
+ linkColor: null,
183
+ selectionBackgroundColor: null,
184
+ selectionTextColor: null,
185
+ visitedColor: null
186
+ };
187
+ }
188
+ return themeProps;
189
+ };
190
+
191
+ // src/preferences/helpers/fontPref/bunnyFonts.ts
192
+ var DEFAULT_FALLBACK = "sans-serif";
193
+ var createDefinitionsFromBunnyFonts = (params) => {
194
+ const { cssUrl, options } = params;
195
+ const { fallbacks, order, labels } = options || {};
196
+ const processedUrl = cssUrl.includes("@import") ? cssUrl.match(/@import\s+url\(['"]?([^'")]+)['"]?\)/i)?.[1] || cssUrl : cssUrl.includes("href=") ? cssUrl.match(/href=["']([^"']+)["']/)?.[1] || cssUrl : cssUrl;
197
+ const url = new URL(processedUrl);
198
+ if (!url.hostname.includes("fonts.bunny.net")) {
199
+ throw new Error("Invalid Bunny Fonts URL");
200
+ }
201
+ const familyParam = url.searchParams.get("family");
202
+ if (!familyParam) {
203
+ throw new Error("No family parameter found in Bunny Fonts URL");
204
+ }
205
+ const fontEntries = familyParam.split("|").map((familyStr) => {
206
+ const [familyName, weightsStr = ""] = familyStr.split(":");
207
+ if (!familyName) {
208
+ throw new Error(`Invalid font family format: ${familyStr}`);
209
+ }
210
+ const weightStyles = /* @__PURE__ */ new Map();
211
+ if (weightsStr) {
212
+ weightsStr.split(",").forEach((weightStr) => {
213
+ const isItalic = weightStr.endsWith("i");
214
+ const weightValue = parseInt(isItalic ? weightStr.slice(0, -1) : weightStr, 10);
215
+ if (!isNaN(weightValue)) {
216
+ if (!weightStyles.has(weightValue)) {
217
+ weightStyles.set(weightValue, /* @__PURE__ */ new Set());
218
+ }
219
+ weightStyles.get(weightValue)?.add(isItalic ? "italic" : "normal");
220
+ }
221
+ });
222
+ }
223
+ const weights = Array.from(weightStyles.keys()).sort((a, b) => a - b);
224
+ const hasItalic = Array.from(weightStyles.values()).some((styles2) => styles2.has("italic"));
225
+ const styles = hasItalic ? ["normal", "italic"] : ["normal"];
226
+ const fontId = familyName;
227
+ const familyDisplayName = familyName.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
228
+ return [
229
+ fontId,
230
+ {
231
+ id: fontId,
232
+ name: familyDisplayName,
233
+ ...labels?.[fontId] && { label: labels[fontId] },
234
+ source: {
235
+ type: "custom",
236
+ provider: "bunny"
237
+ },
238
+ spec: {
239
+ family: familyDisplayName,
240
+ fallbacks: fallbacks?.[fontId] || [DEFAULT_FALLBACK],
241
+ weights: {
242
+ type: "static",
243
+ values: weights.length ? weights : [400]
244
+ },
245
+ styles
246
+ }
247
+ }
248
+ ];
249
+ });
250
+ const result = Object.fromEntries(fontEntries);
251
+ if (order && order.length > 0) {
252
+ const orderedResult = {};
253
+ order.forEach((fontId) => {
254
+ if (result[fontId]) {
255
+ orderedResult[fontId] = result[fontId];
256
+ }
257
+ });
258
+ Object.entries(result).forEach(([fontId, definition]) => {
259
+ if (!orderedResult[fontId]) {
260
+ orderedResult[fontId] = definition;
261
+ }
262
+ });
263
+ return orderedResult;
264
+ }
265
+ return result;
266
+ };
267
+
268
+ // src/preferences/helpers/fontPref/googleFonts.ts
269
+ var DEFAULT_FALLBACK2 = "sans-serif";
270
+ var DEFAULT_WIDTH_STEP = 20;
271
+ var DEFAULT_WEIGHT_STEP = 20;
272
+ var createDefinitionsFromGoogleFonts = (params) => {
273
+ const { cssUrl, options } = params;
274
+ const { widthStep = DEFAULT_WIDTH_STEP, weightStep = DEFAULT_WEIGHT_STEP, display, labels, fallbacks, order } = options || {};
275
+ const processedUrl = cssUrl.includes("@import") ? cssUrl.match(/@import\s+url\(['"]?([^'")]+)['"]?\)/i)?.[1] || cssUrl : cssUrl.includes("href=") ? cssUrl.match(/href=["']([^"']+)["']/)?.[1] || cssUrl : cssUrl;
276
+ const url = new URL(processedUrl);
277
+ if (!url.hostname.includes("fonts.googleapis.com")) {
278
+ throw new Error("Invalid Google Fonts URL");
279
+ }
280
+ const familyParams = url.searchParams.getAll("family");
281
+ if (familyParams.length === 0) {
282
+ throw new Error("No family parameter found in Google Fonts URL");
283
+ }
284
+ const families = familyParams.map((familyParam) => {
285
+ const decodedFamily = decodeURIComponent(familyParam);
286
+ const [familyName, axesStr] = decodedFamily.split(":");
287
+ if (!familyName) {
288
+ throw new Error(`Invalid family format: ${familyParam}`);
289
+ }
290
+ const family = {
291
+ name: familyName.replace(/\+/g, " "),
292
+ styles: ["normal"],
293
+ weights: { type: "static", values: [400] }
294
+ // Default weight
295
+ };
296
+ let hasExplicitWeights = false;
297
+ if (axesStr) {
298
+ const [axisNames, valuesStr] = axesStr.split("@");
299
+ if (axisNames && valuesStr) {
300
+ const axes = axisNames.split(",");
301
+ const variations = valuesStr.split(";");
302
+ variations.forEach((variation) => {
303
+ const values = variation.split(",");
304
+ axes.forEach((axis, index) => {
305
+ const value = values[index];
306
+ if (!value) return;
307
+ switch (axis) {
308
+ case "ital":
309
+ if (value === "1") {
310
+ family.styles = Array.from(/* @__PURE__ */ new Set([...family.styles, "italic"]));
311
+ }
312
+ break;
313
+ case "wght":
314
+ if (value.includes("..")) {
315
+ const [min, max] = value.split("..").map(Number);
316
+ if (!isNaN(min) && !isNaN(max)) {
317
+ family.weights = {
318
+ type: "variable",
319
+ min,
320
+ max,
321
+ step: weightStep
322
+ };
323
+ }
324
+ } else {
325
+ const weight = Number(value);
326
+ if (!isNaN(weight) && family.weights.type === "static") {
327
+ const currentWeights = family.weights.values;
328
+ const newWeights = !hasExplicitWeights ? [weight] : Array.from(/* @__PURE__ */ new Set([...currentWeights, weight])).sort((a, b) => a - b);
329
+ family.weights = {
330
+ type: "static",
331
+ values: newWeights
332
+ };
333
+ hasExplicitWeights = true;
334
+ }
335
+ }
336
+ break;
337
+ case "wdth":
338
+ if (value.includes("..")) {
339
+ const [min, max] = value.split("..").map(Number);
340
+ if (!isNaN(min) && !isNaN(max)) {
341
+ family.widths = {
342
+ min,
343
+ max,
344
+ step: widthStep
345
+ };
346
+ }
347
+ }
348
+ break;
349
+ }
350
+ });
351
+ });
352
+ }
353
+ }
354
+ return family;
355
+ });
356
+ const fontEntries = families.map((family) => {
357
+ const fontId = family.name.toLowerCase().replace(/\s+/g, "-");
358
+ return [
359
+ fontId,
360
+ {
361
+ id: fontId,
362
+ name: family.name,
363
+ ...labels?.[fontId] && { label: labels[fontId] },
364
+ source: { type: "custom", provider: "google" },
365
+ spec: {
366
+ family: family.name,
367
+ fallbacks: fallbacks?.[fontId] || [DEFAULT_FALLBACK2],
368
+ weights: family.weights,
369
+ styles: family.styles,
370
+ ...family.widths && { widths: family.widths },
371
+ ...display && { display }
372
+ }
373
+ }
374
+ ];
375
+ });
376
+ if (order && order.length > 0) {
377
+ const orderedEntries = [];
378
+ const fontMap = new Map(fontEntries);
379
+ for (const fontId of order) {
380
+ const fontEntry = fontMap.get(fontId);
381
+ if (fontEntry) {
382
+ orderedEntries.push([fontId, fontEntry]);
383
+ fontMap.delete(fontId);
384
+ }
385
+ }
386
+ for (const [fontId, fontEntry] of fontMap.entries()) {
387
+ orderedEntries.push([fontId, fontEntry]);
388
+ }
389
+ return Object.fromEntries(orderedEntries);
390
+ }
391
+ return Object.fromEntries(fontEntries);
392
+ };
393
+
394
+ // src/preferences/helpers/fontPref/localFonts.ts
395
+ var createDefinitionFromStaticFonts = (params) => {
396
+ const { id, name, files, family, label, fallbacks = ["sans-serif"] } = params;
397
+ if (!files || files.length === 0) {
398
+ throw new Error("No files provided to infer font specification");
399
+ }
400
+ if (!files.every((file) => file.weight !== void 0)) {
401
+ throw new Error("All files must have explicit weights for static font specification inference");
402
+ }
403
+ const weights = Array.from(new Set(files.map((file) => file.weight))).sort((a, b) => a - b);
404
+ const styles = Array.from(new Set(files.map((file) => file.style)));
405
+ const source = {
406
+ type: "custom",
407
+ provider: "local",
408
+ variant: "static",
409
+ files
410
+ };
411
+ const spec = {
412
+ family: family || name,
413
+ fallbacks,
414
+ weights: {
415
+ type: "static",
416
+ values: weights
417
+ },
418
+ styles
419
+ };
420
+ return {
421
+ id,
422
+ name,
423
+ ...label && { label },
424
+ source,
425
+ spec
426
+ };
427
+ };
428
+
429
+ // src/preferences/models/const.ts
131
430
  var defaultActionKeysObject = {
132
431
  visibility: "partially" /* partially */,
133
432
  shortcut: null
@@ -159,13 +458,134 @@ var defaultSpacingPresetsOrder = [
159
458
  "balanced" /* balanced */,
160
459
  "loose" /* loose */
161
460
  ];
162
- var defaultFontFamilyOptions = {
163
- publisher: null,
164
- oldStyle: fontStacks.RS__oldStyleTf,
165
- modern: fontStacks.RS__modernTf,
166
- sans: fontStacks.RS__sansTf,
167
- humanist: fontStacks.RS__humanistTf,
168
- monospace: fontStacks.RS__monospaceTf
461
+ var readiumCSSFontCollection = {
462
+ oldStyle: {
463
+ id: "oldStyle",
464
+ name: "Old Style",
465
+ label: "reader.preferences.fontFamily.oldStyle.descriptive",
466
+ source: { type: "system" },
467
+ spec: {
468
+ family: fontStacks.RS__oldStyleTf,
469
+ weights: { type: "static", values: [400, 700] },
470
+ fallbacks: []
471
+ }
472
+ },
473
+ modern: {
474
+ id: "modern",
475
+ name: "Modern",
476
+ label: "reader.preferences.fontFamily.modern.descriptive",
477
+ source: { type: "system" },
478
+ spec: {
479
+ family: fontStacks.RS__modernTf,
480
+ weights: { type: "static", values: [400, 700] },
481
+ fallbacks: []
482
+ }
483
+ },
484
+ sans: {
485
+ id: "sans",
486
+ name: "Sans",
487
+ label: "reader.preferences.fontFamily.sans",
488
+ source: { type: "system" },
489
+ spec: {
490
+ family: fontStacks.RS__sansTf,
491
+ weights: { type: "static", values: [400, 700] },
492
+ fallbacks: []
493
+ }
494
+ },
495
+ humanist: {
496
+ id: "humanist",
497
+ name: "Humanist",
498
+ label: "reader.preferences.fontFamily.humanist.descriptive",
499
+ source: { type: "system" },
500
+ spec: {
501
+ family: fontStacks.RS__humanistTf,
502
+ weights: { type: "static", values: [400, 700] },
503
+ fallbacks: []
504
+ }
505
+ },
506
+ monospace: {
507
+ id: "monospace",
508
+ name: "Monospace",
509
+ label: "reader.preferences.fontFamily.monospace",
510
+ source: { type: "system" },
511
+ spec: {
512
+ family: fontStacks.RS__monospaceTf,
513
+ weights: { type: "static", values: [400, 700] },
514
+ fallbacks: []
515
+ }
516
+ }
517
+ };
518
+ var defaultFontCollection = {
519
+ ...createDefinitionsFromGoogleFonts({
520
+ cssUrl: "https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible+Next:ital,wght@0,200..800;1,200..800&family=Literata:ital,opsz,wght@0,7..72,200..900;1,7..72,200..900",
521
+ options: {
522
+ order: ["literata", "atkinson-hyperlegible-next"],
523
+ fallbacks: {
524
+ "literata": ["serif"],
525
+ "atkinson-hyperlegible-next": ["sans-serif"]
526
+ }
527
+ }
528
+ }),
529
+ luciole: createDefinitionFromStaticFonts({
530
+ id: "luciole",
531
+ name: "Luciole",
532
+ files: [
533
+ { path: "/fonts/Luciole/Luciole-Regular.woff2", weight: 400, style: "normal" },
534
+ { path: "/fonts/Luciole/Luciole-Italic.woff2", weight: 400, style: "italic" },
535
+ { path: "/fonts/Luciole/Luciole-Bold.woff2", weight: 700, style: "normal" },
536
+ { path: "/fonts/Luciole/Luciole-BoldItalic.woff2", weight: 700, style: "italic" }
537
+ ]
538
+ }),
539
+ ...readiumCSSFontCollection,
540
+ iAWriterDuo: createDefinitionFromStaticFonts({
541
+ id: "iAWriterDuo",
542
+ name: "iA Writer Duo",
543
+ label: "iA Writer Duospace",
544
+ fallbacks: ["monospace"],
545
+ files: [
546
+ { path: "/fonts/iAWriterDuo/iAWriterDuoS-Regular.woff2", weight: 400, style: "normal" },
547
+ { path: "/fonts/iAWriterDuo/iAWriterDuoS-Bold.woff2", weight: 700, style: "normal" },
548
+ { path: "/fonts/iAWriterDuo/iAWriterDuoS-Italic.woff2", weight: 400, style: "italic" },
549
+ { path: "/fonts/iAWriterDuo/iAWriterDuoS-BoldItalic.woff2", weight: 700, style: "italic" }
550
+ ]
551
+ }),
552
+ openDyslexic: createDefinitionFromStaticFonts({
553
+ id: "openDyslexic",
554
+ name: "Open Dyslexic",
555
+ files: [
556
+ { path: "/fonts/OpenDyslexic/OpenDyslexic-Regular.otf", weight: 400, style: "normal" },
557
+ { path: "/fonts/OpenDyslexic/OpenDyslexic-Italic.otf", weight: 400, style: "italic" },
558
+ { path: "/fonts/OpenDyslexic/OpenDyslexic-Bold.otf", weight: 700, style: "normal" },
559
+ { path: "/fonts/OpenDyslexic/OpenDyslexic-BoldItalic.otf", weight: 700, style: "italic" }
560
+ ]
561
+ }),
562
+ accessibleDfA: createDefinitionFromStaticFonts({
563
+ id: "accessibleDfA",
564
+ name: "Accessible DfA",
565
+ files: [
566
+ { path: "/fonts/AccessibleDfA/AccessibleDfA-Regular.woff2", weight: 400, style: "normal" },
567
+ { path: "/fonts/AccessibleDfA/AccessibleDfA-Italic.woff2", weight: 400, style: "italic" },
568
+ { path: "/fonts/AccessibleDfA/AccessibleDfA-Bold.woff2", weight: 700, style: "normal" }
569
+ ]
570
+ })
571
+ };
572
+ var tamilCollection = {
573
+ ...createDefinitionsFromGoogleFonts({
574
+ cssUrl: "https://fonts.googleapis.com/css2?family=Anek+Tamil:wght@100..800&family=Catamaran:wght@100..900&family=Hind+Madurai:wght@400;700&family=Mukta+Malar:wght@400;700&family=Noto+Sans+Tamil:wght@100..900&family=Noto+Serif+Tamil:ital,wght@0,100..900;1,100..900",
575
+ options: {
576
+ order: ["noto-sans-tamil", "noto-serif-tamil", "anek-tamil", "catamaran", "hind-madurai", "mukta-malar"],
577
+ labels: {
578
+ "noto-sans-tamil": "Noto Sans",
579
+ "noto-serif-tamil": "Noto Serif",
580
+ "anek-tamil": "\u0B85\u0BA9\u0BC7\u0B95\u0BCD \u0BA4\u0BAE\u0BBF\u0BB4\u0BCD",
581
+ "catamaran": "\u0B95\u0B9F\u0BCD\u0B9F\u0BC1\u0BAE\u0BB0\u0BA9\u0BCD",
582
+ "mukta-malar": "\u0BAE\u0BC1\u0B95\u0BCD\u0BA4 \u0BAE\u0BB2\u0BB0\u0BCD"
583
+ },
584
+ fallbacks: {
585
+ "noto-serif-tamil": ["serif"]
586
+ }
587
+ }
588
+ })
169
589
  };
170
590
  var defaultParagraphSpacing = {
171
591
  variant: "numberField" /* numberField */,
@@ -721,6 +1141,13 @@ var defaultPreferences = createPreferences({
721
1141
  "spacingGroup" /* spacingGroup */
722
1142
  ],
723
1143
  keys: {
1144
+ ["fontFamily" /* fontFamily */]: {
1145
+ default: defaultFontCollection,
1146
+ tamil: {
1147
+ supportedLanguages: ["ta"],
1148
+ fonts: tamilCollection
1149
+ }
1150
+ },
724
1151
  ["letterSpacing" /* letterSpacing */]: defaultLetterSpacing,
725
1152
  ["lineHeight" /* lineHeight */]: {
726
1153
  allowUnset: false,
@@ -732,10 +1159,14 @@ var defaultPreferences = createPreferences({
732
1159
  ["zoom" /* zoom */]: defaultZoom
733
1160
  },
734
1161
  text: {
735
- header: "previous" /* previous */
1162
+ header: "previous" /* previous */,
1163
+ main: defaultTextSettingsMain,
1164
+ subPanel: defaultTextSettingsSubpanel
736
1165
  },
737
1166
  spacing: {
738
1167
  header: "previous" /* previous */,
1168
+ main: defaultSpacingSettingsMain,
1169
+ subPanel: defaultSpacingSettingsSubpanel,
739
1170
  presets: {
740
1171
  reflowOrder: defaultSpacingPresetsOrder,
741
1172
  webPubOrder: defaultSpacingPresetsOrder,
@@ -820,51 +1251,396 @@ function ThPreferencesProvider({
820
1251
  return /* @__PURE__ */ jsx(ThPreferencesContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(ThDirectionSetter, { direction: preferences.direction, children }) });
821
1252
  }
822
1253
 
823
- // src/preferences/helpers/buildThemeObject.ts
824
- var buildThemeObject = ({
825
- theme,
826
- themeKeys,
827
- systemThemes,
828
- colorScheme
1254
+ // src/preferences/services/createBunnyFontResources.ts
1255
+ var buildBunnyFontsUrl = ({
1256
+ family,
1257
+ weights,
1258
+ styles = ["normal"]
829
1259
  }) => {
830
- if (!theme) {
831
- return {};
1260
+ if (weights.type !== "static") {
1261
+ throw new Error("Bunny Fonts only supports static fonts");
832
1262
  }
833
- if (theme === "auto" && colorScheme && systemThemes) {
834
- theme = colorScheme === "dark" /* dark */ ? systemThemes.dark : systemThemes.light;
1263
+ const weightValues = weights.values;
1264
+ const variants = /* @__PURE__ */ new Set();
1265
+ for (const weight of weightValues) {
1266
+ variants.add(weight.toString());
1267
+ if (styles.includes("italic")) {
1268
+ variants.add(`${weight}i`);
1269
+ }
835
1270
  }
836
- let themeProps = {};
837
- const themeToken = themeKeys[theme];
838
- if (themeToken) {
839
- themeProps = {
840
- backgroundColor: themeToken.background,
841
- textColor: themeToken.text,
842
- linkColor: themeToken.link,
843
- selectionBackgroundColor: themeToken.select,
844
- selectionTextColor: themeToken.onSelect,
845
- visitedColor: themeToken.visited
846
- };
1271
+ const variantList = Array.from(variants).sort();
1272
+ const familyParam = family.replace(/ /g, "-").toLowerCase();
1273
+ const variantParam = variantList.join(",");
1274
+ return `https://fonts.bunny.net/css?family=${familyParam}:${variantParam}`;
1275
+ };
1276
+ var createBunnyFontResources = (font) => {
1277
+ if (font.source.type !== "custom" || font.source.provider !== "bunny" || font.spec.weights.type !== "static") {
1278
+ return null;
1279
+ }
1280
+ const { family, weights, styles } = font.spec;
1281
+ const url = buildBunnyFontsUrl({
1282
+ family,
1283
+ weights,
1284
+ styles
1285
+ });
1286
+ return {
1287
+ as: "link",
1288
+ rel: "stylesheet",
1289
+ url
1290
+ };
1291
+ };
1292
+
1293
+ // src/preferences/services/createGoogleFontResources.ts
1294
+ var buildGoogleFontsV2Url = ({
1295
+ family,
1296
+ weights,
1297
+ styles = ["normal"],
1298
+ widths,
1299
+ display = "block",
1300
+ text
1301
+ }) => {
1302
+ if (text) {
1303
+ return `https://fonts.googleapis.com/css2?family=${family.replace(/ /g, "+")}&text=${encodeURIComponent(text)}`;
1304
+ }
1305
+ const hasItalic = styles.includes("italic");
1306
+ const hasWidth = !!widths;
1307
+ const weightValues = weights.type === "static" ? weights.values.join(",") : `${weights.min}..${weights.max}`;
1308
+ const widthValues = hasWidth && widths ? `${widths.min}..${widths.max}` : void 0;
1309
+ const familyParam = family.replace(/ /g, "+");
1310
+ let axesParam;
1311
+ if (hasItalic && hasWidth) {
1312
+ const variants = [
1313
+ `0,${widthValues},${weightValues}`,
1314
+ // normal
1315
+ `1,${widthValues},${weightValues}`
1316
+ // italic
1317
+ ];
1318
+ axesParam = `:ital,wdth,wght@${variants.join(";")}`;
1319
+ } else if (hasItalic) {
1320
+ const variants = [
1321
+ `0,${weightValues}`,
1322
+ // normal
1323
+ `1,${weightValues}`
1324
+ // italic
1325
+ ];
1326
+ axesParam = `:ital,wght@${variants.join(";")}`;
1327
+ } else if (hasWidth) {
1328
+ axesParam = `:wdth,wght@${widthValues},${weightValues}`;
847
1329
  } else {
848
- console.warn(`Theme key "${String(theme)}" not found in themeKeys.`);
849
- themeProps = {
850
- backgroundColor: null,
851
- textColor: null,
852
- linkColor: null,
853
- selectionBackgroundColor: null,
854
- selectionTextColor: null,
855
- visitedColor: null
856
- };
1330
+ axesParam = `:wght@${weightValues}`;
857
1331
  }
858
- return themeProps;
1332
+ const displayParam = display ? `&display=${display}` : "";
1333
+ return `https://fonts.googleapis.com/css2?family=${familyParam}${axesParam}${displayParam}`;
1334
+ };
1335
+ var createGoogleFontResources = (font, text) => {
1336
+ if (font.source.type !== "custom" || font.source.provider !== "google") {
1337
+ return null;
1338
+ }
1339
+ const { family, weights, display, styles, widths } = font.spec;
1340
+ const url = buildGoogleFontsV2Url({
1341
+ family,
1342
+ weights,
1343
+ display,
1344
+ styles,
1345
+ widths,
1346
+ text
1347
+ });
1348
+ return {
1349
+ as: "link",
1350
+ rel: "stylesheet",
1351
+ url
1352
+ };
859
1353
  };
1354
+
1355
+ // src/preferences/services/createLocalFontResources.ts
1356
+ var getFontFormat = (path) => {
1357
+ const ext = path.split(".").pop()?.toLowerCase();
1358
+ switch (ext) {
1359
+ case "woff":
1360
+ return "woff";
1361
+ case "woff2":
1362
+ return "woff2";
1363
+ case "ttf":
1364
+ return "truetype";
1365
+ case "otf":
1366
+ return "opentype";
1367
+ case "eot":
1368
+ return "embedded-opentype";
1369
+ case "svg":
1370
+ return "svg";
1371
+ default:
1372
+ return "woff2";
1373
+ }
1374
+ };
1375
+ var createLocalFontResources = (font) => {
1376
+ if (font.source.type !== "custom" || font.source.provider !== "local") {
1377
+ return null;
1378
+ }
1379
+ const { family, weights, display, widths } = font.spec;
1380
+ const fontFiles = font.source.files || [];
1381
+ const cssContent = fontFiles.map((fontFile) => {
1382
+ const format = getFontFormat(fontFile.path);
1383
+ const fontUrl = new URL(fontFile.path, window.location.origin).toString();
1384
+ const isVariable = font.source.type === "custom" && font.source.provider === "local" && "variant" in font.source && font.source.variant === "variable";
1385
+ const rules = [
1386
+ `@font-face {`,
1387
+ ` font-family: "${family}";`,
1388
+ ` src: url("${fontUrl}") format("${format}");`
1389
+ ];
1390
+ if (isVariable && weights.type === "variable") {
1391
+ rules.push(` font-weight: ${weights.min} ${weights.max};`);
1392
+ } else if ("weight" in fontFile) {
1393
+ rules.push(` font-weight: ${fontFile.weight};`);
1394
+ }
1395
+ if ("style" in fontFile) {
1396
+ rules.push(` font-style: ${fontFile.style};`);
1397
+ }
1398
+ if (isVariable && widths) {
1399
+ rules.push(` font-stretch: ${widths.min}% ${widths.max}%;`);
1400
+ }
1401
+ if (display) {
1402
+ rules.push(` font-display: ${display};`);
1403
+ } else {
1404
+ rules.push(` font-display: block;`);
1405
+ }
1406
+ return rules.join("\n") + "\n}";
1407
+ }).filter(Boolean).join("\n\n");
1408
+ const blob = new Blob([cssContent], { type: "text/css" });
1409
+ return {
1410
+ as: "link",
1411
+ rel: "stylesheet",
1412
+ blob
1413
+ };
1414
+ };
1415
+
1416
+ // src/preferences/services/fonts.ts
1417
+ var createFontService = (fontFamilyPref) => {
1418
+ const allSupportedLanguages = [];
1419
+ const parsedFonts = /* @__PURE__ */ new Map();
1420
+ const bunnyFonts = /* @__PURE__ */ new Map();
1421
+ const googleFonts = /* @__PURE__ */ new Map();
1422
+ const localFonts = /* @__PURE__ */ new Map();
1423
+ const resolveFontLanguage = (bcp47Tag, direction = "ltr") => {
1424
+ if (!bcp47Tag) return "default";
1425
+ if (allSupportedLanguages.includes(bcp47Tag)) {
1426
+ return bcp47Tag;
1427
+ }
1428
+ const parts = bcp47Tag.split(/[-_]/);
1429
+ const language = parts[0].toLowerCase();
1430
+ const scriptOrRegion = parts[1]?.toLowerCase();
1431
+ if (scriptOrRegion) {
1432
+ const langScriptOrRegion = `${language}-${scriptOrRegion}`;
1433
+ if (allSupportedLanguages.includes(langScriptOrRegion)) {
1434
+ return langScriptOrRegion;
1435
+ }
1436
+ }
1437
+ if (language === "ja" && !scriptOrRegion) {
1438
+ if (direction === "rtl" && allSupportedLanguages.includes("ja-v")) {
1439
+ return "ja-v";
1440
+ }
1441
+ if (allSupportedLanguages.includes("ja")) {
1442
+ return "ja";
1443
+ }
1444
+ }
1445
+ const shouldFilter = language === "mn" && (scriptOrRegion === "mong" || scriptOrRegion === "cyrl") || language === "zh" && (scriptOrRegion === "hant" || scriptOrRegion === "tw" || scriptOrRegion === "hk");
1446
+ if (!shouldFilter && allSupportedLanguages.includes(language)) {
1447
+ return language;
1448
+ }
1449
+ return "default";
1450
+ };
1451
+ Object.entries(fontFamilyPref).forEach(([collectionName, collectionData]) => {
1452
+ const fontCollection = "fonts" in collectionData ? collectionData.fonts : collectionData;
1453
+ if ("supportedLanguages" in collectionData) {
1454
+ const reducedLanguages = collectionData.supportedLanguages.map((lang) => {
1455
+ const parts = lang.split(/[-_]/);
1456
+ const language = parts[0].toLowerCase();
1457
+ const scriptOrRegion = parts[1]?.toLowerCase();
1458
+ return scriptOrRegion ? `${language}-${scriptOrRegion}` : language;
1459
+ });
1460
+ allSupportedLanguages.push(...reducedLanguages);
1461
+ }
1462
+ bunnyFonts.set(collectionName, []);
1463
+ googleFonts.set(collectionName, []);
1464
+ localFonts.set(collectionName, []);
1465
+ const collectionBunnyFonts = bunnyFonts.get(collectionName);
1466
+ const collectionGoogleFonts = googleFonts.get(collectionName);
1467
+ const collectionLocalFonts = localFonts.get(collectionName);
1468
+ Object.entries(fontCollection).forEach(([id, font]) => {
1469
+ const fontFamily = font.spec.family;
1470
+ let fontStack = fontFamily;
1471
+ if (font.source.type === "custom") {
1472
+ switch (font.source.provider) {
1473
+ case "bunny":
1474
+ collectionBunnyFonts.push(font);
1475
+ break;
1476
+ case "google":
1477
+ collectionGoogleFonts.push(font);
1478
+ break;
1479
+ case "local":
1480
+ collectionLocalFonts.push(font);
1481
+ break;
1482
+ }
1483
+ }
1484
+ const wrapIfNeeded = (name) => {
1485
+ const trimmed = name.trim();
1486
+ if (!trimmed) return "";
1487
+ if (trimmed.includes(" ") && !/^['"].*['"]$/.test(trimmed)) {
1488
+ return `"${trimmed}"`;
1489
+ }
1490
+ return trimmed;
1491
+ };
1492
+ const wrappedFontFamily = wrapIfNeeded(fontFamily);
1493
+ if (font.spec.fallbacks?.length) {
1494
+ const uniqueFallbacks = [...new Set(
1495
+ font.spec.fallbacks.filter((fallback) => fallback.toLowerCase() !== fontFamily.toLowerCase()).map(wrapIfNeeded)
1496
+ )];
1497
+ if (uniqueFallbacks.length > 0) {
1498
+ fontStack = [wrappedFontFamily, ...uniqueFallbacks].join(", ");
1499
+ }
1500
+ }
1501
+ parsedFonts.set(id, {
1502
+ fontStack: fontStack || wrappedFontFamily,
1503
+ fontFamily: wrappedFontFamily,
1504
+ weights: font.spec.weights || null,
1505
+ widths: font.spec.widths || null
1506
+ });
1507
+ });
1508
+ });
1509
+ const defaultBunnyFonts = bunnyFonts.get("default") || [];
1510
+ const defaultGoogleFonts = googleFonts.get("default") || [];
1511
+ const defaultLocalFonts = localFonts.get("default") || [];
1512
+ const processFonts = (bunnyFontsList, googleFontsList, localFontsList, optimize = false) => {
1513
+ const result = {
1514
+ allowedDomains: [],
1515
+ prepend: [],
1516
+ append: []
1517
+ };
1518
+ const bunnyResources = bunnyFontsList.map((font) => createBunnyFontResources(font)).filter((resource) => resource !== null);
1519
+ if (bunnyResources.length > 0) {
1520
+ result.allowedDomains.push(
1521
+ "https://fonts.bunny.net"
1522
+ );
1523
+ result.prepend.push(
1524
+ {
1525
+ as: "link",
1526
+ rel: "preconnect",
1527
+ url: "https://fonts.bunny.net"
1528
+ }
1529
+ );
1530
+ result.append.push(...bunnyResources);
1531
+ }
1532
+ const googleResources = googleFontsList.map((font) => createGoogleFontResources(font, optimize ? font.name : void 0)).filter((resource) => resource !== null);
1533
+ if (googleResources.length > 0) {
1534
+ result.allowedDomains.push(
1535
+ "https://fonts.googleapis.com",
1536
+ "https://fonts.gstatic.com"
1537
+ );
1538
+ result.prepend.push(
1539
+ {
1540
+ as: "link",
1541
+ rel: "preconnect",
1542
+ url: "https://fonts.googleapis.com"
1543
+ },
1544
+ {
1545
+ as: "link",
1546
+ rel: "preconnect",
1547
+ url: "https://fonts.gstatic.com",
1548
+ attributes: { crossOrigin: "anonymous" }
1549
+ }
1550
+ );
1551
+ result.append.push(...googleResources);
1552
+ }
1553
+ const localResources = localFontsList.map(createLocalFontResources).filter((resource) => resource !== null);
1554
+ if (localResources.length > 0) {
1555
+ result.allowedDomains.push(window.location.origin);
1556
+ result.append.push(...localResources);
1557
+ }
1558
+ return result.append.length > 0 ? result : null;
1559
+ };
1560
+ const getInjectables = (options, optimize = false) => {
1561
+ if (options && "key" in options) {
1562
+ const { key } = options;
1563
+ if (!key || !(key in fontFamilyPref)) {
1564
+ return null;
1565
+ }
1566
+ return processFonts(bunnyFonts.get(key) || [], googleFonts.get(key) || [], localFonts.get(key) || [], optimize);
1567
+ }
1568
+ if (options && "language" in options) {
1569
+ const { language: publicationLanguage } = options;
1570
+ for (const [collectionName, collectionData] of Object.entries(fontFamilyPref)) {
1571
+ if (collectionName === "default") continue;
1572
+ const supportedLangs = "supportedLanguages" in collectionData ? collectionData.supportedLanguages : null;
1573
+ if (supportedLangs && Array.isArray(supportedLangs) && publicationLanguage && supportedLangs.includes(publicationLanguage)) {
1574
+ return processFonts(bunnyFonts.get(collectionName) || [], googleFonts.get(collectionName) || [], localFonts.get(collectionName) || [], optimize);
1575
+ }
1576
+ }
1577
+ }
1578
+ return processFonts(defaultBunnyFonts, defaultGoogleFonts, defaultLocalFonts, optimize);
1579
+ };
1580
+ const getFontMetadata = (fontId) => {
1581
+ const parsed = parsedFonts.get(fontId);
1582
+ return parsed || { fontStack: null, fontFamily: null, weights: null, widths: null };
1583
+ };
1584
+ const getFontCollection = (options) => {
1585
+ if (options && "key" in options) {
1586
+ const { key } = options;
1587
+ if (!key || !(key in fontFamilyPref)) {
1588
+ return fontFamilyPref.default;
1589
+ }
1590
+ if (key === "default") {
1591
+ return fontFamilyPref.default;
1592
+ }
1593
+ const prefRecord = fontFamilyPref;
1594
+ const collection = prefRecord[key];
1595
+ if (collection && "fonts" in collection) {
1596
+ return collection.fonts;
1597
+ }
1598
+ return fontFamilyPref.default;
1599
+ }
1600
+ if (options && "language" in options) {
1601
+ const { language: publicationLanguage } = options;
1602
+ for (const [collectionName, collectionData] of Object.entries(fontFamilyPref)) {
1603
+ if (collectionName === "default") continue;
1604
+ const collection = "fonts" in collectionData ? collectionData : { fonts: collectionData };
1605
+ const supportedLangs = "supportedLanguages" in collection ? collection.supportedLanguages : null;
1606
+ if (supportedLangs?.includes(publicationLanguage)) {
1607
+ return collection.fonts;
1608
+ }
1609
+ }
1610
+ return fontFamilyPref.default;
1611
+ }
1612
+ return fontFamilyPref.default;
1613
+ };
1614
+ return {
1615
+ getInjectables,
1616
+ getFontMetadata,
1617
+ getFontCollection,
1618
+ resolveFontLanguage
1619
+ };
1620
+ };
1621
+
1622
+ // src/preferences/hooks/usePreferences.ts
860
1623
  function usePreferences() {
861
1624
  const context = useContext(ThPreferencesContext);
862
1625
  if (!context) {
863
1626
  throw new Error("usePreferences must be used within a ThPreferencesProvider");
864
1627
  }
1628
+ const fontService = createFontService(context.preferences.settings.keys.fontFamily);
865
1629
  return {
866
1630
  preferences: context.preferences,
867
- updatePreferences: context.updatePreferences
1631
+ updatePreferences: context.updatePreferences,
1632
+ getFontInjectables: (options, optimize) => {
1633
+ return fontService.getInjectables(options, optimize);
1634
+ },
1635
+ getFontsList: (options) => {
1636
+ return fontService.getFontCollection(options);
1637
+ },
1638
+ getFontMetadata: (fontId) => {
1639
+ return fontService.getFontMetadata(fontId);
1640
+ },
1641
+ resolveFontLanguage: (bcp47Tag, direction) => {
1642
+ return fontService.resolveFontLanguage(bcp47Tag, direction);
1643
+ }
868
1644
  };
869
1645
  }
870
1646
 
@@ -996,6 +1772,6 @@ var useTheming = ({
996
1772
  };
997
1773
  };
998
1774
 
999
- export { ThMemoryPreferencesAdapter, ThPreferencesContext, ThPreferencesProvider, buildThemeObject, createPreferences, defaultActionKeysObject, defaultFontFamilyOptions, defaultLetterSpacing, defaultLineHeights, defaultParagraphIndent, defaultParagraphSpacing, defaultPreferences, defaultPreferencesContextValue, defaultSpacingPresets, defaultSpacingPresetsOrder, defaultSpacingSettingsMain, defaultSpacingSettingsSubpanel, defaultTextSettingsMain, defaultTextSettingsSubpanel, defaultWordSpacing, defaultZoom, prefixString, usePreferenceKeys, usePreferences, useTheming };
1000
- //# sourceMappingURL=chunk-IRA4ZKAX.mjs.map
1001
- //# sourceMappingURL=chunk-IRA4ZKAX.mjs.map
1775
+ export { ThMemoryPreferencesAdapter, ThPreferencesContext, ThPreferencesProvider, buildThemeObject, createDefinitionFromStaticFonts, createDefinitionsFromBunnyFonts, createDefinitionsFromGoogleFonts, createPreferences, defaultActionKeysObject, defaultFontCollection, defaultLetterSpacing, defaultLineHeights, defaultParagraphIndent, defaultParagraphSpacing, defaultPreferences, defaultPreferencesContextValue, defaultSpacingPresets, defaultSpacingPresetsOrder, defaultSpacingSettingsMain, defaultSpacingSettingsSubpanel, defaultTextSettingsMain, defaultTextSettingsSubpanel, defaultWordSpacing, defaultZoom, prefixString, readiumCSSFontCollection, tamilCollection, usePreferenceKeys, usePreferences, useTheming };
1776
+ //# sourceMappingURL=chunk-VN44OJDD.mjs.map
1777
+ //# sourceMappingURL=chunk-VN44OJDD.mjs.map