ngwr 14.5.0 → 14.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +9 -3
  2. package/avatar/styles/_index.scss +46 -0
  3. package/fesm2022/ngwr-avatar.mjs +58 -7
  4. package/fesm2022/ngwr-avatar.mjs.map +1 -1
  5. package/fesm2022/ngwr-i18n-en.mjs +16 -5
  6. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  7. package/fesm2022/ngwr-i18n.mjs +13 -0
  8. package/fesm2022/ngwr-i18n.mjs.map +1 -1
  9. package/fesm2022/ngwr-image-cropper-testing.mjs +34 -3
  10. package/fesm2022/ngwr-image-cropper-testing.mjs.map +1 -1
  11. package/fesm2022/ngwr-image-cropper.mjs +98 -5
  12. package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
  13. package/fesm2022/ngwr-pagination.mjs +1 -1
  14. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  15. package/fesm2022/ngwr-schema-form.mjs +1 -1
  16. package/fesm2022/ngwr-schema-form.mjs.map +1 -1
  17. package/fesm2022/ngwr-select-testing.mjs +21 -2
  18. package/fesm2022/ngwr-select-testing.mjs.map +1 -1
  19. package/fesm2022/ngwr-select.mjs +233 -35
  20. package/fesm2022/ngwr-select.mjs.map +1 -1
  21. package/fesm2022/ngwr-table.mjs +10 -2
  22. package/fesm2022/ngwr-table.mjs.map +1 -1
  23. package/fesm2022/ngwr-version.mjs +1 -1
  24. package/fesm2022/ngwr-version.mjs.map +1 -1
  25. package/image-cropper/styles/_index.scss +7 -0
  26. package/llms-full.txt +5 -5
  27. package/llms.txt +12 -3
  28. package/mcp/providers.js +8 -2
  29. package/package.json +1 -1
  30. package/schematics/migrations/v14/index.js +90 -34
  31. package/schematics/migrations/v7/index.js +15 -4
  32. package/schematics/migrations/v8/index.js +13 -2
  33. package/schematics/migrations/v9/index.js +19 -10
  34. package/schematics/use/symbol-map.json +1 -0
  35. package/select/styles/_index.scss +34 -0
  36. package/skills/ngwr/SKILL.md +9 -4
  37. package/skills/ngwr/references/catalog.md +1 -1
  38. package/skills/ngwr/references/setup.md +2 -2
  39. package/table/styles/_index.scss +39 -12
  40. package/types/ngwr-avatar.d.ts +36 -3
  41. package/types/ngwr-i18n-en.d.ts +16 -5
  42. package/types/ngwr-i18n.d.ts +13 -0
  43. package/types/ngwr-image-cropper-testing.d.ts +25 -3
  44. package/types/ngwr-image-cropper.d.ts +88 -2
  45. package/types/ngwr-select-testing.d.ts +18 -1
  46. package/types/ngwr-select.d.ts +181 -10
  47. package/types/ngwr-table.d.ts +8 -0
  48. package/types/ngwr-version.d.ts +1 -1
package/README.md CHANGED
@@ -59,9 +59,15 @@ export class SignupCard {
59
59
  }
60
60
  ```
61
61
 
62
- Classic `[(ngModel)]` and reactive forms still work — Angular 22 synthesises the
63
- accessor for a signal-forms control — and every control is usable standalone
64
- through its two-way `[(value)]` / `[(checked)]` model.
62
+ Classic `[(ngModel)]` and reactive forms still bind, with no `ControlValueAccessor`
63
+ created: Angular's `NgModel` / `FormControlDirective` drive the control's `value`
64
+ or `checked` model directly. That bridge does **not** apply template validator
65
+ directives — `required`, `minlength`, `maxlength`, `pattern` or `email` on an ngwr
66
+ control is silently ignored and the form submits — so put validators on the
67
+ `FormControl`. It also ignores `updateOn`, and a `{ emitEvent: false }` write needs
68
+ `markForCheck()`; the [forms guide](https://ngwr.dev/guides/forms) has the detail.
69
+ Every control is also usable standalone through its two-way `[(value)]` /
70
+ `[(checked)]` model.
65
71
 
66
72
  > **Status:** active development. v14 is the current major line (Angular 22 peer).
67
73
  > Upgrading? `ng update ngwr@14` rewrites v14's six renames and reports the
@@ -36,7 +36,44 @@
36
36
  --wr-avatar-ring: transparent;
37
37
  }
38
38
 
39
+ // The projected fallback. `display: contents` keeps whatever is projected a
40
+ // flex item of the host, laid out by the host's centring (and by any flex
41
+ // setting a consumer put on the host) exactly as before this wrapper existed.
42
+ &__content {
43
+ display: contents;
44
+ }
45
+
46
+ // Once loaded, how the fallback leaves the paint follows whether the image is
47
+ // NAMED, which the template states as `aria-hidden` on the wrapper. Named, the
48
+ // initials are already out of the accessibility tree, so `visibility` (which
49
+ // bare text nodes inherit) takes them out of the paint as well.
50
+ &--loaded &__content[aria-hidden='true'] {
51
+ visibility: hidden;
52
+ // Held until the image's own fade has finished, so the photo crossfades in
53
+ // over the initials instead of over an empty box.
54
+ transition: visibility 0s linear var(--wr-duration-base);
55
+ }
56
+
57
+ // Unnamed, the image is only "Avatar" and the initials are what identifies the
58
+ // person, so they are clipped rather than hidden and stay announced. A clip
59
+ // needs a box, hence the switch from `contents`; the host has a fixed size,
60
+ // so taking them out of flow moves nothing around it.
61
+ &--loaded &__content:not([aria-hidden='true']) {
62
+ display: block;
63
+ position: absolute;
64
+ width: 1px;
65
+ height: 1px;
66
+ overflow: hidden;
67
+ clip: rect(0 0 0 0);
68
+ clip-path: inset(50%);
69
+ white-space: nowrap;
70
+ }
71
+
39
72
  &__img {
73
+ // Out of flow, so it covers the fallback rather than sharing the box with it
74
+ // — in flow, the initials were squeezed beside the loaded photo.
75
+ position: absolute;
76
+ inset: 0;
40
77
  display: block;
41
78
  width: 100%;
42
79
  height: 100%;
@@ -54,4 +91,13 @@
54
91
  color: var(--wr-color-on-surface-muted);
55
92
  --wr-spinner-size: 40%;
56
93
  }
94
+
95
+ // With a fallback projected, the spinner is dropped: both are centred, so at
96
+ // 40% of a 32px avatar its arc is drawn straight through the letters and
97
+ // neither reads. The initials are placeholder enough while the photo loads.
98
+ // `:empty` ignores comment nodes, so a projected `@if` that renders nothing
99
+ // still gets the spinner.
100
+ &__content:not(:empty) ~ &__spin {
101
+ display: none;
102
+ }
57
103
  }
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, signal, effect, untracked, computed, ViewEncapsulation, Component } from '@angular/core';
2
+ import { input, signal, viewChild, effect, untracked, afterNextRender, computed, ViewEncapsulation, Component } from '@angular/core';
3
3
  import { useI18nText } from 'ngwr/i18n';
4
4
  import { WrSpinner } from 'ngwr/spinner';
5
5
  import { resolveCssSize } from 'ngwr/utils';
@@ -14,19 +14,25 @@ const DEFAULT_SIZE = '6rem';
14
14
  /**
15
15
  * Image avatar with configurable corner treatment.
16
16
  *
17
- * A spinner is shown while the image loads, then crossfades in.
17
+ * Projected content (typically initials) is the FALLBACK: it shows with no
18
+ * `url`, while the image loads and after it fails, and leaves the paint once the
19
+ * image has loaded. It is projected into a `.wr-avatar__content` wrapper, so a
20
+ * `wr-avatar > …` child selector no longer reaches it. While it is there, no
21
+ * spinner is drawn over it; with nothing projected, the spinner marks the
22
+ * loading state instead. See `alt` for what a screen reader hears.
18
23
  *
19
24
  * @example
20
25
  * ```html
21
26
  * <wr-avatar url="/me.png" alt="Roman" size="3rem" shape="circle" />
