@mmstack/translate 21.1.2 → 21.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.
- package/README.md +56 -0
- package/fesm2022/mmstack-translate.mjs +323 -22
- package/fesm2022/mmstack-translate.mjs.map +1 -1
- package/package.json +1 -1
- package/types/mmstack-translate.d.ts +229 -4
package/README.md
CHANGED
|
@@ -516,6 +516,62 @@ When switching locales dynamically, the library:
|
|
|
516
516
|
3. Updates all reactive outputs automatically
|
|
517
517
|
4. Falls back to the default locale if unavailable
|
|
518
518
|
|
|
519
|
+
## Remote / Unsafe Namespaces
|
|
520
|
+
|
|
521
|
+
For cases where you need to load translations from a remote API (where keys aren't known at compile-time), use `registerRemoteNamespace`. This provides an untyped experience but allows you to integrate dynamic content into the same system.
|
|
522
|
+
|
|
523
|
+
```typescript
|
|
524
|
+
import { registerRemoteNamespace } from '@mmstack/translate';
|
|
525
|
+
|
|
526
|
+
// Returns an untyped t function: t('any.key')
|
|
527
|
+
const { injectNamespaceT: injectRemoteT } = registerRemoteNamespace('remote', () => fetch('/api/en').then((r) => r.json()), {
|
|
528
|
+
'sl-SI': () => fetch('/api/sl').then((r) => r.json()),
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
// usage
|
|
532
|
+
const t = injectRemoteT();
|
|
533
|
+
|
|
534
|
+
// .asSignal variants also work
|
|
535
|
+
const value = t('remote.myKey');
|
|
536
|
+
const valueThatNeedsProps = t('remote.myOtherKey', {
|
|
537
|
+
name: 'John',
|
|
538
|
+
});
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
## Formatters
|
|
542
|
+
|
|
543
|
+
The library includes a set of reactive formatters that automatically adapt to the current locale. They are standalone functions that do not require dependency injection, making them easy to use anywhere.
|
|
544
|
+
|
|
545
|
+
**Note:** For reactivity, wrap them in a `computed()` if the input signals change or if you want them to react to dynamic locale changes.
|
|
546
|
+
|
|
547
|
+
Available formatters:
|
|
548
|
+
|
|
549
|
+
- **`formatDate`**: Wraps `Intl.DateTimeFormat`
|
|
550
|
+
- **`formatNumber`**: Wraps `Intl.NumberFormat`
|
|
551
|
+
- **`formatCurrency`**: Wraps `Intl.NumberFormat` (currency style)
|
|
552
|
+
- **`formatPercent`**: Wraps `Intl.NumberFormat` (percent style)
|
|
553
|
+
- **`formatList`**: Wraps `Intl.ListFormat`
|
|
554
|
+
- **`formatRelativeTime`**: Wraps `Intl.RelativeTimeFormat`
|
|
555
|
+
- **`formatDisplayName`**: Wraps `Intl.DisplayNames`
|
|
556
|
+
|
|
557
|
+
**Example:**
|
|
558
|
+
|
|
559
|
+
```typescript
|
|
560
|
+
import { computed, signal } from '@angular/core';
|
|
561
|
+
import { formatCurrency, formatDate } from '@mmstack/translate';
|
|
562
|
+
|
|
563
|
+
export class MyComponent {
|
|
564
|
+
readonly price = signal(1234.56);
|
|
565
|
+
readonly date = new Date();
|
|
566
|
+
|
|
567
|
+
// Reacts to price changes OR locale changes
|
|
568
|
+
readonly displayPrice = computed(() => formatCurrency(this.price(), 'EUR'));
|
|
569
|
+
|
|
570
|
+
// Reacts to locale changes
|
|
571
|
+
readonly displayDate = computed(() => formatDate(this.date));
|
|
572
|
+
}
|
|
573
|
+
```
|
|
574
|
+
|
|
519
575
|
## Migration from Other Libraries
|
|
520
576
|
|
|
521
577
|
### From @angular/localize
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { inject, computed, InjectionToken, LOCALE_ID, signal, resource, untracked, isDevMode, effect, Injectable, isSignal, input, Renderer2, ElementRef, afterRenderEffect, Directive, ChangeDetectorRef } from '@angular/core';
|
|
3
|
-
import { Router, ActivatedRoute } from '@angular/router';
|
|
4
3
|
import { createIntlCache, createIntl } from '@formatjs/intl';
|
|
5
4
|
import { toSignal } from '@angular/core/rxjs-interop';
|
|
5
|
+
import { Router, ActivatedRoute } from '@angular/router';
|
|
6
6
|
|
|
7
7
|
const KEY_DELIM = '::MMT_DELIM::';
|
|
8
8
|
function prependDelim(prefix, key) {
|
|
@@ -127,11 +127,24 @@ function injectDefaultLocale() {
|
|
|
127
127
|
function injectSupportedLocales() {
|
|
128
128
|
return injectIntlConfig()?.supportedLocales ?? [injectDefaultLocale()];
|
|
129
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* @internal
|
|
132
|
+
* the actual locale signal used to store the current locale string
|
|
133
|
+
*/
|
|
134
|
+
const STORE_LOCALE = signal('en-US', ...(ngDevMode ? [{ debugName: "STORE_LOCALE" }] : []));
|
|
135
|
+
function injectLocaleInternal() {
|
|
136
|
+
try {
|
|
137
|
+
return injectDynamicLocale();
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return STORE_LOCALE;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
130
143
|
class TranslationStore {
|
|
131
144
|
cache = createIntlCache();
|
|
132
145
|
config = injectIntlConfig();
|
|
133
146
|
loadQueue = signal([], ...(ngDevMode ? [{ debugName: "loadQueue" }] : []));
|
|
134
|
-
locale
|
|
147
|
+
locale;
|
|
135
148
|
defaultLocale = injectDefaultLocale();
|
|
136
149
|
translations = signal({
|
|
137
150
|
[this.defaultLocale]: {},
|
|
@@ -187,6 +200,8 @@ class TranslationStore {
|
|
|
187
200
|
messages: this.messages(),
|
|
188
201
|
}, this.cache), ...(ngDevMode ? [{ debugName: "intl" }] : []));
|
|
189
202
|
constructor() {
|
|
203
|
+
this.locale = STORE_LOCALE;
|
|
204
|
+
this.locale.set(injectDefaultLocale());
|
|
190
205
|
const paramName = this.config?.localeParamName;
|
|
191
206
|
if (paramName) {
|
|
192
207
|
const param = pathParam(paramName);
|
|
@@ -324,6 +339,243 @@ function injectDynamicLocale() {
|
|
|
324
339
|
return source;
|
|
325
340
|
}
|
|
326
341
|
|
|
342
|
+
function unwrap(value) {
|
|
343
|
+
return isSignal(value) ? unwrap(value()) : value;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const FORMAT_PRESETS = {
|
|
347
|
+
short: { dateStyle: 'short', timeStyle: 'short' },
|
|
348
|
+
medium: { dateStyle: 'medium', timeStyle: 'medium' },
|
|
349
|
+
long: { dateStyle: 'long', timeStyle: 'long' },
|
|
350
|
+
full: { dateStyle: 'full', timeStyle: 'full' },
|
|
351
|
+
shortDate: { dateStyle: 'short' },
|
|
352
|
+
mediumDate: { dateStyle: 'medium' },
|
|
353
|
+
longDate: { dateStyle: 'long' },
|
|
354
|
+
fullDate: { dateStyle: 'full' },
|
|
355
|
+
shortTime: { timeStyle: 'short' },
|
|
356
|
+
mediumTime: { timeStyle: 'medium' },
|
|
357
|
+
longTime: { timeStyle: 'long' },
|
|
358
|
+
fullTime: { timeStyle: 'full' },
|
|
359
|
+
};
|
|
360
|
+
function validDateOrNull(date) {
|
|
361
|
+
if (date == null)
|
|
362
|
+
return null;
|
|
363
|
+
const d = date instanceof Date ? date : new Date(date);
|
|
364
|
+
return isNaN(d.getTime()) ? null : d;
|
|
365
|
+
}
|
|
366
|
+
const cache$4 = new Map();
|
|
367
|
+
function getFormatter$4(locale, format, timeZone) {
|
|
368
|
+
const cacheKey = `${locale}|${format}|${timeZone ?? ''}`;
|
|
369
|
+
let formatter = cache$4.get(cacheKey);
|
|
370
|
+
if (!formatter) {
|
|
371
|
+
formatter = new Intl.DateTimeFormat(locale, {
|
|
372
|
+
...FORMAT_PRESETS[format],
|
|
373
|
+
timeZone,
|
|
374
|
+
});
|
|
375
|
+
cache$4.set(cacheKey, formatter);
|
|
376
|
+
}
|
|
377
|
+
return formatter;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Format a date using the current or provided locale & timezone
|
|
381
|
+
* By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes
|
|
382
|
+
*
|
|
383
|
+
* @param date - Date to format
|
|
384
|
+
* @param opt - Options for formatting
|
|
385
|
+
* @returns Formatted date string
|
|
386
|
+
*/
|
|
387
|
+
function formatDate(date, opt) {
|
|
388
|
+
const validDate = validDateOrNull(unwrap(date));
|
|
389
|
+
if (validDate === null)
|
|
390
|
+
return '';
|
|
391
|
+
const unwrappedOpt = unwrap(opt);
|
|
392
|
+
const loc = unwrappedOpt?.locale ?? injectLocaleInternal()();
|
|
393
|
+
return getFormatter$4(loc, unwrappedOpt?.format ?? 'medium', unwrappedOpt?.tz).format(validDate);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const cache$3 = new Map();
|
|
397
|
+
function getFormatter$3(locale, type, style) {
|
|
398
|
+
const cacheKey = `${locale}|${type}|${style}`;
|
|
399
|
+
let formatter = cache$3.get(cacheKey);
|
|
400
|
+
if (!formatter) {
|
|
401
|
+
formatter = new Intl.DisplayNames(locale, {
|
|
402
|
+
type,
|
|
403
|
+
style,
|
|
404
|
+
});
|
|
405
|
+
cache$3.set(cacheKey, formatter);
|
|
406
|
+
}
|
|
407
|
+
return formatter;
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Format a display name using the current or provided locale
|
|
411
|
+
* By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes
|
|
412
|
+
*
|
|
413
|
+
* @param value - The code to format
|
|
414
|
+
* @param type - The type of display name to format
|
|
415
|
+
* @param opt - Options for formatting
|
|
416
|
+
* @returns Formatted display name string
|
|
417
|
+
*/
|
|
418
|
+
function formatDisplayName(value, type, opt) {
|
|
419
|
+
const unwrapped = unwrap(value);
|
|
420
|
+
if (!unwrapped?.trim())
|
|
421
|
+
return '';
|
|
422
|
+
const unwrappedType = unwrap(type);
|
|
423
|
+
const unwrappedOpt = unwrap(opt);
|
|
424
|
+
const locale = unwrappedOpt?.locale ?? injectLocaleInternal()();
|
|
425
|
+
return (getFormatter$3(locale, unwrappedType, unwrappedOpt?.style ?? 'long').of(unwrapped) ?? '');
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
const cache$2 = new Map();
|
|
429
|
+
const EMPTY_ARRAY = [];
|
|
430
|
+
function unwrapList(value) {
|
|
431
|
+
const unwrapped = unwrap(value);
|
|
432
|
+
return Array.isArray(unwrapped) ? unwrapped : EMPTY_ARRAY;
|
|
433
|
+
}
|
|
434
|
+
function getFormatter$2(locale, type, style) {
|
|
435
|
+
const cacheKey = `${locale}|${type}|${style}`;
|
|
436
|
+
let formatter = cache$2.get(cacheKey);
|
|
437
|
+
if (!formatter) {
|
|
438
|
+
formatter = new Intl.ListFormat(locale, { type, style });
|
|
439
|
+
cache$2.set(cacheKey, formatter);
|
|
440
|
+
}
|
|
441
|
+
return formatter;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Format a list using the current or provided locale
|
|
445
|
+
* By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes
|
|
446
|
+
*
|
|
447
|
+
* @param value - The list to format
|
|
448
|
+
* @param opt - Options for formatting
|
|
449
|
+
* @returns Formatted list string
|
|
450
|
+
*/
|
|
451
|
+
function formatList(value, opt) {
|
|
452
|
+
const unwrapped = unwrapList(value);
|
|
453
|
+
if (unwrapped.length === 0)
|
|
454
|
+
return '';
|
|
455
|
+
const unwrappedOpt = unwrap(opt);
|
|
456
|
+
const loc = unwrappedOpt?.locale ?? injectLocaleInternal()();
|
|
457
|
+
return getFormatter$2(loc, unwrappedOpt?.type ?? 'conjunction', unwrappedOpt?.style ?? 'long').format(unwrapped);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
const cache$1 = new Map();
|
|
461
|
+
function unwrapValue(value, fallbackToZero = false) {
|
|
462
|
+
const unwrapped = unwrap(value);
|
|
463
|
+
if (unwrapped === null || unwrapped === undefined || isNaN(unwrapped))
|
|
464
|
+
return fallbackToZero ? 0 : null;
|
|
465
|
+
return unwrapped;
|
|
466
|
+
}
|
|
467
|
+
function getFormatter$1(locale, minFractionDigits, maxFractionDigits, useGrouping, notation, currency, display, style) {
|
|
468
|
+
const cacheKey = `${locale}|${notation ?? 'standard'}|${minFractionDigits}|${maxFractionDigits}|${useGrouping ?? true}|${currency ?? 'none'}|${display ?? 'none'}|${style ?? 'decimal'}`;
|
|
469
|
+
let formatter = cache$1.get(cacheKey);
|
|
470
|
+
if (!formatter) {
|
|
471
|
+
formatter = new Intl.NumberFormat(locale, {
|
|
472
|
+
style,
|
|
473
|
+
notation,
|
|
474
|
+
minimumFractionDigits: minFractionDigits,
|
|
475
|
+
maximumFractionDigits: maxFractionDigits,
|
|
476
|
+
useGrouping,
|
|
477
|
+
});
|
|
478
|
+
cache$1.set(cacheKey, formatter);
|
|
479
|
+
}
|
|
480
|
+
return formatter;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Format a number using the current or provided locale
|
|
484
|
+
* By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes
|
|
485
|
+
*
|
|
486
|
+
* @param number - Number to format
|
|
487
|
+
* @param opt - Options for formatting
|
|
488
|
+
* @returns Formatted number string
|
|
489
|
+
*/
|
|
490
|
+
function formatNumber(value, opt) {
|
|
491
|
+
const unwrappedOpt = unwrap(opt);
|
|
492
|
+
const unwrappedNumber = unwrapValue(value, unwrappedOpt?.fallbackToZero);
|
|
493
|
+
if (unwrappedNumber === null)
|
|
494
|
+
return '';
|
|
495
|
+
const loc = unwrappedOpt?.locale ?? injectLocaleInternal()();
|
|
496
|
+
return getFormatter$1(loc, unwrappedOpt?.minFractionDigits ?? 0, unwrappedOpt?.maxFractionDigits ?? 0, unwrappedOpt?.useGrouping ?? true, unwrappedOpt?.notation ?? 'standard').format(unwrappedNumber);
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Format a percentage using the current or provided locale
|
|
500
|
+
* By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes
|
|
501
|
+
*
|
|
502
|
+
* @param number - Number to format
|
|
503
|
+
* @param opt - Options for formatting
|
|
504
|
+
* @returns Formatted percentage string
|
|
505
|
+
*/
|
|
506
|
+
function formatPercent(value, opt) {
|
|
507
|
+
const unwrappedOpt = unwrap(opt);
|
|
508
|
+
let unwrappedNumber = unwrapValue(value, unwrappedOpt?.fallbackToZero);
|
|
509
|
+
if (unwrappedNumber === null)
|
|
510
|
+
return '';
|
|
511
|
+
const loc = unwrappedOpt?.locale ?? injectLocaleInternal()();
|
|
512
|
+
return getFormatter$1(loc, unwrappedOpt?.minFractionDigits ?? 0, unwrappedOpt?.maxFractionDigits ?? 0, undefined, undefined, undefined, undefined, 'percent').format(unwrappedNumber);
|
|
513
|
+
}
|
|
514
|
+
function formatCurrency(value, currency, opt) {
|
|
515
|
+
const unwrappedOpt = unwrap(opt);
|
|
516
|
+
const unwrappedValue = unwrapValue(value, unwrappedOpt?.fallbackToZero);
|
|
517
|
+
if (unwrappedValue === null)
|
|
518
|
+
return '';
|
|
519
|
+
const loc = unwrappedOpt?.locale ?? injectLocaleInternal()();
|
|
520
|
+
return getFormatter$1(loc, 0, 0, undefined, undefined, unwrap(currency), unwrappedOpt?.display ?? 'symbol', 'currency').format(unwrappedValue);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
const cache = new Map();
|
|
524
|
+
function getFormatter(locale, style, numeric) {
|
|
525
|
+
const cacheKey = `${locale}|${style}|${numeric}`;
|
|
526
|
+
let formatter = cache.get(cacheKey);
|
|
527
|
+
if (!formatter) {
|
|
528
|
+
formatter = new Intl.RelativeTimeFormat(locale, { style, numeric });
|
|
529
|
+
cache.set(cacheKey, formatter);
|
|
530
|
+
}
|
|
531
|
+
return formatter;
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Format a relative time using the current or provided locale
|
|
535
|
+
* By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes
|
|
536
|
+
*
|
|
537
|
+
* @param value - The numeric value to use in the relative time internationalization message
|
|
538
|
+
* @param unit - The unit to use in the relative time internationalization message
|
|
539
|
+
* @param opt - Options for formatting
|
|
540
|
+
* @returns Formatted relative time string
|
|
541
|
+
*/
|
|
542
|
+
function formatRelativeTime(value, unit, opt) {
|
|
543
|
+
const unwrappedValue = unwrap(value);
|
|
544
|
+
if (unwrappedValue === null ||
|
|
545
|
+
unwrappedValue === undefined ||
|
|
546
|
+
isNaN(unwrappedValue))
|
|
547
|
+
return '';
|
|
548
|
+
const unwrappedUnit = unwrap(unit);
|
|
549
|
+
if (!unwrappedUnit)
|
|
550
|
+
return '';
|
|
551
|
+
const unwrappedOpt = unwrap(opt);
|
|
552
|
+
const loc = unwrappedOpt?.locale ?? injectLocaleInternal()();
|
|
553
|
+
return getFormatter(loc, unwrappedOpt?.style ?? 'long', unwrappedOpt?.numeric ?? 'always').format(unwrappedValue, unwrappedUnit);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
function injectResolveParamLocale(snapshot) {
|
|
557
|
+
let locale = null;
|
|
558
|
+
const paramName = injectIntlConfig()?.localeParamName;
|
|
559
|
+
const routerConfig = inject(Router)['options'];
|
|
560
|
+
const alwaysInheritParams = typeof routerConfig === 'object' &&
|
|
561
|
+
!!routerConfig &&
|
|
562
|
+
routerConfig.paramsInheritanceStrategy === 'always';
|
|
563
|
+
if (paramName) {
|
|
564
|
+
locale = snapshot.paramMap.get(paramName);
|
|
565
|
+
if (!locale && !alwaysInheritParams) {
|
|
566
|
+
let currentRoute = snapshot;
|
|
567
|
+
while (currentRoute && !locale) {
|
|
568
|
+
locale = currentRoute.paramMap.get('locale');
|
|
569
|
+
currentRoute = currentRoute.parent;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
if (!locale) {
|
|
574
|
+
locale = untracked(inject(TranslationStore).locale);
|
|
575
|
+
}
|
|
576
|
+
return locale;
|
|
577
|
+
}
|
|
578
|
+
|
|
327
579
|
function createEqualsRecord(keys = []) {
|
|
328
580
|
let keyMatcher;
|
|
329
581
|
if (keys.length === 0) {
|
|
@@ -378,25 +630,7 @@ function registerNamespace(defaultTranslation, other) {
|
|
|
378
630
|
let defaultTranslationLoaded = false;
|
|
379
631
|
const resolver = async (snapshot) => {
|
|
380
632
|
const store = inject(TranslationStore);
|
|
381
|
-
|
|
382
|
-
const paramName = injectIntlConfig()?.localeParamName;
|
|
383
|
-
const routerConfig = inject(Router)['options'];
|
|
384
|
-
const alwaysInheritParams = typeof routerConfig === 'object' &&
|
|
385
|
-
!!routerConfig &&
|
|
386
|
-
routerConfig.paramsInheritanceStrategy === 'always';
|
|
387
|
-
if (paramName) {
|
|
388
|
-
locale = snapshot.paramMap.get(paramName);
|
|
389
|
-
if (!locale && !alwaysInheritParams) {
|
|
390
|
-
let currentRoute = snapshot;
|
|
391
|
-
while (currentRoute && !locale) {
|
|
392
|
-
locale = currentRoute.paramMap.get('locale');
|
|
393
|
-
currentRoute = currentRoute.parent;
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
if (!locale) {
|
|
398
|
-
locale = untracked(store.locale);
|
|
399
|
-
}
|
|
633
|
+
const locale = injectResolveParamLocale(snapshot);
|
|
400
634
|
const defaultLocale = injectDefaultLocale();
|
|
401
635
|
const shouldPreloadDefault = injectIntlConfig()?.preloadDefaultLocale ?? false;
|
|
402
636
|
const tPromise = other[locale];
|
|
@@ -450,6 +684,73 @@ function registerNamespace(defaultTranslation, other) {
|
|
|
450
684
|
resolveNamespaceTranslation: resolver,
|
|
451
685
|
};
|
|
452
686
|
}
|
|
687
|
+
/**
|
|
688
|
+
* Registers a type-unsafe namespace, meant for remote loading of unknown key-value pairs using mmstack/translate infrastructure
|
|
689
|
+
* The resolver & t function work the same as they would with typed namespaces, but without type safety
|
|
690
|
+
*/
|
|
691
|
+
function registerRemoteNamespace(ns, defaultTranslation, other) {
|
|
692
|
+
const injectT = () => {
|
|
693
|
+
const store = inject(TranslationStore);
|
|
694
|
+
return addSignalFn(createT(store), store);
|
|
695
|
+
};
|
|
696
|
+
let defaultTranslationLoaded = false;
|
|
697
|
+
const resolver = async (snapshot) => {
|
|
698
|
+
const store = inject(TranslationStore);
|
|
699
|
+
const locale = injectResolveParamLocale(snapshot);
|
|
700
|
+
const defaultLocale = injectDefaultLocale();
|
|
701
|
+
const shouldPreloadDefault = injectIntlConfig()?.preloadDefaultLocale ?? false;
|
|
702
|
+
const tPromise = other[locale];
|
|
703
|
+
const promise = tPromise ?? defaultTranslation;
|
|
704
|
+
if (!promise && isDevMode()) {
|
|
705
|
+
return console.warn(`No translation found for locale: ${locale}`);
|
|
706
|
+
}
|
|
707
|
+
if (promise === defaultTranslation && defaultTranslationLoaded)
|
|
708
|
+
return;
|
|
709
|
+
try {
|
|
710
|
+
const promises = [promise()];
|
|
711
|
+
if (shouldPreloadDefault &&
|
|
712
|
+
!defaultTranslationLoaded &&
|
|
713
|
+
promise !== defaultTranslation)
|
|
714
|
+
promises.push(defaultTranslation());
|
|
715
|
+
const translations = await Promise.allSettled(promises);
|
|
716
|
+
const fullfilled = translations.map((t) => t.status === 'fulfilled' ? t.value : null);
|
|
717
|
+
if (fullfilled.at(0) === null && fullfilled.at(1) === null)
|
|
718
|
+
throw new Error('Failed to load translations');
|
|
719
|
+
const [baseT, baseDefaultT] = fullfilled;
|
|
720
|
+
const t = baseT ? compileTranslation(baseT, ns, locale) : null;
|
|
721
|
+
const defaultT = baseDefaultT
|
|
722
|
+
? compileTranslation(baseDefaultT, ns, defaultLocale)
|
|
723
|
+
: null;
|
|
724
|
+
if (isDevMode() && t && t.locale !== locale && t.locale)
|
|
725
|
+
console.warn(`Expected locale to be ${locale} but got ${t.locale}`);
|
|
726
|
+
store.registerOnDemandLoaders(ns, {
|
|
727
|
+
...other,
|
|
728
|
+
[defaultLocale]: defaultTranslation,
|
|
729
|
+
});
|
|
730
|
+
const toRegister = {};
|
|
731
|
+
if (t)
|
|
732
|
+
toRegister[locale] = t.flat;
|
|
733
|
+
if (defaultT)
|
|
734
|
+
toRegister[defaultLocale] = defaultT.flat;
|
|
735
|
+
store.register(ns, toRegister);
|
|
736
|
+
if (promise === defaultTranslation || defaultT)
|
|
737
|
+
defaultTranslationLoaded = true;
|
|
738
|
+
}
|
|
739
|
+
catch {
|
|
740
|
+
if (isDevMode()) {
|
|
741
|
+
console.warn(`Failed to load translation for locale: ${locale}`);
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
finally {
|
|
745
|
+
if (locale !== untracked(store.locale))
|
|
746
|
+
store.locale.set(locale);
|
|
747
|
+
}
|
|
748
|
+
};
|
|
749
|
+
return {
|
|
750
|
+
injectNamespaceT: injectT,
|
|
751
|
+
resolveNamespaceTranslation: resolver,
|
|
752
|
+
};
|
|
753
|
+
}
|
|
453
754
|
|
|
454
755
|
/**
|
|
455
756
|
* Guard that validates the locale parameter against supported locales.
|
|
@@ -539,5 +840,5 @@ class Translator {
|
|
|
539
840
|
* Generated bundle index. Do not edit.
|
|
540
841
|
*/
|
|
541
842
|
|
|
542
|
-
export { Translate, Translator, canMatchLocale, compileTranslation, createNamespace, injectDynamicLocale, injectIntl, injectSupportedLocales, provideIntlConfig, registerNamespace };
|
|
843
|
+
export { Translate, Translator, canMatchLocale, compileTranslation, createNamespace, formatCurrency, formatDate, formatDisplayName, formatList, formatNumber, formatPercent, formatRelativeTime, injectDynamicLocale, injectIntl, injectResolveParamLocale, injectSupportedLocales, provideIntlConfig, registerNamespace, registerRemoteNamespace };
|
|
543
844
|
//# sourceMappingURL=mmstack-translate.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mmstack-translate.mjs","sources":["../../../../packages/translate/src/lib/delim.ts","../../../../packages/translate/src/lib/compile.ts","../../../../packages/translate/src/lib/create-namespace.ts","../../../../packages/translate/src/lib/path-param.ts","../../../../packages/translate/src/lib/translation-store.ts","../../../../packages/translate/src/lib/register-namespace.ts","../../../../packages/translate/src/lib/route-helpers.ts","../../../../packages/translate/src/lib/translate.ts","../../../../packages/translate/src/lib/translator.ts","../../../../packages/translate/src/mmstack-translate.ts"],"sourcesContent":["const KEY_DELIM = '::MMT_DELIM::';\n\nexport function prependDelim(prefix: string, key: string): string {\n return `${prefix}${KEY_DELIM}${key}`;\n}\n\nexport function replaceWithDelim(str: string, repl = '.'): string {\n return str.replaceAll(repl, KEY_DELIM);\n}\n","import { prependDelim } from './delim';\nimport type {\n inferTranslationParamMap,\n inferTranslationShape,\n} from './parameterize.type';\nimport type { UnknownStringKeyObject } from './string-key-object.type';\n\nconst INTERNAL_SYMBOL = Symbol.for('mmstack-translate-internal');\n\ntype InternalSymbol = typeof INTERNAL_SYMBOL;\n\nexport type CompiledTranslation<\n T extends UnknownStringKeyObject,\n TNS extends string,\n TLocale extends string = string,\n> = {\n flat: Record<string, string>;\n locale?: TLocale;\n namespace: TNS;\n [INTERNAL_SYMBOL]: {\n shape: inferTranslationShape<T>;\n map: inferTranslationParamMap<TNS, T>;\n };\n};\n\nexport type mergeTranslationMaps<\n TMain extends CompiledTranslation<UnknownStringKeyObject, string>,\n TOther extends CompiledTranslation<UnknownStringKeyObject, string>,\n> = Omit<TMain, InternalSymbol> & {\n [INTERNAL_SYMBOL]: {\n shape: inferCompiledTranslationShape<TMain>;\n map: inferCompiledTranslationMap<TOther> &\n inferCompiledTranslationMap<TMain>;\n };\n};\n\nexport type inferCompiledTranslationNamespace<\n T extends CompiledTranslation<UnknownStringKeyObject, string>,\n> = T['namespace'];\n\nexport type inferCompiledTranslationShape<\n T extends CompiledTranslation<UnknownStringKeyObject, string>,\n> = T[InternalSymbol]['shape'];\n\nexport type inferCompiledTranslationMap<\n T extends CompiledTranslation<UnknownStringKeyObject, string>,\n> = T[InternalSymbol]['map'];\n\nfunction isTranslationObject(t: unknown): t is UnknownStringKeyObject {\n return typeof t === 'object' && t !== null;\n}\n\nfunction flattenTranslation<T extends UnknownStringKeyObject>(obj: T) {\n return Object.entries(obj).reduce(\n (acc, [key, value]) => {\n if (typeof value === 'string') {\n acc[key] = value;\n } else if (isTranslationObject(value)) {\n Object.entries(flattenTranslation(value)).forEach(\n ([nestedKey, nestedValue]) => {\n acc[prependDelim(key, nestedKey)] = nestedValue;\n },\n );\n }\n\n return acc;\n },\n {} as Record<string, string>,\n );\n}\n\nexport function compileTranslation<\n T extends UnknownStringKeyObject,\n TNS extends string,\n TLocale extends string = string,\n>(\n translation: T,\n ns: TNS,\n locale?: TLocale,\n): CompiledTranslation<T, TNS, TLocale> {\n type $Shape = inferTranslationShape<T>;\n type $Map = inferTranslationParamMap<TNS, T>;\n\n return {\n locale,\n flat: flattenTranslation(translation),\n namespace: ns,\n [INTERNAL_SYMBOL]: {\n shape: {} as $Shape,\n map: {} as $Map,\n },\n };\n}\n","import {\n CompiledTranslation,\n compileTranslation,\n inferCompiledTranslationShape,\n mergeTranslationMaps,\n} from './compile';\nimport { UnknownStringKeyObject } from './string-key-object.type';\n\ntype TranslationNamespace<\n TNS extends string,\n T extends CompiledTranslation<UnknownStringKeyObject, TNS>,\n TShape extends UnknownStringKeyObject,\n> = {\n translation: T;\n createTranslation: <TLocale extends string>(\n locale: TLocale,\n translation: TShape,\n ) => CompiledTranslation<TShape, TNS, TLocale>;\n createMergedNamespace: <\n TOtherNS extends string,\n const TOther extends UnknownStringKeyObject,\n TOtherCompiled extends CompiledTranslation<TOther, TOtherNS>,\n >(\n ns: TOtherNS,\n translation: TOther,\n ) => TranslationNamespace<\n TOtherNS,\n mergeTranslationMaps<TOtherCompiled, T>,\n inferCompiledTranslationShape<TOtherCompiled>\n >;\n};\n\nexport function createNamespace<\n const T extends UnknownStringKeyObject,\n TNS extends string,\n>(ns: TNS, translation: T) {\n const compiled = compileTranslation<T, TNS>(translation, ns);\n\n type TCompiled = typeof compiled;\n type TShape = inferCompiledTranslationShape<typeof compiled>;\n\n const namespace: TranslationNamespace<TNS, TCompiled, TShape> = {\n translation: compileTranslation(translation, ns),\n createTranslation: <TLocale extends string>(\n locale: TLocale,\n translation: TShape,\n ) => {\n return compileTranslation(translation, ns, locale);\n },\n createMergedNamespace: <\n TOther extends UnknownStringKeyObject,\n TOtherNS extends string,\n TOtherCompiled extends CompiledTranslation<\n TOther,\n TOtherNS\n > = CompiledTranslation<TOther, TOtherNS>,\n >(\n otherNs: TOtherNS,\n otherTranslation: TOther,\n ) => {\n return createNamespace(otherNs, otherTranslation) as TranslationNamespace<\n TOtherNS,\n mergeTranslationMaps<TOtherCompiled, TCompiled>,\n inferCompiledTranslationShape<TOtherCompiled>\n > as unknown as any;\n },\n };\n\n return namespace;\n}\n","import { computed, inject, type Signal } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { ActivatedRoute, type ParamMap, Router } from '@angular/router';\n\nexport function pathParam(\n key: string | (() => string),\n route = inject(ActivatedRoute),\n): Signal<string | null> {\n const keySignal =\n typeof key === 'string' ? computed(() => key) : computed(key);\n\n const routerOptions = inject(Router)['options'];\n\n if (\n routerOptions &&\n typeof routerOptions === 'object' &&\n routerOptions.paramsInheritanceStrategy === 'always'\n ) {\n const params = toSignal(route.paramMap, {\n initialValue: route.snapshot.paramMap,\n });\n\n return computed(() => params().get(keySignal()));\n }\n\n const paramMapSignals: Signal<ParamMap>[] = [];\n let currentRoute: ActivatedRoute | null = route;\n\n const isStatic = typeof key === 'string';\n\n while (currentRoute) {\n const initial = currentRoute.snapshot.paramMap;\n paramMapSignals.push(\n toSignal(currentRoute.paramMap, {\n initialValue: initial,\n }),\n );\n\n // For static keys, stop once we find the param, will find first in computed for loop already so basically noop for for loop\n if (isStatic && initial.has(key as string)) break;\n\n currentRoute = currentRoute.parent;\n }\n\n return computed(() => {\n const paramKey = keySignal();\n\n for (const map of paramMapSignals) {\n const v = map().get(paramKey);\n if (v) return v;\n }\n\n return null;\n });\n}\n","import {\n computed,\n effect,\n inject,\n Injectable,\n InjectionToken,\n isDevMode,\n LOCALE_ID,\n type Provider,\n resource,\n type Signal,\n signal,\n untracked,\n type WritableSignal,\n} from '@angular/core';\nimport { createIntl, createIntlCache, type IntlConfig } from '@formatjs/intl';\nimport { type CompiledTranslation } from './compile';\nimport { prependDelim } from './delim';\nimport { pathParam } from './path-param';\nimport { type UnknownStringKeyObject } from './string-key-object.type';\n\nconst CONFIG_TOKEN = new InjectionToken<\n Omit<IntlConfig, 'locale' | 'messages'> & {\n supportedLocales?: string[];\n preloadDefaultLocale?: boolean;\n localeParamName?: string;\n }\n>('mmstack-intl-config');\n\nexport function provideIntlConfig(\n config: Omit<IntlConfig, 'locale' | 'messages'> & {\n /** Checks next locale is in provided array before switching locales */\n supportedLocales?: string[];\n /** Preloads the default locale ensuring sync fallback, not necessary for most cases as it will lazily load automatically when needed */\n preloadDefaultLocale?: boolean;\n /** Auto-resolution when using a locale parameter via angular router */\n localeParamName?: string;\n },\n): Provider[] {\n const providers: Provider[] = [\n {\n useFactory: (localeId: string) => {\n const next = {\n ...config,\n };\n\n const defaultLocale =\n config.defaultLocale ?? config.supportedLocales?.at(0) ?? localeId;\n\n if (\n next.supportedLocales &&\n !next.supportedLocales.includes(defaultLocale)\n ) {\n next.supportedLocales = [...next.supportedLocales, defaultLocale];\n }\n\n return next;\n },\n deps: [LOCALE_ID],\n provide: CONFIG_TOKEN,\n },\n ];\n\n const defaultLocale = config.defaultLocale ?? config.supportedLocales?.at(0);\n\n if (!defaultLocale) return providers;\n\n providers.push({\n provide: LOCALE_ID,\n useValue: defaultLocale,\n });\n\n return providers;\n}\n\nexport function injectIntlConfig() {\n return inject(CONFIG_TOKEN, { optional: true }) ?? undefined;\n}\n\nexport function injectDefaultLocale() {\n return injectIntlConfig()?.defaultLocale ?? inject(LOCALE_ID) ?? 'en-US';\n}\n\nexport function injectSupportedLocales() {\n return injectIntlConfig()?.supportedLocales ?? [injectDefaultLocale()];\n}\n\n@Injectable({\n providedIn: 'root',\n})\nexport class TranslationStore {\n private readonly cache = createIntlCache();\n private readonly config = injectIntlConfig();\n readonly loadQueue = signal<string[]>([]);\n readonly locale = signal(injectDefaultLocale());\n private readonly defaultLocale = injectDefaultLocale();\n private readonly translations = signal<\n Record<string, Record<string, string>>\n >({\n [this.defaultLocale]: {},\n });\n private attemptedFallbackLoad = false;\n\n private readonly onDemandLoaders = new Map<\n string,\n Record<\n string,\n () => Promise<CompiledTranslation<UnknownStringKeyObject, string>>\n >\n >();\n\n private readonly nonMessageConfig = computed(() => ({\n ...this.config,\n locale: this.locale(),\n }));\n\n private readonly messages = computed(\n () =>\n this.translations()[this.locale()] ??\n this.translations()[this.defaultLocale] ??\n {},\n );\n\n readonly dynamicLocaleLoader = resource({\n params: computed(() => this.loadQueue().at(0) ?? null),\n loader: async ({ params: newLocale, abortSignal }) => {\n if (!newLocale) return;\n\n const currentTranslations = untracked(this.translations);\n\n const loadPromises: Promise<{\n namespace: string;\n flat: Record<string, string>;\n } | null>[] = [];\n\n for (const [namespace, loaders] of this.onDemandLoaders.entries()) {\n const loader = loaders[newLocale];\n if (loader) {\n const hasNamespaceForLocale =\n currentTranslations[newLocale] &&\n Object.keys(currentTranslations[newLocale]).some((key) =>\n key.startsWith(`${prependDelim(namespace, '').slice(0, -1)}`),\n );\n\n if (!hasNamespaceForLocale) {\n loadPromises.push(\n loader()\n .then((translation) => {\n if (abortSignal.aborted) return null;\n return {\n namespace: translation.namespace,\n flat: translation.flat,\n };\n })\n .catch((err) => {\n if (isDevMode()) {\n console.error(\n '[Translate] Failed to load',\n namespace,\n newLocale,\n err,\n );\n }\n\n return null;\n }),\n );\n }\n }\n }\n\n return Promise.all(loadPromises)\n .then((res) => res.filter((r) => r !== null))\n .then((res) => ({\n locales: res,\n locale: newLocale,\n }));\n },\n });\n\n readonly intl = computed(() =>\n createIntl(\n {\n ...this.nonMessageConfig(),\n messages: this.messages(),\n },\n this.cache,\n ),\n );\n\n constructor() {\n const paramName = this.config?.localeParamName;\n if (paramName) {\n const param = pathParam(paramName);\n\n effect(() => {\n const loc = param();\n if (\n !loc ||\n loc === untracked(this.locale) ||\n untracked(this.loadQueue).includes(loc)\n )\n return;\n if (this.hasLocaleLoaders(loc)) this.locale.set(loc);\n else this.loadQueue.update((q) => [...q, loc]);\n });\n }\n\n effect(() => {\n if (\n // should never be in error state, but best to check in case something throws\n this.dynamicLocaleLoader.error() ||\n this.dynamicLocaleLoader.isLoading()\n )\n return;\n const dynamicLocales = this.dynamicLocaleLoader.value();\n\n if (!dynamicLocales) return;\n\n // Register loaded translations\n for (const locale of dynamicLocales.locales) {\n this.register(locale.namespace, {\n [dynamicLocales.locale]: locale.flat,\n });\n }\n\n const hasTranslations =\n dynamicLocales.locales.length > 0 ||\n this.translations()[dynamicLocales.locale];\n\n if (hasTranslations) {\n this.loadQueue.update((q) =>\n q.filter((l) => l !== dynamicLocales.locale),\n );\n this.locale.set(dynamicLocales.locale);\n }\n });\n }\n\n formatMessage(key: string, values?: Record<string, string | number>) {\n const message =\n this.translations()[this.locale()]?.[key] ??\n this.translations()[this.defaultLocale]?.[key] ??\n '';\n\n if (!message) {\n if (this.attemptedFallbackLoad) return '';\n\n this.attemptedFallbackLoad = true;\n untracked(() => {\n if (!this.loadQueue().includes(this.defaultLocale))\n this.loadQueue.update((q) => [...q, this.defaultLocale]);\n });\n return '';\n }\n\n return this.intl().formatMessage(\n { id: key, defaultMessage: message },\n values,\n );\n }\n\n register(\n namespace: string,\n flat: Partial<Record<string, Record<string, string>>>,\n ) {\n this.translations.update((cur) => {\n return Object.entries(flat).reduce(\n (acc, [locale, translation]) => {\n const localeTranslation = acc[locale] ?? {};\n\n const withNS = Object.entries(translation ?? {}).reduce(\n (acc, [key, value]) => {\n acc[prependDelim(namespace, key)] = value;\n return acc;\n },\n {} as Record<string, string>,\n );\n\n acc[locale] = {\n ...localeTranslation,\n ...withNS,\n };\n\n return acc;\n },\n { ...cur },\n );\n });\n }\n\n registerOnDemandLoaders(\n namespace: string,\n loaders: Record<string, () => Promise<any>>,\n ) {\n this.onDemandLoaders.set(namespace, loaders);\n }\n\n hasLocaleLoaders(locale: string): boolean {\n return Array.from(this.onDemandLoaders.values()).some(\n (loaders) => loaders[locale],\n );\n }\n}\n\nexport function injectIntl() {\n return inject(TranslationStore).intl;\n}\n\n/**\n * Inject a dynamic locale signal that supports runtime language switching.\n *\n * @returns A writable signal with the current locale and loading state.\n * Only allows switching to locales that have registered loaders.\n *\n * @example\n * ```typescript\n * const locale = injectDynamicLocale();\n *\n * // Switch language (triggers automatic translation loading)\n * locale.set('sl-SI');\n *\n * // Check loading state\n * if (locale.isLoading()) {\n * // Show spinner\n * }\n * ```\n */\nexport function injectDynamicLocale(): WritableSignal<string> & {\n isLoading: Signal<boolean>;\n} {\n const store = inject(TranslationStore);\n const supportedLocales = injectIntlConfig()?.supportedLocales;\n\n const source = computed(() => store.locale()) as WritableSignal<string> & {\n isLoading: Signal<boolean>;\n };\n\n const inSupportedLocales =\n supportedLocales === undefined\n ? () => true\n : (locale: string) => supportedLocales.includes(locale);\n\n const set = (value: string) => {\n if (\n value === untracked(source) ||\n untracked(store.loadQueue).includes(value)\n )\n return;\n\n if (!inSupportedLocales(value)) {\n if (isDevMode())\n console.warn(\n `[Translate] Locale \"${value}\" is not in supportedLocales, switch prevented. Available options are:`,\n supportedLocales,\n );\n\n return;\n }\n\n if (isDevMode() && !store.hasLocaleLoaders(value))\n console.warn(\n `[Translate] No loaders registered for locale \"${value}\". Switching to this locale will have no effect.`,\n );\n\n store.loadQueue.update((q) => [...q, value]);\n };\n\n source.set = set;\n source.update = (updater: (value: string) => string) => {\n const next = updater(untracked(source));\n source.set(next);\n };\n source.asReadonly = () => source;\n\n source.isLoading = store.dynamicLocaleLoader.isLoading;\n\n return source;\n}\n","import {\n computed,\n inject,\n isDevMode,\n isSignal,\n type Signal,\n untracked,\n} from '@angular/core';\nimport {\n type ActivatedRouteSnapshot,\n ResolveFn,\n Router,\n} from '@angular/router';\nimport {\n type CompiledTranslation,\n type inferCompiledTranslationMap,\n type inferCompiledTranslationNamespace,\n} from './compile';\nimport { replaceWithDelim } from './delim';\nimport { type UnknownStringKeyObject } from './string-key-object.type';\nimport {\n injectDefaultLocale,\n injectIntlConfig,\n TranslationStore,\n} from './translation-store';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyStringRecord = Record<string, any>;\n\nfunction createEqualsRecord<T extends AnyStringRecord>(keys: (keyof T)[] = []) {\n let keyMatcher: (a: T, b: T) => boolean;\n\n if (keys.length === 0) {\n keyMatcher = () => true;\n } else if (keys.length === 1) {\n const key = keys[0];\n keyMatcher = (a, b) => a[key] === b[key];\n } else {\n keyMatcher = (a, b) => {\n return keys.every((k) => a[k] === b[k]);\n };\n }\n\n return (a?: T, b?: T): boolean => {\n if (!a && !b) return true;\n if (!a || !b) return false;\n return keyMatcher(a, b);\n };\n}\n\ntype TFunction<TMap extends AnyStringRecord> = <\n TKey extends keyof TMap & string,\n>(\n key: TKey,\n ...args: TMap[TKey] extends void ? [] : [TMap[TKey]]\n) => string;\n\ntype SignalTFunction<TMap extends AnyStringRecord> = <\n TKey extends keyof TMap & string,\n>(\n key: TKey,\n ...args: TMap[TKey] extends void ? [] : [() => TMap[TKey]]\n) => Signal<string>;\n\ntype TFunctionWithSignalConstructor<\n TMap extends AnyStringRecord,\n TFN extends TFunction<TMap>,\n> = TFN & {\n asSignal: SignalTFunction<TMap>;\n};\n\nfunction addSignalFn<TMap extends AnyStringRecord, TFn extends TFunction<TMap>>(\n fn: TFn,\n store: TranslationStore,\n): TFunctionWithSignalConstructor<TMap, TFn> {\n const withSig = fn as TFunctionWithSignalConstructor<TMap, TFn>;\n\n const asSignal = <TKey extends keyof TMap & string>(\n key: TKey,\n ...args: TMap[TKey] extends void ? [] : [() => TMap[TKey]]\n ): Signal<string> => {\n const variables = args[0] as () => AnyStringRecord | undefined;\n const stringKey = key as string;\n\n const flatPath = replaceWithDelim(stringKey);\n\n const varsFn = variables ?? (() => undefined);\n const varsSignal = isSignal(varsFn)\n ? varsFn\n : computed(varsFn, {\n equal: createEqualsRecord(Object.keys(varsFn() ?? {})),\n });\n\n return computed(() => store.formatMessage(flatPath, varsSignal()));\n };\n\n withSig.asSignal = asSignal;\n\n return withSig;\n}\n\nexport function createT<TMap extends AnyStringRecord>(\n store: TranslationStore,\n): TFunction<TMap> {\n return <TKey extends keyof TMap & string>(\n key: TKey,\n ...args: TMap[TKey] extends void ? [] : [TMap[TKey]]\n ): string => {\n const variables = args[0] as AnyStringRecord | undefined;\n const stringKey = key as string;\n\n return store.formatMessage(replaceWithDelim(stringKey), variables);\n };\n}\n\nexport function registerNamespace<\n TDefault extends CompiledTranslation<UnknownStringKeyObject, string>,\n>(\n defaultTranslation: () => Promise<TDefault>,\n other: Record<\n string,\n () => Promise<\n CompiledTranslation<\n UnknownStringKeyObject,\n inferCompiledTranslationNamespace<TDefault>,\n string\n >\n >\n >,\n) {\n type $Map = inferCompiledTranslationMap<TDefault>;\n type $BaseTFN = TFunction<$Map>;\n type $TFN = TFunctionWithSignalConstructor<$Map, $BaseTFN>;\n\n const injectT = (): $TFN => {\n const store = inject(TranslationStore);\n\n return addSignalFn(createT(store), store);\n };\n\n let defaultTranslationLoaded = false;\n const resolver: ResolveFn<void> = async (snapshot) => {\n const store = inject(TranslationStore);\n\n let locale: string | null = null;\n\n const paramName = injectIntlConfig()?.localeParamName;\n\n const routerConfig = inject(Router)['options'];\n const alwaysInheritParams =\n typeof routerConfig === 'object' &&\n !!routerConfig &&\n routerConfig.paramsInheritanceStrategy === 'always';\n\n if (paramName) {\n locale = snapshot.paramMap.get(paramName);\n\n if (!locale && !alwaysInheritParams) {\n let currentRoute: ActivatedRouteSnapshot | null = snapshot;\n while (currentRoute && !locale) {\n locale = currentRoute.paramMap.get('locale');\n currentRoute = currentRoute.parent;\n }\n }\n }\n\n if (!locale) {\n locale = untracked(store.locale);\n }\n\n const defaultLocale = injectDefaultLocale();\n const shouldPreloadDefault =\n injectIntlConfig()?.preloadDefaultLocale ?? false;\n\n const tPromise = other[locale] as (typeof other)[string] | undefined;\n\n const promise = tPromise ?? defaultTranslation;\n if (!promise && isDevMode()) {\n return console.warn(`No translation found for locale: ${locale}`);\n }\n\n if (promise === defaultTranslation && defaultTranslationLoaded) return;\n\n try {\n const promises = [promise()];\n\n if (\n shouldPreloadDefault &&\n !defaultTranslationLoaded &&\n promise !== defaultTranslation\n )\n promises.push(defaultTranslation());\n\n const translations = await Promise.allSettled(promises);\n\n const fullfilled = translations.map((t) =>\n t.status === 'fulfilled' ? t.value : null,\n );\n\n if (fullfilled.at(0) === null && fullfilled.at(1) === null)\n throw new Error('Failed to load translations');\n\n const [t, defaultT] = fullfilled;\n\n const ns = t?.namespace ?? defaultT?.namespace;\n if (!ns) throw new Error('No namespace found in translation');\n\n if (isDevMode() && t && t.locale !== locale && t.locale)\n console.warn(`Expected locale to be ${locale} but got ${t.locale}`);\n\n store.registerOnDemandLoaders(ns, {\n ...other,\n [defaultLocale]: defaultTranslation,\n });\n\n const toRegister: Record<string, Record<string, string>> = {};\n if (t) toRegister[locale] = t.flat;\n if (defaultT) toRegister[defaultLocale] = defaultT.flat;\n\n store.register(ns, toRegister);\n\n if (promise === defaultTranslation || defaultT)\n defaultTranslationLoaded = true;\n } catch {\n if (isDevMode()) {\n console.warn(`Failed to load translation for locale: ${locale}`);\n }\n } finally {\n if (locale !== untracked(store.locale)) store.locale.set(locale);\n }\n };\n\n return {\n injectNamespaceT: injectT,\n resolveNamespaceTranslation: resolver,\n };\n}\n","import { inject } from '@angular/core';\nimport {\n Router,\n type CanMatchFn,\n type Route,\n type UrlSegment,\n} from '@angular/router';\nimport {\n injectDefaultLocale,\n injectSupportedLocales,\n} from './translation-store';\n\n/**\n * Guard that validates the locale parameter against supported locales.\n * Redirects to default locale if the locale is invalid.\n *\n * @param prefixSegments Optional array of path segments preceding the locale segment.\n * if (you wanted to match /app/:locale/... you would pass ['app'] here) & the function would match the second parameter + redirect accordingly\n *\n * @example\n * ```typescript\n * {\n * path: ':locale',\n * canMatch: [canMatchLocale()],\n * children: [...]\n * }\n * ```\n */\nexport function canMatchLocale(prefixSegments: string[] = []): CanMatchFn {\n return (_route: Route, segments: UrlSegment[]) => {\n const supportedLocales = injectSupportedLocales();\n\n const locale = segments.at(prefixSegments.length)?.path;\n\n if (!locale || !supportedLocales.includes(locale))\n return inject(Router).createUrlTree([\n ...prefixSegments,\n injectDefaultLocale(),\n ]);\n\n return true;\n };\n}\n","import {\n afterRenderEffect,\n computed,\n Directive,\n ElementRef,\n inject,\n input,\n Renderer2,\n} from '@angular/core';\nimport {\n type CompiledTranslation,\n type inferCompiledTranslationMap,\n} from './compile';\nimport { createT } from './register-namespace';\nimport { type UnknownStringKeyObject } from './string-key-object.type';\nimport { TranslationStore } from './translation-store';\n\n@Directive()\nexport abstract class Translate<\n TInput extends string,\n T extends CompiledTranslation<UnknownStringKeyObject, string>,\n TMap extends inferCompiledTranslationMap<T> = inferCompiledTranslationMap<T>,\n TKey extends TInput & keyof TMap & string = TInput & keyof TMap & string,\n> {\n private readonly t = createT(inject(TranslationStore));\n\n readonly translate =\n input.required<\n TMap[TKey] extends void\n ? TKey | [key: TKey]\n : [key: TKey, vars: TMap[TKey]]\n >();\n\n constructor() {\n const key = computed(() => {\n const vars = this.translate();\n return (Array.isArray(vars) ? vars[0] : vars) as TKey;\n });\n\n const args = computed(\n () => {\n const vars = this.translate();\n return (Array.isArray(vars) ? vars[1] : undefined) as TMap[TKey];\n },\n {\n equal: (a, b) => {\n if (a === undefined && b === undefined) return true;\n if (a === undefined || b === undefined) return false;\n\n const aObj = a as Record<string, string>;\n const keys = Object.keys(aObj);\n const bObj = b as Record<string, string>;\n\n if (!keys.length) return !Object.keys(bObj).length;\n\n return keys.every((key) => aObj[key] === bObj[key]);\n },\n },\n );\n\n const translation = computed(() => this.t(key(), args()));\n\n const renderer = inject(Renderer2);\n const el = inject<ElementRef<HTMLElement>>(ElementRef);\n\n afterRenderEffect({\n write: () => {\n renderer.setProperty(el.nativeElement, 'textContent', translation());\n },\n });\n }\n}\n","import { ChangeDetectorRef, effect, inject } from '@angular/core';\nimport { CompiledTranslation, inferCompiledTranslationMap } from './compile';\nimport { createT } from './register-namespace';\nimport { UnknownStringKeyObject } from './string-key-object.type';\nimport { TranslationStore } from './translation-store';\n\nexport abstract class Translator<\n T extends CompiledTranslation<UnknownStringKeyObject, string>,\n TMap extends inferCompiledTranslationMap<T> = inferCompiledTranslationMap<T>,\n> {\n private readonly store = inject(TranslationStore);\n private readonly t = createT<TMap>(this.store);\n\n constructor() {\n const cdr = inject(ChangeDetectorRef);\n\n effect(() => {\n this.store.locale();\n cdr.markForCheck();\n });\n }\n\n transform<K extends keyof TMap & string>(\n key: K,\n ...args: TMap[K] extends void\n ? [locale?: string]\n : [TMap[K], locale?: string]\n ): string {\n const actualArgs = args.filter(\n (a) => typeof a === 'object',\n ) as TMap[K] extends void ? [] : [TMap[K]];\n\n return this.t(key, ...actualArgs);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;AAAA,MAAM,SAAS,GAAG,eAAe;AAE3B,SAAU,YAAY,CAAC,MAAc,EAAE,GAAW,EAAA;AACtD,IAAA,OAAO,GAAG,MAAM,CAAA,EAAG,SAAS,CAAA,EAAG,GAAG,EAAE;AACtC;SAEgB,gBAAgB,CAAC,GAAW,EAAE,IAAI,GAAG,GAAG,EAAA;IACtD,OAAO,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC;AACxC;;ACDA,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC;AAyChE,SAAS,mBAAmB,CAAC,CAAU,EAAA;IACrC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI;AAC5C;AAEA,SAAS,kBAAkB,CAAmC,GAAM,EAAA;AAClE,IAAA,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAC/B,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,KAAI;AACpB,QAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AAC7B,YAAA,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK;QAClB;AAAO,aAAA,IAAI,mBAAmB,CAAC,KAAK,CAAC,EAAE;AACrC,YAAA,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAC/C,CAAC,CAAC,SAAS,EAAE,WAAW,CAAC,KAAI;gBAC3B,GAAG,CAAC,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,GAAG,WAAW;AACjD,YAAA,CAAC,CACF;QACH;AAEA,QAAA,OAAO,GAAG;IACZ,CAAC,EACD,EAA4B,CAC7B;AACH;SAEgB,kBAAkB,CAKhC,WAAc,EACd,EAAO,EACP,MAAgB,EAAA;IAKhB,OAAO;QACL,MAAM;AACN,QAAA,IAAI,EAAE,kBAAkB,CAAC,WAAW,CAAC;AACrC,QAAA,SAAS,EAAE,EAAE;QACb,CAAC,eAAe,GAAG;AACjB,YAAA,KAAK,EAAE,EAAY;AACnB,YAAA,GAAG,EAAE,EAAU;AAChB,SAAA;KACF;AACH;;AC5DM,SAAU,eAAe,CAG7B,EAAO,EAAE,WAAc,EAAA;IACvB,MAAM,QAAQ,GAAG,kBAAkB,CAAS,WAAW,EAAE,EAAE,CAAC;AAK5D,IAAA,MAAM,SAAS,GAAiD;AAC9D,QAAA,WAAW,EAAE,kBAAkB,CAAC,WAAW,EAAE,EAAE,CAAC;AAChD,QAAA,iBAAiB,EAAE,CACjB,MAAe,EACf,WAAmB,KACjB;YACF,OAAO,kBAAkB,CAAC,WAAW,EAAE,EAAE,EAAE,MAAM,CAAC;QACpD,CAAC;AACD,QAAA,qBAAqB,EAAE,CAQrB,OAAiB,EACjB,gBAAwB,KACtB;AACF,YAAA,OAAO,eAAe,CAAC,OAAO,EAAE,gBAAgB,CAI7B;QACrB,CAAC;KACF;AAED,IAAA,OAAO,SAAS;AAClB;;ACjEM,SAAU,SAAS,CACvB,GAA4B,EAC5B,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,EAAA;IAE9B,MAAM,SAAS,GACb,OAAO,GAAG,KAAK,QAAQ,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC;IAE/D,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC;AAE/C,IAAA,IACE,aAAa;QACb,OAAO,aAAa,KAAK,QAAQ;AACjC,QAAA,aAAa,CAAC,yBAAyB,KAAK,QAAQ,EACpD;AACA,QAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE;AACtC,YAAA,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ;AACtC,SAAA,CAAC;AAEF,QAAA,OAAO,QAAQ,CAAC,MAAM,MAAM,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;IAClD;IAEA,MAAM,eAAe,GAAuB,EAAE;IAC9C,IAAI,YAAY,GAA0B,KAAK;AAE/C,IAAA,MAAM,QAAQ,GAAG,OAAO,GAAG,KAAK,QAAQ;IAExC,OAAO,YAAY,EAAE;AACnB,QAAA,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,QAAQ;QAC9C,eAAe,CAAC,IAAI,CAClB,QAAQ,CAAC,YAAY,CAAC,QAAQ,EAAE;AAC9B,YAAA,YAAY,EAAE,OAAO;AACtB,SAAA,CAAC,CACH;;AAGD,QAAA,IAAI,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,GAAa,CAAC;YAAE;AAE5C,QAAA,YAAY,GAAG,YAAY,CAAC,MAAM;IACpC;IAEA,OAAO,QAAQ,CAAC,MAAK;AACnB,QAAA,MAAM,QAAQ,GAAG,SAAS,EAAE;AAE5B,QAAA,KAAK,MAAM,GAAG,IAAI,eAAe,EAAE;YACjC,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC7B,YAAA,IAAI,CAAC;AAAE,gBAAA,OAAO,CAAC;QACjB;AAEA,QAAA,OAAO,IAAI;AACb,IAAA,CAAC,CAAC;AACJ;;ACjCA,MAAM,YAAY,GAAG,IAAI,cAAc,CAMrC,qBAAqB,CAAC;AAElB,SAAU,iBAAiB,CAC/B,MAOC,EAAA;AAED,IAAA,MAAM,SAAS,GAAe;AAC5B,QAAA;AACE,YAAA,UAAU,EAAE,CAAC,QAAgB,KAAI;AAC/B,gBAAA,MAAM,IAAI,GAAG;AACX,oBAAA,GAAG,MAAM;iBACV;AAED,gBAAA,MAAM,aAAa,GACjB,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,QAAQ;gBAEpE,IACE,IAAI,CAAC,gBAAgB;oBACrB,CAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,aAAa,CAAC,EAC9C;oBACA,IAAI,CAAC,gBAAgB,GAAG,CAAC,GAAG,IAAI,CAAC,gBAAgB,EAAE,aAAa,CAAC;gBACnE;AAEA,gBAAA,OAAO,IAAI;YACb,CAAC;YACD,IAAI,EAAE,CAAC,SAAS,CAAC;AACjB,YAAA,OAAO,EAAE,YAAY;AACtB,SAAA;KACF;AAED,IAAA,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,CAAC;AAE5E,IAAA,IAAI,CAAC,aAAa;AAAE,QAAA,OAAO,SAAS;IAEpC,SAAS,CAAC,IAAI,CAAC;AACb,QAAA,OAAO,EAAE,SAAS;AAClB,QAAA,QAAQ,EAAE,aAAa;AACxB,KAAA,CAAC;AAEF,IAAA,OAAO,SAAS;AAClB;SAEgB,gBAAgB,GAAA;AAC9B,IAAA,OAAO,MAAM,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,SAAS;AAC9D;SAEgB,mBAAmB,GAAA;IACjC,OAAO,gBAAgB,EAAE,EAAE,aAAa,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,OAAO;AAC1E;SAEgB,sBAAsB,GAAA;IACpC,OAAO,gBAAgB,EAAE,EAAE,gBAAgB,IAAI,CAAC,mBAAmB,EAAE,CAAC;AACxE;MAKa,gBAAgB,CAAA;IACV,KAAK,GAAG,eAAe,EAAE;IACzB,MAAM,GAAG,gBAAgB,EAAE;AACnC,IAAA,SAAS,GAAG,MAAM,CAAW,EAAE,qDAAC;AAChC,IAAA,MAAM,GAAG,MAAM,CAAC,mBAAmB,EAAE,kDAAC;IAC9B,aAAa,GAAG,mBAAmB,EAAE;IACrC,YAAY,GAAG,MAAM,CAEpC;AACA,QAAA,CAAC,IAAI,CAAC,aAAa,GAAG,EAAE;AACzB,KAAA,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,cAAA,EAAA,CAAA,GAAA,EAAA,CAAA,CAAC;IACM,qBAAqB,GAAG,KAAK;AAEpB,IAAA,eAAe,GAAG,IAAI,GAAG,EAMvC;AAEc,IAAA,gBAAgB,GAAG,QAAQ,CAAC,OAAO;QAClD,GAAG,IAAI,CAAC,MAAM;AACd,QAAA,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE;AACtB,KAAA,CAAC,4DAAC;AAEc,IAAA,QAAQ,GAAG,QAAQ,CAClC,MACE,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;AAClC,QAAA,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC;AACvC,QAAA,EAAE,oDACL;IAEQ,mBAAmB,GAAG,QAAQ,CAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,qBAAA,EAAA,GAAA,EAAA,CAAA,EACrC,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QACtD,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,KAAI;AACnD,YAAA,IAAI,CAAC,SAAS;gBAAE;YAEhB,MAAM,mBAAmB,GAAG,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC;YAExD,MAAM,YAAY,GAGJ,EAAE;AAEhB,YAAA,KAAK,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,EAAE;AACjE,gBAAA,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;gBACjC,IAAI,MAAM,EAAE;AACV,oBAAA,MAAM,qBAAqB,GACzB,mBAAmB,CAAC,SAAS,CAAC;AAC9B,wBAAA,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,KACnD,GAAG,CAAC,UAAU,CAAC,CAAA,EAAG,YAAY,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA,CAAE,CAAC,CAC9D;oBAEH,IAAI,CAAC,qBAAqB,EAAE;AAC1B,wBAAA,YAAY,CAAC,IAAI,CACf,MAAM;AACH,6BAAA,IAAI,CAAC,CAAC,WAAW,KAAI;4BACpB,IAAI,WAAW,CAAC,OAAO;AAAE,gCAAA,OAAO,IAAI;4BACpC,OAAO;gCACL,SAAS,EAAE,WAAW,CAAC,SAAS;gCAChC,IAAI,EAAE,WAAW,CAAC,IAAI;6BACvB;AACH,wBAAA,CAAC;AACA,6BAAA,KAAK,CAAC,CAAC,GAAG,KAAI;4BACb,IAAI,SAAS,EAAE,EAAE;gCACf,OAAO,CAAC,KAAK,CACX,4BAA4B,EAC5B,SAAS,EACT,SAAS,EACT,GAAG,CACJ;4BACH;AAEA,4BAAA,OAAO,IAAI;wBACb,CAAC,CAAC,CACL;oBACH;gBACF;YACF;AAEA,YAAA,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY;AAC5B,iBAAA,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;AAC3C,iBAAA,IAAI,CAAC,CAAC,GAAG,MAAM;AACd,gBAAA,OAAO,EAAE,GAAG;AACZ,gBAAA,MAAM,EAAE,SAAS;AAClB,aAAA,CAAC,CAAC;AACP,QAAA,CAAC,GACD;AAEO,IAAA,IAAI,GAAG,QAAQ,CAAC,MACvB,UAAU,CACR;QACE,GAAG,IAAI,CAAC,gBAAgB,EAAE;AAC1B,QAAA,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;AAC1B,KAAA,EACD,IAAI,CAAC,KAAK,CACX,gDACF;AAED,IAAA,WAAA,GAAA;AACE,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,eAAe;QAC9C,IAAI,SAAS,EAAE;AACb,YAAA,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC;YAElC,MAAM,CAAC,MAAK;AACV,gBAAA,MAAM,GAAG,GAAG,KAAK,EAAE;AACnB,gBAAA,IACE,CAAC,GAAG;AACJ,oBAAA,GAAG,KAAK,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;oBAC9B,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;oBAEvC;AACF,gBAAA,IAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC;AAAE,oBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;;AAC/C,oBAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;AAChD,YAAA,CAAC,CAAC;QACJ;QAEA,MAAM,CAAC,MAAK;AACV,YAAA;;AAEE,YAAA,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE;AAChC,gBAAA,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE;gBAEpC;YACF,MAAM,cAAc,GAAG,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE;AAEvD,YAAA,IAAI,CAAC,cAAc;gBAAE;;AAGrB,YAAA,KAAK,MAAM,MAAM,IAAI,cAAc,CAAC,OAAO,EAAE;AAC3C,gBAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE;AAC9B,oBAAA,CAAC,cAAc,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI;AACrC,iBAAA,CAAC;YACJ;YAEA,MAAM,eAAe,GACnB,cAAc,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;gBACjC,IAAI,CAAC,YAAY,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC;YAE5C,IAAI,eAAe,EAAE;gBACnB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,KACtB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,cAAc,CAAC,MAAM,CAAC,CAC7C;gBACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC;YACxC;AACF,QAAA,CAAC,CAAC;IACJ;IAEA,aAAa,CAAC,GAAW,EAAE,MAAwC,EAAA;AACjE,QAAA,MAAM,OAAO,GACX,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,GAAG,CAAC;YACzC,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC;AAC9C,YAAA,EAAE;QAEJ,IAAI,CAAC,OAAO,EAAE;YACZ,IAAI,IAAI,CAAC,qBAAqB;AAAE,gBAAA,OAAO,EAAE;AAEzC,YAAA,IAAI,CAAC,qBAAqB,GAAG,IAAI;YACjC,SAAS,CAAC,MAAK;gBACb,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC;AAChD,oBAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;AAC5D,YAAA,CAAC,CAAC;AACF,YAAA,OAAO,EAAE;QACX;AAEA,QAAA,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,aAAa,CAC9B,EAAE,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,EACpC,MAAM,CACP;IACH;IAEA,QAAQ,CACN,SAAiB,EACjB,IAAqD,EAAA;QAErD,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,KAAI;AAC/B,YAAA,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAChC,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,KAAI;gBAC7B,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE;gBAE3C,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,MAAM,CACrD,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,KAAI;oBACpB,GAAG,CAAC,YAAY,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,GAAG,KAAK;AACzC,oBAAA,OAAO,GAAG;gBACZ,CAAC,EACD,EAA4B,CAC7B;gBAED,GAAG,CAAC,MAAM,CAAC,GAAG;AACZ,oBAAA,GAAG,iBAAiB;AACpB,oBAAA,GAAG,MAAM;iBACV;AAED,gBAAA,OAAO,GAAG;AACZ,YAAA,CAAC,EACD,EAAE,GAAG,GAAG,EAAE,CACX;AACH,QAAA,CAAC,CAAC;IACJ;IAEA,uBAAuB,CACrB,SAAiB,EACjB,OAA2C,EAAA;QAE3C,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC;IAC9C;AAEA,IAAA,gBAAgB,CAAC,MAAc,EAAA;QAC7B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CACnD,CAAC,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,CAC7B;IACH;uGApNW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAhB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,cAFf,MAAM,EAAA,CAAA;;2FAEP,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAH5B,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA;;SAwNe,UAAU,GAAA;AACxB,IAAA,OAAO,MAAM,CAAC,gBAAgB,CAAC,CAAC,IAAI;AACtC;AAEA;;;;;;;;;;;;;;;;;;AAkBG;SACa,mBAAmB,GAAA;AAGjC,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,gBAAgB,CAAC;AACtC,IAAA,MAAM,gBAAgB,GAAG,gBAAgB,EAAE,EAAE,gBAAgB;AAE7D,IAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC,MAAM,EAAE,CAE3C;AAED,IAAA,MAAM,kBAAkB,GACtB,gBAAgB,KAAK;AACnB,UAAE,MAAM;AACR,UAAE,CAAC,MAAc,KAAK,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC;AAE3D,IAAA,MAAM,GAAG,GAAG,CAAC,KAAa,KAAI;AAC5B,QAAA,IACE,KAAK,KAAK,SAAS,CAAC,MAAM,CAAC;YAC3B,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;YAE1C;AAEF,QAAA,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE;AAC9B,YAAA,IAAI,SAAS,EAAE;gBACb,OAAO,CAAC,IAAI,CACV,CAAA,oBAAA,EAAuB,KAAK,CAAA,sEAAA,CAAwE,EACpG,gBAAgB,CACjB;YAEH;QACF;QAEA,IAAI,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,CAAC;AAC/C,YAAA,OAAO,CAAC,IAAI,CACV,iDAAiD,KAAK,CAAA,gDAAA,CAAkD,CACzG;AAEH,QAAA,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;AAC9C,IAAA,CAAC;AAED,IAAA,MAAM,CAAC,GAAG,GAAG,GAAG;AAChB,IAAA,MAAM,CAAC,MAAM,GAAG,CAAC,OAAkC,KAAI;QACrD,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AACvC,QAAA,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;AAClB,IAAA,CAAC;AACD,IAAA,MAAM,CAAC,UAAU,GAAG,MAAM,MAAM;IAEhC,MAAM,CAAC,SAAS,GAAG,KAAK,CAAC,mBAAmB,CAAC,SAAS;AAEtD,IAAA,OAAO,MAAM;AACf;;AC7VA,SAAS,kBAAkB,CAA4B,IAAA,GAAoB,EAAE,EAAA;AAC3E,IAAA,IAAI,UAAmC;AAEvC,IAAA,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;AACrB,QAAA,UAAU,GAAG,MAAM,IAAI;IACzB;AAAO,SAAA,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;AAC5B,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC;AACnB,QAAA,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC;IAC1C;SAAO;AACL,QAAA,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC,KAAI;AACpB,YAAA,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACzC,QAAA,CAAC;IACH;AAEA,IAAA,OAAO,CAAC,CAAK,EAAE,CAAK,KAAa;AAC/B,QAAA,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAAE,YAAA,OAAO,IAAI;AACzB,QAAA,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAAE,YAAA,OAAO,KAAK;AAC1B,QAAA,OAAO,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC;AACzB,IAAA,CAAC;AACH;AAuBA,SAAS,WAAW,CAClB,EAAO,EACP,KAAuB,EAAA;IAEvB,MAAM,OAAO,GAAG,EAA+C;IAE/D,MAAM,QAAQ,GAAG,CACf,GAAS,EACT,GAAG,IAAuD,KACxC;AAClB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAsC;QAC9D,MAAM,SAAS,GAAG,GAAa;AAE/B,QAAA,MAAM,QAAQ,GAAG,gBAAgB,CAAC,SAAS,CAAC;QAE5C,MAAM,MAAM,GAAG,SAAS,KAAK,MAAM,SAAS,CAAC;AAC7C,QAAA,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM;AAChC,cAAE;AACF,cAAE,QAAQ,CAAC,MAAM,EAAE;AACf,gBAAA,KAAK,EAAE,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AACvD,aAAA,CAAC;AAEN,QAAA,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,aAAa,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;AACpE,IAAA,CAAC;AAED,IAAA,OAAO,CAAC,QAAQ,GAAG,QAAQ;AAE3B,IAAA,OAAO,OAAO;AAChB;AAEM,SAAU,OAAO,CACrB,KAAuB,EAAA;AAEvB,IAAA,OAAO,CACL,GAAS,EACT,GAAG,IAAiD,KAC1C;AACV,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAgC;QACxD,MAAM,SAAS,GAAG,GAAa;QAE/B,OAAO,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;AACpE,IAAA,CAAC;AACH;AAEM,SAAU,iBAAiB,CAG/B,kBAA2C,EAC3C,KASC,EAAA;IAMD,MAAM,OAAO,GAAG,MAAW;AACzB,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,gBAAgB,CAAC;QAEtC,OAAO,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;AAC3C,IAAA,CAAC;IAED,IAAI,wBAAwB,GAAG,KAAK;AACpC,IAAA,MAAM,QAAQ,GAAoB,OAAO,QAAQ,KAAI;AACnD,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,gBAAgB,CAAC;QAEtC,IAAI,MAAM,GAAkB,IAAI;AAEhC,QAAA,MAAM,SAAS,GAAG,gBAAgB,EAAE,EAAE,eAAe;QAErD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC;AAC9C,QAAA,MAAM,mBAAmB,GACvB,OAAO,YAAY,KAAK,QAAQ;AAChC,YAAA,CAAC,CAAC,YAAY;AACd,YAAA,YAAY,CAAC,yBAAyB,KAAK,QAAQ;QAErD,IAAI,SAAS,EAAE;YACb,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC;AAEzC,YAAA,IAAI,CAAC,MAAM,IAAI,CAAC,mBAAmB,EAAE;gBACnC,IAAI,YAAY,GAAkC,QAAQ;AAC1D,gBAAA,OAAO,YAAY,IAAI,CAAC,MAAM,EAAE;oBAC9B,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC5C,oBAAA,YAAY,GAAG,YAAY,CAAC,MAAM;gBACpC;YACF;QACF;QAEA,IAAI,CAAC,MAAM,EAAE;AACX,YAAA,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;QAClC;AAEA,QAAA,MAAM,aAAa,GAAG,mBAAmB,EAAE;QAC3C,MAAM,oBAAoB,GACxB,gBAAgB,EAAE,EAAE,oBAAoB,IAAI,KAAK;AAEnD,QAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAuC;AAEpE,QAAA,MAAM,OAAO,GAAG,QAAQ,IAAI,kBAAkB;AAC9C,QAAA,IAAI,CAAC,OAAO,IAAI,SAAS,EAAE,EAAE;YAC3B,OAAO,OAAO,CAAC,IAAI,CAAC,oCAAoC,MAAM,CAAA,CAAE,CAAC;QACnE;AAEA,QAAA,IAAI,OAAO,KAAK,kBAAkB,IAAI,wBAAwB;YAAE;AAEhE,QAAA,IAAI;AACF,YAAA,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,CAAC;AAE5B,YAAA,IACE,oBAAoB;AACpB,gBAAA,CAAC,wBAAwB;AACzB,gBAAA,OAAO,KAAK,kBAAkB;AAE9B,gBAAA,QAAQ,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAErC,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC;YAEvD,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,KACpC,CAAC,CAAC,MAAM,KAAK,WAAW,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,CAC1C;AAED,YAAA,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI;AACxD,gBAAA,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC;AAEhD,YAAA,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,UAAU;YAEhC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,IAAI,QAAQ,EAAE,SAAS;AAC9C,YAAA,IAAI,CAAC,EAAE;AAAE,gBAAA,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC;AAE7D,YAAA,IAAI,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM;gBACrD,OAAO,CAAC,IAAI,CAAC,CAAA,sBAAA,EAAyB,MAAM,CAAA,SAAA,EAAY,CAAC,CAAC,MAAM,CAAA,CAAE,CAAC;AAErE,YAAA,KAAK,CAAC,uBAAuB,CAAC,EAAE,EAAE;AAChC,gBAAA,GAAG,KAAK;gBACR,CAAC,aAAa,GAAG,kBAAkB;AACpC,aAAA,CAAC;YAEF,MAAM,UAAU,GAA2C,EAAE;AAC7D,YAAA,IAAI,CAAC;AAAE,gBAAA,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI;AAClC,YAAA,IAAI,QAAQ;AAAE,gBAAA,UAAU,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC,IAAI;AAEvD,YAAA,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;AAE9B,YAAA,IAAI,OAAO,KAAK,kBAAkB,IAAI,QAAQ;gBAC5C,wBAAwB,GAAG,IAAI;QACnC;AAAE,QAAA,MAAM;YACN,IAAI,SAAS,EAAE,EAAE;AACf,gBAAA,OAAO,CAAC,IAAI,CAAC,0CAA0C,MAAM,CAAA,CAAE,CAAC;YAClE;QACF;gBAAU;AACR,YAAA,IAAI,MAAM,KAAK,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;AAAE,gBAAA,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;QAClE;AACF,IAAA,CAAC;IAED,OAAO;AACL,QAAA,gBAAgB,EAAE,OAAO;AACzB,QAAA,2BAA2B,EAAE,QAAQ;KACtC;AACH;;AChOA;;;;;;;;;;;;;;;AAeG;AACG,SAAU,cAAc,CAAC,cAAA,GAA2B,EAAE,EAAA;AAC1D,IAAA,OAAO,CAAC,MAAa,EAAE,QAAsB,KAAI;AAC/C,QAAA,MAAM,gBAAgB,GAAG,sBAAsB,EAAE;AAEjD,QAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,IAAI;QAEvD,IAAI,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC;AAC/C,YAAA,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC;AAClC,gBAAA,GAAG,cAAc;AACjB,gBAAA,mBAAmB,EAAE;AACtB,aAAA,CAAC;AAEJ,QAAA,OAAO,IAAI;AACb,IAAA,CAAC;AACH;;MCxBsB,SAAS,CAAA;IAMZ,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAE7C,IAAA,SAAS,GAChB,KAAK,CAAC,QAAQ,oDAIX;AAEL,IAAA,WAAA,GAAA;AACE,QAAA,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAK;AACxB,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE;AAC7B,YAAA,QAAQ,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI;AAC9C,QAAA,CAAC,+CAAC;AAEF,QAAA,MAAM,IAAI,GAAG,QAAQ,CACnB,MAAK;AACH,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE;AAC7B,YAAA,QAAQ,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,SAAS;QACnD,CAAC,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,MAAA,EAAA,GAAA,EAAA,CAAA,EAEC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,KAAI;AACd,gBAAA,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS;AAAE,oBAAA,OAAO,IAAI;AACnD,gBAAA,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS;AAAE,oBAAA,OAAO,KAAK;gBAEpD,MAAM,IAAI,GAAG,CAA2B;gBACxC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC9B,MAAM,IAAI,GAAG,CAA2B;gBAExC,IAAI,CAAC,IAAI,CAAC,MAAM;oBAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM;AAElD,gBAAA,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC;AACrD,YAAA,CAAC,GAEJ;AAED,QAAA,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,uDAAC;AAEzD,QAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC;AAClC,QAAA,MAAM,EAAE,GAAG,MAAM,CAA0B,UAAU,CAAC;AAEtD,QAAA,iBAAiB,CAAC;YAChB,KAAK,EAAE,MAAK;AACV,gBAAA,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC;YACtE,CAAC;AACF,SAAA,CAAC;IACJ;uGApDoB,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAT,SAAS,EAAA,YAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAT,SAAS,EAAA,UAAA,EAAA,CAAA;kBAD9B;;;MCXqB,UAAU,CAAA;AAIb,IAAA,KAAK,GAAG,MAAM,CAAC,gBAAgB,CAAC;AAChC,IAAA,CAAC,GAAG,OAAO,CAAO,IAAI,CAAC,KAAK,CAAC;AAE9C,IAAA,WAAA,GAAA;AACE,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC;QAErC,MAAM,CAAC,MAAK;AACV,YAAA,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YACnB,GAAG,CAAC,YAAY,EAAE;AACpB,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,SAAS,CACP,GAAM,EACN,GAAG,IAE2B,EAAA;AAE9B,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAC5B,CAAC,CAAC,KAAK,OAAO,CAAC,KAAK,QAAQ,CACY;QAE1C,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC;IACnC;AACD;;AClCD;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"mmstack-translate.mjs","sources":["../../../../packages/translate/src/lib/delim.ts","../../../../packages/translate/src/lib/compile.ts","../../../../packages/translate/src/lib/create-namespace.ts","../../../../packages/translate/src/lib/path-param.ts","../../../../packages/translate/src/lib/translation-store.ts","../../../../packages/translate/src/lib/format/unwrap.ts","../../../../packages/translate/src/lib/format/date.ts","../../../../packages/translate/src/lib/format/display-name.ts","../../../../packages/translate/src/lib/format/list.ts","../../../../packages/translate/src/lib/format/numeric.ts","../../../../packages/translate/src/lib/format/relative-time.ts","../../../../packages/translate/src/lib/resovler-locale.ts","../../../../packages/translate/src/lib/register-namespace.ts","../../../../packages/translate/src/lib/route-helpers.ts","../../../../packages/translate/src/lib/translate.ts","../../../../packages/translate/src/lib/translator.ts","../../../../packages/translate/src/mmstack-translate.ts"],"sourcesContent":["const KEY_DELIM = '::MMT_DELIM::';\n\nexport function prependDelim(prefix: string, key: string): string {\n return `${prefix}${KEY_DELIM}${key}`;\n}\n\nexport function replaceWithDelim(str: string, repl = '.'): string {\n return str.replaceAll(repl, KEY_DELIM);\n}\n","import { prependDelim } from './delim';\nimport type {\n inferTranslationParamMap,\n inferTranslationShape,\n} from './parameterize.type';\nimport type { UnknownStringKeyObject } from './string-key-object.type';\n\nconst INTERNAL_SYMBOL = Symbol.for('mmstack-translate-internal');\n\ntype InternalSymbol = typeof INTERNAL_SYMBOL;\n\nexport type CompiledTranslation<\n T extends UnknownStringKeyObject,\n TNS extends string,\n TLocale extends string = string,\n> = {\n flat: Record<string, string>;\n locale?: TLocale;\n namespace: TNS;\n [INTERNAL_SYMBOL]: {\n shape: inferTranslationShape<T>;\n map: inferTranslationParamMap<TNS, T>;\n };\n};\n\nexport type mergeTranslationMaps<\n TMain extends CompiledTranslation<UnknownStringKeyObject, string>,\n TOther extends CompiledTranslation<UnknownStringKeyObject, string>,\n> = Omit<TMain, InternalSymbol> & {\n [INTERNAL_SYMBOL]: {\n shape: inferCompiledTranslationShape<TMain>;\n map: inferCompiledTranslationMap<TOther> &\n inferCompiledTranslationMap<TMain>;\n };\n};\n\nexport type inferCompiledTranslationNamespace<\n T extends CompiledTranslation<UnknownStringKeyObject, string>,\n> = T['namespace'];\n\nexport type inferCompiledTranslationShape<\n T extends CompiledTranslation<UnknownStringKeyObject, string>,\n> = T[InternalSymbol]['shape'];\n\nexport type inferCompiledTranslationMap<\n T extends CompiledTranslation<UnknownStringKeyObject, string>,\n> = T[InternalSymbol]['map'];\n\nfunction isTranslationObject(t: unknown): t is UnknownStringKeyObject {\n return typeof t === 'object' && t !== null;\n}\n\nfunction flattenTranslation<T extends UnknownStringKeyObject>(obj: T) {\n return Object.entries(obj).reduce(\n (acc, [key, value]) => {\n if (typeof value === 'string') {\n acc[key] = value;\n } else if (isTranslationObject(value)) {\n Object.entries(flattenTranslation(value)).forEach(\n ([nestedKey, nestedValue]) => {\n acc[prependDelim(key, nestedKey)] = nestedValue;\n },\n );\n }\n\n return acc;\n },\n {} as Record<string, string>,\n );\n}\n\nexport function compileTranslation<\n T extends UnknownStringKeyObject,\n TNS extends string,\n TLocale extends string = string,\n>(\n translation: T,\n ns: TNS,\n locale?: TLocale,\n): CompiledTranslation<T, TNS, TLocale> {\n type $Shape = inferTranslationShape<T>;\n type $Map = inferTranslationParamMap<TNS, T>;\n\n return {\n locale,\n flat: flattenTranslation(translation),\n namespace: ns,\n [INTERNAL_SYMBOL]: {\n shape: {} as $Shape,\n map: {} as $Map,\n },\n };\n}\n","import {\n CompiledTranslation,\n compileTranslation,\n inferCompiledTranslationShape,\n mergeTranslationMaps,\n} from './compile';\nimport { UnknownStringKeyObject } from './string-key-object.type';\n\ntype TranslationNamespace<\n TNS extends string,\n T extends CompiledTranslation<UnknownStringKeyObject, TNS>,\n TShape extends UnknownStringKeyObject,\n> = {\n translation: T;\n createTranslation: <TLocale extends string>(\n locale: TLocale,\n translation: TShape,\n ) => CompiledTranslation<TShape, TNS, TLocale>;\n createMergedNamespace: <\n TOtherNS extends string,\n const TOther extends UnknownStringKeyObject,\n TOtherCompiled extends CompiledTranslation<TOther, TOtherNS>,\n >(\n ns: TOtherNS,\n translation: TOther,\n ) => TranslationNamespace<\n TOtherNS,\n mergeTranslationMaps<TOtherCompiled, T>,\n inferCompiledTranslationShape<TOtherCompiled>\n >;\n};\n\nexport function createNamespace<\n const T extends UnknownStringKeyObject,\n TNS extends string,\n>(ns: TNS, translation: T) {\n const compiled = compileTranslation<T, TNS>(translation, ns);\n\n type TCompiled = typeof compiled;\n type TShape = inferCompiledTranslationShape<typeof compiled>;\n\n const namespace: TranslationNamespace<TNS, TCompiled, TShape> = {\n translation: compileTranslation(translation, ns),\n createTranslation: <TLocale extends string>(\n locale: TLocale,\n translation: TShape,\n ) => {\n return compileTranslation(translation, ns, locale);\n },\n createMergedNamespace: <\n TOther extends UnknownStringKeyObject,\n TOtherNS extends string,\n TOtherCompiled extends CompiledTranslation<\n TOther,\n TOtherNS\n > = CompiledTranslation<TOther, TOtherNS>,\n >(\n otherNs: TOtherNS,\n otherTranslation: TOther,\n ) => {\n return createNamespace(otherNs, otherTranslation) as TranslationNamespace<\n TOtherNS,\n mergeTranslationMaps<TOtherCompiled, TCompiled>,\n inferCompiledTranslationShape<TOtherCompiled>\n > as unknown as any;\n },\n };\n\n return namespace;\n}\n","import { computed, inject, type Signal } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { ActivatedRoute, type ParamMap, Router } from '@angular/router';\n\nexport function pathParam(\n key: string | (() => string),\n route = inject(ActivatedRoute),\n): Signal<string | null> {\n const keySignal =\n typeof key === 'string' ? computed(() => key) : computed(key);\n\n const routerOptions = inject(Router)['options'];\n\n if (\n routerOptions &&\n typeof routerOptions === 'object' &&\n routerOptions.paramsInheritanceStrategy === 'always'\n ) {\n const params = toSignal(route.paramMap, {\n initialValue: route.snapshot.paramMap,\n });\n\n return computed(() => params().get(keySignal()));\n }\n\n const paramMapSignals: Signal<ParamMap>[] = [];\n let currentRoute: ActivatedRoute | null = route;\n\n const isStatic = typeof key === 'string';\n\n while (currentRoute) {\n const initial = currentRoute.snapshot.paramMap;\n paramMapSignals.push(\n toSignal(currentRoute.paramMap, {\n initialValue: initial,\n }),\n );\n\n // For static keys, stop once we find the param, will find first in computed for loop already so basically noop for for loop\n if (isStatic && initial.has(key as string)) break;\n\n currentRoute = currentRoute.parent;\n }\n\n return computed(() => {\n const paramKey = keySignal();\n\n for (const map of paramMapSignals) {\n const v = map().get(paramKey);\n if (v) return v;\n }\n\n return null;\n });\n}\n","import {\n computed,\n effect,\n inject,\n Injectable,\n InjectionToken,\n isDevMode,\n LOCALE_ID,\n type Provider,\n resource,\n type Signal,\n signal,\n untracked,\n type WritableSignal,\n} from '@angular/core';\nimport { createIntl, createIntlCache, type IntlConfig } from '@formatjs/intl';\nimport { type CompiledTranslation } from './compile';\nimport { prependDelim } from './delim';\nimport { pathParam } from './path-param';\nimport { type UnknownStringKeyObject } from './string-key-object.type';\n\nconst CONFIG_TOKEN = new InjectionToken<\n Omit<IntlConfig, 'locale' | 'messages'> & {\n supportedLocales?: string[];\n preloadDefaultLocale?: boolean;\n localeParamName?: string;\n }\n>('mmstack-intl-config');\n\nexport function provideIntlConfig(\n config: Omit<IntlConfig, 'locale' | 'messages'> & {\n /** Checks next locale is in provided array before switching locales */\n supportedLocales?: string[];\n /** Preloads the default locale ensuring sync fallback, not necessary for most cases as it will lazily load automatically when needed */\n preloadDefaultLocale?: boolean;\n /** Auto-resolution when using a locale parameter via angular router */\n localeParamName?: string;\n },\n): Provider[] {\n const providers: Provider[] = [\n {\n useFactory: (localeId: string) => {\n const next = {\n ...config,\n };\n\n const defaultLocale =\n config.defaultLocale ?? config.supportedLocales?.at(0) ?? localeId;\n\n if (\n next.supportedLocales &&\n !next.supportedLocales.includes(defaultLocale)\n ) {\n next.supportedLocales = [...next.supportedLocales, defaultLocale];\n }\n\n return next;\n },\n deps: [LOCALE_ID],\n provide: CONFIG_TOKEN,\n },\n ];\n\n const defaultLocale = config.defaultLocale ?? config.supportedLocales?.at(0);\n\n if (!defaultLocale) return providers;\n\n providers.push({\n provide: LOCALE_ID,\n useValue: defaultLocale,\n });\n\n return providers;\n}\n\nexport function injectIntlConfig() {\n return inject(CONFIG_TOKEN, { optional: true }) ?? undefined;\n}\n\nexport function injectDefaultLocale() {\n return injectIntlConfig()?.defaultLocale ?? inject(LOCALE_ID) ?? 'en-US';\n}\n\nexport function injectSupportedLocales() {\n return injectIntlConfig()?.supportedLocales ?? [injectDefaultLocale()];\n}\n\n/**\n * @internal\n * the actual locale signal used to store the current locale string\n */\nconst STORE_LOCALE = signal('en-US');\n\nexport function injectLocaleInternal() {\n try {\n return injectDynamicLocale();\n } catch {\n return STORE_LOCALE;\n }\n}\n\n@Injectable({\n providedIn: 'root',\n})\nexport class TranslationStore {\n private readonly cache = createIntlCache();\n private readonly config = injectIntlConfig();\n readonly loadQueue = signal<string[]>([]);\n readonly locale: WritableSignal<string>;\n private readonly defaultLocale = injectDefaultLocale();\n private readonly translations = signal<\n Record<string, Record<string, string>>\n >({\n [this.defaultLocale]: {},\n });\n private attemptedFallbackLoad = false;\n\n private readonly onDemandLoaders = new Map<\n string,\n Record<\n string,\n () => Promise<CompiledTranslation<UnknownStringKeyObject, string>>\n >\n >();\n\n private readonly nonMessageConfig = computed(() => ({\n ...this.config,\n locale: this.locale(),\n }));\n\n private readonly messages = computed(\n () =>\n this.translations()[this.locale()] ??\n this.translations()[this.defaultLocale] ??\n {},\n );\n\n readonly dynamicLocaleLoader = resource({\n params: computed(() => this.loadQueue().at(0) ?? null),\n loader: async ({ params: newLocale, abortSignal }) => {\n if (!newLocale) return;\n\n const currentTranslations = untracked(this.translations);\n\n const loadPromises: Promise<{\n namespace: string;\n flat: Record<string, string>;\n } | null>[] = [];\n\n for (const [namespace, loaders] of this.onDemandLoaders.entries()) {\n const loader = loaders[newLocale];\n if (loader) {\n const hasNamespaceForLocale =\n currentTranslations[newLocale] &&\n Object.keys(currentTranslations[newLocale]).some((key) =>\n key.startsWith(`${prependDelim(namespace, '').slice(0, -1)}`),\n );\n\n if (!hasNamespaceForLocale) {\n loadPromises.push(\n loader()\n .then((translation) => {\n if (abortSignal.aborted) return null;\n return {\n namespace: translation.namespace,\n flat: translation.flat,\n };\n })\n .catch((err) => {\n if (isDevMode()) {\n console.error(\n '[Translate] Failed to load',\n namespace,\n newLocale,\n err,\n );\n }\n\n return null;\n }),\n );\n }\n }\n }\n\n return Promise.all(loadPromises)\n .then((res) => res.filter((r) => r !== null))\n .then((res) => ({\n locales: res,\n locale: newLocale,\n }));\n },\n });\n\n readonly intl = computed(() =>\n createIntl(\n {\n ...this.nonMessageConfig(),\n messages: this.messages(),\n },\n this.cache,\n ),\n );\n\n constructor() {\n this.locale = STORE_LOCALE;\n this.locale.set(injectDefaultLocale());\n const paramName = this.config?.localeParamName;\n if (paramName) {\n const param = pathParam(paramName);\n\n effect(() => {\n const loc = param();\n if (\n !loc ||\n loc === untracked(this.locale) ||\n untracked(this.loadQueue).includes(loc)\n )\n return;\n if (this.hasLocaleLoaders(loc)) this.locale.set(loc);\n else this.loadQueue.update((q) => [...q, loc]);\n });\n }\n\n effect(() => {\n if (\n // should never be in error state, but best to check in case something throws\n this.dynamicLocaleLoader.error() ||\n this.dynamicLocaleLoader.isLoading()\n )\n return;\n const dynamicLocales = this.dynamicLocaleLoader.value();\n\n if (!dynamicLocales) return;\n\n // Register loaded translations\n for (const locale of dynamicLocales.locales) {\n this.register(locale.namespace, {\n [dynamicLocales.locale]: locale.flat,\n });\n }\n\n const hasTranslations =\n dynamicLocales.locales.length > 0 ||\n this.translations()[dynamicLocales.locale];\n\n if (hasTranslations) {\n this.loadQueue.update((q) =>\n q.filter((l) => l !== dynamicLocales.locale),\n );\n this.locale.set(dynamicLocales.locale);\n }\n });\n }\n\n formatMessage(key: string, values?: Record<string, string | number>) {\n const message =\n this.translations()[this.locale()]?.[key] ??\n this.translations()[this.defaultLocale]?.[key] ??\n '';\n\n if (!message) {\n if (this.attemptedFallbackLoad) return '';\n\n this.attemptedFallbackLoad = true;\n untracked(() => {\n if (!this.loadQueue().includes(this.defaultLocale))\n this.loadQueue.update((q) => [...q, this.defaultLocale]);\n });\n return '';\n }\n\n return this.intl().formatMessage(\n { id: key, defaultMessage: message },\n values,\n );\n }\n\n register(\n namespace: string,\n flat: Partial<Record<string, Record<string, string>>>,\n ) {\n this.translations.update((cur) => {\n return Object.entries(flat).reduce(\n (acc, [locale, translation]) => {\n const localeTranslation = acc[locale] ?? {};\n\n const withNS = Object.entries(translation ?? {}).reduce(\n (acc, [key, value]) => {\n acc[prependDelim(namespace, key)] = value;\n return acc;\n },\n {} as Record<string, string>,\n );\n\n acc[locale] = {\n ...localeTranslation,\n ...withNS,\n };\n\n return acc;\n },\n { ...cur },\n );\n });\n }\n\n registerOnDemandLoaders(\n namespace: string,\n loaders: Record<string, () => Promise<any>>,\n ) {\n this.onDemandLoaders.set(namespace, loaders);\n }\n\n hasLocaleLoaders(locale: string): boolean {\n return Array.from(this.onDemandLoaders.values()).some(\n (loaders) => loaders[locale],\n );\n }\n}\n\nexport function injectIntl() {\n return inject(TranslationStore).intl;\n}\n\n/**\n * Inject a dynamic locale signal that supports runtime language switching.\n *\n * @returns A writable signal with the current locale and loading state.\n * Only allows switching to locales that have registered loaders.\n *\n * @example\n * ```typescript\n * const locale = injectDynamicLocale();\n *\n * // Switch language (triggers automatic translation loading)\n * locale.set('sl-SI');\n *\n * // Check loading state\n * if (locale.isLoading()) {\n * // Show spinner\n * }\n * ```\n */\nexport function injectDynamicLocale(): WritableSignal<string> & {\n isLoading: Signal<boolean>;\n} {\n const store = inject(TranslationStore);\n const supportedLocales = injectIntlConfig()?.supportedLocales;\n\n const source = computed(() => store.locale()) as WritableSignal<string> & {\n isLoading: Signal<boolean>;\n };\n\n const inSupportedLocales =\n supportedLocales === undefined\n ? () => true\n : (locale: string) => supportedLocales.includes(locale);\n\n const set = (value: string) => {\n if (\n value === untracked(source) ||\n untracked(store.loadQueue).includes(value)\n )\n return;\n\n if (!inSupportedLocales(value)) {\n if (isDevMode())\n console.warn(\n `[Translate] Locale \"${value}\" is not in supportedLocales, switch prevented. Available options are:`,\n supportedLocales,\n );\n\n return;\n }\n\n if (isDevMode() && !store.hasLocaleLoaders(value))\n console.warn(\n `[Translate] No loaders registered for locale \"${value}\". Switching to this locale will have no effect.`,\n );\n\n store.loadQueue.update((q) => [...q, value]);\n };\n\n source.set = set;\n source.update = (updater: (value: string) => string) => {\n const next = updater(untracked(source));\n source.set(next);\n };\n source.asReadonly = () => source;\n\n source.isLoading = store.dynamicLocaleLoader.isLoading;\n\n return source;\n}\n","import { isSignal, type Signal } from '@angular/core';\n\nexport function unwrap<T>(value: T | Signal<T>): T {\n return isSignal(value) ? unwrap(value()) : value;\n}\n","import { type Signal } from '@angular/core';\nimport { injectLocaleInternal } from '../translation-store';\nimport { unwrap } from './unwrap';\n\nconst FORMAT_PRESETS: Record<string, Intl.DateTimeFormatOptions> = {\n short: { dateStyle: 'short', timeStyle: 'short' },\n medium: { dateStyle: 'medium', timeStyle: 'medium' },\n long: { dateStyle: 'long', timeStyle: 'long' },\n full: { dateStyle: 'full', timeStyle: 'full' },\n\n shortDate: { dateStyle: 'short' },\n mediumDate: { dateStyle: 'medium' },\n longDate: { dateStyle: 'long' },\n fullDate: { dateStyle: 'full' },\n\n shortTime: { timeStyle: 'short' },\n mediumTime: { timeStyle: 'medium' },\n longTime: { timeStyle: 'long' },\n fullTime: { timeStyle: 'full' },\n};\n\ntype DateFormat = keyof typeof FORMAT_PRESETS;\n\n/**\n * Supported date inputs\n */\nexport type SupportedDateInput = Date | string | number | null | undefined;\n\n/**\n * Options for formatting a date\n */\nexport type FormatDateOptions = {\n /**\n * Timezone to use for formatting\n */\n tz?: string;\n /**\n * Format to use for formatting\n * @default 'medium'\n */\n format?: DateFormat;\n /**\n * Locale to use for formatting, opts out to dynamic locale changes\n */\n locale?: string;\n};\n\nfunction validDateOrNull(\n date: Date | string | number | null | undefined,\n): Date | null {\n if (date == null) return null;\n\n const d = date instanceof Date ? date : new Date(date);\n return isNaN(d.getTime()) ? null : d;\n}\n\nconst cache = new Map<string, Intl.DateTimeFormat>();\n\nfunction getFormatter(\n locale: string,\n format: DateFormat,\n timeZone?: string,\n): Intl.DateTimeFormat {\n const cacheKey = `${locale}|${format}|${timeZone ?? ''}`;\n let formatter = cache.get(cacheKey);\n\n if (!formatter) {\n formatter = new Intl.DateTimeFormat(locale, {\n ...FORMAT_PRESETS[format],\n timeZone,\n });\n cache.set(cacheKey, formatter);\n }\n\n return formatter;\n}\n\n/**\n * Format a date using the current or provided locale & timezone\n * By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes\n *\n * @param date - Date to format\n * @param opt - Options for formatting\n * @returns Formatted date string\n */\nexport function formatDate(\n date: SupportedDateInput | Signal<SupportedDateInput>,\n opt?: FormatDateOptions | Signal<FormatDateOptions>,\n): string {\n const validDate = validDateOrNull(unwrap(date));\n if (validDate === null) return '';\n\n const unwrappedOpt = unwrap(opt);\n const loc = unwrappedOpt?.locale ?? injectLocaleInternal()();\n\n return getFormatter(\n loc,\n unwrappedOpt?.format ?? 'medium',\n unwrappedOpt?.tz,\n ).format(validDate);\n}\n","import { Signal } from '@angular/core';\nimport { injectLocaleInternal } from '../translation-store';\nimport { unwrap } from './unwrap';\n\nconst cache = new Map<string, Intl.DisplayNames>();\n\n/**\n * Options for formatting a display name\n */\nexport type FormatDisplayNameOptions = {\n /**\n * The display style for the result set\n */\n style: Intl.RelativeTimeFormatStyle;\n /**\n * Locale to use for formatting, opts out to dynamic locale changes\n */\n locale?: string;\n};\n\nfunction getFormatter(\n locale: string,\n type: Intl.DisplayNamesType,\n style: Intl.RelativeTimeFormatStyle,\n): Intl.DisplayNames {\n const cacheKey = `${locale}|${type}|${style}`;\n let formatter = cache.get(cacheKey);\n\n if (!formatter) {\n formatter = new Intl.DisplayNames(locale, {\n type,\n style,\n });\n cache.set(cacheKey, formatter);\n }\n\n return formatter;\n}\n\ntype SupportedCode = string | null | undefined;\n\n/**\n * Format a display name using the current or provided locale\n * By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes\n *\n * @param value - The code to format\n * @param type - The type of display name to format\n * @param opt - Options for formatting\n * @returns Formatted display name string\n */\nexport function formatDisplayName(\n value: SupportedCode | Signal<SupportedCode>,\n type: Intl.DisplayNamesType | Signal<Intl.DisplayNamesType>,\n opt?: FormatDisplayNameOptions | Signal<FormatDisplayNameOptions>,\n): string {\n const unwrapped = unwrap(value);\n if (!unwrapped?.trim()) return '';\n\n const unwrappedType = unwrap(type);\n const unwrappedOpt = unwrap(opt);\n\n const locale = unwrappedOpt?.locale ?? injectLocaleInternal()();\n\n return (\n getFormatter(locale, unwrappedType, unwrappedOpt?.style ?? 'long').of(\n unwrapped,\n ) ?? ''\n );\n}\n","import { type Signal } from '@angular/core';\nimport { injectLocaleInternal } from '../translation-store';\nimport { unwrap } from './unwrap';\n\ntype ListType = 'conjunction' | 'disjunction' | 'unit';\ntype ListStyle = 'long' | 'short' | 'narrow';\n\nexport type SupportedListInput = string[] | null | undefined;\n\nconst cache = new Map<string, Intl.ListFormat>();\n\n/**\n * Options for formatting a list\n */\nexport type FormatListOptions = {\n /**\n * The type of list to format\n */\n type?: ListType;\n /**\n * The style of list to format\n */\n style?: ListStyle;\n /**\n * Locale to use for formatting, opts out to dynamic locale changes\n */\n locale?: string;\n};\n\nconst EMPTY_ARRAY: string[] = [];\n\nfunction unwrapList(\n value: SupportedListInput | Signal<SupportedListInput>,\n): string[] {\n const unwrapped = unwrap(value);\n return Array.isArray(unwrapped) ? unwrapped : EMPTY_ARRAY;\n}\n\nfunction getFormatter(\n locale: string,\n type: ListType,\n style: ListStyle,\n): Intl.ListFormat {\n const cacheKey = `${locale}|${type}|${style}`;\n let formatter = cache.get(cacheKey);\n\n if (!formatter) {\n formatter = new Intl.ListFormat(locale, { type, style });\n cache.set(cacheKey, formatter);\n }\n\n return formatter;\n}\n\n/**\n * Format a list using the current or provided locale\n * By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes\n *\n * @param value - The list to format\n * @param opt - Options for formatting\n * @returns Formatted list string\n */\nexport function formatList(\n value: SupportedListInput | Signal<SupportedListInput>,\n opt?: FormatListOptions | Signal<FormatListOptions>,\n): string {\n const unwrapped = unwrapList(value);\n if (unwrapped.length === 0) return '';\n\n const unwrappedOpt = unwrap(opt);\n const loc = unwrappedOpt?.locale ?? injectLocaleInternal()();\n\n return getFormatter(\n loc,\n unwrappedOpt?.type ?? 'conjunction',\n unwrappedOpt?.style ?? 'long',\n ).format(unwrapped);\n}\n","import { type Signal } from '@angular/core';\nimport { injectLocaleInternal } from '../translation-store';\nimport { unwrap } from './unwrap';\n\ntype NumberNotation = 'standard' | 'scientific' | 'engineering' | 'compact';\n\ntype SupportedNumberValue = number | null | undefined;\n\nconst cache = new Map<string, Intl.NumberFormat>();\n\nfunction unwrapValue(\n value: SupportedNumberValue | Signal<SupportedNumberValue>,\n fallbackToZero: boolean = false,\n): number | null {\n const unwrapped = unwrap(value);\n\n if (unwrapped === null || unwrapped === undefined || isNaN(unwrapped))\n return fallbackToZero ? 0 : null;\n\n return unwrapped;\n}\n\n/**\n * Options for formatting a number\n */\nexport type FormatNumberOptions = {\n /**\n * The notation to use for formatting\n */\n notation?: NumberNotation;\n /**\n * Minimum number of fraction digits to use\n */\n minFractionDigits?: number;\n /**\n * Maximum number of fraction digits to use\n */\n maxFractionDigits?: number;\n /**\n * Whether to use grouping\n */\n useGrouping?: boolean;\n /**\n * Locale to use for formatting, opts out to dynamic locale changes\n */\n locale?: string;\n /**\n * If the number is not a valid number, return formatted 0. By default formatter returns an empty string\n * @default false\n */\n fallbackToZero?: boolean;\n};\n\nfunction getFormatter(\n locale: string,\n minFractionDigits: number,\n maxFractionDigits: number,\n useGrouping?: boolean,\n notation?: NumberNotation,\n currency?: string,\n display?: CurrencyDisplay,\n style?: 'currency' | 'percent',\n): Intl.NumberFormat {\n const cacheKey = `${locale}|${notation ?? 'standard'}|${minFractionDigits}|${maxFractionDigits}|${useGrouping ?? true}|${currency ?? 'none'}|${display ?? 'none'}|${style ?? 'decimal'}`;\n let formatter = cache.get(cacheKey);\n\n if (!formatter) {\n formatter = new Intl.NumberFormat(locale, {\n style,\n notation,\n minimumFractionDigits: minFractionDigits,\n maximumFractionDigits: maxFractionDigits,\n useGrouping,\n });\n cache.set(cacheKey, formatter);\n }\n\n return formatter;\n}\n\n/**\n * Format a number using the current or provided locale\n * By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes\n *\n * @param number - Number to format\n * @param opt - Options for formatting\n * @returns Formatted number string\n */\nexport function formatNumber(\n value: SupportedNumberValue | Signal<SupportedNumberValue>,\n opt?: FormatNumberOptions | Signal<FormatNumberOptions>,\n): string {\n const unwrappedOpt = unwrap(opt);\n const unwrappedNumber = unwrapValue(value, unwrappedOpt?.fallbackToZero);\n\n if (unwrappedNumber === null) return '';\n\n const loc = unwrappedOpt?.locale ?? injectLocaleInternal()();\n\n return getFormatter(\n loc,\n unwrappedOpt?.minFractionDigits ?? 0,\n unwrappedOpt?.maxFractionDigits ?? 0,\n unwrappedOpt?.useGrouping ?? true,\n unwrappedOpt?.notation ?? 'standard',\n ).format(unwrappedNumber);\n}\n\n/**\n * Options for formatting a percentage value\n */\nexport type FormatPercentOptions = {\n /**\n * Minimum number of fraction digits to use\n */\n minFractionDigits?: number;\n /**\n * Maximum number of fraction digits to use\n */\n maxFractionDigits?: number;\n /**\n * Locale to use for formatting, opts out to dynamic locale changes\n */\n locale?: string;\n /**\n * If the number is not a valid number, return formatted 0. By default formatter returns an empty string\n * @default false\n */\n fallbackToZero?: boolean;\n};\n\n/**\n * Format a percentage using the current or provided locale\n * By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes\n *\n * @param number - Number to format\n * @param opt - Options for formatting\n * @returns Formatted percentage string\n */\nexport function formatPercent(\n value: SupportedNumberValue | Signal<SupportedNumberValue>,\n opt?: FormatPercentOptions | Signal<FormatPercentOptions>,\n): string {\n const unwrappedOpt = unwrap(opt);\n\n let unwrappedNumber = unwrapValue(value, unwrappedOpt?.fallbackToZero);\n\n if (unwrappedNumber === null) return '';\n\n const loc = unwrappedOpt?.locale ?? injectLocaleInternal()();\n\n return getFormatter(\n loc,\n unwrappedOpt?.minFractionDigits ?? 0,\n unwrappedOpt?.maxFractionDigits ?? 0,\n undefined,\n undefined,\n undefined,\n undefined,\n 'percent',\n ).format(unwrappedNumber);\n}\n\ntype CurrencyDisplay = 'symbol' | 'narrowSymbol' | 'code' | 'name';\n\n/**\n * Options for formatting a currency\n */\nexport type FormatCurrencyOptions = {\n /*\n * The display type for the currency format\n */\n display?: CurrencyDisplay;\n /**\n * Locale to use for formatting, opts out to dynamic locale changes\n */\n locale?: string;\n /**\n * If the number is not a valid number, return formatted 0. By default formatter returns an empty string\n * @default false\n */\n fallbackToZero?: boolean;\n};\n\nexport function formatCurrency(\n value: SupportedNumberValue | Signal<SupportedNumberValue>,\n currency: string | Signal<string>,\n opt?: FormatCurrencyOptions | Signal<FormatCurrencyOptions>,\n): string {\n const unwrappedOpt = unwrap(opt);\n const unwrappedValue = unwrapValue(value, unwrappedOpt?.fallbackToZero);\n\n if (unwrappedValue === null) return '';\n\n const loc = unwrappedOpt?.locale ?? injectLocaleInternal()();\n\n return getFormatter(\n loc,\n 0,\n 0,\n undefined,\n undefined,\n unwrap(currency),\n unwrappedOpt?.display ?? 'symbol',\n 'currency',\n ).format(unwrappedValue);\n}\n","import { type Signal } from '@angular/core';\nimport { injectLocaleInternal } from '../translation-store';\nimport { unwrap } from './unwrap';\n\nconst cache = new Map<string, Intl.RelativeTimeFormat>();\n\n/**\n * Options for formatting a relative time value\n */\nexport type FormatRelativeTimeOptions = {\n /**\n * The length of the internationalized message.\n * @default 'long'\n */\n style?: Intl.RelativeTimeFormatStyle;\n /**\n * Controls whether to use numeric values in the output.\n * @default 'always'\n */\n numeric?: Intl.RelativeTimeFormatNumeric;\n /**\n * Locale to use for formatting, opts out to dynamic locale changes\n */\n locale?: string;\n};\n\nfunction getFormatter(\n locale: string,\n style: Intl.RelativeTimeFormatStyle,\n numeric: Intl.RelativeTimeFormatNumeric,\n): Intl.RelativeTimeFormat {\n const cacheKey = `${locale}|${style}|${numeric}`;\n let formatter = cache.get(cacheKey);\n\n if (!formatter) {\n formatter = new Intl.RelativeTimeFormat(locale, { style, numeric });\n cache.set(cacheKey, formatter);\n }\n\n return formatter;\n}\n\nexport type RelativeTimeUnit = Intl.RelativeTimeFormatUnit;\n\ntype SupportedRelativeTimeInput = number | null | undefined;\n\n/**\n * Format a relative time using the current or provided locale\n * By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes\n *\n * @param value - The numeric value to use in the relative time internationalization message\n * @param unit - The unit to use in the relative time internationalization message\n * @param opt - Options for formatting\n * @returns Formatted relative time string\n */\nexport function formatRelativeTime(\n value: SupportedRelativeTimeInput | Signal<SupportedRelativeTimeInput>,\n unit: RelativeTimeUnit | Signal<RelativeTimeUnit>,\n opt?: FormatRelativeTimeOptions | Signal<FormatRelativeTimeOptions>,\n): string {\n const unwrappedValue = unwrap(value);\n if (\n unwrappedValue === null ||\n unwrappedValue === undefined ||\n isNaN(unwrappedValue)\n )\n return '';\n\n const unwrappedUnit = unwrap(unit);\n if (!unwrappedUnit) return '';\n\n const unwrappedOpt = unwrap(opt);\n const loc = unwrappedOpt?.locale ?? injectLocaleInternal()();\n\n return getFormatter(\n loc,\n unwrappedOpt?.style ?? 'long',\n unwrappedOpt?.numeric ?? 'always',\n ).format(unwrappedValue, unwrappedUnit);\n}\n","import { inject, untracked } from '@angular/core';\nimport { ActivatedRouteSnapshot, Router } from '@angular/router';\nimport { injectIntlConfig, TranslationStore } from './translation-store';\n\nexport function injectResolveParamLocale(snapshot: ActivatedRouteSnapshot) {\n let locale: string | null = null;\n\n const paramName = injectIntlConfig()?.localeParamName;\n\n const routerConfig = inject(Router)['options'];\n\n const alwaysInheritParams =\n typeof routerConfig === 'object' &&\n !!routerConfig &&\n routerConfig.paramsInheritanceStrategy === 'always';\n\n if (paramName) {\n locale = snapshot.paramMap.get(paramName);\n\n if (!locale && !alwaysInheritParams) {\n let currentRoute: ActivatedRouteSnapshot | null = snapshot;\n while (currentRoute && !locale) {\n locale = currentRoute.paramMap.get('locale');\n currentRoute = currentRoute.parent;\n }\n }\n }\n\n if (!locale) {\n locale = untracked(inject(TranslationStore).locale);\n }\n\n return locale;\n}\n","import {\n computed,\n inject,\n isDevMode,\n isSignal,\n untracked,\n type Signal,\n} from '@angular/core';\nimport { ResolveFn } from '@angular/router';\nimport {\n compileTranslation,\n type CompiledTranslation,\n type inferCompiledTranslationMap,\n type inferCompiledTranslationNamespace,\n} from './compile';\nimport { replaceWithDelim } from './delim';\nimport { injectResolveParamLocale } from './resovler-locale';\nimport { type UnknownStringKeyObject } from './string-key-object.type';\nimport {\n injectDefaultLocale,\n injectIntlConfig,\n TranslationStore,\n} from './translation-store';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyStringRecord = Record<string, any>;\n\nfunction createEqualsRecord<T extends AnyStringRecord>(keys: (keyof T)[] = []) {\n let keyMatcher: (a: T, b: T) => boolean;\n\n if (keys.length === 0) {\n keyMatcher = () => true;\n } else if (keys.length === 1) {\n const key = keys[0];\n keyMatcher = (a, b) => a[key] === b[key];\n } else {\n keyMatcher = (a, b) => {\n return keys.every((k) => a[k] === b[k]);\n };\n }\n\n return (a?: T, b?: T): boolean => {\n if (!a && !b) return true;\n if (!a || !b) return false;\n return keyMatcher(a, b);\n };\n}\n\ntype TFunction<TMap extends AnyStringRecord> = <\n TKey extends keyof TMap & string,\n>(\n key: TKey,\n ...args: TMap[TKey] extends void ? [] : [TMap[TKey]]\n) => string;\n\ntype SignalTFunction<TMap extends AnyStringRecord> = <\n TKey extends keyof TMap & string,\n>(\n key: TKey,\n ...args: TMap[TKey] extends void ? [] : [() => TMap[TKey]]\n) => Signal<string>;\n\ntype TFunctionWithSignalConstructor<\n TMap extends AnyStringRecord,\n TFN extends TFunction<TMap>,\n> = TFN & {\n asSignal: SignalTFunction<TMap>;\n};\n\nfunction addSignalFn<TMap extends AnyStringRecord, TFn extends TFunction<TMap>>(\n fn: TFn,\n store: TranslationStore,\n): TFunctionWithSignalConstructor<TMap, TFn> {\n const withSig = fn as TFunctionWithSignalConstructor<TMap, TFn>;\n\n const asSignal = <TKey extends keyof TMap & string>(\n key: TKey,\n ...args: TMap[TKey] extends void ? [] : [() => TMap[TKey]]\n ): Signal<string> => {\n const variables = args[0] as () => AnyStringRecord | undefined;\n const stringKey = key as string;\n\n const flatPath = replaceWithDelim(stringKey);\n\n const varsFn = variables ?? (() => undefined);\n const varsSignal = isSignal(varsFn)\n ? varsFn\n : computed(varsFn, {\n equal: createEqualsRecord(Object.keys(varsFn() ?? {})),\n });\n\n return computed(() => store.formatMessage(flatPath, varsSignal()));\n };\n\n withSig.asSignal = asSignal;\n\n return withSig;\n}\n\nexport function createT<TMap extends AnyStringRecord>(\n store: TranslationStore,\n): TFunction<TMap> {\n return <TKey extends keyof TMap & string>(\n key: TKey,\n ...args: TMap[TKey] extends void ? [] : [TMap[TKey]]\n ): string => {\n const variables = args[0] as AnyStringRecord | undefined;\n const stringKey = key as string;\n\n return store.formatMessage(replaceWithDelim(stringKey), variables);\n };\n}\n\nexport function registerNamespace<\n TDefault extends CompiledTranslation<UnknownStringKeyObject, string>,\n>(\n defaultTranslation: () => Promise<TDefault>,\n other: Record<\n string,\n () => Promise<\n CompiledTranslation<\n UnknownStringKeyObject,\n inferCompiledTranslationNamespace<TDefault>,\n string\n >\n >\n >,\n) {\n type $Map = inferCompiledTranslationMap<TDefault>;\n type $BaseTFN = TFunction<$Map>;\n type $TFN = TFunctionWithSignalConstructor<$Map, $BaseTFN>;\n\n const injectT = (): $TFN => {\n const store = inject(TranslationStore);\n\n return addSignalFn(createT(store), store);\n };\n\n let defaultTranslationLoaded = false;\n const resolver: ResolveFn<void> = async (snapshot) => {\n const store = inject(TranslationStore);\n\n const locale = injectResolveParamLocale(snapshot);\n\n const defaultLocale = injectDefaultLocale();\n const shouldPreloadDefault =\n injectIntlConfig()?.preloadDefaultLocale ?? false;\n\n const tPromise = other[locale] as (typeof other)[string] | undefined;\n\n const promise = tPromise ?? defaultTranslation;\n if (!promise && isDevMode()) {\n return console.warn(`No translation found for locale: ${locale}`);\n }\n\n if (promise === defaultTranslation && defaultTranslationLoaded) return;\n\n try {\n const promises = [promise()];\n\n if (\n shouldPreloadDefault &&\n !defaultTranslationLoaded &&\n promise !== defaultTranslation\n )\n promises.push(defaultTranslation());\n\n const translations = await Promise.allSettled(promises);\n\n const fullfilled = translations.map((t) =>\n t.status === 'fulfilled' ? t.value : null,\n );\n\n if (fullfilled.at(0) === null && fullfilled.at(1) === null)\n throw new Error('Failed to load translations');\n\n const [t, defaultT] = fullfilled;\n\n const ns = t?.namespace ?? defaultT?.namespace;\n if (!ns) throw new Error('No namespace found in translation');\n\n if (isDevMode() && t && t.locale !== locale && t.locale)\n console.warn(`Expected locale to be ${locale} but got ${t.locale}`);\n\n store.registerOnDemandLoaders(ns, {\n ...other,\n [defaultLocale]: defaultTranslation,\n });\n\n const toRegister: Record<string, Record<string, string>> = {};\n if (t) toRegister[locale] = t.flat;\n if (defaultT) toRegister[defaultLocale] = defaultT.flat;\n\n store.register(ns, toRegister);\n\n if (promise === defaultTranslation || defaultT)\n defaultTranslationLoaded = true;\n } catch {\n if (isDevMode()) {\n console.warn(`Failed to load translation for locale: ${locale}`);\n }\n } finally {\n if (locale !== untracked(store.locale)) store.locale.set(locale);\n }\n };\n\n return {\n injectNamespaceT: injectT,\n resolveNamespaceTranslation: resolver,\n };\n}\n\ntype UntypedTFunction<TNS extends string> = {\n (key: `${TNS}.${string}`, args?: Record<string, string>): string;\n asSignal: (\n key: `${TNS}.${string}`,\n args?: () => Record<string, string>,\n ) => Signal<string>;\n};\n\n/**\n * Registers a type-unsafe namespace, meant for remote loading of unknown key-value pairs using mmstack/translate infrastructure\n * The resolver & t function work the same as they would with typed namespaces, but without type safety\n */\nexport function registerRemoteNamespace<TNS extends string>(\n ns: TNS,\n defaultTranslation: () => Promise<Record<string, string>>,\n other: Record<string, () => Promise<Record<string, string>>>,\n) {\n const injectT = (): UntypedTFunction<TNS> => {\n const store = inject(TranslationStore);\n\n return addSignalFn(createT(store), store) as UntypedTFunction<TNS>;\n };\n\n let defaultTranslationLoaded = false;\n const resolver: ResolveFn<void> = async (snapshot) => {\n const store = inject(TranslationStore);\n\n const locale = injectResolveParamLocale(snapshot);\n\n const defaultLocale = injectDefaultLocale();\n const shouldPreloadDefault =\n injectIntlConfig()?.preloadDefaultLocale ?? false;\n\n const tPromise = other[locale] as (typeof other)[string] | undefined;\n\n const promise = tPromise ?? defaultTranslation;\n\n if (!promise && isDevMode()) {\n return console.warn(`No translation found for locale: ${locale}`);\n }\n\n if (promise === defaultTranslation && defaultTranslationLoaded) return;\n\n try {\n const promises = [promise()];\n\n if (\n shouldPreloadDefault &&\n !defaultTranslationLoaded &&\n promise !== defaultTranslation\n )\n promises.push(defaultTranslation());\n\n const translations = await Promise.allSettled(promises);\n\n const fullfilled = translations.map((t) =>\n t.status === 'fulfilled' ? t.value : null,\n );\n\n if (fullfilled.at(0) === null && fullfilled.at(1) === null)\n throw new Error('Failed to load translations');\n\n const [baseT, baseDefaultT] = fullfilled;\n\n const t = baseT ? compileTranslation(baseT, ns, locale) : null;\n const defaultT = baseDefaultT\n ? compileTranslation(baseDefaultT, ns, defaultLocale)\n : null;\n\n if (isDevMode() && t && t.locale !== locale && t.locale)\n console.warn(`Expected locale to be ${locale} but got ${t.locale}`);\n\n store.registerOnDemandLoaders(ns, {\n ...other,\n [defaultLocale]: defaultTranslation,\n });\n\n const toRegister: Record<string, Record<string, string>> = {};\n if (t) toRegister[locale] = t.flat;\n if (defaultT) toRegister[defaultLocale] = defaultT.flat;\n\n store.register(ns, toRegister);\n\n if (promise === defaultTranslation || defaultT)\n defaultTranslationLoaded = true;\n } catch {\n if (isDevMode()) {\n console.warn(`Failed to load translation for locale: ${locale}`);\n }\n } finally {\n if (locale !== untracked(store.locale)) store.locale.set(locale);\n }\n };\n\n return {\n injectNamespaceT: injectT,\n resolveNamespaceTranslation: resolver,\n };\n}\n","import { inject } from '@angular/core';\nimport {\n Router,\n type CanMatchFn,\n type Route,\n type UrlSegment,\n} from '@angular/router';\nimport {\n injectDefaultLocale,\n injectSupportedLocales,\n} from './translation-store';\n\n/**\n * Guard that validates the locale parameter against supported locales.\n * Redirects to default locale if the locale is invalid.\n *\n * @param prefixSegments Optional array of path segments preceding the locale segment.\n * if (you wanted to match /app/:locale/... you would pass ['app'] here) & the function would match the second parameter + redirect accordingly\n *\n * @example\n * ```typescript\n * {\n * path: ':locale',\n * canMatch: [canMatchLocale()],\n * children: [...]\n * }\n * ```\n */\nexport function canMatchLocale(prefixSegments: string[] = []): CanMatchFn {\n return (_route: Route, segments: UrlSegment[]) => {\n const supportedLocales = injectSupportedLocales();\n\n const locale = segments.at(prefixSegments.length)?.path;\n\n if (!locale || !supportedLocales.includes(locale))\n return inject(Router).createUrlTree([\n ...prefixSegments,\n injectDefaultLocale(),\n ]);\n\n return true;\n };\n}\n","import {\n afterRenderEffect,\n computed,\n Directive,\n ElementRef,\n inject,\n input,\n Renderer2,\n} from '@angular/core';\nimport {\n type CompiledTranslation,\n type inferCompiledTranslationMap,\n} from './compile';\nimport { createT } from './register-namespace';\nimport { type UnknownStringKeyObject } from './string-key-object.type';\nimport { TranslationStore } from './translation-store';\n\n@Directive()\nexport abstract class Translate<\n TInput extends string,\n T extends CompiledTranslation<UnknownStringKeyObject, string>,\n TMap extends inferCompiledTranslationMap<T> = inferCompiledTranslationMap<T>,\n TKey extends TInput & keyof TMap & string = TInput & keyof TMap & string,\n> {\n private readonly t = createT(inject(TranslationStore));\n\n readonly translate =\n input.required<\n TMap[TKey] extends void\n ? TKey | [key: TKey]\n : [key: TKey, vars: TMap[TKey]]\n >();\n\n constructor() {\n const key = computed(() => {\n const vars = this.translate();\n return (Array.isArray(vars) ? vars[0] : vars) as TKey;\n });\n\n const args = computed(\n () => {\n const vars = this.translate();\n return (Array.isArray(vars) ? vars[1] : undefined) as TMap[TKey];\n },\n {\n equal: (a, b) => {\n if (a === undefined && b === undefined) return true;\n if (a === undefined || b === undefined) return false;\n\n const aObj = a as Record<string, string>;\n const keys = Object.keys(aObj);\n const bObj = b as Record<string, string>;\n\n if (!keys.length) return !Object.keys(bObj).length;\n\n return keys.every((key) => aObj[key] === bObj[key]);\n },\n },\n );\n\n const translation = computed(() => this.t(key(), args()));\n\n const renderer = inject(Renderer2);\n const el = inject<ElementRef<HTMLElement>>(ElementRef);\n\n afterRenderEffect({\n write: () => {\n renderer.setProperty(el.nativeElement, 'textContent', translation());\n },\n });\n }\n}\n","import { ChangeDetectorRef, effect, inject } from '@angular/core';\nimport { CompiledTranslation, inferCompiledTranslationMap } from './compile';\nimport { createT } from './register-namespace';\nimport { UnknownStringKeyObject } from './string-key-object.type';\nimport { TranslationStore } from './translation-store';\n\nexport abstract class Translator<\n T extends CompiledTranslation<UnknownStringKeyObject, string>,\n TMap extends inferCompiledTranslationMap<T> = inferCompiledTranslationMap<T>,\n> {\n private readonly store = inject(TranslationStore);\n private readonly t = createT<TMap>(this.store);\n\n constructor() {\n const cdr = inject(ChangeDetectorRef);\n\n effect(() => {\n this.store.locale();\n cdr.markForCheck();\n });\n }\n\n transform<K extends keyof TMap & string>(\n key: K,\n ...args: TMap[K] extends void\n ? [locale?: string]\n : [TMap[K], locale?: string]\n ): string {\n const actualArgs = args.filter(\n (a) => typeof a === 'object',\n ) as TMap[K] extends void ? [] : [TMap[K]];\n\n return this.t(key, ...actualArgs);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["cache","getFormatter"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
import { ResolveFn, CanMatchFn } from '@angular/router';
|
|
2
|
+
import { Signal, WritableSignal, Provider } from '@angular/core';
|
|
3
|
+
import { ResolveFn, ActivatedRouteSnapshot, CanMatchFn } from '@angular/router';
|
|
4
4
|
import * as _formatjs_intl from '@formatjs/intl';
|
|
5
5
|
import { IntlConfig } from '@formatjs/intl';
|
|
6
6
|
|
|
@@ -65,6 +65,217 @@ type TranslationNamespace<TNS extends string, T extends CompiledTranslation<Unkn
|
|
|
65
65
|
};
|
|
66
66
|
declare function createNamespace<const T extends UnknownStringKeyObject, TNS extends string>(ns: TNS, translation: T): TranslationNamespace<TNS, CompiledTranslation<T, TNS, string>, inferTranslationShape<T>>;
|
|
67
67
|
|
|
68
|
+
declare const FORMAT_PRESETS: Record<string, Intl.DateTimeFormatOptions>;
|
|
69
|
+
type DateFormat = keyof typeof FORMAT_PRESETS;
|
|
70
|
+
/**
|
|
71
|
+
* Supported date inputs
|
|
72
|
+
*/
|
|
73
|
+
type SupportedDateInput = Date | string | number | null | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* Options for formatting a date
|
|
76
|
+
*/
|
|
77
|
+
type FormatDateOptions = {
|
|
78
|
+
/**
|
|
79
|
+
* Timezone to use for formatting
|
|
80
|
+
*/
|
|
81
|
+
tz?: string;
|
|
82
|
+
/**
|
|
83
|
+
* Format to use for formatting
|
|
84
|
+
* @default 'medium'
|
|
85
|
+
*/
|
|
86
|
+
format?: DateFormat;
|
|
87
|
+
/**
|
|
88
|
+
* Locale to use for formatting, opts out to dynamic locale changes
|
|
89
|
+
*/
|
|
90
|
+
locale?: string;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Format a date using the current or provided locale & timezone
|
|
94
|
+
* By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes
|
|
95
|
+
*
|
|
96
|
+
* @param date - Date to format
|
|
97
|
+
* @param opt - Options for formatting
|
|
98
|
+
* @returns Formatted date string
|
|
99
|
+
*/
|
|
100
|
+
declare function formatDate(date: SupportedDateInput | Signal<SupportedDateInput>, opt?: FormatDateOptions | Signal<FormatDateOptions>): string;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Options for formatting a display name
|
|
104
|
+
*/
|
|
105
|
+
type FormatDisplayNameOptions = {
|
|
106
|
+
/**
|
|
107
|
+
* The display style for the result set
|
|
108
|
+
*/
|
|
109
|
+
style: Intl.RelativeTimeFormatStyle;
|
|
110
|
+
/**
|
|
111
|
+
* Locale to use for formatting, opts out to dynamic locale changes
|
|
112
|
+
*/
|
|
113
|
+
locale?: string;
|
|
114
|
+
};
|
|
115
|
+
type SupportedCode = string | null | undefined;
|
|
116
|
+
/**
|
|
117
|
+
* Format a display name using the current or provided locale
|
|
118
|
+
* By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes
|
|
119
|
+
*
|
|
120
|
+
* @param value - The code to format
|
|
121
|
+
* @param type - The type of display name to format
|
|
122
|
+
* @param opt - Options for formatting
|
|
123
|
+
* @returns Formatted display name string
|
|
124
|
+
*/
|
|
125
|
+
declare function formatDisplayName(value: SupportedCode | Signal<SupportedCode>, type: Intl.DisplayNamesType | Signal<Intl.DisplayNamesType>, opt?: FormatDisplayNameOptions | Signal<FormatDisplayNameOptions>): string;
|
|
126
|
+
|
|
127
|
+
type ListType = 'conjunction' | 'disjunction' | 'unit';
|
|
128
|
+
type ListStyle = 'long' | 'short' | 'narrow';
|
|
129
|
+
type SupportedListInput = string[] | null | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* Options for formatting a list
|
|
132
|
+
*/
|
|
133
|
+
type FormatListOptions = {
|
|
134
|
+
/**
|
|
135
|
+
* The type of list to format
|
|
136
|
+
*/
|
|
137
|
+
type?: ListType;
|
|
138
|
+
/**
|
|
139
|
+
* The style of list to format
|
|
140
|
+
*/
|
|
141
|
+
style?: ListStyle;
|
|
142
|
+
/**
|
|
143
|
+
* Locale to use for formatting, opts out to dynamic locale changes
|
|
144
|
+
*/
|
|
145
|
+
locale?: string;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Format a list using the current or provided locale
|
|
149
|
+
* By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes
|
|
150
|
+
*
|
|
151
|
+
* @param value - The list to format
|
|
152
|
+
* @param opt - Options for formatting
|
|
153
|
+
* @returns Formatted list string
|
|
154
|
+
*/
|
|
155
|
+
declare function formatList(value: SupportedListInput | Signal<SupportedListInput>, opt?: FormatListOptions | Signal<FormatListOptions>): string;
|
|
156
|
+
|
|
157
|
+
type NumberNotation = 'standard' | 'scientific' | 'engineering' | 'compact';
|
|
158
|
+
type SupportedNumberValue = number | null | undefined;
|
|
159
|
+
/**
|
|
160
|
+
* Options for formatting a number
|
|
161
|
+
*/
|
|
162
|
+
type FormatNumberOptions = {
|
|
163
|
+
/**
|
|
164
|
+
* The notation to use for formatting
|
|
165
|
+
*/
|
|
166
|
+
notation?: NumberNotation;
|
|
167
|
+
/**
|
|
168
|
+
* Minimum number of fraction digits to use
|
|
169
|
+
*/
|
|
170
|
+
minFractionDigits?: number;
|
|
171
|
+
/**
|
|
172
|
+
* Maximum number of fraction digits to use
|
|
173
|
+
*/
|
|
174
|
+
maxFractionDigits?: number;
|
|
175
|
+
/**
|
|
176
|
+
* Whether to use grouping
|
|
177
|
+
*/
|
|
178
|
+
useGrouping?: boolean;
|
|
179
|
+
/**
|
|
180
|
+
* Locale to use for formatting, opts out to dynamic locale changes
|
|
181
|
+
*/
|
|
182
|
+
locale?: string;
|
|
183
|
+
/**
|
|
184
|
+
* If the number is not a valid number, return formatted 0. By default formatter returns an empty string
|
|
185
|
+
* @default false
|
|
186
|
+
*/
|
|
187
|
+
fallbackToZero?: boolean;
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* Format a number using the current or provided locale
|
|
191
|
+
* By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes
|
|
192
|
+
*
|
|
193
|
+
* @param number - Number to format
|
|
194
|
+
* @param opt - Options for formatting
|
|
195
|
+
* @returns Formatted number string
|
|
196
|
+
*/
|
|
197
|
+
declare function formatNumber(value: SupportedNumberValue | Signal<SupportedNumberValue>, opt?: FormatNumberOptions | Signal<FormatNumberOptions>): string;
|
|
198
|
+
/**
|
|
199
|
+
* Options for formatting a percentage value
|
|
200
|
+
*/
|
|
201
|
+
type FormatPercentOptions = {
|
|
202
|
+
/**
|
|
203
|
+
* Minimum number of fraction digits to use
|
|
204
|
+
*/
|
|
205
|
+
minFractionDigits?: number;
|
|
206
|
+
/**
|
|
207
|
+
* Maximum number of fraction digits to use
|
|
208
|
+
*/
|
|
209
|
+
maxFractionDigits?: number;
|
|
210
|
+
/**
|
|
211
|
+
* Locale to use for formatting, opts out to dynamic locale changes
|
|
212
|
+
*/
|
|
213
|
+
locale?: string;
|
|
214
|
+
/**
|
|
215
|
+
* If the number is not a valid number, return formatted 0. By default formatter returns an empty string
|
|
216
|
+
* @default false
|
|
217
|
+
*/
|
|
218
|
+
fallbackToZero?: boolean;
|
|
219
|
+
};
|
|
220
|
+
/**
|
|
221
|
+
* Format a percentage using the current or provided locale
|
|
222
|
+
* By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes
|
|
223
|
+
*
|
|
224
|
+
* @param number - Number to format
|
|
225
|
+
* @param opt - Options for formatting
|
|
226
|
+
* @returns Formatted percentage string
|
|
227
|
+
*/
|
|
228
|
+
declare function formatPercent(value: SupportedNumberValue | Signal<SupportedNumberValue>, opt?: FormatPercentOptions | Signal<FormatPercentOptions>): string;
|
|
229
|
+
type CurrencyDisplay = 'symbol' | 'narrowSymbol' | 'code' | 'name';
|
|
230
|
+
/**
|
|
231
|
+
* Options for formatting a currency
|
|
232
|
+
*/
|
|
233
|
+
type FormatCurrencyOptions = {
|
|
234
|
+
display?: CurrencyDisplay;
|
|
235
|
+
/**
|
|
236
|
+
* Locale to use for formatting, opts out to dynamic locale changes
|
|
237
|
+
*/
|
|
238
|
+
locale?: string;
|
|
239
|
+
/**
|
|
240
|
+
* If the number is not a valid number, return formatted 0. By default formatter returns an empty string
|
|
241
|
+
* @default false
|
|
242
|
+
*/
|
|
243
|
+
fallbackToZero?: boolean;
|
|
244
|
+
};
|
|
245
|
+
declare function formatCurrency(value: SupportedNumberValue | Signal<SupportedNumberValue>, currency: string | Signal<string>, opt?: FormatCurrencyOptions | Signal<FormatCurrencyOptions>): string;
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Options for formatting a relative time value
|
|
249
|
+
*/
|
|
250
|
+
type FormatRelativeTimeOptions = {
|
|
251
|
+
/**
|
|
252
|
+
* The length of the internationalized message.
|
|
253
|
+
* @default 'long'
|
|
254
|
+
*/
|
|
255
|
+
style?: Intl.RelativeTimeFormatStyle;
|
|
256
|
+
/**
|
|
257
|
+
* Controls whether to use numeric values in the output.
|
|
258
|
+
* @default 'always'
|
|
259
|
+
*/
|
|
260
|
+
numeric?: Intl.RelativeTimeFormatNumeric;
|
|
261
|
+
/**
|
|
262
|
+
* Locale to use for formatting, opts out to dynamic locale changes
|
|
263
|
+
*/
|
|
264
|
+
locale?: string;
|
|
265
|
+
};
|
|
266
|
+
type RelativeTimeUnit = Intl.RelativeTimeFormatUnit;
|
|
267
|
+
type SupportedRelativeTimeInput = number | null | undefined;
|
|
268
|
+
/**
|
|
269
|
+
* Format a relative time using the current or provided locale
|
|
270
|
+
* By default it is reactive to the global dynamic locale, works best when wrapped in a computed() if you need to react to locale changes
|
|
271
|
+
*
|
|
272
|
+
* @param value - The numeric value to use in the relative time internationalization message
|
|
273
|
+
* @param unit - The unit to use in the relative time internationalization message
|
|
274
|
+
* @param opt - Options for formatting
|
|
275
|
+
* @returns Formatted relative time string
|
|
276
|
+
*/
|
|
277
|
+
declare function formatRelativeTime(value: SupportedRelativeTimeInput | Signal<SupportedRelativeTimeInput>, unit: RelativeTimeUnit | Signal<RelativeTimeUnit>, opt?: FormatRelativeTimeOptions | Signal<FormatRelativeTimeOptions>): string;
|
|
278
|
+
|
|
68
279
|
declare function provideIntlConfig(config: Omit<IntlConfig, 'locale' | 'messages'> & {
|
|
69
280
|
/** Checks next locale is in provided array before switching locales */
|
|
70
281
|
supportedLocales?: string[];
|
|
@@ -108,6 +319,20 @@ declare function registerNamespace<TDefault extends CompiledTranslation<UnknownS
|
|
|
108
319
|
injectNamespaceT: () => TFunctionWithSignalConstructor<inferCompiledTranslationMap<TDefault>, TFunction<inferCompiledTranslationMap<TDefault>>>;
|
|
109
320
|
resolveNamespaceTranslation: ResolveFn<void>;
|
|
110
321
|
};
|
|
322
|
+
type UntypedTFunction<TNS extends string> = {
|
|
323
|
+
(key: `${TNS}.${string}`, args?: Record<string, string>): string;
|
|
324
|
+
asSignal: (key: `${TNS}.${string}`, args?: () => Record<string, string>) => Signal<string>;
|
|
325
|
+
};
|
|
326
|
+
/**
|
|
327
|
+
* Registers a type-unsafe namespace, meant for remote loading of unknown key-value pairs using mmstack/translate infrastructure
|
|
328
|
+
* The resolver & t function work the same as they would with typed namespaces, but without type safety
|
|
329
|
+
*/
|
|
330
|
+
declare function registerRemoteNamespace<TNS extends string>(ns: TNS, defaultTranslation: () => Promise<Record<string, string>>, other: Record<string, () => Promise<Record<string, string>>>): {
|
|
331
|
+
injectNamespaceT: () => UntypedTFunction<TNS>;
|
|
332
|
+
resolveNamespaceTranslation: ResolveFn<void>;
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
declare function injectResolveParamLocale(snapshot: ActivatedRouteSnapshot): string;
|
|
111
336
|
|
|
112
337
|
/**
|
|
113
338
|
* Guard that validates the locale parameter against supported locales.
|
|
@@ -142,5 +367,5 @@ declare abstract class Translator<T extends CompiledTranslation<UnknownStringKey
|
|
|
142
367
|
transform<K extends keyof TMap & string>(key: K, ...args: TMap[K] extends void ? [locale?: string] : [TMap[K], locale?: string]): string;
|
|
143
368
|
}
|
|
144
369
|
|
|
145
|
-
export { Translate, Translator, canMatchLocale, compileTranslation, createNamespace, injectDynamicLocale, injectIntl, injectSupportedLocales, provideIntlConfig, registerNamespace };
|
|
146
|
-
export type { CompiledTranslation, inferCompiledTranslationMap, inferCompiledTranslationNamespace, inferCompiledTranslationShape, mergeTranslationMaps };
|
|
370
|
+
export { Translate, Translator, canMatchLocale, compileTranslation, createNamespace, formatCurrency, formatDate, formatDisplayName, formatList, formatNumber, formatPercent, formatRelativeTime, injectDynamicLocale, injectIntl, injectResolveParamLocale, injectSupportedLocales, provideIntlConfig, registerNamespace, registerRemoteNamespace };
|
|
371
|
+
export type { CompiledTranslation, FormatCurrencyOptions, FormatDateOptions, FormatDisplayNameOptions, FormatListOptions, FormatNumberOptions, FormatPercentOptions, FormatRelativeTimeOptions, RelativeTimeUnit, SupportedDateInput, SupportedListInput, inferCompiledTranslationMap, inferCompiledTranslationNamespace, inferCompiledTranslationShape, mergeTranslationMaps };
|