22
- * <wr-avatar url="/me.png" alt="Roman" [size]="48" />
27
+ * <wr-avatar [url]="photo" alt="Roman Khegay" [size]="48">RK</wr-avatar>
23
28
  * ```
24
29
  *
25
30
  * @see https://ngwr.dev/reference/components/avatar
26
31
  */
27
32
  class WrAvatar {
28
33
  /**
29
- * Image URL. When unset, only projected content (e.g. initials) renders.
34
+ * Image URL. Projected content (e.g. initials) shows while it is unset,
35
+ * loading or broken, and gives way once the image has loaded.
30
36
  *
31
37
  * @default null
32
38
  */
@@ -36,6 +42,11 @@ class WrAvatar {
36
42
  * Alt text for the image. Falls back to `avatar.alt`, then `'Avatar'` — pass
37
43
  * the person's name where you have it, since that is what a reader wants.
38
44
  *
45
+ * With an `alt`, projected initials are hidden from assistive technology while
46
+ * an image is in play, so the name is announced once. Without one, the image
47
+ * carries only the generic name, so the initials stay announced beside it —
48
+ * visually hidden once it has loaded, never dropped.
49
+ *
39
50
  * @default null
40
51
  */
41
52
  alt = input(null, /* @ts-ignore */
@@ -65,6 +76,8 @@ class WrAvatar {
65
76
  */
66
77
  failed = signal(false, /* @ts-ignore */
67
78
  ...(ngDevMode ? [{ debugName: "failed" }] : /* istanbul ignore next */ []));
79
+ img = viewChild('img', /* @ts-ignore */
80
+ ...(ngDevMode ? [{ debugName: "img" }] : /* istanbul ignore next */ []));
68
81
  constructor() {
69
82
  // A new URL is a new attempt: after a failure the fallback would otherwise
70
83
  // stay put for an image that loads perfectly well.
@@ -75,6 +88,31 @@ class WrAvatar {
75
88
  this.failed.set(false);
76
89
  });
77
90
  });
91
+ afterNextRender(() => this.adoptSettledImage());
92
+ }
93
+ /**
94
+ * A prerendered `<img>` starts loading when the browser parses the HTML, and
95
+ * `(load)` / `(error)` are only attached at hydration — so on a slow bundle the
96
+ * image settles first, both events go nowhere, and the avatar sits on its
97
+ * fallback over a photo it already has (or names a broken image it never
98
+ * learns about). Only the FIRST render can race: every later `<img>` is
99
+ * created on the client with its listeners in place before `src` is set.
100
+ */
101
+ adoptSettledImage() {
102
+ const img = this.img()?.nativeElement;
103
+ if (!img?.complete || this.loaded() || this.failed())
104
+ return;
105
+ if (img.naturalWidth > 0) {
106
+ this.loaded.set(true);
107
+ return;
108
+ }
109
+ // Zero wide is a broken image, or an SVG with no intrinsic size in an engine
110
+ // that reports it as 0 — only the element can tell. Setting `src` to the
111
+ // value it already has makes it fire `load` or `error` again, to listeners
112
+ // that exist now.
113
+ const src = img.getAttribute('src');
114
+ if (src !== null)
115
+ img.setAttribute('src', src);
78
116
  }
79
117
  resolved = computed(() => {
80
118
  const result = resolveCssSize(this.size(), { defaultValue: DEFAULT_SIZE });
@@ -84,6 +122,19 @@ class WrAvatar {
84
122
  return result;
85
123
  }, /* @ts-ignore */
86
124
  ...(ngDevMode ? [{ debugName: "resolved" }] : /* istanbul ignore next */ []));
125
+ /**
126
+ * Whether the projected fallback is `aria-hidden`: an `<img>` is in the DOM
127
+ * (loading or loaded) AND the consumer named it. Then the image's `alt` owns
128
+ * the name, announced once and unchanged at the moment the photo arrives.
129
+ * Without a real `alt` the image is only "Avatar", and hiding the initials
130
+ * would drop the one thing that says who this is.
131
+ *
132
+ * The stylesheet keys on the same attribute once `--loaded`: a hidden fallback
133
+ * leaves the paint through `visibility`, a named-by-initials one is clipped and
134
+ * stays in the accessibility tree. While loading it is painted either way.
135
+ */
136
+ fallbackHidden = computed(() => !!this.url() && !this.failed() && !!this.alt()?.trim(), /* @ts-ignore */
137
+ ...(ngDevMode ? [{ debugName: "fallbackHidden" }] : /* istanbul ignore next */ []));
87
138
  cssSize = computed(() => this.resolved().cssValue, /* @ts-ignore */
88
139
  ...(ngDevMode ? [{ debugName: "cssSize" }] : /* istanbul ignore next */ []));
89
140
  pxSize = computed(() => this.resolved().pxValue, /* @ts-ignore */
@@ -105,7 +156,7 @@ class WrAvatar {
105
156
  this.failed.set(true);
106
157
  }
107
158
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrAvatar, deps: [], target: i0.ɵɵFactoryTarget.Component });
108
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrAvatar, isStandalone: true, selector: "wr-avatar", inputs: { url: { classPropertyName: "url", publicName: "url", isSignal: true, isRequired: false, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()", "style.width": "cssSize()", "style.height": "cssSize()" } }, ngImport: i0, template: "<ng-content />\n\n@if (url(); as src) {\n @if (!failed()) {\n <img\n class=\"wr-avatar__img\"\n [src]=\"src\"\n [alt]=\"resolvedAlt()\"\n [attr.width]=\"pxSize()\"\n [attr.height]=\"pxSize()\"\n (load)=\"onImageLoad()\"\n (error)=\"onImageError()\"\n decoding=\"async\"\n />\n\n @if (!loaded()) {\n <wr-spinner class=\"wr-avatar__spin\" />\n }\n }\n}\n", dependencies: [{ kind: "component", type: WrSpinner, selector: "wr-spinner", inputs: ["size", "ariaLabel"] }], encapsulation: i0.ViewEncapsulation.None });
159
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: WrAvatar, isStandalone: true, selector: "wr-avatar", inputs: { url: { classPropertyName: "url", publicName: "url", isSignal: true, isRequired: false, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()", "style.width": "cssSize()", "style.height": "cssSize()" } }, viewQueries: [{ propertyName: "img", first: true, predicate: ["img"], descendants: true, isSignal: true }], ngImport: i0, template: "<span class=\"wr-avatar__content\" [attr.aria-hidden]=\"fallbackHidden() ? 'true' : null\"><ng-content /></span>\n\n@if (url(); as src) {\n @if (!failed()) {\n <img\n #img\n class=\"wr-avatar__img\"\n [src]=\"src\"\n [alt]=\"resolvedAlt()\"\n [attr.width]=\"pxSize()\"\n [attr.height]=\"pxSize()\"\n (load)=\"onImageLoad()\"\n (error)=\"onImageError()\"\n decoding=\"async\"\n />\n\n @if (!loaded()) {\n <wr-spinner class=\"wr-avatar__spin\" />\n }\n }\n}\n", dependencies: [{ kind: "component", type: WrSpinner, selector: "wr-spinner", inputs: ["size", "ariaLabel"] }], encapsulation: i0.ViewEncapsulation.None });
109
160
  }
110
161
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: WrAvatar, decorators: [{
111
162
  type: Component,
@@ -113,8 +164,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
113
164
  '[class]': 'classes()',
114
165
  '[style.width]': 'cssSize()',
115
166
  '[style.height]': 'cssSize()',
116
- }, imports: [WrSpinner], template: "<ng-content />\n\n@if (url(); as src) {\n @if (!failed()) {\n <img\n class=\"wr-avatar__img\"\n [src]=\"src\"\n [alt]=\"resolvedAlt()\"\n [attr.width]=\"pxSize()\"\n [attr.height]=\"pxSize()\"\n (load)=\"onImageLoad()\"\n (error)=\"onImageError()\"\n decoding=\"async\"\n />\n\n @if (!loaded()) {\n <wr-spinner class=\"wr-avatar__spin\" />\n }\n }\n}\n" }]
117
- }], ctorParameters: () => [], propDecorators: { url: [{ type: i0.Input, args: [{ isSignal: true, alias: "url", required: false }] }], alt: [{ type: i0.Input, args: [{ isSignal: true, alias: "alt", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
167
+ }, imports: [WrSpinner], template: "<span class=\"wr-avatar__content\" [attr.aria-hidden]=\"fallbackHidden() ? 'true' : null\"><ng-content /></span>\n\n@if (url(); as src) {\n @if (!failed()) {\n <img\n #img\n class=\"wr-avatar__img\"\n [src]=\"src\"\n [alt]=\"resolvedAlt()\"\n [attr.width]=\"pxSize()\"\n [attr.height]=\"pxSize()\"\n (load)=\"onImageLoad()\"\n (error)=\"onImageError()\"\n decoding=\"async\"\n />\n\n @if (!loaded()) {\n <wr-spinner class=\"wr-avatar__spin\" />\n }\n }\n}\n" }]
168
+ }], ctorParameters: () => [], propDecorators: { url: [{ type: i0.Input, args: [{ isSignal: true, alias: "url", required: false }] }], alt: [{ type: i0.Input, args: [{ isSignal: true, alias: "alt", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], img: [{ type: i0.ViewChild, args: ['img', { isSignal: true }] }] } });
118
169
 
119
170
  /**
120
171
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-avatar.mjs","sources":["../../../projects/lib/avatar/avatar.ts","../../../projects/lib/avatar/avatar.html","../../../projects/lib/avatar/ngwr-avatar.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Component, ViewEncapsulation, computed, effect, input, signal, untracked } from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\nimport { WrSpinner } from 'ngwr/spinner';\nimport { resolveCssSize, type ResolvedCssSize } from 'ngwr/utils';\n\nimport type { WrAvatarShape, WrAvatarSize } from './interfaces';\n\nconst DEFAULT_SIZE: WrAvatarSize = '6rem';\n\n/**\n * Image avatar with configurable corner treatment.\n *\n * A spinner is shown while the image loads, then crossfades in.\n *\n * @example\n * ```html\n * <wr-avatar url=\"/me.png\" alt=\"Roman\" size=\"3rem\" shape=\"circle\" />\n * <wr-avatar url=\"/me.png\" alt=\"Roman\" [size]=\"48\" />\n * ```\n *\n * @see https://ngwr.dev/reference/components/avatar\n */\n@Component({\n selector: 'wr-avatar',\n templateUrl: './avatar.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[style.width]': 'cssSize()',\n '[style.height]': 'cssSize()',\n },\n imports: [WrSpinner],\n})\nexport class WrAvatar {\n /**\n * Image URL. When unset, only projected content (e.g. initials) renders.\n *\n * @default null\n */\n readonly url = input<string | null>(null);\n\n /**\n * Alt text for the image. Falls back to `avatar.alt`, then `'Avatar'` — pass\n * the person's name where you have it, since that is what a reader wants.\n *\n * @default null\n */\n readonly alt = input<string | null>(null);\n\n protected readonly resolvedAlt = useI18nText(this.alt, 'avatar.alt', 'Avatar');\n\n /**\n * Corner treatment. `rounded` (default) is a soft rounded square,\n * `circle` is the classic profile avatar, `squircle` is the iOS look.\n *\n * @default 'rounded'\n */\n readonly shape = input<WrAvatarShape>('rounded');\n\n /**\n * Box size. See {@link WrAvatarSize} for accepted values.\n *\n * @default '6rem'\n */\n readonly size = input<WrAvatarSize>(DEFAULT_SIZE);\n\n protected readonly loaded = signal(false);\n\n /**\n * Whether the image failed. Without this the spinner spun forever on a broken\n * URL — the one state where an avatar is guaranteed to have projected initials\n * worth showing instead.\n */\n protected readonly failed = signal(false);\n\n constructor() {\n // A new URL is a new attempt: after a failure the fallback would otherwise\n // stay put for an image that loads perfectly well.\n effect(() => {\n this.url();\n untracked(() => {\n this.loaded.set(false);\n this.failed.set(false);\n });\n });\n }\n\n protected readonly resolved = computed<ResolvedCssSize>(() => {\n const result = resolveCssSize(this.size(), { defaultValue: DEFAULT_SIZE });\n if (result.pxValue == null || result.pxValue <= 0) {\n return resolveCssSize(DEFAULT_SIZE, { defaultValue: DEFAULT_SIZE });\n }\n return result;\n });\n\n protected readonly cssSize = computed(() => this.resolved().cssValue);\n protected readonly pxSize = computed(() => this.resolved().pxValue);\n\n protected readonly classes = computed(() => {\n const parts = ['wr-avatar'];\n const shape = this.shape();\n if (shape !== 'rounded') parts.push(`wr-avatar--${shape}`);\n if (this.loaded()) parts.push('wr-avatar--loaded');\n return parts.join(' ');\n });\n\n protected onImageLoad(): void {\n this.loaded.set(true);\n }\n\n protected onImageError(): void {\n this.failed.set(true);\n }\n}\n","<ng-content />\n\n@if (url(); as src) {\n @if (!failed()) {\n <img\n class=\"wr-avatar__img\"\n [src]=\"src\"\n [alt]=\"resolvedAlt()\"\n [attr.width]=\"pxSize()\"\n [attr.height]=\"pxSize()\"\n (load)=\"onImageLoad()\"\n (error)=\"onImageError()\"\n decoding=\"async\"\n />\n\n @if (!loaded()) {\n <wr-spinner class=\"wr-avatar__spin\" />\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-avatar.mjs","sources":["../../../projects/lib/avatar/avatar.ts","../../../projects/lib/avatar/avatar.html","../../../projects/lib/avatar/ngwr-avatar.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport {\n Component,\n type ElementRef,\n ViewEncapsulation,\n afterNextRender,\n computed,\n effect,\n input,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\n\nimport { useI18nText } from 'ngwr/i18n';\nimport { WrSpinner } from 'ngwr/spinner';\nimport { resolveCssSize, type ResolvedCssSize } from 'ngwr/utils';\n\nimport type { WrAvatarShape, WrAvatarSize } from './interfaces';\n\nconst DEFAULT_SIZE: WrAvatarSize = '6rem';\n\n/**\n * Image avatar with configurable corner treatment.\n *\n * Projected content (typically initials) is the FALLBACK: it shows with no\n * `url`, while the image loads and after it fails, and leaves the paint once the\n * image has loaded. It is projected into a `.wr-avatar__content` wrapper, so a\n * `wr-avatar > …` child selector no longer reaches it. While it is there, no\n * spinner is drawn over it; with nothing projected, the spinner marks the\n * loading state instead. See `alt` for what a screen reader hears.\n *\n * @example\n * ```html\n * <wr-avatar url=\"/me.png\" alt=\"Roman\" size=\"3rem\" shape=\"circle\" />\n * <wr-avatar [url]=\"photo\" alt=\"Roman Khegay\" [size]=\"48\">RK</wr-avatar>\n * ```\n *\n * @see https://ngwr.dev/reference/components/avatar\n */\n@Component({\n selector: 'wr-avatar',\n templateUrl: './avatar.html',\n encapsulation: ViewEncapsulation.None,\n host: {\n '[class]': 'classes()',\n '[style.width]': 'cssSize()',\n '[style.height]': 'cssSize()',\n },\n imports: [WrSpinner],\n})\nexport class WrAvatar {\n /**\n * Image URL. Projected content (e.g. initials) shows while it is unset,\n * loading or broken, and gives way once the image has loaded.\n *\n * @default null\n */\n readonly url = input<string | null>(null);\n\n /**\n * Alt text for the image. Falls back to `avatar.alt`, then `'Avatar'` — pass\n * the person's name where you have it, since that is what a reader wants.\n *\n * With an `alt`, projected initials are hidden from assistive technology while\n * an image is in play, so the name is announced once. Without one, the image\n * carries only the generic name, so the initials stay announced beside it —\n * visually hidden once it has loaded, never dropped.\n *\n * @default null\n */\n readonly alt = input<string | null>(null);\n\n protected readonly resolvedAlt = useI18nText(this.alt, 'avatar.alt', 'Avatar');\n\n /**\n * Corner treatment. `rounded` (default) is a soft rounded square,\n * `circle` is the classic profile avatar, `squircle` is the iOS look.\n *\n * @default 'rounded'\n */\n readonly shape = input<WrAvatarShape>('rounded');\n\n /**\n * Box size. See {@link WrAvatarSize} for accepted values.\n *\n * @default '6rem'\n */\n readonly size = input<WrAvatarSize>(DEFAULT_SIZE);\n\n protected readonly loaded = signal(false);\n\n /**\n * Whether the image failed. Without this the spinner spun forever on a broken\n * URL — the one state where an avatar is guaranteed to have projected initials\n * worth showing instead.\n */\n protected readonly failed = signal(false);\n\n private readonly img = viewChild<ElementRef<HTMLImageElement>>('img');\n\n constructor() {\n // A new URL is a new attempt: after a failure the fallback would otherwise\n // stay put for an image that loads perfectly well.\n effect(() => {\n this.url();\n untracked(() => {\n this.loaded.set(false);\n this.failed.set(false);\n });\n });\n\n afterNextRender(() => this.adoptSettledImage());\n }\n\n /**\n * A prerendered `<img>` starts loading when the browser parses the HTML, and\n * `(load)` / `(error)` are only attached at hydration — so on a slow bundle the\n * image settles first, both events go nowhere, and the avatar sits on its\n * fallback over a photo it already has (or names a broken image it never\n * learns about). Only the FIRST render can race: every later `<img>` is\n * created on the client with its listeners in place before `src` is set.\n */\n private adoptSettledImage(): void {\n const img = this.img()?.nativeElement;\n if (!img?.complete || this.loaded() || this.failed()) return;\n\n if (img.naturalWidth > 0) {\n this.loaded.set(true);\n return;\n }\n\n // Zero wide is a broken image, or an SVG with no intrinsic size in an engine\n // that reports it as 0 — only the element can tell. Setting `src` to the\n // value it already has makes it fire `load` or `error` again, to listeners\n // that exist now.\n const src = img.getAttribute('src');\n if (src !== null) img.setAttribute('src', src);\n }\n\n protected readonly resolved = computed<ResolvedCssSize>(() => {\n const result = resolveCssSize(this.size(), { defaultValue: DEFAULT_SIZE });\n if (result.pxValue == null || result.pxValue <= 0) {\n return resolveCssSize(DEFAULT_SIZE, { defaultValue: DEFAULT_SIZE });\n }\n return result;\n });\n\n /**\n * Whether the projected fallback is `aria-hidden`: an `<img>` is in the DOM\n * (loading or loaded) AND the consumer named it. Then the image's `alt` owns\n * the name, announced once and unchanged at the moment the photo arrives.\n * Without a real `alt` the image is only \"Avatar\", and hiding the initials\n * would drop the one thing that says who this is.\n *\n * The stylesheet keys on the same attribute once `--loaded`: a hidden fallback\n * leaves the paint through `visibility`, a named-by-initials one is clipped and\n * stays in the accessibility tree. While loading it is painted either way.\n */\n protected readonly fallbackHidden = computed(() => !!this.url() && !this.failed() && !!this.alt()?.trim());\n\n protected readonly cssSize = computed(() => this.resolved().cssValue);\n protected readonly pxSize = computed(() => this.resolved().pxValue);\n\n protected readonly classes = computed(() => {\n const parts = ['wr-avatar'];\n const shape = this.shape();\n if (shape !== 'rounded') parts.push(`wr-avatar--${shape}`);\n if (this.loaded()) parts.push('wr-avatar--loaded');\n return parts.join(' ');\n });\n\n protected onImageLoad(): void {\n this.loaded.set(true);\n }\n\n protected onImageError(): void {\n this.failed.set(true);\n }\n}\n","<span class=\"wr-avatar__content\" [attr.aria-hidden]=\"fallbackHidden() ? 'true' : null\"><ng-content /></span>\n\n@if (url(); as src) {\n @if (!failed()) {\n <img\n #img\n class=\"wr-avatar__img\"\n [src]=\"src\"\n [alt]=\"resolvedAlt()\"\n [attr.width]=\"pxSize()\"\n [attr.height]=\"pxSize()\"\n (load)=\"onImageLoad()\"\n (error)=\"onImageError()\"\n decoding=\"async\"\n />\n\n @if (!loaded()) {\n <wr-spinner class=\"wr-avatar__spin\" />\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -1,14 +1,25 @@
1
1
  /**
2
- * Base English catalog for ngwr built-in component strings. Spread this
3
- * into your root catalog or pass it to `provideWrI18nStaticLoader`.
2
+ * Base English catalog for ngwr built-in component strings. Register it with
3
+ * `provideWrI18nBaseCatalogs` and keep only your own keys in the loader.
4
+ *
5
+ * Do not spread it into your own catalog. A spread is shallow, so any namespace
6
+ * you share with ngwr, e.g. `common`, `validation`, `table`, keeps only the keys
7
+ * of the side spread last, and the other side's keys stop resolving with nothing
8
+ * logged: ngwr's components fall back to their English defaults, and a `wrT`
9
+ * read of a lost key renders the raw key under the default missing handler. A
10
+ * base catalog is looked up key by key underneath yours, so both halves of a
11
+ * shared namespace resolve.
4
12
  *
5
13
  * @example
6
14
  * ```ts
15
+ * import { provideWrI18n, provideWrI18nBaseCatalogs, provideWrI18nStaticLoader } from 'ngwr/i18n';
7
16
  * import { wrEn } from 'ngwr/i18n/en';
8
17
  *
9
- * provideWrI18nStaticLoader({
10
- * en: { ...wrEn, app: { title: 'My app' } },
11
- * });
18
+ * providers: [
19
+ * provideWrI18n(),
20
+ * provideWrI18nBaseCatalogs({ en: wrEn }),
21
+ * provideWrI18nStaticLoader({ en: { app: { title: 'My app' } } }),
22
+ * ]
12
23
  * ```
13
24
  */
14
25
  const wrEn = {
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-i18n-en.mjs","sources":["../../../projects/lib/i18n/en/public-api.ts","../../../projects/lib/i18n/en/ngwr-i18n-en.ts"],"sourcesContent":["import { type WrI18nCatalog } from 'ngwr/i18n';\n\n/**\n * Base English catalog for ngwr built-in component strings. Spread this\n * into your root catalog or pass it to `provideWrI18nStaticLoader`.\n *\n * @example\n * ```ts\n * import { wrEn } from 'ngwr/i18n/en';\n *\n * provideWrI18nStaticLoader({\n * en: { ...wrEn, app: { title: 'My app' } },\n * });\n * ```\n */\nexport const wrEn: WrI18nCatalog = {\n common: {\n ok: 'OK',\n cancel: 'Cancel',\n close: 'Close',\n confirm: 'Confirm',\n delete: 'Delete',\n save: 'Save',\n edit: 'Edit',\n add: 'Add',\n remove: 'Remove',\n clear: 'Clear',\n search: 'Search',\n loading: 'Loading…',\n select: 'Select',\n next: 'Next',\n previous: 'Previous',\n back: 'Back',\n today: 'Today',\n yesterday: 'Yesterday',\n tomorrow: 'Tomorrow',\n of: 'of',\n },\n pagination: {\n prev: 'Previous page',\n next: 'Next page',\n itemsPerPage: 'Items per page',\n perPage: '{{size}} / page',\n goToPage: 'Go to page {{page}}',\n label: 'Pagination',\n pageOf: 'Page {{current}} of {{total}}',\n // The whole \"1–10 of 235\" line, as ONE template. It used to be assembled in\n // TypeScript around `of` above, which localised the word in the middle and\n // froze everything else: an ASCII hyphen between the bounds, and an operand\n // order many languages do not use. `of` stays because removing a shipped key\n // breaks catalogs that override it; nothing in the library reads it now.\n range: '{{from}}–{{to}} of {{total}}',\n // The compact pager's own text, for the same reason: it was\n // `{{ page() }} / {{ totalPages() }}` in the template.\n compact: '{{current}} / {{total}}',\n },\n table: {\n empty: 'No data',\n loading: 'Loading…',\n sort: 'Sort column',\n filter: 'Filter column',\n selectAll: 'Select all rows',\n selectRow: 'Select row',\n expandRow: 'Toggle row details',\n toggleRow: 'Toggle child rows',\n selectGroup: 'Select group',\n toggleGroup: 'Toggle group',\n noMatches: 'No matches',\n // The filter panel's search box has no visible label, so `search` is both its\n // placeholder AND its accessible name.\n search: 'Search',\n reset: 'Reset',\n },\n eventCalendar: {\n today: 'Today',\n previous: 'Previous',\n next: 'Next',\n month: 'Month',\n week: 'Week',\n day: 'Day',\n time: 'Time',\n allDay: 'All day',\n label: 'Calendar',\n more: '+{{count}} more',\n // The five composed strings below are the same defect `wr-calendar` fixed\n // one component over: each was a TypeScript template literal, so the month\n // name and the date came from `Intl` and the ORDER and the punctuation\n // between them did not. A locale could translate every word in them and\n // still be stuck with English word order — ja-JP writes 2026年3月.\n header: '{{month}} {{year}}',\n range: '{{from}} – {{to}}',\n // Accessible names, which is why they matter more than they look: these\n // three are what a screen reader announces for every chip and every cell in\n // the grid, so a frozen separator is heard on every one of them.\n chipLabel: '{{title}}, {{time}}',\n slotLabel: '{{time}} — {{date}}',\n allDayCellLabel: '{{label}} — {{date}}',\n },\n tour: {\n next: 'Next',\n back: 'Back',\n done: 'Done',\n skip: 'Skip tour',\n progress: 'Step {{current}} of {{total}}',\n },\n splitter: {\n divider: 'Resize panes',\n },\n stepper: {\n // Rendered as a badge beside the step's own label, so it reads as part of the\n // header rather than as a sentence — lowercase on purpose.\n optional: 'optional',\n },\n transfer: {\n source: 'Available',\n target: 'Selected',\n search: 'Search',\n empty: 'Nothing here',\n selectAll: 'Select all',\n toTarget: 'Move to selected',\n toSource: 'Move to available',\n count: '{{checked}} / {{total}}',\n selectAllAria: '{{pane}} — {{action}}',\n },\n form: {\n // Rendered inside the label's parentheses — `(optional)` — so it is a bare\n // lowercase word and no locale has to repeat the punctuation. Same shape as\n // `stepper.optional`, and unlike the `*` marker this one is NOT `aria-hidden`.\n optional: 'optional',\n },\n validation: {\n required: 'This field is required.',\n requiredTrue: 'This field must be checked.',\n email: 'Enter a valid email address.',\n // A noun straight after a count is a plural bug waiting for the value 1 —\n // \"Enter at least 1 characters.\" — and there is no plural machinery anywhere\n // in this layer, so the wording has to be right at EVERY value rather than\n // at the common ones. Putting the number last does it: the sentence reads\n // the same at 1 and at 80.\n //\n // The other twenty-one catalogs carry the same shape in their own\n // morphology — ru's \"символов\" is genitive plural, correct for 5–20 and\n // wrong for 1 and for 2–4. Each needs a native speaker; guessing at Czech\n // plural rules from here would be the same mistake in a new language.\n minlength: 'Minimum length is {{requiredLength}}.',\n maxlength: 'Maximum length is {{requiredLength}}.',\n min: 'Enter {{min}} or more.',\n max: 'Enter {{max}} or less.',\n pattern: 'This value is not in the expected format.',\n noWhitespace: 'This value cannot contain spaces.',\n hexColor: 'Enter a hex colour, e.g. #1a2b3c.',\n url: 'Enter a valid URL.',\n cardNumber: 'Enter a valid card number.',\n cvc: 'Enter the {{length}}-digit security code.',\n iban: 'Enter a valid IBAN.',\n match: 'The two values do not match.',\n matchFields: 'These fields do not match.',\n oneOf: 'Choose one of the allowed values.',\n minDate: 'Choose a later date.',\n maxDate: 'Choose an earlier date.',\n },\n select: {\n label: 'Select',\n placeholder: 'Select…',\n empty: 'No options',\n clearSelection: 'Clear selection',\n removeItem: 'Remove {{label}}',\n noResults: 'No results',\n loading: 'Loading…',\n more: '+{{count}} more',\n },\n // `tree` covers both inline display and combobox-mode pickers\n // (replaces the dropped `treeSelect` namespace).\n tree: {\n expand: 'Expand',\n collapse: 'Collapse',\n placeholder: 'Select…',\n clearSelection: 'Clear selection',\n removeItem: 'Remove {{label}}',\n // Same string and same shape as `select.more` — the two components render\n // the identical overflow chip, and only one of them could be translated.\n more: '+{{count}} more',\n },\n commandPalette: {\n label: 'Command palette',\n placeholder: 'Type a command or search…',\n noResults: 'No results',\n // Shown INSTEAD of `noResults` while a host-driven search is in flight.\n // Without it an async palette reads \"No results\" between every keystroke\n // and its answer, which states something false about the query.\n loading: 'Searching…',\n // The key-cap chip in the search row. A key NAME rather than prose, so most\n // locales will leave it alone — but a keyboard whose key is not labelled\n // \"esc\" had no way to say so.\n escHint: 'esc',\n },\n empty: {\n noData: 'No data',\n },\n fileUpload: {\n browse: 'Click to browse',\n dropZone: 'or drop files here',\n dropZoneLabel: 'File upload drop zone — click or drop files',\n removeFile: 'Remove file',\n invalid: 'Unsupported file type',\n tooBig: 'File too large',\n // File size, as a template plus a unit table. The number itself goes through\n // `Intl.NumberFormat`, so the decimal separator follows `LOCALE_ID`; what a\n // catalog owns here is the unit abbreviation and whether a space sits before\n // it. Binary units (1024), which is what the component counts in.\n size: '{{value}} {{unit}}',\n unitByte: 'B',\n unitKb: 'KB',\n unitMb: 'MB',\n unitGb: 'GB',\n unitTb: 'TB',\n },\n popconfirm: {\n label: 'Confirm action',\n confirm: 'Confirm',\n cancel: 'Cancel',\n },\n toast: {\n region: 'Notifications',\n close: 'Close',\n copy: 'Copy',\n copied: 'Copied',\n closeAll: 'Close all',\n },\n input: {\n showPassword: 'Show password',\n hidePassword: 'Hide password',\n },\n inputNumber: {\n increment: 'Increment',\n decrement: 'Decrement',\n },\n // Two names for one box, chosen by `mode`: only the numeric strip holds digits.\n // One key saying \"Digit\" would be a lie on the alphanumeric and text modes, which\n // accept letters — a wrong name is worse than an untranslated one.\n inputOtp: {\n label: 'Verification code',\n digit: 'Digit {{index}}',\n character: 'Character {{index}}',\n },\n anchor: {\n label: 'Table of contents',\n },\n avatar: {\n alt: 'Avatar',\n },\n backTop: {\n label: 'Back to top',\n },\n breadcrumbs: {\n label: 'Breadcrumbs',\n },\n burger: {\n label: 'Toggle menu',\n },\n calendar: {\n prevMonth: 'Previous month',\n nextMonth: 'Next month',\n prevYear: 'Previous year',\n nextYear: 'Next year',\n // The month / year pickers are `role=\"listbox\"`, and a listbox owes a\n // name — without one a screen reader announces the control as nothing at\n // all. Caught by `check:state-a11y` once a state finally opened the view.\n monthList: 'Months',\n yearList: 'Years',\n prevYears: 'Previous 12 years',\n nextYears: 'Next 12 years',\n // The header above the grid, as ONE template. It was `${month} ${year}` in\n // TypeScript, which is English word order with an English separator: ja-JP\n // writes 2026年3月 and cannot get there by translating a word.\n header: '{{month}} {{year}}',\n // The year view's header, same reason — the en dash was hardcoded too.\n yearRange: '{{from}} – {{to}}',\n // A day cell's accessible name. `{{date}}` is the adapter's `longDate`, so\n // the date itself is `Intl`-ordered and `Intl`-punctuated; the catalog owns\n // only where the weekday goes relative to it.\n dayLabel: '{{weekday}}, {{date}}',\n },\n imageCropper: {\n empty: 'No image',\n window: 'Crop region',\n keyHelp:\n 'Arrow keys move the crop. Hold Alt with an arrow key to resize it, and Shift for larger steps. ' +\n 'The crop is announced as left, top, width and height in image pixels.',\n },\n sortableList: {\n keyHelp:\n 'Press Space to pick this item up, then use the arrow keys to move it. ' +\n 'Press Space again to drop it, or Escape to put it back.',\n grabbed: 'Grabbed. {{index}} of {{total}}.',\n moved: '{{index}} of {{total}}.',\n dropped: 'Dropped. {{index}} of {{total}}.',\n cancelled: 'Move cancelled.',\n },\n colorPicker: {\n // The saturation / brightness canvas is a `role=\"group\"`, which has no\n // `aria-valuenow` — so its two values ride in its name.\n area: 'Saturation and brightness, {{saturation}}% and {{brightness}}%',\n hue: 'Hue',\n alpha: 'Opacity',\n // The format strip. Three initialisms most locales keep as they are — which\n // is the reason they were left as literals, and not a reason a locale should\n // be unable to change them.\n formatHex: 'HEX',\n formatRgb: 'RGB',\n formatHsl: 'HSL',\n // Channel field labels. Each `<span>` is inside the `<label>` that names its\n // number input, so these are accessible names, not decoration. The `%` is\n // part of the string on purpose: a locale that spaces it differently, or\n // spells the channel with a different letter, needs to move both together.\n channelHex: 'HEX',\n channelRed: 'R',\n channelGreen: 'G',\n channelBlue: 'B',\n channelHue: 'H',\n channelSaturation: 'S%',\n channelLightness: 'L%',\n channelAlpha: 'A%',\n },\n calendarHeatmap: {\n label: 'Calendar heatmap',\n cell: '{{date}}: {{count}}',\n },\n lineChart: {\n label: 'Line chart',\n // The Y-axis tick abbreviation. `k` is a Latin convention — ru writes\n // `тыс.` — and the axis had it hardcoded, so it was the one number on the\n // chart no locale could reach. The digits go through `Intl.NumberFormat`,\n // so the catalog owns the suffix and whether a space sits before it.\n thousands: '{{value}}k',\n },\n donutChart: {\n label: 'Donut chart',\n },\n compare: {\n label: 'Comparison divider',\n },\n // The two `roledescription` values are spoken INSTEAD of the role name, so they\n // are lowercase nouns (\"carousel\", \"slide\") the way a role name would be — not\n // sentence-case labels like the ones above them.\n carousel: {\n label: 'Carousel',\n goToSlide: 'Go to slide {{index}}',\n prev: 'Previous slide',\n next: 'Next slide',\n pagination: 'Carousel pagination',\n roledescription: 'carousel',\n slideRoledescription: 'slide',\n },\n actionSheet: {\n label: 'Actions',\n },\n alert: {\n close: 'Close alert',\n },\n qr: {\n label: 'QR code',\n },\n image: {\n viewer: 'Image preview',\n open: 'Open preview',\n close: 'Close preview',\n },\n window: {\n close: 'Close',\n minimize: 'Minimize',\n maximize: 'Maximize',\n restore: 'Restore',\n restoreDown: 'Restore down',\n restoreWindow: 'Restore {{title}}',\n closeWindow: 'Close window',\n untitled: 'Untitled',\n taskbar: 'Minimized windows',\n },\n dialog: {\n close: 'Close dialog',\n },\n // Deliberately generic: a popover panel has no universal name, and an unnamed\n // `role=\"dialog\"` announces as nothing at all. Override per instance with\n // `[ariaLabel]`.\n popover: {\n label: 'Popover',\n },\n markdown: {\n copy: 'Copy code',\n copied: 'Copied',\n // Read before a task item's text, so a screen reader gets the state that the\n // checkbox glyph carries visually.\n taskDone: 'Done:',\n taskTodo: 'To do:',\n },\n // Count-neutral on purpose: `wrInterpolate` does `{{name}}` substitution only,\n // with no plural support, so \"Matches available: 1\" has to read correctly too.\n marquee: {\n label: 'Marquee',\n link: 'link',\n },\n mention: {\n listbox: 'Mentions',\n available: 'Matches available: {{count}}',\n inserted: 'Inserted: {{label}}',\n },\n drawer: {\n close: 'Close drawer',\n },\n datePicker: {\n open: 'Open calendar',\n openTime: 'Open time picker',\n openDateTime: 'Open date and time picker',\n openRange: 'Open range calendar',\n panel: 'Choose date',\n panelTime: 'Choose time',\n panelDateTime: 'Choose date and time',\n panelRange: 'Choose date range',\n panelRangeDateTime: 'Choose date and time range',\n rangeStart: 'Range start',\n rangeEnd: 'Range end',\n startTime: 'Start time',\n endTime: 'End time',\n hours: 'Hours',\n minutes: 'Minutes',\n seconds: 'Seconds',\n incrementHours: 'Increment hours',\n decrementHours: 'Decrement hours',\n incrementMinutes: 'Increment minutes',\n decrementMinutes: 'Decrement minutes',\n incrementSeconds: 'Increment seconds',\n decrementSeconds: 'Decrement seconds',\n toggleAmPm: 'Toggle AM / PM',\n // Rendered in the meridiem column and re-announced by its `aria-live` span on\n // every toggle, so it is a translated word rather than a fixed glyph — `wrRu`\n // spells these ДП / ПП.\n am: 'AM',\n pm: 'PM',\n },\n sidebar: {\n label: 'Sidebar',\n },\n spinner: {\n label: 'Loading',\n },\n rating: {\n label: 'Rating',\n },\n gauge: {\n label: 'Gauge',\n },\n graph: {\n label: 'Graph',\n // Read out inside each node of <wr-graph>. `{{names}}` is a list the component\n // has already joined with Intl.ListFormat, so the sentence never carries a count.\n // Each value is a whole sentence with its own terminator: a node with both reads\n // the two joined by a single space, and adds no punctuation of its own.\n parents: 'Parents: {{names}}.',\n children: 'Children: {{names}}.',\n },\n progress: {\n label: 'Progress',\n },\n meterGroup: {\n label: 'Meter',\n },\n knob: {\n label: 'Value',\n },\n slider: {\n label: 'Value',\n // Range mode gives each end its own thumb, and each thumb its own name — a\n // screen reader otherwise reads the same word twice for two different values.\n lower: 'Lower value',\n upper: 'Upper value',\n },\n speedDial: {\n label: 'Actions',\n },\n statistic: {\n // The delta chip, e.g. `+12.4%`. The number is formatted through\n // `Intl.NumberFormat` (so its sign, digits and decimal separator follow\n // `LOCALE_ID`, matching the value above it), and this template owns whether\n // a space sits between it and the unit.\n delta: '{{value}}{{suffix}}',\n // The unit the component appends when the consumer binds no `deltaSuffix`.\n deltaSuffix: '%',\n },\n result: {\n notFound: 'Sorry, the page you visited does not exist.',\n forbidden: 'Sorry, you are not authorized to access this page.',\n serverError: 'Sorry, something went wrong.',\n },\n date: {\n months: {\n jan: 'January',\n feb: 'February',\n mar: 'March',\n apr: 'April',\n may: 'May',\n jun: 'June',\n jul: 'July',\n aug: 'August',\n sep: 'September',\n oct: 'October',\n nov: 'November',\n dec: 'December',\n },\n },\n};\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-i18n-en.mjs","sources":["../../../projects/lib/i18n/en/public-api.ts","../../../projects/lib/i18n/en/ngwr-i18n-en.ts"],"sourcesContent":["import { type WrI18nCatalog } from 'ngwr/i18n';\n\n/**\n * Base English catalog for ngwr built-in component strings. Register it with\n * `provideWrI18nBaseCatalogs` and keep only your own keys in the loader.\n *\n * Do not spread it into your own catalog. A spread is shallow, so any namespace\n * you share with ngwr, e.g. `common`, `validation`, `table`, keeps only the keys\n * of the side spread last, and the other side's keys stop resolving with nothing\n * logged: ngwr's components fall back to their English defaults, and a `wrT`\n * read of a lost key renders the raw key under the default missing handler. A\n * base catalog is looked up key by key underneath yours, so both halves of a\n * shared namespace resolve.\n *\n * @example\n * ```ts\n * import { provideWrI18n, provideWrI18nBaseCatalogs, provideWrI18nStaticLoader } from 'ngwr/i18n';\n * import { wrEn } from 'ngwr/i18n/en';\n *\n * providers: [\n * provideWrI18n(),\n * provideWrI18nBaseCatalogs({ en: wrEn }),\n * provideWrI18nStaticLoader({ en: { app: { title: 'My app' } } }),\n * ]\n * ```\n */\nexport const wrEn: WrI18nCatalog = {\n common: {\n ok: 'OK',\n cancel: 'Cancel',\n close: 'Close',\n confirm: 'Confirm',\n delete: 'Delete',\n save: 'Save',\n edit: 'Edit',\n add: 'Add',\n remove: 'Remove',\n clear: 'Clear',\n search: 'Search',\n loading: 'Loading…',\n select: 'Select',\n next: 'Next',\n previous: 'Previous',\n back: 'Back',\n today: 'Today',\n yesterday: 'Yesterday',\n tomorrow: 'Tomorrow',\n of: 'of',\n },\n pagination: {\n prev: 'Previous page',\n next: 'Next page',\n itemsPerPage: 'Items per page',\n perPage: '{{size}} / page',\n goToPage: 'Go to page {{page}}',\n label: 'Pagination',\n pageOf: 'Page {{current}} of {{total}}',\n // The whole \"1–10 of 235\" line, as ONE template. It used to be assembled in\n // TypeScript around `of` above, which localised the word in the middle and\n // froze everything else: an ASCII hyphen between the bounds, and an operand\n // order many languages do not use. `of` stays because removing a shipped key\n // breaks catalogs that override it; nothing in the library reads it now.\n range: '{{from}}–{{to}} of {{total}}',\n // The compact pager's own text, for the same reason: it was\n // `{{ page() }} / {{ totalPages() }}` in the template.\n compact: '{{current}} / {{total}}',\n },\n table: {\n empty: 'No data',\n loading: 'Loading…',\n sort: 'Sort column',\n filter: 'Filter column',\n selectAll: 'Select all rows',\n selectRow: 'Select row',\n expandRow: 'Toggle row details',\n toggleRow: 'Toggle child rows',\n selectGroup: 'Select group',\n toggleGroup: 'Toggle group',\n noMatches: 'No matches',\n // The filter panel's search box has no visible label, so `search` is both its\n // placeholder AND its accessible name.\n search: 'Search',\n reset: 'Reset',\n },\n eventCalendar: {\n today: 'Today',\n previous: 'Previous',\n next: 'Next',\n month: 'Month',\n week: 'Week',\n day: 'Day',\n time: 'Time',\n allDay: 'All day',\n label: 'Calendar',\n more: '+{{count}} more',\n // The five composed strings below are the same defect `wr-calendar` fixed\n // one component over: each was a TypeScript template literal, so the month\n // name and the date came from `Intl` and the ORDER and the punctuation\n // between them did not. A locale could translate every word in them and\n // still be stuck with English word order — ja-JP writes 2026年3月.\n header: '{{month}} {{year}}',\n range: '{{from}} – {{to}}',\n // Accessible names, which is why they matter more than they look: these\n // three are what a screen reader announces for every chip and every cell in\n // the grid, so a frozen separator is heard on every one of them.\n chipLabel: '{{title}}, {{time}}',\n slotLabel: '{{time}} — {{date}}',\n allDayCellLabel: '{{label}} — {{date}}',\n },\n tour: {\n next: 'Next',\n back: 'Back',\n done: 'Done',\n skip: 'Skip tour',\n progress: 'Step {{current}} of {{total}}',\n },\n splitter: {\n divider: 'Resize panes',\n },\n stepper: {\n // Rendered as a badge beside the step's own label, so it reads as part of the\n // header rather than as a sentence — lowercase on purpose.\n optional: 'optional',\n },\n transfer: {\n source: 'Available',\n target: 'Selected',\n search: 'Search',\n empty: 'Nothing here',\n selectAll: 'Select all',\n toTarget: 'Move to selected',\n toSource: 'Move to available',\n count: '{{checked}} / {{total}}',\n selectAllAria: '{{pane}} — {{action}}',\n },\n form: {\n // Rendered inside the label's parentheses — `(optional)` — so it is a bare\n // lowercase word and no locale has to repeat the punctuation. Same shape as\n // `stepper.optional`, and unlike the `*` marker this one is NOT `aria-hidden`.\n optional: 'optional',\n },\n validation: {\n required: 'This field is required.',\n requiredTrue: 'This field must be checked.',\n email: 'Enter a valid email address.',\n // A noun straight after a count is a plural bug waiting for the value 1 —\n // \"Enter at least 1 characters.\" — and there is no plural machinery anywhere\n // in this layer, so the wording has to be right at EVERY value rather than\n // at the common ones. Putting the number last does it: the sentence reads\n // the same at 1 and at 80.\n //\n // The other twenty-one catalogs carry the same shape in their own\n // morphology — ru's \"символов\" is genitive plural, correct for 5–20 and\n // wrong for 1 and for 2–4. Each needs a native speaker; guessing at Czech\n // plural rules from here would be the same mistake in a new language.\n minlength: 'Minimum length is {{requiredLength}}.',\n maxlength: 'Maximum length is {{requiredLength}}.',\n min: 'Enter {{min}} or more.',\n max: 'Enter {{max}} or less.',\n pattern: 'This value is not in the expected format.',\n noWhitespace: 'This value cannot contain spaces.',\n hexColor: 'Enter a hex colour, e.g. #1a2b3c.',\n url: 'Enter a valid URL.',\n cardNumber: 'Enter a valid card number.',\n cvc: 'Enter the {{length}}-digit security code.',\n iban: 'Enter a valid IBAN.',\n match: 'The two values do not match.',\n matchFields: 'These fields do not match.',\n oneOf: 'Choose one of the allowed values.',\n minDate: 'Choose a later date.',\n maxDate: 'Choose an earlier date.',\n },\n select: {\n label: 'Select',\n placeholder: 'Select…',\n empty: 'No options',\n clearSelection: 'Clear selection',\n removeItem: 'Remove {{label}}',\n noResults: 'No results',\n loading: 'Loading…',\n more: '+{{count}} more',\n },\n // `tree` covers both inline display and combobox-mode pickers\n // (replaces the dropped `treeSelect` namespace).\n tree: {\n expand: 'Expand',\n collapse: 'Collapse',\n placeholder: 'Select…',\n clearSelection: 'Clear selection',\n removeItem: 'Remove {{label}}',\n // Same string and same shape as `select.more` — the two components render\n // the identical overflow chip, and only one of them could be translated.\n more: '+{{count}} more',\n },\n commandPalette: {\n label: 'Command palette',\n placeholder: 'Type a command or search…',\n noResults: 'No results',\n // Shown INSTEAD of `noResults` while a host-driven search is in flight.\n // Without it an async palette reads \"No results\" between every keystroke\n // and its answer, which states something false about the query.\n loading: 'Searching…',\n // The key-cap chip in the search row. A key NAME rather than prose, so most\n // locales will leave it alone — but a keyboard whose key is not labelled\n // \"esc\" had no way to say so.\n escHint: 'esc',\n },\n empty: {\n noData: 'No data',\n },\n fileUpload: {\n browse: 'Click to browse',\n dropZone: 'or drop files here',\n dropZoneLabel: 'File upload drop zone — click or drop files',\n removeFile: 'Remove file',\n invalid: 'Unsupported file type',\n tooBig: 'File too large',\n // File size, as a template plus a unit table. The number itself goes through\n // `Intl.NumberFormat`, so the decimal separator follows `LOCALE_ID`; what a\n // catalog owns here is the unit abbreviation and whether a space sits before\n // it. Binary units (1024), which is what the component counts in.\n size: '{{value}} {{unit}}',\n unitByte: 'B',\n unitKb: 'KB',\n unitMb: 'MB',\n unitGb: 'GB',\n unitTb: 'TB',\n },\n popconfirm: {\n label: 'Confirm action',\n confirm: 'Confirm',\n cancel: 'Cancel',\n },\n toast: {\n region: 'Notifications',\n close: 'Close',\n copy: 'Copy',\n copied: 'Copied',\n closeAll: 'Close all',\n },\n input: {\n showPassword: 'Show password',\n hidePassword: 'Hide password',\n },\n inputNumber: {\n increment: 'Increment',\n decrement: 'Decrement',\n },\n // Two names for one box, chosen by `mode`: only the numeric strip holds digits.\n // One key saying \"Digit\" would be a lie on the alphanumeric and text modes, which\n // accept letters — a wrong name is worse than an untranslated one.\n inputOtp: {\n label: 'Verification code',\n digit: 'Digit {{index}}',\n character: 'Character {{index}}',\n },\n anchor: {\n label: 'Table of contents',\n },\n avatar: {\n alt: 'Avatar',\n },\n backTop: {\n label: 'Back to top',\n },\n breadcrumbs: {\n label: 'Breadcrumbs',\n },\n burger: {\n label: 'Toggle menu',\n },\n calendar: {\n prevMonth: 'Previous month',\n nextMonth: 'Next month',\n prevYear: 'Previous year',\n nextYear: 'Next year',\n // The month / year pickers are `role=\"listbox\"`, and a listbox owes a\n // name — without one a screen reader announces the control as nothing at\n // all. Caught by `check:state-a11y` once a state finally opened the view.\n monthList: 'Months',\n yearList: 'Years',\n prevYears: 'Previous 12 years',\n nextYears: 'Next 12 years',\n // The header above the grid, as ONE template. It was `${month} ${year}` in\n // TypeScript, which is English word order with an English separator: ja-JP\n // writes 2026年3月 and cannot get there by translating a word.\n header: '{{month}} {{year}}',\n // The year view's header, same reason — the en dash was hardcoded too.\n yearRange: '{{from}} – {{to}}',\n // A day cell's accessible name. `{{date}}` is the adapter's `longDate`, so\n // the date itself is `Intl`-ordered and `Intl`-punctuated; the catalog owns\n // only where the weekday goes relative to it.\n dayLabel: '{{weekday}}, {{date}}',\n },\n imageCropper: {\n empty: 'No image',\n window: 'Crop region',\n keyHelp:\n 'Arrow keys move the crop. Hold Alt with an arrow key to resize it, and Shift for larger steps. ' +\n 'The crop is announced as left, top, width and height in image pixels.',\n },\n sortableList: {\n keyHelp:\n 'Press Space to pick this item up, then use the arrow keys to move it. ' +\n 'Press Space again to drop it, or Escape to put it back.',\n grabbed: 'Grabbed. {{index}} of {{total}}.',\n moved: '{{index}} of {{total}}.',\n dropped: 'Dropped. {{index}} of {{total}}.',\n cancelled: 'Move cancelled.',\n },\n colorPicker: {\n // The saturation / brightness canvas is a `role=\"group\"`, which has no\n // `aria-valuenow` — so its two values ride in its name.\n area: 'Saturation and brightness, {{saturation}}% and {{brightness}}%',\n hue: 'Hue',\n alpha: 'Opacity',\n // The format strip. Three initialisms most locales keep as they are — which\n // is the reason they were left as literals, and not a reason a locale should\n // be unable to change them.\n formatHex: 'HEX',\n formatRgb: 'RGB',\n formatHsl: 'HSL',\n // Channel field labels. Each `<span>` is inside the `<label>` that names its\n // number input, so these are accessible names, not decoration. The `%` is\n // part of the string on purpose: a locale that spaces it differently, or\n // spells the channel with a different letter, needs to move both together.\n channelHex: 'HEX',\n channelRed: 'R',\n channelGreen: 'G',\n channelBlue: 'B',\n channelHue: 'H',\n channelSaturation: 'S%',\n channelLightness: 'L%',\n channelAlpha: 'A%',\n },\n calendarHeatmap: {\n label: 'Calendar heatmap',\n cell: '{{date}}: {{count}}',\n },\n lineChart: {\n label: 'Line chart',\n // The Y-axis tick abbreviation. `k` is a Latin convention — ru writes\n // `тыс.` — and the axis had it hardcoded, so it was the one number on the\n // chart no locale could reach. The digits go through `Intl.NumberFormat`,\n // so the catalog owns the suffix and whether a space sits before it.\n thousands: '{{value}}k',\n },\n donutChart: {\n label: 'Donut chart',\n },\n compare: {\n label: 'Comparison divider',\n },\n // The two `roledescription` values are spoken INSTEAD of the role name, so they\n // are lowercase nouns (\"carousel\", \"slide\") the way a role name would be — not\n // sentence-case labels like the ones above them.\n carousel: {\n label: 'Carousel',\n goToSlide: 'Go to slide {{index}}',\n prev: 'Previous slide',\n next: 'Next slide',\n pagination: 'Carousel pagination',\n roledescription: 'carousel',\n slideRoledescription: 'slide',\n },\n actionSheet: {\n label: 'Actions',\n },\n alert: {\n close: 'Close alert',\n },\n qr: {\n label: 'QR code',\n },\n image: {\n viewer: 'Image preview',\n open: 'Open preview',\n close: 'Close preview',\n },\n window: {\n close: 'Close',\n minimize: 'Minimize',\n maximize: 'Maximize',\n restore: 'Restore',\n restoreDown: 'Restore down',\n restoreWindow: 'Restore {{title}}',\n closeWindow: 'Close window',\n untitled: 'Untitled',\n taskbar: 'Minimized windows',\n },\n dialog: {\n close: 'Close dialog',\n },\n // Deliberately generic: a popover panel has no universal name, and an unnamed\n // `role=\"dialog\"` announces as nothing at all. Override per instance with\n // `[ariaLabel]`.\n popover: {\n label: 'Popover',\n },\n markdown: {\n copy: 'Copy code',\n copied: 'Copied',\n // Read before a task item's text, so a screen reader gets the state that the\n // checkbox glyph carries visually.\n taskDone: 'Done:',\n taskTodo: 'To do:',\n },\n // Count-neutral on purpose: `wrInterpolate` does `{{name}}` substitution only,\n // with no plural support, so \"Matches available: 1\" has to read correctly too.\n marquee: {\n label: 'Marquee',\n link: 'link',\n },\n mention: {\n listbox: 'Mentions',\n available: 'Matches available: {{count}}',\n inserted: 'Inserted: {{label}}',\n },\n drawer: {\n close: 'Close drawer',\n },\n datePicker: {\n open: 'Open calendar',\n openTime: 'Open time picker',\n openDateTime: 'Open date and time picker',\n openRange: 'Open range calendar',\n panel: 'Choose date',\n panelTime: 'Choose time',\n panelDateTime: 'Choose date and time',\n panelRange: 'Choose date range',\n panelRangeDateTime: 'Choose date and time range',\n rangeStart: 'Range start',\n rangeEnd: 'Range end',\n startTime: 'Start time',\n endTime: 'End time',\n hours: 'Hours',\n minutes: 'Minutes',\n seconds: 'Seconds',\n incrementHours: 'Increment hours',\n decrementHours: 'Decrement hours',\n incrementMinutes: 'Increment minutes',\n decrementMinutes: 'Decrement minutes',\n incrementSeconds: 'Increment seconds',\n decrementSeconds: 'Decrement seconds',\n toggleAmPm: 'Toggle AM / PM',\n // Rendered in the meridiem column and re-announced by its `aria-live` span on\n // every toggle, so it is a translated word rather than a fixed glyph — `wrRu`\n // spells these ДП / ПП.\n am: 'AM',\n pm: 'PM',\n },\n sidebar: {\n label: 'Sidebar',\n },\n spinner: {\n label: 'Loading',\n },\n rating: {\n label: 'Rating',\n },\n gauge: {\n label: 'Gauge',\n },\n graph: {\n label: 'Graph',\n // Read out inside each node of <wr-graph>. `{{names}}` is a list the component\n // has already joined with Intl.ListFormat, so the sentence never carries a count.\n // Each value is a whole sentence with its own terminator: a node with both reads\n // the two joined by a single space, and adds no punctuation of its own.\n parents: 'Parents: {{names}}.',\n children: 'Children: {{names}}.',\n },\n progress: {\n label: 'Progress',\n },\n meterGroup: {\n label: 'Meter',\n },\n knob: {\n label: 'Value',\n },\n slider: {\n label: 'Value',\n // Range mode gives each end its own thumb, and each thumb its own name — a\n // screen reader otherwise reads the same word twice for two different values.\n lower: 'Lower value',\n upper: 'Upper value',\n },\n speedDial: {\n label: 'Actions',\n },\n statistic: {\n // The delta chip, e.g. `+12.4%`. The number is formatted through\n // `Intl.NumberFormat` (so its sign, digits and decimal separator follow\n // `LOCALE_ID`, matching the value above it), and this template owns whether\n // a space sits between it and the unit.\n delta: '{{value}}{{suffix}}',\n // The unit the component appends when the consumer binds no `deltaSuffix`.\n deltaSuffix: '%',\n },\n result: {\n notFound: 'Sorry, the page you visited does not exist.',\n forbidden: 'Sorry, you are not authorized to access this page.',\n serverError: 'Sorry, something went wrong.',\n },\n date: {\n months: {\n jan: 'January',\n feb: 'February',\n mar: 'March',\n apr: 'April',\n may: 'May',\n jun: 'June',\n jul: 'July',\n aug: 'August',\n sep: 'September',\n oct: 'October',\n nov: 'November',\n dec: 'December',\n },\n },\n};\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;AAuBG;AACI,MAAM,IAAI,GAAkB;AACjC,IAAA,MAAM,EAAE;AACN,QAAA,EAAE,EAAE,IAAI;AACR,QAAA,MAAM,EAAE,QAAQ;AAChB,QAAA,KAAK,EAAE,OAAO;AACd,QAAA,OAAO,EAAE,SAAS;AAClB,QAAA,MAAM,EAAE,QAAQ;AAChB,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,GAAG,EAAE,KAAK;AACV,QAAA,MAAM,EAAE,QAAQ;AAChB,QAAA,KAAK,EAAE,OAAO;AACd,QAAA,MAAM,EAAE,QAAQ;AAChB,QAAA,OAAO,EAAE,UAAU;AACnB,QAAA,MAAM,EAAE,QAAQ;AAChB,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,QAAQ,EAAE,UAAU;AACpB,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,KAAK,EAAE,OAAO;AACd,QAAA,SAAS,EAAE,WAAW;AACtB,QAAA,QAAQ,EAAE,UAAU;AACpB,QAAA,EAAE,EAAE,IAAI;AACT,KAAA;AACD,IAAA,UAAU,EAAE;AACV,QAAA,IAAI,EAAE,eAAe;AACrB,QAAA,IAAI,EAAE,WAAW;AACjB,QAAA,YAAY,EAAE,gBAAgB;AAC9B,QAAA,OAAO,EAAE,iBAAiB;AAC1B,QAAA,QAAQ,EAAE,qBAAqB;AAC/B,QAAA,KAAK,EAAE,YAAY;AACnB,QAAA,MAAM,EAAE,+BAA+B;;;;;;AAMvC,QAAA,KAAK,EAAE,8BAA8B;;;AAGrC,QAAA,OAAO,EAAE,yBAAyB;AACnC,KAAA;AACD,IAAA,KAAK,EAAE;AACL,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,OAAO,EAAE,UAAU;AACnB,QAAA,IAAI,EAAE,aAAa;AACnB,QAAA,MAAM,EAAE,eAAe;AACvB,QAAA,SAAS,EAAE,iBAAiB;AAC5B,QAAA,SAAS,EAAE,YAAY;AACvB,QAAA,SAAS,EAAE,oBAAoB;AAC/B,QAAA,SAAS,EAAE,mBAAmB;AAC9B,QAAA,WAAW,EAAE,cAAc;AAC3B,QAAA,WAAW,EAAE,cAAc;AAC3B,QAAA,SAAS,EAAE,YAAY;;;AAGvB,QAAA,MAAM,EAAE,QAAQ;AAChB,QAAA,KAAK,EAAE,OAAO;AACf,KAAA;AACD,IAAA,aAAa,EAAE;AACb,QAAA,KAAK,EAAE,OAAO;AACd,QAAA,QAAQ,EAAE,UAAU;AACpB,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,KAAK,EAAE,OAAO;AACd,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,GAAG,EAAE,KAAK;AACV,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,MAAM,EAAE,SAAS;AACjB,QAAA,KAAK,EAAE,UAAU;AACjB,QAAA,IAAI,EAAE,iBAAiB;;;;;;AAMvB,QAAA,MAAM,EAAE,oBAAoB;AAC5B,QAAA,KAAK,EAAE,mBAAmB;;;;AAI1B,QAAA,SAAS,EAAE,qBAAqB;AAChC,QAAA,SAAS,EAAE,qBAAqB;AAChC,QAAA,eAAe,EAAE,sBAAsB;AACxC,KAAA;AACD,IAAA,IAAI,EAAE;AACJ,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,IAAI,EAAE,WAAW;AACjB,QAAA,QAAQ,EAAE,+BAA+B;AAC1C,KAAA;AACD,IAAA,QAAQ,EAAE;AACR,QAAA,OAAO,EAAE,cAAc;AACxB,KAAA;AACD,IAAA,OAAO,EAAE;;;AAGP,QAAA,QAAQ,EAAE,UAAU;AACrB,KAAA;AACD,IAAA,QAAQ,EAAE;AACR,QAAA,MAAM,EAAE,WAAW;AACnB,QAAA,MAAM,EAAE,UAAU;AAClB,QAAA,MAAM,EAAE,QAAQ;AAChB,QAAA,KAAK,EAAE,cAAc;AACrB,QAAA,SAAS,EAAE,YAAY;AACvB,QAAA,QAAQ,EAAE,kBAAkB;AAC5B,QAAA,QAAQ,EAAE,mBAAmB;AAC7B,QAAA,KAAK,EAAE,yBAAyB;AAChC,QAAA,aAAa,EAAE,uBAAuB;AACvC,KAAA;AACD,IAAA,IAAI,EAAE;;;;AAIJ,QAAA,QAAQ,EAAE,UAAU;AACrB,KAAA;AACD,IAAA,UAAU,EAAE;AACV,QAAA,QAAQ,EAAE,yBAAyB;AACnC,QAAA,YAAY,EAAE,6BAA6B;AAC3C,QAAA,KAAK,EAAE,8BAA8B;;;;;;;;;;;AAWrC,QAAA,SAAS,EAAE,uCAAuC;AAClD,QAAA,SAAS,EAAE,uCAAuC;AAClD,QAAA,GAAG,EAAE,wBAAwB;AAC7B,QAAA,GAAG,EAAE,wBAAwB;AAC7B,QAAA,OAAO,EAAE,2CAA2C;AACpD,QAAA,YAAY,EAAE,mCAAmC;AACjD,QAAA,QAAQ,EAAE,mCAAmC;AAC7C,QAAA,GAAG,EAAE,oBAAoB;AACzB,QAAA,UAAU,EAAE,4BAA4B;AACxC,QAAA,GAAG,EAAE,2CAA2C;AAChD,QAAA,IAAI,EAAE,qBAAqB;AAC3B,QAAA,KAAK,EAAE,8BAA8B;AACrC,QAAA,WAAW,EAAE,4BAA4B;AACzC,QAAA,KAAK,EAAE,mCAAmC;AAC1C,QAAA,OAAO,EAAE,sBAAsB;AAC/B,QAAA,OAAO,EAAE,yBAAyB;AACnC,KAAA;AACD,IAAA,MAAM,EAAE;AACN,QAAA,KAAK,EAAE,QAAQ;AACf,QAAA,WAAW,EAAE,SAAS;AACtB,QAAA,KAAK,EAAE,YAAY;AACnB,QAAA,cAAc,EAAE,iBAAiB;AACjC,QAAA,UAAU,EAAE,kBAAkB;AAC9B,QAAA,SAAS,EAAE,YAAY;AACvB,QAAA,OAAO,EAAE,UAAU;AACnB,QAAA,IAAI,EAAE,iBAAiB;AACxB,KAAA;;;AAGD,IAAA,IAAI,EAAE;AACJ,QAAA,MAAM,EAAE,QAAQ;AAChB,QAAA,QAAQ,EAAE,UAAU;AACpB,QAAA,WAAW,EAAE,SAAS;AACtB,QAAA,cAAc,EAAE,iBAAiB;AACjC,QAAA,UAAU,EAAE,kBAAkB;;;AAG9B,QAAA,IAAI,EAAE,iBAAiB;AACxB,KAAA;AACD,IAAA,cAAc,EAAE;AACd,QAAA,KAAK,EAAE,iBAAiB;AACxB,QAAA,WAAW,EAAE,2BAA2B;AACxC,QAAA,SAAS,EAAE,YAAY;;;;AAIvB,QAAA,OAAO,EAAE,YAAY;;;;AAIrB,QAAA,OAAO,EAAE,KAAK;AACf,KAAA;AACD,IAAA,KAAK,EAAE;AACL,QAAA,MAAM,EAAE,SAAS;AAClB,KAAA;AACD,IAAA,UAAU,EAAE;AACV,QAAA,MAAM,EAAE,iBAAiB;AACzB,QAAA,QAAQ,EAAE,oBAAoB;AAC9B,QAAA,aAAa,EAAE,6CAA6C;AAC5D,QAAA,UAAU,EAAE,aAAa;AACzB,QAAA,OAAO,EAAE,uBAAuB;AAChC,QAAA,MAAM,EAAE,gBAAgB;;;;;AAKxB,QAAA,IAAI,EAAE,oBAAoB;AAC1B,QAAA,QAAQ,EAAE,GAAG;AACb,QAAA,MAAM,EAAE,IAAI;AACZ,QAAA,MAAM,EAAE,IAAI;AACZ,QAAA,MAAM,EAAE,IAAI;AACZ,QAAA,MAAM,EAAE,IAAI;AACb,KAAA;AACD,IAAA,UAAU,EAAE;AACV,QAAA,KAAK,EAAE,gBAAgB;AACvB,QAAA,OAAO,EAAE,SAAS;AAClB,QAAA,MAAM,EAAE,QAAQ;AACjB,KAAA;AACD,IAAA,KAAK,EAAE;AACL,QAAA,MAAM,EAAE,eAAe;AACvB,QAAA,KAAK,EAAE,OAAO;AACd,QAAA,IAAI,EAAE,MAAM;AACZ,QAAA,MAAM,EAAE,QAAQ;AAChB,QAAA,QAAQ,EAAE,WAAW;AACtB,KAAA;AACD,IAAA,KAAK,EAAE;AACL,QAAA,YAAY,EAAE,eAAe;AAC7B,QAAA,YAAY,EAAE,eAAe;AAC9B,KAAA;AACD,IAAA,WAAW,EAAE;AACX,QAAA,SAAS,EAAE,WAAW;AACtB,QAAA,SAAS,EAAE,WAAW;AACvB,KAAA;;;;AAID,IAAA,QAAQ,EAAE;AACR,QAAA,KAAK,EAAE,mBAAmB;AAC1B,QAAA,KAAK,EAAE,iBAAiB;AACxB,QAAA,SAAS,EAAE,qBAAqB;AACjC,KAAA;AACD,IAAA,MAAM,EAAE;AACN,QAAA,KAAK,EAAE,mBAAmB;AAC3B,KAAA;AACD,IAAA,MAAM,EAAE;AACN,QAAA,GAAG,EAAE,QAAQ;AACd,KAAA;AACD,IAAA,OAAO,EAAE;AACP,QAAA,KAAK,EAAE,aAAa;AACrB,KAAA;AACD,IAAA,WAAW,EAAE;AACX,QAAA,KAAK,EAAE,aAAa;AACrB,KAAA;AACD,IAAA,MAAM,EAAE;AACN,QAAA,KAAK,EAAE,aAAa;AACrB,KAAA;AACD,IAAA,QAAQ,EAAE;AACR,QAAA,SAAS,EAAE,gBAAgB;AAC3B,QAAA,SAAS,EAAE,YAAY;AACvB,QAAA,QAAQ,EAAE,eAAe;AACzB,QAAA,QAAQ,EAAE,WAAW;;;;AAIrB,QAAA,SAAS,EAAE,QAAQ;AACnB,QAAA,QAAQ,EAAE,OAAO;AACjB,QAAA,SAAS,EAAE,mBAAmB;AAC9B,QAAA,SAAS,EAAE,eAAe;;;;AAI1B,QAAA,MAAM,EAAE,oBAAoB;;AAE5B,QAAA,SAAS,EAAE,mBAAmB;;;;AAI9B,QAAA,QAAQ,EAAE,uBAAuB;AAClC,KAAA;AACD,IAAA,YAAY,EAAE;AACZ,QAAA,KAAK,EAAE,UAAU;AACjB,QAAA,MAAM,EAAE,aAAa;AACrB,QAAA,OAAO,EACL,iGAAiG;YACjG,uEAAuE;AAC1E,KAAA;AACD,IAAA,YAAY,EAAE;AACZ,QAAA,OAAO,EACL,wEAAwE;YACxE,yDAAyD;AAC3D,QAAA,OAAO,EAAE,kCAAkC;AAC3C,QAAA,KAAK,EAAE,yBAAyB;AAChC,QAAA,OAAO,EAAE,kCAAkC;AAC3C,QAAA,SAAS,EAAE,iBAAiB;AAC7B,KAAA;AACD,IAAA,WAAW,EAAE;;;AAGX,QAAA,IAAI,EAAE,gEAAgE;AACtE,QAAA,GAAG,EAAE,KAAK;AACV,QAAA,KAAK,EAAE,SAAS;;;;AAIhB,QAAA,SAAS,EAAE,KAAK;AAChB,QAAA,SAAS,EAAE,KAAK;AAChB,QAAA,SAAS,EAAE,KAAK;;;;;AAKhB,QAAA,UAAU,EAAE,KAAK;AACjB,QAAA,UAAU,EAAE,GAAG;AACf,QAAA,YAAY,EAAE,GAAG;AACjB,QAAA,WAAW,EAAE,GAAG;AAChB,QAAA,UAAU,EAAE,GAAG;AACf,QAAA,iBAAiB,EAAE,IAAI;AACvB,QAAA,gBAAgB,EAAE,IAAI;AACtB,QAAA,YAAY,EAAE,IAAI;AACnB,KAAA;AACD,IAAA,eAAe,EAAE;AACf,QAAA,KAAK,EAAE,kBAAkB;AACzB,QAAA,IAAI,EAAE,qBAAqB;AAC5B,KAAA;AACD,IAAA,SAAS,EAAE;AACT,QAAA,KAAK,EAAE,YAAY;;;;;AAKnB,QAAA,SAAS,EAAE,YAAY;AACxB,KAAA;AACD,IAAA,UAAU,EAAE;AACV,QAAA,KAAK,EAAE,aAAa;AACrB,KAAA;AACD,IAAA,OAAO,EAAE;AACP,QAAA,KAAK,EAAE,oBAAoB;AAC5B,KAAA;;;;AAID,IAAA,QAAQ,EAAE;AACR,QAAA,KAAK,EAAE,UAAU;AACjB,QAAA,SAAS,EAAE,uBAAuB;AAClC,QAAA,IAAI,EAAE,gBAAgB;AACtB,QAAA,IAAI,EAAE,YAAY;AAClB,QAAA,UAAU,EAAE,qBAAqB;AACjC,QAAA,eAAe,EAAE,UAAU;AAC3B,QAAA,oBAAoB,EAAE,OAAO;AAC9B,KAAA;AACD,IAAA,WAAW,EAAE;AACX,QAAA,KAAK,EAAE,SAAS;AACjB,KAAA;AACD,IAAA,KAAK,EAAE;AACL,QAAA,KAAK,EAAE,aAAa;AACrB,KAAA;AACD,IAAA,EAAE,EAAE;AACF,QAAA,KAAK,EAAE,SAAS;AACjB,KAAA;AACD,IAAA,KAAK,EAAE;AACL,QAAA,MAAM,EAAE,eAAe;AACvB,QAAA,IAAI,EAAE,cAAc;AACpB,QAAA,KAAK,EAAE,eAAe;AACvB,KAAA;AACD,IAAA,MAAM,EAAE;AACN,QAAA,KAAK,EAAE,OAAO;AACd,QAAA,QAAQ,EAAE,UAAU;AACpB,QAAA,QAAQ,EAAE,UAAU;AACpB,QAAA,OAAO,EAAE,SAAS;AAClB,QAAA,WAAW,EAAE,cAAc;AAC3B,QAAA,aAAa,EAAE,mBAAmB;AAClC,QAAA,WAAW,EAAE,cAAc;AAC3B,QAAA,QAAQ,EAAE,UAAU;AACpB,QAAA,OAAO,EAAE,mBAAmB;AAC7B,KAAA;AACD,IAAA,MAAM,EAAE;AACN,QAAA,KAAK,EAAE,cAAc;AACtB,KAAA;;;;AAID,IAAA,OAAO,EAAE;AACP,QAAA,KAAK,EAAE,SAAS;AACjB,KAAA;AACD,IAAA,QAAQ,EAAE;AACR,QAAA,IAAI,EAAE,WAAW;AACjB,QAAA,MAAM,EAAE,QAAQ;;;AAGhB,QAAA,QAAQ,EAAE,OAAO;AACjB,QAAA,QAAQ,EAAE,QAAQ;AACnB,KAAA;;;AAGD,IAAA,OAAO,EAAE;AACP,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,IAAI,EAAE,MAAM;AACb,KAAA;AACD,IAAA,OAAO,EAAE;AACP,QAAA,OAAO,EAAE,UAAU;AACnB,QAAA,SAAS,EAAE,8BAA8B;AACzC,QAAA,QAAQ,EAAE,qBAAqB;AAChC,KAAA;AACD,IAAA,MAAM,EAAE;AACN,QAAA,KAAK,EAAE,cAAc;AACtB,KAAA;AACD,IAAA,UAAU,EAAE;AACV,QAAA,IAAI,EAAE,eAAe;AACrB,QAAA,QAAQ,EAAE,kBAAkB;AAC5B,QAAA,YAAY,EAAE,2BAA2B;AACzC,QAAA,SAAS,EAAE,qBAAqB;AAChC,QAAA,KAAK,EAAE,aAAa;AACpB,QAAA,SAAS,EAAE,aAAa;AACxB,QAAA,aAAa,EAAE,sBAAsB;AACrC,QAAA,UAAU,EAAE,mBAAmB;AAC/B,QAAA,kBAAkB,EAAE,4BAA4B;AAChD,QAAA,UAAU,EAAE,aAAa;AACzB,QAAA,QAAQ,EAAE,WAAW;AACrB,QAAA,SAAS,EAAE,YAAY;AACvB,QAAA,OAAO,EAAE,UAAU;AACnB,QAAA,KAAK,EAAE,OAAO;AACd,QAAA,OAAO,EAAE,SAAS;AAClB,QAAA,OAAO,EAAE,SAAS;AAClB,QAAA,cAAc,EAAE,iBAAiB;AACjC,QAAA,cAAc,EAAE,iBAAiB;AACjC,QAAA,gBAAgB,EAAE,mBAAmB;AACrC,QAAA,gBAAgB,EAAE,mBAAmB;AACrC,QAAA,gBAAgB,EAAE,mBAAmB;AACrC,QAAA,gBAAgB,EAAE,mBAAmB;AACrC,QAAA,UAAU,EAAE,gBAAgB;;;;AAI5B,QAAA,EAAE,EAAE,IAAI;AACR,QAAA,EAAE,EAAE,IAAI;AACT,KAAA;AACD,IAAA,OAAO,EAAE;AACP,QAAA,KAAK,EAAE,SAAS;AACjB,KAAA;AACD,IAAA,OAAO,EAAE;AACP,QAAA,KAAK,EAAE,SAAS;AACjB,KAAA;AACD,IAAA,MAAM,EAAE;AACN,QAAA,KAAK,EAAE,QAAQ;AAChB,KAAA;AACD,IAAA,KAAK,EAAE;AACL,QAAA,KAAK,EAAE,OAAO;AACf,KAAA;AACD,IAAA,KAAK,EAAE;AACL,QAAA,KAAK,EAAE,OAAO;;;;;AAKd,QAAA,OAAO,EAAE,qBAAqB;AAC9B,QAAA,QAAQ,EAAE,sBAAsB;AACjC,KAAA;AACD,IAAA,QAAQ,EAAE;AACR,QAAA,KAAK,EAAE,UAAU;AAClB,KAAA;AACD,IAAA,UAAU,EAAE;AACV,QAAA,KAAK,EAAE,OAAO;AACf,KAAA;AACD,IAAA,IAAI,EAAE;AACJ,QAAA,KAAK,EAAE,OAAO;AACf,KAAA;AACD,IAAA,MAAM,EAAE;AACN,QAAA,KAAK,EAAE,OAAO;;;AAGd,QAAA,KAAK,EAAE,aAAa;AACpB,QAAA,KAAK,EAAE,aAAa;AACrB,KAAA;AACD,IAAA,SAAS,EAAE;AACT,QAAA,KAAK,EAAE,SAAS;AACjB,KAAA;AACD,IAAA,SAAS,EAAE;;;;;AAKT,QAAA,KAAK,EAAE,qBAAqB;;AAE5B,QAAA,WAAW,EAAE,GAAG;AACjB,KAAA;AACD,IAAA,MAAM,EAAE;AACN,QAAA,QAAQ,EAAE,6CAA6C;AACvD,QAAA,SAAS,EAAE,oDAAoD;AAC/D,QAAA,WAAW,EAAE,8BAA8B;AAC5C,KAAA;AACD,IAAA,IAAI,EAAE;AACJ,QAAA,MAAM,EAAE;AACN,YAAA,GAAG,EAAE,SAAS;AACd,YAAA,GAAG,EAAE,UAAU;AACf,YAAA,GAAG,EAAE,OAAO;AACZ,YAAA,GAAG,EAAE,OAAO;AACZ,YAAA,GAAG,EAAE,KAAK;AACV,YAAA,GAAG,EAAE,MAAM;AACX,YAAA,GAAG,EAAE,MAAM;AACX,YAAA,GAAG,EAAE,QAAQ;AACb,YAAA,GAAG,EAAE,WAAW;AAChB,YAAA,GAAG,EAAE,SAAS;AACd,YAAA,GAAG,EAAE,UAAU;AACf,YAAA,GAAG,EAAE,UAAU;AAChB,SAAA;AACF,KAAA;;;ACxgBH;;AAEG;;;;"}
@@ -559,6 +559,15 @@ function provideWrI18n(options = {}) {
559
559
  /**
560
560
  * Provide a static loader — catalogs already in memory.
561
561
  *
562
+ * A loader serves only the catalog you pass it, and ngwr registers none of its
563
+ * own. Pass only your own keys here and register ngwr's catalogs with
564
+ * {@link provideWrI18nBaseCatalogs} — not `{ ...wrRu, ...yours }`. A spread is
565
+ * shallow, so any namespace you share with ngwr, e.g. `common`, `validation`,
566
+ * `table`, keeps only the keys of the side spread last, and the other side's
567
+ * keys stop resolving with nothing logged: ngwr's components fall back to their
568
+ * English defaults, and a `wrT` read of a lost key renders the raw key under the
569
+ * default missing handler.
570
+ *
562
571
  * @param catalogs Root catalogs keyed by locale.
563
572
  * @param scopes Optional per-scope catalogs served to `registerScope(name)`.
564
573
  */
@@ -586,6 +595,10 @@ function provideWrI18nStaticLoader(catalogs, scopes) {
586
595
  *
587
596
  * Pass only the locales you ship — the ones you leave out stay out of the
588
597
  * bundle. Your own keys always win; this is a floor, not an override.
598
+ *
599
+ * Use it instead of spreading `wrRu` into your own catalog, too: the lookup
600
+ * walks these key by key after the loader's catalog misses, so a namespace both
601
+ * define keeps both halves, where a shallow spread keeps only one.
589
602
  */
590
603
  function provideWrI18nBaseCatalogs(catalogs) {
591
604
  return { provide: WR_I18N_BASE_CATALOGS, useValue: catalogs, multi: true };