@ethlete/core 5.0.0-next.52 → 5.0.0-next.54

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.
@@ -1,10 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, ElementRef, Directive, assertInInjectionContext, DestroyRef, TemplateRef, QueryList, RendererFactory2, RendererStyleFlags2, isSignal, DOCUMENT, signal, linkedSignal, isDevMode, computed, afterNextRender, effect, NgZone, untracked, EnvironmentInjector, runInInjectionContext, Injector, booleanAttribute, numberAttribute, PLATFORM_ID, ApplicationRef, createComponent, model, ViewContainerRef, input, ViewEncapsulation, Component, provideEnvironmentInitializer, output, Pipe, afterEveryRender } from '@angular/core';
2
+ import { InjectionToken, inject, ElementRef, isDevMode, Directive, assertInInjectionContext, DestroyRef, TemplateRef, QueryList, RendererFactory2, RendererStyleFlags2, isSignal, DOCUMENT, signal, linkedSignal, computed, afterNextRender, effect, untracked, EnvironmentInjector, runInInjectionContext, NgZone, Injector, booleanAttribute, numberAttribute, PLATFORM_ID, ApplicationRef, createComponent, model, ViewContainerRef, input, ViewEncapsulation, Component, provideEnvironmentInitializer, output, createEnvironmentInjector, Pipe, afterEveryRender } from '@angular/core';
3
3
  import { takeUntilDestroyed, toSignal, toObservable, outputFromObservable } from '@angular/core/rxjs-interop';
4
4
  import { Subject, BehaviorSubject, debounceTime, combineLatest, map, merge, fromEvent, filter, tap, switchMap, startWith, of, defer, from, catchError, timer, takeUntil, pairwise, distinctUntilChanged, EMPTY, take, Observable, isObservable, firstValueFrom, defaultIfEmpty, concatMap, concat, finalize, exhaustMap, share, shareReplay } from 'rxjs';
5
5
  import { FormGroup, FormArray, FormControl } from '@angular/forms';
6
6
  import { SIGNAL, signalSetFn } from '@angular/core/primitives/signals';
7
- import { DOCUMENT as DOCUMENT$1, isPlatformBrowser } from '@angular/common';
7
+ import { isPlatformBrowser, DOCUMENT as DOCUMENT$1 } from '@angular/common';
8
8
  import { Router, NavigationEnd, NavigationSkipped, NavigationStart, NavigationError, RouterLink } from '@angular/router';
9
9
  import { Title, Meta, DomSanitizer } from '@angular/platform-browser';
10
10
  import { offset, flip, shift, limitShift, computePosition, autoUpdate, hide, arrow, size } from '@floating-ui/dom';
@@ -83,7 +83,9 @@ class AnimatableDirective {
83
83
  }
84
84
  else {
85
85
  animationDebugLog(`animatable ${el.tagName.toLowerCase()}`, `${eventType} ignored - count already 0 (start ${didEmitStart ? '' : 'not '}emitted)`);
86
- console.warn(`${el.tagName} received animation end/cancel event but activeAnimationCount is already 0. Start was ${didEmitStart ? '' : 'not '}emitted.`);
86
+ if (isDevMode()) {
87
+ console.warn(`${el.tagName} received animation end/cancel event but activeAnimationCount is already 0. Start was ${didEmitStart ? '' : 'not '}emitted.`);
88
+ }
87
89
  }
88
90
  break;
89
91
  }
@@ -277,59 +279,40 @@ const maybeMergeValues = (defaultValue, valueOverride) => {
277
279
  };
278
280
 
279
281
  const cloneFormGroup = (formGroup) => {
280
- const cloneLevel = (group, cloneGroup) => {
281
- Object.entries(group.controls).forEach(([key, control]) => {
282
- if (control instanceof FormGroup) {
283
- const cloneControl = new FormGroup({}, control.validator, control.asyncValidator);
284
- cloneGroup.addControl(key, cloneControl);
285
- cloneLevel(control, cloneControl);
286
- }
287
- else if (control instanceof FormArray) {
288
- const cloneArrayControl = new FormArray([], control.validator, control.asyncValidator);
289
- control.controls.forEach((control) => {
290
- if (control instanceof FormGroup) {
291
- const cloneControl = new FormGroup({}, control.validator, control.asyncValidator);
292
- const innerClone = cloneLevel(control, cloneControl);
293
- cloneArrayControl.push(innerClone);
294
- }
295
- else {
296
- const cloneControlItem = new FormControl({ value: control.value, disabled: control.disabled }, control.validator, control.asyncValidator);
297
- cloneArrayControl.push(cloneControlItem);
298
- }
299
- });
300
- cloneGroup.addControl(key, cloneArrayControl);
301
- }
302
- else {
303
- const cloneControl = new FormControl({ value: control.value, disabled: control.disabled }, control.validator, control.asyncValidator);
304
- cloneGroup.addControl(key, cloneControl);
305
- }
306
- });
307
- return cloneGroup;
282
+ const cloneControl = (control) => {
283
+ let clonedControl;
284
+ if (control instanceof FormGroup) {
285
+ const controls = Object.fromEntries(Object.entries(control.controls).map(([key, child]) => [key, cloneControl(child)]));
286
+ clonedControl = new FormGroup(controls, control.validator, control.asyncValidator);
287
+ }
288
+ else if (control instanceof FormArray) {
289
+ clonedControl = new FormArray(control.controls.map((child) => cloneControl(child)), control.validator, control.asyncValidator);
290
+ }
291
+ else {
292
+ clonedControl = new FormControl({ value: control.value, disabled: control.disabled }, control.validator, control.asyncValidator);
293
+ }
294
+ if (control.disabled && clonedControl.enabled) {
295
+ clonedControl.disable({ emitEvent: false });
296
+ }
297
+ return clonedControl;
308
298
  };
309
- const clonedForm = cloneLevel(formGroup, new FormGroup({}));
310
- clonedForm.setValue(formGroup.value);
299
+ const clonedForm = cloneControl(formGroup);
311
300
  clonedForm.updateValueAndValidity();
312
301
  return clonedForm;
313
302
  };
314
303
  const getFormGroupValue = (formGroup) => {
315
- const value = {};
316
- Object.entries(formGroup.controls).forEach(([key, control]) => {
304
+ const getControlValue = (control) => {
317
305
  if (control instanceof FormGroup) {
318
- value[key] = getFormGroupValue(control);
319
- }
320
- else if (control instanceof FormArray) {
321
- value[key] = control.controls.map((control) => {
322
- if (control instanceof FormGroup) {
323
- return getFormGroupValue(control);
324
- }
325
- else {
326
- return control.value ?? null;
327
- }
328
- });
306
+ return getFormGroupValue(control);
329
307
  }
330
- else {
331
- value[key] = control.value ?? null;
308
+ if (control instanceof FormArray) {
309
+ return control.controls.map(getControlValue);
332
310
  }
311
+ return control.value ?? null;
312
+ };
313
+ const value = {};
314
+ Object.entries(formGroup.controls).forEach(([key, control]) => {
315
+ value[key] = getControlValue(control);
333
316
  });
334
317
  return value;
335
318
  };
@@ -393,7 +376,7 @@ const ValidateAtLeastOneRequired = (config) => {
393
376
  const IS_ARRAY_NOT_EMPTY = 'isArrayNotEmpty';
394
377
  const IsArrayNotEmpty = (control) => {
395
378
  const value = control.value;
396
- if (!value) {
379
+ if (!Array.isArray(value)) {
397
380
  return null;
398
381
  }
399
382
  return value.length > 0 ? null : { [IS_ARRAY_NOT_EMPTY]: true };
@@ -404,7 +387,10 @@ const IsEmail = (control) => {
404
387
  if (!value) {
405
388
  return null;
406
389
  }
407
- const regex = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/;
390
+ if (typeof value !== 'string') {
391
+ return null;
392
+ }
393
+ const regex = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i;
408
394
  return regex.test(value) ? null : { [IS_EMAIL]: true };
409
395
  };
410
396
  const MUST_MATCH = 'mustMatch';
@@ -412,20 +398,13 @@ const MustMatch = (controlName, matchingControlName) => {
412
398
  return (formGroup) => {
413
399
  const control = formGroup.get(controlName);
414
400
  const matchingControl = formGroup.get(matchingControlName);
415
- if (matchingControl?.errors && !matchingControl.errors[MUST_MATCH]) {
416
- return null;
417
- }
418
401
  if (control?.value !== matchingControl?.value) {
419
- matchingControl?.setErrors({ [MUST_MATCH]: true });
420
402
  return { [MUST_MATCH]: true };
421
403
  }
422
- else {
423
- matchingControl?.setErrors(null);
424
- return null;
425
- }
404
+ return null;
426
405
  };
427
406
  };
428
- const Validators = {
407
+ const EthleteValidators = {
429
408
  MustMatch,
430
409
  IsEmail,
431
410
  IsArrayNotEmpty,
@@ -490,18 +469,23 @@ const copyToClipboardViaExecCommand = (text) => {
490
469
  *
491
470
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
492
471
  */
493
- const set = (obj, key, val) => {
494
- if (typeof val.value === 'object')
495
- val.value = clone(val.value);
472
+ const set = (obj, key, val, seen) => {
473
+ if (typeof val.value === 'object' && val.value !== null)
474
+ val.value = cloneValue(val.value, seen);
496
475
  if (!val.enumerable || val.get || val.set || !val.configurable || !val.writable || key === '__proto__') {
497
476
  Object.defineProperty(obj, key, val);
498
477
  }
499
478
  else
500
479
  obj[key] = val.value;
501
480
  };
502
- const clone = (original) => {
481
+ const cloneValue = (original, seen) => {
503
482
  if (typeof original !== 'object')
504
483
  return original;
484
+ if (original === null)
485
+ return original;
486
+ const existing = seen.get(original);
487
+ if (existing)
488
+ return existing;
505
489
  var _og = original;
506
490
  var i = 0;
507
491
  var k;
@@ -509,21 +493,23 @@ const clone = (original) => {
509
493
  var tmp;
510
494
  var str = Object.prototype.toString.call(_og);
511
495
  if (str === '[object Object]') {
512
- tmp = Object.create(_og.__proto__ || null);
496
+ tmp = Object.create(Object.getPrototypeOf(_og));
513
497
  }
514
498
  else if (str === '[object Array]') {
515
499
  tmp = Array(_og.length);
516
500
  }
517
501
  else if (str === '[object Set]') {
518
502
  tmp = new Set();
503
+ seen.set(_og, tmp);
519
504
  _og.forEach(function (val) {
520
- tmp.add(clone(val));
505
+ tmp.add(cloneValue(val, seen));
521
506
  });
522
507
  }
523
508
  else if (str === '[object Map]') {
524
509
  tmp = new Map();
510
+ seen.set(_og, tmp);
525
511
  _og.forEach(function (val, key) {
526
- tmp.set(clone(key), clone(val));
512
+ tmp.set(cloneValue(key, seen), cloneValue(val, seen));
527
513
  });
528
514
  }
529
515
  else if (str === '[object Date]') {
@@ -533,7 +519,7 @@ const clone = (original) => {
533
519
  tmp = new RegExp(_og.source, _og.flags);
534
520
  }
535
521
  else if (str === '[object DataView]') {
536
- tmp = new _og.constructor(clone(_og.buffer));
522
+ tmp = new _og.constructor(cloneValue(_og.buffer, seen));
537
523
  }
538
524
  else if (str === '[object ArrayBuffer]') {
539
525
  tmp = _og.slice(0);
@@ -542,17 +528,19 @@ const clone = (original) => {
542
528
  tmp = new _og.constructor(_og);
543
529
  }
544
530
  if (tmp) {
531
+ seen.set(_og, tmp);
545
532
  for (list = Object.getOwnPropertySymbols(_og); i < list.length; i++) {
546
- set(tmp, list[i], Object.getOwnPropertyDescriptor(_og, list[i]));
533
+ set(tmp, list[i], Object.getOwnPropertyDescriptor(_og, list[i]), seen);
547
534
  }
548
535
  for (i = 0, list = Object.getOwnPropertyNames(_og); i < list.length; i++) {
549
536
  if (Object.hasOwnProperty.call(tmp, (k = list[i])) && tmp[k] === _og[k])
550
537
  continue;
551
- set(tmp, k, Object.getOwnPropertyDescriptor(_og, k));
538
+ set(tmp, k, Object.getOwnPropertyDescriptor(_og, k), seen);
552
539
  }
553
540
  }
554
541
  return tmp || _og;
555
542
  };
543
+ const clone = (original) => cloneValue(original, new WeakMap());
556
544
  /**
557
545
  * Stolen from dequal to avoid adding a dependency
558
546
  * https://github.com/lukeed/dequal
@@ -592,7 +580,12 @@ const equal = (foo, bar) => {
592
580
  var tmp;
593
581
  if (foo === bar)
594
582
  return true;
595
- if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
583
+ if (foo &&
584
+ bar &&
585
+ ((ctor = foo.constructor) === bar.constructor ||
586
+ (!ctor && bar.constructor === Object) ||
587
+ (ctor === Object && !bar.constructor))) {
588
+ ctor ??= bar.constructor;
596
589
  if (ctor === Date)
597
590
  return foo.getTime() === bar.getTime();
598
591
  if (ctor === RegExp)
@@ -683,8 +676,8 @@ const getCookie = (name) => {
683
676
  if (typeof document === 'undefined') {
684
677
  return null;
685
678
  }
686
- // From https://stackoverflow.com/questions/10730362/get-cookie-by-name
687
- return ('; ' + document.cookie).split(`; ${name}=`).pop()?.split(';')[0];
679
+ const cookie = document.cookie.split(';').find((entry) => entry.trim().startsWith(`${name}=`));
680
+ return cookie?.trim().slice(name.length + 1) ?? null;
688
681
  };
689
682
  const setCookie = (name, data, expiresInDays, domain = getDomain(), path = '/', sameSite = 'lax') => {
690
683
  if (typeof document === 'undefined') {
@@ -698,7 +691,14 @@ const setCookie = (name, data, expiresInDays, domain = getDomain(), path = '/',
698
691
  date.setTime(date.getTime() + expires * 24 * 60 * 60 * 1000);
699
692
  cookieString += `; expires=${date.toUTCString()}`;
700
693
  }
701
- cookieString += `; domain=${domain}; SameSite=${sameSiteUpper};`;
694
+ if (domain) {
695
+ cookieString += `; domain=${domain}`;
696
+ }
697
+ cookieString += `; SameSite=${sameSiteUpper}`;
698
+ if (sameSite === 'none' || window.location.protocol === 'https:') {
699
+ cookieString += '; Secure';
700
+ }
701
+ cookieString += ';';
702
702
  document.cookie = cookieString;
703
703
  };
704
704
  const deleteCookie = (name, path = '/', domain = getDomain()) => {
@@ -733,15 +733,15 @@ const getDomain = () => {
733
733
  class KeyPressManager {
734
734
  constructor(key) {
735
735
  this.key = key;
736
- this._isKeyPressed$ = new BehaviorSubject(false);
737
- this._keyPressCount$ = new BehaviorSubject(0);
736
+ this.isKeyPressed = false;
737
+ this.keyPressCount = 0;
738
738
  this._stopTimeout$ = new Subject();
739
739
  }
740
740
  isPressed(event) {
741
741
  const key = event.keyCode;
742
742
  if (key === this.key) {
743
- this._isKeyPressed$.next(this._keyPressCount$.value > 1);
744
- this._keyPressCount$.next(this._keyPressCount$.value + 1);
743
+ this.isKeyPressed = this.keyPressCount >= 1;
744
+ this.keyPressCount++;
745
745
  this._stopTimeout$.next();
746
746
  timer(100)
747
747
  .pipe(takeUntil(this._stopTimeout$))
@@ -750,11 +750,11 @@ class KeyPressManager {
750
750
  else {
751
751
  this.clear();
752
752
  }
753
- return this._isKeyPressed$.value;
753
+ return this.isKeyPressed;
754
754
  }
755
755
  clear() {
756
- this._isKeyPressed$.next(false);
757
- this._keyPressCount$.next(0);
756
+ this.isKeyPressed = false;
757
+ this.keyPressCount = 0;
758
758
  this._stopTimeout$.next();
759
759
  }
760
760
  }
@@ -880,9 +880,6 @@ const RENDERER_DEF = /* @__PURE__ */ defineRootProvider(() => {
880
880
  const setTextContent = (element, text) => {
881
881
  renderer.setProperty(element, 'textContent', text);
882
882
  };
883
- const setInnerHTML = (element, html) => {
884
- renderer.setProperty(element, 'innerHTML', html);
885
- };
886
883
  const setAttributes = (element, attributes, namespace) => {
887
884
  Object.entries(attributes).forEach(([name, value]) => {
888
885
  setAttribute(element, name, value, namespace);
@@ -933,7 +930,6 @@ const RENDERER_DEF = /* @__PURE__ */ defineRootProvider(() => {
933
930
  replaceChild,
934
931
  empty,
935
932
  setTextContent,
936
- setInnerHTML,
937
933
  setAttributes,
938
934
  setDataAttributes,
939
935
  setCssProperty,
@@ -949,8 +945,13 @@ const coerceElement = (el) => (el instanceof ElementRef ? el.nativeElement : el)
949
945
  const isElementSignal = (el) => {
950
946
  if (!isSignal(el))
951
947
  return false;
952
- const val = el();
953
- return typeof val === 'object' && val !== null && 'currentElements' in val && 'previousElements' in val;
948
+ try {
949
+ const val = el();
950
+ return typeof val === 'object' && val !== null && 'currentElements' in val && 'previousElements' in val;
951
+ }
952
+ catch {
953
+ return false;
954
+ }
954
955
  };
955
956
  const createDocumentElementSignal = () => {
956
957
  const documentElement = inject(DOCUMENT).documentElement;
@@ -979,8 +980,6 @@ const areElementSignalValuesEqual = (a, b) => areElementArraysEqual(a.currentEle
979
980
  const buildElementSignal = (el) => {
980
981
  if (el === null || el === undefined)
981
982
  return createEmptyElementSignal();
982
- if (isElementSignal(el))
983
- return el;
984
983
  if (el instanceof HTMLElement || el instanceof ElementRef) {
985
984
  const element = coerceElement(el);
986
985
  if (!element)
@@ -998,6 +997,12 @@ const createElementSignalFromSignal = (input) => {
998
997
  return linkedSignal({
999
998
  source: input,
1000
999
  computation: (source, previous) => {
1000
+ if (typeof source === 'object' &&
1001
+ source !== null &&
1002
+ 'currentElements' in source &&
1003
+ 'previousElements' in source) {
1004
+ return source;
1005
+ }
1001
1006
  const currentElements = coerceValueToElementArray(source);
1002
1007
  const previousElements = previous?.value.currentElements ?? [];
1003
1008
  return {
@@ -1089,109 +1094,12 @@ const createCanAnimateSignal = () => {
1089
1094
  };
1090
1095
  };
1091
1096
 
1092
- const boundingClientRectToElementRect = (rect) => ({
1093
- bottom: rect.bottom,
1094
- height: rect.height,
1095
- left: rect.left,
1096
- right: rect.right,
1097
- top: rect.top,
1098
- width: rect.width,
1099
- x: rect.x,
1100
- y: rect.y,
1101
- });
1102
- const createElementDimensions = (el, rect) => {
1103
- if (!el) {
1104
- return {
1105
- rect: null,
1106
- client: null,
1107
- scroll: null,
1108
- offset: null,
1109
- };
1110
- }
1111
- const cachedNormalizedRect = rect ? boundingClientRectToElementRect(rect) : null;
1112
- const rectFn = () => cachedNormalizedRect ? cachedNormalizedRect : boundingClientRectToElementRect(el.getBoundingClientRect());
1113
- return {
1114
- rect: rectFn,
1115
- client: { width: el.clientWidth, height: el.clientHeight },
1116
- scroll: { width: el.scrollWidth, height: el.scrollHeight },
1117
- offset: { width: el.offsetWidth, height: el.offsetHeight },
1118
- };
1119
- };
1120
- const signalElementDimensions = (el) => {
1121
- const destroyRef = inject(DestroyRef);
1122
- const elements = buildElementSignal(el);
1123
- const firstEl = firstElementSignal(elements);
1124
- const zone = inject(NgZone);
1125
- const isRendered = signalIsRendered();
1126
- const initialValue = () => createElementDimensions(firstEl().currentElement);
1127
- const elementDimensionsSignal = signal(initialValue(), /* @ts-ignore */
1128
- ...(ngDevMode ? [{ debugName: "elementDimensionsSignal" }] : /* istanbul ignore next */ []));
1129
- const observer = new ResizeObserver((e) => {
1130
- if (!isRendered())
1131
- return;
1132
- const entry = e[0];
1133
- if (entry) {
1134
- const target = entry.target;
1135
- const newDimensions = createElementDimensions(target);
1136
- zone.run(() => elementDimensionsSignal.set(newDimensions));
1137
- }
1138
- });
1139
- effect(() => {
1140
- const els = firstEl();
1141
- untracked(() => {
1142
- elementDimensionsSignal.set(initialValue());
1143
- if (els.previousElement) {
1144
- observer.disconnect();
1145
- }
1146
- if (els.currentElement) {
1147
- const computedDisplay = getComputedStyle(els.currentElement).display;
1148
- const currentElIsAngularComponent = els.currentElement?.tagName.toLowerCase().includes('-');
1149
- if (computedDisplay === 'inline' && isDevMode() && currentElIsAngularComponent) {
1150
- console.error(`Element <${els.currentElement?.tagName.toLowerCase()}> is an Angular component and has a display of 'inline'. Inline elements cannot be observed for dimensions. Please change it to 'block' or something else.`);
1151
- }
1152
- observer.observe(els.currentElement);
1153
- }
1154
- });
1155
- });
1156
- destroyRef.onDestroy(() => observer.disconnect());
1157
- return computed(() => elementDimensionsSignal(), {
1158
- equal: (a, b) => equal(a, b),
1159
- });
1160
- };
1161
- const signalHostElementDimensions = () => signalElementDimensions(inject(ElementRef));
1162
- const injectViewportSize = () => {
1163
- const document = inject(DOCUMENT$1);
1164
- const zone = inject(NgZone);
1165
- const destroyRef = inject(DestroyRef);
1166
- const getSize = () => {
1167
- const vv = document.defaultView?.visualViewport;
1168
- if (vv)
1169
- return { width: vv.width, height: vv.height };
1170
- const win = document.defaultView;
1171
- return { width: win?.innerWidth ?? 0, height: win?.innerHeight ?? 0 };
1172
- };
1173
- const size = signal(getSize(), /* @ts-ignore */
1174
- ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
1175
- const onResize = () => zone.run(() => size.set(getSize()));
1176
- const vv = document.defaultView?.visualViewport;
1177
- if (vv) {
1178
- vv.addEventListener('resize', onResize);
1179
- destroyRef.onDestroy(() => vv.removeEventListener('resize', onResize));
1180
- }
1181
- else {
1182
- const win = document.defaultView;
1183
- win?.addEventListener('resize', onResize);
1184
- destroyRef.onDestroy(() => win?.removeEventListener('resize', onResize));
1185
- }
1186
- return size;
1187
- };
1188
-
1189
1097
  const previousSignalValue = (signal) => {
1190
1098
  const obs = toObservable(signal).pipe(pairwise(), map(([prev]) => prev));
1191
1099
  return toSignal(obs);
1192
1100
  };
1193
1101
  const syncSignal = (from, to, options) => {
1194
- let isFirstRun = options?.skipSyncRead ? false : true;
1102
+ let isFirstRun = true;
1195
1103
  if (!options?.skipSyncRead) {
1196
1104
  try {
1197
1105
  // this might throw if the signal is not yet initialized (eg. a required signal input inside the constructor)
@@ -1283,6 +1191,104 @@ const memoizeSignal = (factory) => {
1283
1191
  };
1284
1192
  };
1285
1193
 
1194
+ const boundingClientRectToElementRect = (rect) => ({
1195
+ bottom: rect.bottom,
1196
+ height: rect.height,
1197
+ left: rect.left,
1198
+ right: rect.right,
1199
+ top: rect.top,
1200
+ width: rect.width,
1201
+ x: rect.x,
1202
+ y: rect.y,
1203
+ });
1204
+ const createElementDimensions = (el, rect) => {
1205
+ if (!el) {
1206
+ return {
1207
+ rect: null,
1208
+ client: null,
1209
+ scroll: null,
1210
+ offset: null,
1211
+ };
1212
+ }
1213
+ const cachedNormalizedRect = rect ? boundingClientRectToElementRect(rect) : null;
1214
+ const rectFn = () => cachedNormalizedRect ? cachedNormalizedRect : boundingClientRectToElementRect(el.getBoundingClientRect());
1215
+ return {
1216
+ rect: rectFn,
1217
+ client: { width: el.clientWidth, height: el.clientHeight },
1218
+ scroll: { width: el.scrollWidth, height: el.scrollHeight },
1219
+ offset: { width: el.offsetWidth, height: el.offsetHeight },
1220
+ };
1221
+ };
1222
+ const signalElementDimensions = (el) => {
1223
+ const destroyRef = inject(DestroyRef);
1224
+ const elements = buildElementSignal(el);
1225
+ const firstEl = firstElementSignal(elements);
1226
+ const zone = inject(NgZone);
1227
+ const isRendered = signalIsRendered();
1228
+ const initialValue = () => createElementDimensions(firstEl().currentElement);
1229
+ const elementDimensionsSignal = signal(initialValue(), /* @ts-ignore */
1230
+ ...(ngDevMode ? [{ debugName: "elementDimensionsSignal" }] : /* istanbul ignore next */ []));
1231
+ let observer = null;
1232
+ effect(() => {
1233
+ const els = firstEl();
1234
+ const rendered = isRendered();
1235
+ untracked(() => {
1236
+ elementDimensionsSignal.set(initialValue());
1237
+ if (!rendered || typeof ResizeObserver === 'undefined') {
1238
+ return;
1239
+ }
1240
+ observer ??= new ResizeObserver((entries) => {
1241
+ const entry = entries[0];
1242
+ if (entry) {
1243
+ const target = entry.target;
1244
+ const newDimensions = createElementDimensions(target);
1245
+ zone.run(() => elementDimensionsSignal.set(newDimensions));
1246
+ }
1247
+ });
1248
+ observer.disconnect();
1249
+ if (els.currentElement) {
1250
+ const computedDisplay = els.currentElement.ownerDocument.defaultView?.getComputedStyle(els.currentElement).display;
1251
+ const currentElIsAngularComponent = els.currentElement?.tagName.toLowerCase().includes('-');
1252
+ if (computedDisplay === 'inline' && isDevMode() && currentElIsAngularComponent) {
1253
+ console.error(`Element <${els.currentElement?.tagName.toLowerCase()}> is an Angular component and has a display of 'inline'. Inline elements cannot be observed for dimensions. Please change it to 'block' or something else.`);
1254
+ }
1255
+ observer.observe(els.currentElement);
1256
+ }
1257
+ });
1258
+ });
1259
+ destroyRef.onDestroy(() => observer?.disconnect());
1260
+ return computed(() => elementDimensionsSignal(), {
1261
+ equal: (a, b) => equal(a, b),
1262
+ });
1263
+ };
1264
+ const signalHostElementDimensions = () => signalElementDimensions(inject(ElementRef));
1265
+ const injectViewportSize = /* @__PURE__ */ memoizeSignal(() => {
1266
+ const document = inject(DOCUMENT);
1267
+ const zone = inject(NgZone);
1268
+ const destroyRef = inject(DestroyRef);
1269
+ const getSize = () => {
1270
+ const vv = document.defaultView?.visualViewport;
1271
+ if (vv)
1272
+ return { width: vv.width, height: vv.height };
1273
+ const win = document.defaultView;
1274
+ return { width: win?.innerWidth ?? 0, height: win?.innerHeight ?? 0 };
1275
+ };
1276
+ const size = signal(getSize(), /* @ts-ignore */
1277
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
1278
+ const onResize = () => zone.run(() => size.set(getSize()));
1279
+ const vv = document.defaultView?.visualViewport;
1280
+ if (vv) {
1281
+ vv.addEventListener('resize', onResize);
1282
+ destroyRef.onDestroy(() => vv.removeEventListener('resize', onResize));
1283
+ }
1284
+ else {
1285
+ const win = document.defaultView;
1286
+ win?.addEventListener('resize', onResize);
1287
+ destroyRef.onDestroy(() => win?.removeEventListener('resize', onResize));
1288
+ }
1289
+ return size;
1290
+ });
1291
+
1286
1292
  /** Inject a signal containing a boolean value indicating if the viewport is xs */
1287
1293
  const injectIsXs = /* @__PURE__ */ memoizeSignal(() => injectObserveBreakpoint({ max: 'xs' }));
1288
1294
  /** Inject a signal containing a boolean value indicating if the viewport is sm */
@@ -1365,15 +1371,24 @@ const injectViewportDimensions = /* @__PURE__ */ memoizeSignal(() => signalEleme
1365
1371
  /** Inject a signal containing the scrollbar dimensions. Dimensions will be 0 if scrollbars overlap the page contents (like on mobile). */
1366
1372
  const injectScrollbarDimensions = /* @__PURE__ */ memoizeSignal(() => {
1367
1373
  const document = inject(DOCUMENT);
1374
+ const destroyRef = inject(DestroyRef);
1368
1375
  const renderer = injectRenderer();
1376
+ const view = document.defaultView;
1377
+ if (!view)
1378
+ return signal(null).asReadonly();
1369
1379
  const scrollbarRuler = renderer.createElement('div');
1370
1380
  scrollbarRuler.style.width = '100px';
1371
1381
  scrollbarRuler.style.height = '100px';
1372
1382
  scrollbarRuler.style.overflow = 'scroll';
1373
1383
  scrollbarRuler.style.position = 'absolute';
1374
1384
  scrollbarRuler.style.top = '-9999px';
1375
- scrollbarRuler.style.scrollbarWidth = getComputedStyle(document.documentElement).scrollbarWidth;
1385
+ scrollbarRuler.style.scrollbarWidth = view.getComputedStyle(document.documentElement).scrollbarWidth;
1376
1386
  renderer.appendChild(document.body, scrollbarRuler);
1387
+ destroyRef.onDestroy(() => {
1388
+ const parent = renderer.parentNode(scrollbarRuler);
1389
+ if (parent)
1390
+ renderer.removeChild(parent, scrollbarRuler);
1391
+ });
1377
1392
  const scrollContainerDimensions = signalElementDimensions(scrollbarRuler);
1378
1393
  return computed(() => {
1379
1394
  const client = scrollContainerDimensions().client;
@@ -1408,6 +1423,7 @@ const injectAnimatedBlockSize = (config) => {
1408
1423
  const renderer = injectRenderer();
1409
1424
  const prefersReducedMotion = injectPrefersReducedMotion();
1410
1425
  const destroyRef = inject(DestroyRef);
1426
+ const isRendered = signalIsRendered();
1411
1427
  const hostSignal = firstElementSignal(buildElementSignal(hostBinding));
1412
1428
  const observeTargets = Array.isArray(config.observe) ? config.observe : [config.observe];
1413
1429
  const observedElements = observeTargets.map((target) => firstElementSignal(buildElementSignal(target)));
@@ -1447,7 +1463,7 @@ const injectAnimatedBlockSize = (config) => {
1447
1463
  if (!animateBlock && !animateInline) {
1448
1464
  return;
1449
1465
  }
1450
- if (config.resizingClass && renderer) {
1466
+ if (config.resizingClass) {
1451
1467
  renderer.addClass(host, config.resizingClass);
1452
1468
  }
1453
1469
  const fromFrame = {};
@@ -1470,7 +1486,7 @@ const injectAnimatedBlockSize = (config) => {
1470
1486
  if (animation !== null && animation !== nextAnimation) {
1471
1487
  return;
1472
1488
  }
1473
- if (config.resizingClass && renderer) {
1489
+ if (config.resizingClass) {
1474
1490
  renderer.removeClass(host, config.resizingClass);
1475
1491
  }
1476
1492
  if (animation === nextAnimation) {
@@ -1480,15 +1496,18 @@ const injectAnimatedBlockSize = (config) => {
1480
1496
  nextAnimation.finished.then(cleanup).catch(cleanup);
1481
1497
  animation = nextAnimation;
1482
1498
  };
1483
- // no zone/signal indirection - see the pre-paint timing note in the doc comment above
1484
- const observer = new ResizeObserver(() => {
1485
- if (!ready)
1486
- return;
1487
- run();
1488
- });
1499
+ let observer = null;
1489
1500
  effect(() => {
1490
1501
  const elements = observedElements.map((element) => element().currentElement);
1502
+ const rendered = isRendered();
1491
1503
  untracked(() => {
1504
+ if (!rendered || typeof ResizeObserver === 'undefined') {
1505
+ return;
1506
+ }
1507
+ observer ??= new ResizeObserver(() => {
1508
+ if (ready)
1509
+ run();
1510
+ });
1492
1511
  observer.disconnect();
1493
1512
  for (const element of elements) {
1494
1513
  if (element) {
@@ -1497,7 +1516,6 @@ const injectAnimatedBlockSize = (config) => {
1497
1516
  }
1498
1517
  });
1499
1518
  });
1500
- // Capture the settled size of the first render as the baseline, then only animate later changes.
1501
1519
  afterNextRender(() => {
1502
1520
  const host = hostElement();
1503
1521
  const rect = host ? host.getBoundingClientRect() : null;
@@ -1506,7 +1524,7 @@ const injectAnimatedBlockSize = (config) => {
1506
1524
  ready = true;
1507
1525
  });
1508
1526
  destroyRef.onDestroy(() => {
1509
- observer.disconnect();
1527
+ observer?.disconnect();
1510
1528
  animation?.cancel();
1511
1529
  });
1512
1530
  };
@@ -1516,6 +1534,7 @@ const injectAnimatedBlockSize = (config) => {
1516
1534
  */
1517
1535
  const signalAnimatedNumber = (source, options = {}) => {
1518
1536
  const ngZone = inject(NgZone);
1537
+ const destroyRef = inject(DestroyRef);
1519
1538
  const duration = options.duration ?? 1000;
1520
1539
  const easing = options.easing ?? easeOut;
1521
1540
  const round = options.round ?? ((v) => Math.round(v));
@@ -1524,6 +1543,7 @@ const signalAnimatedNumber = (source, options = {}) => {
1524
1543
  ...(ngDevMode ? [{ debugName: "animatedValue" }] : /* istanbul ignore next */ []));
1525
1544
  let rafId = null;
1526
1545
  let currentAnimatedValue = initialValue;
1546
+ let destroyed = false;
1527
1547
  const cancelAnimation = () => {
1528
1548
  if (rafId !== null) {
1529
1549
  cancelAnimationFrame(rafId);
@@ -1537,14 +1557,21 @@ const signalAnimatedNumber = (source, options = {}) => {
1537
1557
  const startValue = currentAnimatedValue;
1538
1558
  const startTime = performance.now();
1539
1559
  const delta = targetValue - startValue;
1540
- // Skip animation if no change
1541
1560
  if (delta === 0) {
1542
1561
  options.onAnimationEnd?.();
1543
1562
  return readonlySignal;
1544
1563
  }
1545
1564
  options.onAnimationStart?.();
1565
+ if (typeof requestAnimationFrame === 'undefined') {
1566
+ currentAnimatedValue = targetValue;
1567
+ animatedValue.set(round(targetValue));
1568
+ options.onAnimationEnd?.();
1569
+ return readonlySignal;
1570
+ }
1546
1571
  ngZone.runOutsideAngular(() => {
1547
1572
  const animate = (timestamp) => {
1573
+ if (destroyed)
1574
+ return;
1548
1575
  const elapsed = timestamp - startTime;
1549
1576
  const progress = Math.min(elapsed / duration, 1);
1550
1577
  const easedProgress = easing(progress);
@@ -1580,6 +1607,10 @@ const signalAnimatedNumber = (source, options = {}) => {
1580
1607
  readonlySignal.play = play;
1581
1608
  readonlySignal.reset = reset;
1582
1609
  readonlySignal.stop = stop;
1610
+ destroyRef.onDestroy(() => {
1611
+ destroyed = true;
1612
+ cancelAnimation();
1613
+ });
1583
1614
  return readonlySignal;
1584
1615
  };
1585
1616
  /* Linear easing function */
@@ -1630,10 +1661,12 @@ const provideViewportConfig = /* @__PURE__ */ toProvideFn(VIEWPORT_CONFIG_DEF);
1630
1661
  const injectViewportConfig = /* @__PURE__ */ toInjectFn(VIEWPORT_CONFIG_DEF);
1631
1662
  const BREAKPOINT_OBSERVER_DEF = /* @__PURE__ */ defineRootProvider(() => {
1632
1663
  const viewportConfig = injectViewportConfig();
1664
+ const destroyRef = inject(DestroyRef);
1633
1665
  const defaultView = inject(DOCUMENT).defaultView;
1634
1666
  const matchMedia = defaultView?.matchMedia?.bind(defaultView) ?? null;
1635
1667
  const queryLists = new Map();
1636
1668
  const querySignals = new Map();
1669
+ const queryListenerCleanups = new Map();
1637
1670
  const getQueryList = (mediaQuery) => {
1638
1671
  if (!matchMedia)
1639
1672
  return null;
@@ -1652,9 +1685,11 @@ const BREAKPOINT_OBSERVER_DEF = /* @__PURE__ */ defineRootProvider(() => {
1652
1685
  const queryList = getQueryList(mediaQuery);
1653
1686
  const matches = signal(queryList?.matches ?? false, /* @ts-ignore */
1654
1687
  ...(ngDevMode ? [{ debugName: "matches" }] : /* istanbul ignore next */ []));
1655
- // the root provider outlives every consumer, so the listener is intentionally never removed -
1656
- // the same query list is shared by all of them
1657
- queryList?.addEventListener('change', (event) => matches.set(event.matches));
1688
+ if (queryList) {
1689
+ const onChange = (event) => matches.set(event.matches);
1690
+ queryList.addEventListener('change', onChange);
1691
+ queryListenerCleanups.set(mediaQuery, () => queryList.removeEventListener('change', onChange));
1692
+ }
1658
1693
  const result = matches.asReadonly();
1659
1694
  querySignals.set(mediaQuery, result);
1660
1695
  return result;
@@ -1676,11 +1711,11 @@ const BREAKPOINT_OBSERVER_DEF = /* @__PURE__ */ defineRootProvider(() => {
1676
1711
  return size + 0.9;
1677
1712
  };
1678
1713
  const buildMediaQueryString = (options) => {
1679
- if (!options.min && !options.max) {
1714
+ if (options.min === undefined && options.max === undefined) {
1680
1715
  throw new Error('At least one of min or max must be defined');
1681
1716
  }
1682
1717
  const mediaQueryParts = [];
1683
- if (options.min) {
1718
+ if (options.min !== undefined) {
1684
1719
  if (typeof options.min === 'number') {
1685
1720
  mediaQueryParts.push(`(min-width: ${options.min}px)`);
1686
1721
  }
@@ -1688,19 +1723,16 @@ const BREAKPOINT_OBSERVER_DEF = /* @__PURE__ */ defineRootProvider(() => {
1688
1723
  mediaQueryParts.push(`(min-width: ${getBreakpointSize(options.min, 'min')}px)`);
1689
1724
  }
1690
1725
  }
1691
- if (options.min && options.max) {
1692
- mediaQueryParts.push('and');
1693
- }
1694
- if (options.max) {
1695
- if (typeof options.max === 'number') {
1696
- mediaQueryParts.push(`(max-width: ${options.max}px)`);
1697
- }
1698
- else {
1699
- mediaQueryParts.push(`(max-width: ${getBreakpointSize(options.max, 'max')}px)`);
1700
- }
1726
+ if (options.max !== undefined) {
1727
+ const max = typeof options.max === 'number' ? options.max : getBreakpointSize(options.max, 'max');
1728
+ if (max !== Infinity)
1729
+ mediaQueryParts.push(`(max-width: ${max}px)`);
1701
1730
  }
1702
- return mediaQueryParts.join(' ');
1731
+ return mediaQueryParts.length > 0 ? mediaQueryParts.join(' and ') : '(min-width: 0px)';
1703
1732
  };
1733
+ destroyRef.onDestroy(() => {
1734
+ queryListenerCleanups.forEach((cleanup) => cleanup());
1735
+ });
1704
1736
  return {
1705
1737
  observeBreakpoint,
1706
1738
  isBreakpointMatched,
@@ -1741,31 +1773,24 @@ const resolveFromMap = (map, bp, defaultValue) => {
1741
1773
  }
1742
1774
  return defaultValue;
1743
1775
  };
1744
- const breakpointTransformBase = (coerce) => {
1776
+ const breakpointTransformBase = (coerce, defaultValue) => {
1745
1777
  const currentBp = injectCurrentBreakpoint();
1746
1778
  const injector = inject(Injector);
1747
1779
  const raw = signal(undefined, /* @ts-ignore */
1748
1780
  ...(ngDevMode ? [{ debugName: "raw" }] : /* istanbul ignore next */ []));
1749
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1750
- let capturedDefault = undefined;
1751
- let initialized = false;
1752
1781
  let cachedSig = null;
1753
1782
  const transformFn = (value) => {
1754
1783
  const coerced = isBreakpointMap(value) ? value : coerce(value);
1755
- if (!initialized) {
1756
- capturedDefault = coerced;
1757
- initialized = true;
1758
- }
1759
1784
  raw.set(coerced);
1760
- return isBreakpointMap(coerced)
1761
- ? resolveFromMap(coerced, currentBp(), capturedDefault)
1762
- : coerced;
1785
+ return isBreakpointMap(coerced) ? resolveFromMap(coerced, currentBp(), defaultValue) : coerced;
1763
1786
  };
1764
1787
  effect(() => {
1765
1788
  const bp = currentBp();
1766
1789
  const r = raw();
1767
1790
  if (!cachedSig) {
1768
- const instance = injector.get(BREAKPOINT_INSTANCE_TOKEN);
1791
+ const instance = injector.get(BREAKPOINT_INSTANCE_TOKEN, null);
1792
+ if (!instance)
1793
+ return;
1769
1794
  for (const key of Object.keys(instance)) {
1770
1795
  const val = instance[key];
1771
1796
  if (val && typeof val === 'function' && val[SIGNAL]?.transformFn === transformFn) {
@@ -1776,7 +1801,7 @@ const breakpointTransformBase = (coerce) => {
1776
1801
  }
1777
1802
  if (!cachedSig || r === undefined || !isBreakpointMap(r))
1778
1803
  return;
1779
- const resolved = resolveFromMap(r, bp, capturedDefault);
1804
+ const resolved = resolveFromMap(r, bp, defaultValue);
1780
1805
  untracked(() => setInputSignal(cachedSig, resolved));
1781
1806
  });
1782
1807
  return transformFn;
@@ -1786,30 +1811,30 @@ const breakpointTransformBase = (coerce) => {
1786
1811
  * Coerces plain values with `booleanAttribute`; resolves {@link BreakpointMap} mobile-first.
1787
1812
  *
1788
1813
  * @example
1789
- * snap = input(false, { transform: boolBreakpointTransform() });
1814
+ * snap = input(false, { transform: boolBreakpointTransform(false) });
1790
1815
  * // Template: `snap` | `[snap]="true"` | `[snap]="{ xs: false, md: true }"`
1791
1816
  */
1792
- const boolBreakpointTransform = () => breakpointTransformBase(booleanAttribute);
1817
+ const boolBreakpointTransform = (defaultValue = false) => breakpointTransformBase(booleanAttribute, defaultValue);
1793
1818
  /**
1794
1819
  * Transform factory for number inputs.
1795
1820
  * Coerces plain values with `numberAttribute`; resolves {@link BreakpointMap} mobile-first.
1796
1821
  *
1797
1822
  * @example
1798
- * scrollMargin = input(0, { transform: numberBreakpointTransform() });
1823
+ * scrollMargin = input(0, { transform: numberBreakpointTransform(0) });
1799
1824
  * // Template: `[scrollMargin]="16"` | `[scrollMargin]="{ xs: 0, md: 16 }"`
1800
1825
  */
1801
- const numberBreakpointTransform = () => breakpointTransformBase((v) => numberAttribute(v));
1826
+ const numberBreakpointTransform = (defaultValue = 0) => breakpointTransformBase((v) => numberAttribute(v), defaultValue);
1802
1827
  /**
1803
1828
  * Transform factory for any typed input (string unions, arrays, objects, etc.).
1804
1829
  * Passes plain values through as-is; resolves {@link BreakpointMap} mobile-first.
1805
1830
  * A value is treated as a {@link BreakpointMap} only when all its keys are valid breakpoint names.
1806
1831
  *
1807
1832
  * @example
1808
- * itemSize = input('auto', { transform: typedBreakpointTransform<ScrollableItemSize>() });
1809
- * tags = input([], { transform: typedBreakpointTransform<string[]>() });
1833
+ * itemSize = input('auto', { transform: typedBreakpointTransform<ScrollableItemSize>('auto') });
1834
+ * tags = input([], { transform: typedBreakpointTransform<string[]>([]) });
1810
1835
  * // Template: `[itemSize]="'third'"` | `[itemSize]="{ xs: 'full', md: 'third' }"`
1811
1836
  */
1812
- const typedBreakpointTransform = () => breakpointTransformBase((v) => v);
1837
+ const typedBreakpointTransform = (defaultValue) => breakpointTransformBase((v) => v, defaultValue);
1813
1838
  const injectBreakpointInput = (inputSignal, defaultValue) => {
1814
1839
  const currentBreakpoint = injectCurrentBreakpoint();
1815
1840
  return computed(() => {
@@ -1819,16 +1844,6 @@ const injectBreakpointInput = (inputSignal, defaultValue) => {
1819
1844
  return resolveFromMap(value, currentBreakpoint(), defaultValue);
1820
1845
  });
1821
1846
  };
1822
- const booleanBreakpointAttribute = (value) => {
1823
- if (isBreakpointMap(value))
1824
- return value;
1825
- return booleanAttribute(value);
1826
- };
1827
- const numberBreakpointAttribute = (value) => {
1828
- if (isBreakpointMap(value))
1829
- return value;
1830
- return numberAttribute(value);
1831
- };
1832
1847
  const BREAKPOINT_INSTANCE_TOKEN = new InjectionToken('BREAKPOINT_INSTANCE_TOKEN');
1833
1848
  const provideBreakpointInstance = (componentClass) => ({
1834
1849
  provide: BREAKPOINT_INSTANCE_TOKEN,
@@ -1852,14 +1867,17 @@ const controlValueSignal = (control, options) => {
1852
1867
  const controlObs = controlStream.pipe(switchMap((ctrl) => {
1853
1868
  if (!ctrl)
1854
1869
  return of(null);
1855
- const vcsObs = options?.debounceTime
1856
- ? ctrl.valueChanges.pipe(debounceTime(options.debounceTime))
1857
- : ctrl.valueChanges;
1858
- return vcsObs.pipe(startWith(ctrl.getRawValue()), map(() => ctrl.getRawValue()));
1870
+ const changes = ctrl.valueChanges.pipe(map(() => ctrl.getRawValue()));
1871
+ const debouncedChanges = options?.debounceTime ? changes.pipe(debounceTime(options.debounceTime)) : changes;
1872
+ if (!options?.debounceFirst) {
1873
+ return merge(of(ctrl.getRawValue()), debouncedChanges);
1874
+ }
1875
+ const values = merge(of(ctrl.getRawValue()), changes);
1876
+ return options.debounceTime ? values.pipe(debounceTime(options.debounceTime)) : values;
1859
1877
  }));
1860
- const obs = !options?.debounceFirst ? merge(of(initialValue), controlObs) : controlObs;
1878
+ const obs = controlObs;
1861
1879
  return toSignal(obs.pipe(distinctUntilChanged((a, b) => equal(a, b))), {
1862
- initialValue,
1880
+ initialValue: options?.debounceFirst ? null : initialValue,
1863
1881
  });
1864
1882
  };
1865
1883
  /**
@@ -1924,25 +1942,26 @@ const signalElementMutations = (el, options) => {
1924
1942
  const isRendered = signalIsRendered();
1925
1943
  const elementMutationsSignal = signal(null, /* @ts-ignore */
1926
1944
  ...(ngDevMode ? [{ debugName: "elementMutationsSignal" }] : /* istanbul ignore next */ []));
1927
- const observer = new MutationObserver((e) => {
1928
- if (!isRendered())
1929
- return;
1930
- const entry = e[0];
1931
- if (entry) {
1932
- zone.run(() => elementMutationsSignal.set(entry));
1933
- }
1934
- });
1945
+ let observer = null;
1935
1946
  effect(() => {
1936
1947
  const els = firstEl();
1948
+ const rendered = isRendered();
1937
1949
  elementMutationsSignal.set(null);
1938
- if (els.previousElement) {
1939
- observer.disconnect();
1950
+ if (!rendered || typeof MutationObserver === 'undefined') {
1951
+ return;
1940
1952
  }
1953
+ observer ??= new MutationObserver((entries) => {
1954
+ const entry = entries[0];
1955
+ if (entry) {
1956
+ zone.run(() => elementMutationsSignal.set(entry));
1957
+ }
1958
+ });
1959
+ observer.disconnect();
1941
1960
  if (els.currentElement) {
1942
1961
  observer.observe(els.currentElement, options);
1943
1962
  }
1944
1963
  });
1945
- destroyRef.onDestroy(() => observer.disconnect());
1964
+ destroyRef.onDestroy(() => observer?.disconnect());
1946
1965
  return elementMutationsSignal.asReadonly();
1947
1966
  };
1948
1967
  const signalHostElementMutations = (options) => signalElementMutations(inject(ElementRef), options);
@@ -2149,20 +2168,6 @@ const isElementVisible = (options) => {
2149
2168
  }
2150
2169
  const elementRect = options.elementRect || element.getBoundingClientRect();
2151
2170
  const containerRect = container ? options.containerRect || container.getBoundingClientRect() : createViewportRect();
2152
- const canScroll = elementCanScroll(container);
2153
- if (!canScroll) {
2154
- return {
2155
- inline: true,
2156
- block: true,
2157
- blockIntersection: 1,
2158
- inlineIntersection: 1,
2159
- intersectionRatio: 1,
2160
- isIntersecting: true,
2161
- element,
2162
- containerRect,
2163
- elementRect,
2164
- };
2165
- }
2166
2171
  const elLeft = elementRect.left;
2167
2172
  const elTop = elementRect.top;
2168
2173
  const elWidth = elementRect.width || 1;
@@ -2184,7 +2189,7 @@ const isElementVisible = (options) => {
2184
2189
  block: isElementBlockVisible,
2185
2190
  inlineIntersection: inlineIntersectionPercentage,
2186
2191
  blockIntersection: blockIntersectionPercentage,
2187
- isIntersecting: isElementInlineVisible && isElementBlockVisible,
2192
+ isIntersecting: inlineIntersectionPercentage > 0 && blockIntersectionPercentage > 0,
2188
2193
  element,
2189
2194
  containerRect,
2190
2195
  elementRect,
@@ -2432,12 +2437,13 @@ const createPositionObject = (entry) => {
2432
2437
  };
2433
2438
  };
2434
2439
  const signalElementIntersection = (el, options) => {
2440
+ const { root: rootBinding, enabled, ...observerOptions } = options ?? {};
2435
2441
  const destroyRef = inject(DestroyRef);
2436
2442
  const elements = buildElementSignal(el);
2437
- const root = firstElementSignal(options?.root ? buildElementSignal(options?.root) : createEmptyElementSignal());
2443
+ const root = firstElementSignal(rootBinding ? buildElementSignal(rootBinding) : createEmptyElementSignal());
2438
2444
  const zone = inject(NgZone);
2439
2445
  const isRendered = signalIsRendered();
2440
- const isEnabled = options?.enabled ?? signal(true);
2446
+ const isEnabled = enabled ?? signal(true);
2441
2447
  const elementIntersectionSignal = signal([], /* @ts-ignore */
2442
2448
  ...(ngDevMode ? [{ debugName: "elementIntersectionSignal" }] : /* istanbul ignore next */ []));
2443
2449
  const observer = signal(null, /* @ts-ignore */
@@ -2477,18 +2483,21 @@ const signalElementIntersection = (el, options) => {
2477
2483
  currentlyObservedElements.clear();
2478
2484
  if (!rendered || !enabled) {
2479
2485
  observer.set(null);
2486
+ elementIntersectionSignal.set([]);
2480
2487
  return;
2481
2488
  }
2482
2489
  const newObserver = new IntersectionObserver((entries) => updateIntersections(entries), {
2483
- ...options,
2490
+ ...observerOptions,
2484
2491
  root: rootEl,
2485
2492
  });
2486
2493
  observer.set(newObserver);
2487
2494
  };
2488
2495
  const updateObservedElements = (observer, elements) => {
2489
2496
  const rootEl = root().currentElement;
2490
- if (!observer)
2497
+ if (!observer) {
2498
+ elementIntersectionSignal.set([]);
2491
2499
  return;
2500
+ }
2492
2501
  const currIntersectionValue = elementIntersectionSignal();
2493
2502
  const newIntersectionValue = [];
2494
2503
  for (const el of elements.currentElements) {
@@ -2506,13 +2515,8 @@ const signalElementIntersection = (el, options) => {
2506
2515
  container: rootEl,
2507
2516
  element: el,
2508
2517
  });
2509
- if (!initialElementVisibility) {
2510
- console.error('No visibility data found for element.', {
2511
- element: el,
2512
- container: rootEl,
2513
- });
2518
+ if (!initialElementVisibility)
2514
2519
  continue;
2515
- }
2516
2520
  const intersectionEntry = {
2517
2521
  boundingClientRect: initialElementVisibility.elementRect,
2518
2522
  intersectionRatio: initialElementVisibility.intersectionRatio,
@@ -2665,7 +2669,7 @@ const signalElementScrollState = (el, options) => {
2665
2669
  };
2666
2670
  const signalHostElementScrollState = () => signalElementScrollState(inject(ElementRef));
2667
2671
 
2668
- let hasWrittenScrollbarSizes = false;
2672
+ const scrollbarSizeWriters = /* @__PURE__ */ new WeakSet();
2669
2673
  /**
2670
2674
  * Applies scrollbar size CSS variables to the documentElement (html tag) in pixels.
2671
2675
  * - `--et-sw`: scrollbar width
@@ -2675,10 +2679,11 @@ const writeScrollbarSizeToCssVariables = () => {
2675
2679
  if (!isPlatformBrowser(inject(PLATFORM_ID))) {
2676
2680
  return;
2677
2681
  }
2678
- if (hasWrittenScrollbarSizes) {
2682
+ const environmentInjector = inject(EnvironmentInjector);
2683
+ if (scrollbarSizeWriters.has(environmentInjector)) {
2679
2684
  return;
2680
2685
  }
2681
- hasWrittenScrollbarSizes = true;
2686
+ scrollbarSizeWriters.add(environmentInjector);
2682
2687
  const document = inject(DOCUMENT);
2683
2688
  const renderer = injectRenderer();
2684
2689
  const scrollbarDimensions = injectScrollbarDimensions();
@@ -2692,7 +2697,7 @@ const writeScrollbarSizeToCssVariables = () => {
2692
2697
  });
2693
2698
  });
2694
2699
  };
2695
- let hasWrittenViewportSizes = false;
2700
+ const viewportSizeWriters = /* @__PURE__ */ new WeakSet();
2696
2701
  /**
2697
2702
  * Applies viewport size CSS variables to the documentElement (html tag) in pixels.
2698
2703
  * - `--et-vw`: viewport width excluding scrollbar width
@@ -2702,10 +2707,11 @@ const writeViewportSizeToCssVariables = () => {
2702
2707
  if (!isPlatformBrowser(inject(PLATFORM_ID))) {
2703
2708
  return;
2704
2709
  }
2705
- if (hasWrittenViewportSizes) {
2710
+ const environmentInjector = inject(EnvironmentInjector);
2711
+ if (viewportSizeWriters.has(environmentInjector)) {
2706
2712
  return;
2707
2713
  }
2708
- hasWrittenViewportSizes = true;
2714
+ viewportSizeWriters.add(environmentInjector);
2709
2715
  const document = inject(DOCUMENT);
2710
2716
  const renderer = injectRenderer();
2711
2717
  const htmlElementDimensions = injectViewportDimensions();
@@ -2990,7 +2996,10 @@ const createRouterState = (router) => {
2990
2996
  * where `router.url` is already committed. Falls back to the browser location before the first navigation commits.
2991
2997
  */
2992
2998
  const createRoute = (router) => {
2993
- const url = router.navigated ? router.url : window.location.pathname + window.location.search + window.location.hash;
2999
+ const browserUrl = typeof window === 'undefined'
3000
+ ? router.url
3001
+ : window.location.pathname + window.location.search + window.location.hash;
3002
+ const url = router.navigated ? router.url : browserUrl;
2994
3003
  return url.split('?')[0]?.split('#')[0] ?? '';
2995
3004
  };
2996
3005
  /**
@@ -3006,7 +3015,9 @@ const injectRouterState = /* @__PURE__ */ memoizeSignal(() => {
3006
3015
  });
3007
3016
  /** Inject a signal containing the current route fragment (the part after the # inside the url if present) */
3008
3017
  const injectFragment = (config) => {
3009
- const routerState = injectRouterState();
3018
+ const routerState = config?.injector
3019
+ ? runInInjectionContext(config.injector, injectRouterState)
3020
+ : injectRouterState();
3010
3021
  const fragment = computed(() => routerState().fragment, /* @ts-ignore */
3011
3022
  ...(ngDevMode ? [{ debugName: "fragment" }] : /* istanbul ignore next */ []));
3012
3023
  return transformOrReturn(fragment, config);
@@ -3215,6 +3226,7 @@ const setupScrollRestoration = (config = {}) => {
3215
3226
  const router = inject(Router);
3216
3227
  const document = inject(DOCUMENT);
3217
3228
  const injector = inject(Injector);
3229
+ const destroyRef = inject(DestroyRef);
3218
3230
  const holds = injectScrollRestorationHolds();
3219
3231
  const restoreEnabled = config.restore?.enabled === true;
3220
3232
  const restoreTimeout = config.restore?.timeout ?? DEFAULT_RESTORE_TIMEOUT;
@@ -3226,15 +3238,16 @@ const setupScrollRestoration = (config = {}) => {
3226
3238
  };
3227
3239
  // The browser restores the offset against the still-loading (much shorter) document, which is the
3228
3240
  // exact problem we are solving - take it over completely.
3229
- if (restoreEnabled && 'scrollRestoration' in history) {
3241
+ const previousScrollRestoration = 'scrollRestoration' in history ? history.scrollRestoration : null;
3242
+ if (restoreEnabled && previousScrollRestoration !== null) {
3230
3243
  history.scrollRestoration = 'manual';
3231
3244
  }
3232
3245
  /** Saved offsets keyed by the router's per-history-entry `navigationId`, in least-recent-first order. */
3233
3246
  const positions = new Map();
3234
3247
  // Mirrors Angular's own `RouterScroller`: the offset of the currently displayed page belongs to
3235
3248
  // the navigation that produced it, and a popstate reports the id of the entry it moves to.
3236
- let lastNavigationId = 0;
3237
- let restoredNavigationId = 0;
3249
+ let lastNavigationId = null;
3250
+ let restoredNavigationId = null;
3238
3251
  let isPopstate = false;
3239
3252
  let wantsRestore = false;
3240
3253
  let prev = { state: createRouterState(router), route: createRoute(router) };
@@ -3250,7 +3263,7 @@ const setupScrollRestoration = (config = {}) => {
3250
3263
  let cancelled = false;
3251
3264
  // The user scrolling always wins over a restoration we have not committed yet.
3252
3265
  const abortByUser = () => cancelPendingRestore();
3253
- const hardDeadline = Date.now() + Math.max(restoreTimeout, restoreMaxTimeout);
3266
+ const hardDeadline = Date.now() + restoreMaxTimeout;
3254
3267
  let deadline = Date.now() + restoreTimeout;
3255
3268
  const step = () => {
3256
3269
  frame = 0;
@@ -3329,19 +3342,21 @@ const setupScrollRestoration = (config = {}) => {
3329
3342
  return;
3330
3343
  // Re-inserted rather than overwritten so map order stays least-recently-left first, which is both
3331
3344
  // what `findLastVisitedOffset` walks backwards and what the cap below evicts from.
3332
- positions.delete(lastNavigationId);
3333
- positions.set(lastNavigationId, {
3334
- top: resolveScrollElement().scrollTop,
3335
- route: prev.route,
3336
- search: serializeQueryParams(prev.state.queryParams),
3337
- });
3345
+ if (lastNavigationId !== null) {
3346
+ positions.delete(lastNavigationId);
3347
+ positions.set(lastNavigationId, {
3348
+ top: resolveScrollElement().scrollTop,
3349
+ route: prev.route,
3350
+ search: serializeQueryParams(prev.state.queryParams),
3351
+ });
3352
+ }
3338
3353
  if (positions.size > MAX_STORED_POSITIONS) {
3339
3354
  const oldest = positions.keys().next();
3340
3355
  if (!oldest.done)
3341
3356
  positions.delete(oldest.value);
3342
3357
  }
3343
3358
  isPopstate = event.navigationTrigger === 'popstate';
3344
- restoredNavigationId = event.restoredState?.navigationId ?? 0;
3359
+ restoredNavigationId = event.restoredState?.navigationId ?? null;
3345
3360
  // Read off the navigation rather than `history.state`: a symbol key does not survive being
3346
3361
  // structured-cloned into the history entry, which is what keeps the mark from outliving this
3347
3362
  // navigation and re-firing when the user later pops back to the entry it created.
@@ -3363,10 +3378,10 @@ const setupScrollRestoration = (config = {}) => {
3363
3378
  else {
3364
3379
  // A skipped same url navigation is not a history move, so there is nothing to restore.
3365
3380
  isPopstate = false;
3366
- restoredNavigationId = 0;
3381
+ restoredNavigationId = null;
3367
3382
  }
3368
3383
  if (restoreEnabled && isPopstate) {
3369
- const target = positions.get(restoredNavigationId);
3384
+ const target = restoredNavigationId === null ? undefined : positions.get(restoredNavigationId);
3370
3385
  // The saved offset wins over both scroll to top and fragment scrolling: the user may well have
3371
3386
  // scrolled away from the anchor before leaving the page.
3372
3387
  if (target !== undefined) {
@@ -3420,22 +3435,31 @@ const setupScrollRestoration = (config = {}) => {
3420
3435
  }
3421
3436
  onNavigationEnd(event);
3422
3437
  });
3438
+ destroyRef.onDestroy(() => {
3439
+ cancelPendingRestore();
3440
+ if (restoreEnabled && previousScrollRestoration !== null) {
3441
+ history.scrollRestoration = previousScrollRestoration;
3442
+ }
3443
+ });
3423
3444
  };
3424
3445
 
3425
3446
  const DISABLE_LOGGER_PARAM = 'et-logger-quiet';
3426
3447
  const createLogger = (config) => {
3427
3448
  const { scope, feature } = config;
3428
3449
  const disableLogging = injectQueryParam(DISABLE_LOGGER_PARAM);
3429
- const writeLog = (...args) => {
3430
- if (disableLogging()) {
3431
- return;
3432
- }
3433
- console.log(...args);
3434
- };
3435
3450
  return {
3436
- log: (...args) => writeLog(`\x1B[32;40;24m[${scope} ${feature}]\x1B[m`, ...args),
3437
- warn: (...args) => writeLog(`\x1B[93;40;24m[${scope} ${feature}]\x1B[m`, ...args),
3438
- error: (...args) => writeLog(`\x1B[31;40;24m[${scope} ${feature}]\x1B[m`, ...args),
3451
+ log: (...args) => {
3452
+ if (!disableLogging())
3453
+ console.log(`\x1B[32;40;24m[${scope} ${feature}]\x1B[m`, ...args);
3454
+ },
3455
+ warn: (...args) => {
3456
+ if (!disableLogging())
3457
+ console.warn(`\x1B[93;40;24m[${scope} ${feature}]\x1B[m`, ...args);
3458
+ },
3459
+ error: (...args) => {
3460
+ if (!disableLogging())
3461
+ console.error(`\x1B[31;40;24m[${scope} ${feature}]\x1B[m`, ...args);
3462
+ },
3439
3463
  };
3440
3464
  };
3441
3465
 
@@ -3448,12 +3472,15 @@ const escapeHtmlPreservingEntities = (str) => str
3448
3472
  .replace(/</g, '&lt;')
3449
3473
  .replace(/>/g, '&gt;')
3450
3474
  .replace(/"/g, '&quot;');
3451
- /** Rejects URL schemes that execute script when navigated. Whitespace/control characters are
3452
- * stripped before checking - browsers ignore them inside URLs, so `java\tscript:` would
3453
- * otherwise slip through. */
3454
- const isSafeUrl = (url) =>
3455
- // eslint-disable-next-line no-control-regex -- stripping control characters is the point: browsers ignore them inside URLs
3456
- !/^(javascript|data|vbscript):/i.test(url.replace(/[\s\u0000-\u001f]/g, ''));
3475
+ const decodeUrlCharacterReferences = (url) => url
3476
+ .replace(/&#(\d+);?/g, (_, value) => String.fromCodePoint(Number(value)))
3477
+ .replace(/&#x([0-9a-f]+);?/gi, (_, value) => String.fromCodePoint(Number.parseInt(value, 16)))
3478
+ .replace(/&(colon|tab|newline);/gi, (_, entity) => entity.toLowerCase() === 'colon' ? ':' : entity.toLowerCase() === 'tab' ? '\t' : '\n');
3479
+ const isSafeUrl = (url) => {
3480
+ // eslint-disable-next-line no-control-regex -- URL parsers ignore these characters inside schemes.
3481
+ const normalized = decodeUrlCharacterReferences(url).replace(/[\s\u0000-\u001f]/g, '');
3482
+ return (!/^(javascript|vbscript):/i.test(normalized) && !/^data:(?!image\/(?:avif|gif|jpeg|png|webp);)/i.test(normalized));
3483
+ };
3457
3484
  const unescapeHtml = (str) => str
3458
3485
  .replace(/&amp;/g, '&')
3459
3486
  .replace(/&lt;/g, '<')
@@ -3548,7 +3575,6 @@ const processInline = (text) => {
3548
3575
  .replace(placeholderRe('IC'), (_, i) => inlineCodes[+i] ?? '')
3549
3576
  .replace(placeholderRe('NTLINK'), (_, i) => newTabLinks[+i] ?? '');
3550
3577
  };
3551
- // --- Nested list helpers (regex can't match balanced nesting, so these scan by tag depth) ---
3552
3578
  /** The first top-level `<ul>`/`<ol>` in `html`, matched with balanced nesting. */
3553
3579
  const findList = (html) => {
3554
3580
  const open = /<(ul|ol)\b[^>]*>/i.exec(html);
@@ -3981,7 +4007,6 @@ class RuntimeError extends Error {
3981
4007
  }
3982
4008
  }
3983
4009
  function formatRuntimeError(code, message) {
3984
- // prefix code with zeros if it's less than 100
3985
4010
  const codeWithZeros = code < 10 ? `00${code}` : code < 100 ? `0${code}` : code;
3986
4011
  const fullCode = `ET${codeWithZeros}`;
3987
4012
  return `${fullCode}${message ? ': ' + message : ''}`;
@@ -4113,11 +4138,13 @@ const createSwipeTracker = (startEvent) => {
4113
4138
  const positiveMovementX = Math.abs(movementX);
4114
4139
  const positiveMovementY = Math.abs(movementY);
4115
4140
  if (!isSwiping && !isScrolling) {
4116
- if (positiveMovementY > positiveMovementX) {
4117
- isScrolling = true;
4118
- }
4119
- else {
4120
- isSwiping = true;
4141
+ if (positiveMovementY > 0 || positiveMovementX > 0) {
4142
+ if (positiveMovementY > positiveMovementX) {
4143
+ isScrolling = true;
4144
+ }
4145
+ else {
4146
+ isSwiping = true;
4147
+ }
4121
4148
  }
4122
4149
  }
4123
4150
  return {
@@ -4216,20 +4243,26 @@ const suppressTextSelection = (doc) => {
4216
4243
 
4217
4244
  const ANGULAR_ROOT_ELEMENT_DEF = /* @__PURE__ */ defineRootProvider(() => {
4218
4245
  const appRef = inject(ApplicationRef);
4246
+ const destroyRef = inject(DestroyRef);
4219
4247
  const rootElement = signal(null, /* @ts-ignore */
4220
4248
  ...(ngDevMode ? [{ debugName: "rootElement" }] : /* istanbul ignore next */ []));
4249
+ let pollId = null;
4221
4250
  const poll = () => {
4222
4251
  const appComponents = appRef.components;
4223
4252
  if (appComponents.length > 0) {
4224
4253
  rootElement.set(appComponents[0]?.location.nativeElement);
4225
4254
  }
4226
4255
  else {
4227
- setTimeout(poll, 25);
4256
+ pollId = setTimeout(poll, 25);
4228
4257
  }
4229
4258
  };
4230
- setTimeout(poll);
4259
+ pollId = setTimeout(poll);
4260
+ destroyRef.onDestroy(() => {
4261
+ if (pollId !== null)
4262
+ clearTimeout(pollId);
4263
+ });
4231
4264
  return rootElement;
4232
- });
4265
+ }, { name: 'Angular Root Element' });
4233
4266
  const injectAngularRootElement = /* @__PURE__ */ toInjectFn(ANGULAR_ROOT_ELEMENT_DEF);
4234
4267
 
4235
4268
  const BOUNDARY_ELEMENT_DEF = /* @__PURE__ */ defineProvider(() => {
@@ -4293,10 +4326,10 @@ const FOCUS_VISIBLE_TRACKER_DEF = /* @__PURE__ */ defineRootProvider(() => {
4293
4326
  ...(ngDevMode ? [{ debugName: "isFocusVisible" }] : /* istanbul ignore next */ []));
4294
4327
  let hadKeyboardEvent = false;
4295
4328
  const onKeyDown = (e) => {
4296
- if (e.key === 'Tab' || e.key === 'Shift' || e.key === 'Meta' || e.key === 'Alt' || e.key === 'Control') {
4297
- hadKeyboardEvent = true;
4298
- queueMicrotask(() => isFocusVisible.set(true));
4299
- }
4329
+ if (e.metaKey || e.altKey || e.ctrlKey || ['Shift', 'Meta', 'Alt', 'Control'].includes(e.key))
4330
+ return;
4331
+ hadKeyboardEvent = true;
4332
+ queueMicrotask(() => isFocusVisible.set(true));
4300
4333
  };
4301
4334
  const onPointerDown = () => {
4302
4335
  hadKeyboardEvent = false;
@@ -4471,6 +4504,9 @@ const createUserConsentProvider = (options) => ({
4471
4504
  });
4472
4505
 
4473
4506
  const nextFrame = (cb) => {
4507
+ if (typeof requestAnimationFrame === 'undefined') {
4508
+ return;
4509
+ }
4474
4510
  requestAnimationFrame(() => {
4475
4511
  requestAnimationFrame(cb);
4476
4512
  });
@@ -4526,8 +4562,8 @@ class AnimatedLifecycleDirective {
4526
4562
  this.element = this.elementRef.nativeElement;
4527
4563
  this.isConstructed = false;
4528
4564
  this.transitionIdCounter = 0;
4529
- this.forcedAtFrameId = null;
4530
- this.currentFrameId = 0;
4565
+ this.forcedThisFrame = false;
4566
+ this.forcedFrameResetId = null;
4531
4567
  this.state$ = new BehaviorSubject('init');
4532
4568
  this.stateChange = outputFromObservable(this.state$);
4533
4569
  this.skipNextEnter = model(false, /* @ts-ignore */
@@ -4542,15 +4578,9 @@ class AnimatedLifecycleDirective {
4542
4578
  }
4543
4579
  }), takeUntilDestroyed())
4544
4580
  .subscribe();
4545
- this.trackFrameId();
4546
- }
4547
- trackFrameId() {
4548
- const updateFrameId = () => {
4549
- this.currentFrameId = requestAnimationFrame(updateFrameId);
4550
- };
4551
- this.currentFrameId = requestAnimationFrame(updateFrameId);
4552
4581
  this.destroyRef.onDestroy(() => {
4553
- cancelAnimationFrame(this.currentFrameId);
4582
+ if (this.forcedFrameResetId !== null)
4583
+ cancelAnimationFrame(this.forcedFrameResetId);
4554
4584
  });
4555
4585
  }
4556
4586
  ngAfterViewInit() {
@@ -4565,7 +4595,7 @@ class AnimatedLifecycleDirective {
4565
4595
  this.updateState('entered');
4566
4596
  this.skipNextEnter.set(false);
4567
4597
  this.addClass(ANIMATION_CLASSES.enterDone);
4568
- this.forcedAtFrameId = null;
4598
+ this.forcedThisFrame = false;
4569
4599
  return;
4570
4600
  }
4571
4601
  const isInterrupting = currentState === 'leaving';
@@ -4575,8 +4605,8 @@ class AnimatedLifecycleDirective {
4575
4605
  this.cancelCurrentAnimation$ = new Subject();
4576
4606
  const transitionId = `enter-${++this.transitionIdCounter}`;
4577
4607
  this.animatable.setTransitionId(transitionId);
4578
- const skipAnimation = this.forcedAtFrameId !== null && this.forcedAtFrameId === this.currentFrameId;
4579
- this.forcedAtFrameId = null;
4608
+ const skipAnimation = this.forcedThisFrame;
4609
+ this.forcedThisFrame = false;
4580
4610
  this.debugLog(`enter: ${skipAnimation ? 'skip (forced this frame)' : isInterrupting ? 'interrupting leave' : 'normal'}`, {
4581
4611
  currentState,
4582
4612
  transitionId,
@@ -4634,7 +4664,7 @@ class AnimatedLifecycleDirective {
4634
4664
  this.debugLog('leave: instant (state is init, enter never ran)');
4635
4665
  this.updateState('left');
4636
4666
  this.addClass(ANIMATION_CLASSES.leaveDone);
4637
- this.forcedAtFrameId = null;
4667
+ this.forcedThisFrame = false;
4638
4668
  return;
4639
4669
  }
4640
4670
  const isInterrupting = currentState === 'entering';
@@ -4644,8 +4674,8 @@ class AnimatedLifecycleDirective {
4644
4674
  this.cancelCurrentAnimation$ = new Subject();
4645
4675
  const transitionId = `leave-${++this.transitionIdCounter}`;
4646
4676
  this.animatable.setTransitionId(transitionId);
4647
- const skipAnimation = this.forcedAtFrameId !== null && this.forcedAtFrameId === this.currentFrameId;
4648
- this.forcedAtFrameId = null;
4677
+ const skipAnimation = this.forcedThisFrame;
4678
+ this.forcedThisFrame = false;
4649
4679
  this.debugLog(`leave: ${skipAnimation ? 'skip (forced this frame)' : isInterrupting ? 'interrupting enter' : 'normal'}`, {
4650
4680
  currentState,
4651
4681
  transitionId,
@@ -4700,14 +4730,25 @@ class AnimatedLifecycleDirective {
4700
4730
  this.updateState('entered');
4701
4731
  this.removeClasses(ANIMATION_CLASSES.enterFrom, ANIMATION_CLASSES.enterActive, ANIMATION_CLASSES.enterTo, ANIMATION_CLASSES.leaveFrom, ANIMATION_CLASSES.leaveActive, ANIMATION_CLASSES.leaveTo);
4702
4732
  this.addClass(ANIMATION_CLASSES.enterDone);
4703
- this.forcedAtFrameId = this.currentFrameId;
4733
+ this.markForcedThisFrame();
4704
4734
  }
4705
4735
  forceLeftState() {
4706
4736
  this.cancelCurrentAnimation$.next();
4707
4737
  this.updateState('left');
4708
4738
  this.removeClasses(ANIMATION_CLASSES.enterFrom, ANIMATION_CLASSES.enterActive, ANIMATION_CLASSES.enterTo, ANIMATION_CLASSES.leaveFrom, ANIMATION_CLASSES.leaveActive, ANIMATION_CLASSES.leaveTo);
4709
4739
  this.addClass(ANIMATION_CLASSES.leaveDone);
4710
- this.forcedAtFrameId = this.currentFrameId;
4740
+ this.markForcedThisFrame();
4741
+ }
4742
+ markForcedThisFrame() {
4743
+ this.forcedThisFrame = true;
4744
+ if (typeof requestAnimationFrame === 'undefined')
4745
+ return;
4746
+ if (this.forcedFrameResetId !== null)
4747
+ cancelAnimationFrame(this.forcedFrameResetId);
4748
+ this.forcedFrameResetId = requestAnimationFrame(() => {
4749
+ this.forcedThisFrame = false;
4750
+ this.forcedFrameResetId = null;
4751
+ });
4711
4752
  }
4712
4753
  handleNormalTransition(config) {
4713
4754
  const { fromClass, activeClass, toClass, expectedState, transitionId, onComplete, cancelSignal } = config;
@@ -4825,7 +4866,7 @@ class AnimatedIfDirective {
4825
4866
  return of(null);
4826
4867
  }
4827
4868
  this.animatedLifecycle.leave();
4828
- return this.animatedLifecycle.state$.pipe(filter((state) => state === 'left'), tap(() => {
4869
+ return this.animatedLifecycle.state$.pipe(filter((state) => state === 'left'), take(1), tap(() => {
4829
4870
  this.viewContainerRef.clear();
4830
4871
  this.hasView = false;
4831
4872
  }));
@@ -4897,16 +4938,23 @@ const createFlipAnimation = (config) => {
4897
4938
  onCancel$.next();
4898
4939
  };
4899
4940
  const cleanup = () => {
4900
- if (!animation) {
4941
+ const currentAnimation = animation;
4942
+ if (!currentAnimation) {
4901
4943
  return;
4902
4944
  }
4903
- animation.removeEventListener('finish', onAnimationFinish);
4904
- animation.removeEventListener('cancel', onAnimationCancel);
4945
+ currentAnimation.removeEventListener('finish', onAnimationFinish);
4946
+ currentAnimation.removeEventListener('cancel', onAnimationCancel);
4947
+ animation = null;
4948
+ currentAnimation.cancel();
4905
4949
  };
4906
4950
  const updateInit = () => {
4907
4951
  initialRect = originElement.getBoundingClientRect();
4908
4952
  };
4909
4953
  const play = () => {
4954
+ if (animation) {
4955
+ cleanup();
4956
+ onCancel$.next();
4957
+ }
4910
4958
  const lastRect = el.getBoundingClientRect();
4911
4959
  const delta = {
4912
4960
  x: initialRect.left - lastRect.left,
@@ -4940,8 +4988,10 @@ const createFlipAnimation = (config) => {
4940
4988
  onStart$.next();
4941
4989
  };
4942
4990
  const cancel = () => {
4943
- animation?.cancel();
4991
+ if (!animation)
4992
+ return;
4944
4993
  cleanup();
4994
+ onCancel$.next();
4945
4995
  };
4946
4996
  return {
4947
4997
  updateInit,
@@ -5108,36 +5158,38 @@ const applyHeadBinding = (binding, applyFn, removeFn, isValid) => {
5108
5158
  const createPropertyBinding = (configBuilder, applyConfigFn) => {
5109
5159
  return (binding) => {
5110
5160
  applyConfigFn(computed(() => {
5111
- const value = untracked(() => (isSignal(binding) ? binding() : binding));
5161
+ const value = isSignal(binding) ? binding() : binding;
5112
5162
  return value ? configBuilder(value) : null;
5113
5163
  }));
5114
5164
  };
5115
5165
  };
5116
5166
  const createArrayPropertyBinding = (configBuilder, applyConfigFn) => {
5117
5167
  return (binding) => {
5168
+ const injector = inject(Injector);
5118
5169
  const valuesSignal = isSignal(binding) ? binding : signal(binding);
5119
- const valuesList = computed(() => untracked(() => valuesSignal()) ?? [], /* @ts-ignore */
5120
- ...(ngDevMode ? [{ debugName: "valuesList" }] : /* istanbul ignore next */ []));
5121
- valuesList().forEach((value, index) => {
5122
- applyConfigFn(computed(() => configBuilder(value, index)));
5170
+ let bindingCount = 0;
5171
+ effect(() => {
5172
+ const values = valuesSignal() ?? [];
5173
+ untracked(() => {
5174
+ while (bindingCount < values.length) {
5175
+ const index = bindingCount++;
5176
+ runInInjectionContext(injector, () => {
5177
+ applyConfigFn(computed(() => {
5178
+ const value = valuesSignal()?.[index];
5179
+ return value === undefined ? null : configBuilder(value, index);
5180
+ }));
5181
+ });
5182
+ }
5183
+ });
5123
5184
  });
5124
5185
  };
5125
5186
  };
5126
5187
  const toStringBinding = (binding) => {
5127
5188
  return computed(() => {
5128
- const value = untracked(() => (isSignal(binding) ? binding() : binding));
5189
+ const value = isSignal(binding) ? binding() : binding;
5129
5190
  return value !== null && value !== undefined ? String(value) : null;
5130
5191
  });
5131
5192
  };
5132
- const createBulkPropertyBinding = (_propertyPrefix, applyConfigFn) => {
5133
- return (config) => {
5134
- Object.entries(config).forEach(([key, value]) => {
5135
- if (value !== undefined) {
5136
- applyConfigFn(key, value);
5137
- }
5138
- });
5139
- };
5140
- };
5141
5193
 
5142
5194
  /** The rendered favicon is this many device-independent pixels square. */
5143
5195
  const FAVICON_SIZE = 64;
@@ -5486,7 +5538,7 @@ const applyLinkBinding = (binding) => {
5486
5538
  const applyCanonicalBinding = /* @__PURE__ */ createPropertyBinding((href) => ({ rel: 'canonical', href }), applyLinkBinding);
5487
5539
  const applyAlternateBinding = (hreflang, binding) => {
5488
5540
  applyLinkBinding(computed(() => {
5489
- const url = untracked(() => (isSignal(binding) ? binding() : binding));
5541
+ const url = isSignal(binding) ? binding() : binding;
5490
5542
  return url ? { rel: 'alternate', hreflang, href: url } : null;
5491
5543
  }));
5492
5544
  };
@@ -5705,6 +5757,8 @@ const META_STORE_DEF = /* @__PURE__ */ defineRootProvider(() => {
5705
5757
  return `http-equiv="${config.httpEquiv}"`;
5706
5758
  if (config.itemprop)
5707
5759
  return `itemprop="${config.itemprop}"`;
5760
+ if (config.charset)
5761
+ return `charset="${config.charset}"`;
5708
5762
  return config.key ?? '';
5709
5763
  };
5710
5764
  const isMultiInstanceTag = (selector) => {
@@ -5815,14 +5869,14 @@ const applyMetaBinding = (binding) => {
5815
5869
  const applyDescriptionBinding = /* @__PURE__ */ createPropertyBinding((content) => ({ name: 'description', content }), applyMetaBinding);
5816
5870
  const applyKeywordsBinding = (binding) => {
5817
5871
  applyMetaBinding(computed(() => {
5818
- const keywords = untracked(() => (isSignal(binding) ? binding() : binding));
5872
+ const keywords = isSignal(binding) ? binding() : binding;
5819
5873
  return keywords && keywords.length > 0 ? { name: 'keywords', content: keywords.join(', ') } : null;
5820
5874
  }));
5821
5875
  };
5822
5876
  const applyAuthorBinding = /* @__PURE__ */ createPropertyBinding((content) => ({ name: 'author', content }), applyMetaBinding);
5823
5877
  const applyRobotsBinding = (binding) => {
5824
5878
  applyMetaBinding(computed(() => {
5825
- const config = untracked(() => (isSignal(binding) ? binding() : binding));
5879
+ const config = isSignal(binding) ? binding() : binding;
5826
5880
  if (!config)
5827
5881
  return null;
5828
5882
  const directives = [];
@@ -5950,19 +6004,19 @@ const applySocialMediaBindings = (config) => {
5950
6004
  applyDescriptionBinding(config.description);
5951
6005
  if (config.openGraph || config.title || config.description || config.image || config.url) {
5952
6006
  applyOpenGraphBindings({
6007
+ ...config.openGraph,
5953
6008
  title: config.openGraph?.title ?? config.title,
5954
6009
  description: config.openGraph?.description ?? config.description,
5955
6010
  image: config.openGraph?.image ?? config.image,
5956
6011
  url: config.openGraph?.url ?? config.url,
5957
- ...config.openGraph,
5958
6012
  });
5959
6013
  }
5960
6014
  if (config.twitter || config.title || config.description || config.image) {
5961
6015
  applyTwitterCardBindings({
6016
+ ...config.twitter,
5962
6017
  title: config.twitter?.title ?? config.title,
5963
6018
  description: config.twitter?.description ?? config.description,
5964
6019
  image: config.twitter?.image ?? config.image,
5965
- ...config.twitter,
5966
6020
  });
5967
6021
  }
5968
6022
  if (config.article)
@@ -5992,9 +6046,6 @@ const STRUCTURED_DATA_STORE_DEF = /* @__PURE__ */ defineRootProvider(() => {
5992
6046
  }
5993
6047
  const script = renderer.createElement('script');
5994
6048
  renderer.setAttributes(script, { type: 'application/ld+json' });
5995
- // The JSON is the script's *content*, not an attribute. Written as text rather than markup so a
5996
- // `</script>` inside a string can't close the tag early - the escaping problem
5997
- // `StructuredDataComponent` has to solve by hand because it goes through `innerHTML`.
5998
6049
  renderer.setTextContent(script, JSON.stringify(data));
5999
6050
  const target = getTargetElement();
6000
6051
  renderer.appendChild(target, script);
@@ -6033,7 +6084,7 @@ class StructuredDataComponent {
6033
6084
  if (!data) {
6034
6085
  return null;
6035
6086
  }
6036
- const json = data ? JSON.stringify(data, null, 2).replace(/<\/script>/g, '<\\/script>') : '';
6087
+ const json = JSON.stringify(data, null, 2).replace(/</g, '\\u003C');
6037
6088
  const html = `<script type="application/ld+json">${json}</script>`;
6038
6089
  return this.sanitizer.bypassSecurityTrustHtml(html);
6039
6090
  }, /* @ts-ignore */
@@ -6060,19 +6111,18 @@ const UNSAVED_CHANGES_TITLE_MARKER = '●';
6060
6111
  // The badge is a single app-wide surface, so every lock that wants one registers here and the badge
6061
6112
  // is derived from all of them - otherwise the first tracker to go clean would clear a badge that
6062
6113
  // another one still needs.
6063
- const BADGE_HOLDERS = /* @__PURE__ */ new Map();
6064
- const syncAppBadge = () => {
6065
- const nav = typeof navigator === 'undefined' ? null : navigator;
6114
+ const BADGE_HOLDERS = /* @__PURE__ */ new WeakMap();
6115
+ const syncAppBadge = (nav, badgeHolders) => {
6066
6116
  if (!nav?.setAppBadge || !nav.clearAppBadge) {
6067
6117
  return;
6068
6118
  }
6069
6119
  // Unsupported, or not installed - the promise rejects instead of throwing synchronously.
6070
6120
  const ignore = () => undefined;
6071
- if (!BADGE_HOLDERS.size) {
6121
+ if (!badgeHolders.size) {
6072
6122
  nav.clearAppBadge().catch(ignore);
6073
6123
  return;
6074
6124
  }
6075
- const count = Array.from(BADGE_HOLDERS.values()).reduce((total, contents) => (typeof contents === 'number' ? total + contents : total), 0);
6125
+ const count = Array.from(badgeHolders.values()).reduce((total, contents) => (typeof contents === 'number' ? total + contents : total), 0);
6076
6126
  // `setAppBadge()` without a count renders a plain dot.
6077
6127
  nav.setAppBadge(count || undefined).catch(ignore);
6078
6128
  };
@@ -6104,9 +6154,10 @@ const createUnsavedChangesTabLock = (config) => {
6104
6154
  // Blinking needs something to blink, so it implies the default marker.
6105
6155
  const titleMarker = config.titleMarker === true
6106
6156
  ? UNSAVED_CHANGES_TITLE_MARKER
6107
- : (config.titleMarker ?? (flash && !favicon ? UNSAVED_CHANGES_TITLE_MARKER : null));
6157
+ : (config.titleMarker ?? (flash ? UNSAVED_CHANGES_TITLE_MARKER : null));
6108
6158
  const destroyRef = inject(DestroyRef);
6109
6159
  const isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
6160
+ const navigator = inject(DOCUMENT).defaultView?.navigator;
6110
6161
  const releaseFns = [];
6111
6162
  // The blink phase. Always `true` unless flashing is on, so the marker/favicon effects below can read
6112
6163
  // one signal either way.
@@ -6197,26 +6248,31 @@ const createUnsavedChangesTabLock = (config) => {
6197
6248
  detach();
6198
6249
  });
6199
6250
  }
6200
- if (isBrowser && badge !== false) {
6251
+ if (isBrowser && navigator && badge !== false) {
6201
6252
  const badgeId = Symbol('unsaved-changes-badge');
6202
6253
  const contents = badge === true ? true : badge;
6254
+ let badgeHolders = BADGE_HOLDERS.get(navigator);
6255
+ if (!badgeHolders) {
6256
+ badgeHolders = new Map();
6257
+ BADGE_HOLDERS.set(navigator, badgeHolders);
6258
+ }
6203
6259
  const badgeEffect = effect(() => {
6204
6260
  const dirty = hasChanges();
6205
6261
  untracked(() => {
6206
6262
  if (dirty) {
6207
- BADGE_HOLDERS.set(badgeId, contents);
6263
+ badgeHolders.set(badgeId, contents);
6208
6264
  }
6209
6265
  else {
6210
- BADGE_HOLDERS.delete(badgeId);
6266
+ badgeHolders.delete(badgeId);
6211
6267
  }
6212
- syncAppBadge();
6268
+ syncAppBadge(navigator, badgeHolders);
6213
6269
  });
6214
6270
  }, /* @ts-ignore */
6215
6271
  ...(ngDevMode ? [{ debugName: "badgeEffect" }] : /* istanbul ignore next */ []));
6216
6272
  releaseFns.push(() => {
6217
6273
  badgeEffect.destroy();
6218
- BADGE_HOLDERS.delete(badgeId);
6219
- syncAppBadge();
6274
+ badgeHolders.delete(badgeId);
6275
+ syncAppBadge(navigator, badgeHolders);
6220
6276
  });
6221
6277
  }
6222
6278
  const destroy = () => {
@@ -6282,6 +6338,9 @@ const createUnsavedChangesTracker = (config) => {
6282
6338
  return false;
6283
6339
  }
6284
6340
  const defaultValue = _defaultValue();
6341
+ if (defaultValue === null || defaultValue === undefined) {
6342
+ return false;
6343
+ }
6285
6344
  return !(compareFn ? compareFn(current, defaultValue) : equal(current, defaultValue));
6286
6345
  }, /* @ts-ignore */
6287
6346
  ...(ngDevMode ? [{ debugName: "hasChanges" }] : /* istanbul ignore next */ []));
@@ -6347,7 +6406,7 @@ const isCrossOrigin = (source) => /^(https?:)?\/\//.test(source);
6347
6406
  * Cross-origin scripts are left out: an analytics tag with a cache-busting query would otherwise read
6348
6407
  * as a new deploy on every check.
6349
6408
  */
6350
- const readBuildFingerprint = (document) => Array.from(document.querySelectorAll('script[src]'))
6409
+ const readBuildFingerprint = (document) => Array.from(document.head.querySelectorAll('script[src]'))
6351
6410
  .map((script) => script.getAttribute('src') ?? '')
6352
6411
  .filter((source) => !!source && !isCrossOrigin(source))
6353
6412
  .sort()
@@ -6420,7 +6479,7 @@ const isStaleBuildError = (error) => {
6420
6479
  };
6421
6480
 
6422
6481
  const RELOADED_AT_KEY = 'et-app-update-reloaded-at';
6423
- const APP_UPDATES_CONFIG_DEF = /* @__PURE__ */ defineStaticProvider({
6482
+ const APP_UPDATES_CONFIG_DEF = /* @__PURE__ */ defineStaticRootProvider({
6424
6483
  entryUrl: '/',
6425
6484
  pollInterval: 300_000,
6426
6485
  minCheckInterval: 30_000,
@@ -6634,30 +6693,15 @@ class RepeatDirective {
6634
6693
  this.mainTemplateRef = inject(TemplateRef);
6635
6694
  this.viewContainerRef = inject(ViewContainerRef);
6636
6695
  this.repeatCount = input(2, { ...(ngDevMode ? { debugName: "repeatCount" } : /* istanbul ignore next */ {}), alias: 'etRepeat', transform: numberAttribute });
6637
- this.views = linkedSignal({ ...(ngDevMode ? { debugName: "views" } : /* istanbul ignore next */ {}), source: this.repeatCount,
6638
- computation: (count, previous) => {
6639
- const prevCount = previous?.source ?? 0;
6640
- const views = previous?.value ?? [];
6641
- if (count === prevCount && previous?.value) {
6642
- return previous.value;
6643
- }
6644
- const viewsToCreate = count - prevCount;
6645
- if (viewsToCreate > 0) {
6646
- for (let i = 0; i < viewsToCreate; i++) {
6647
- views.push(this.viewContainerRef.createEmbeddedView(this.mainTemplateRef));
6648
- }
6649
- }
6650
- else if (viewsToCreate < 0) {
6651
- for (let i = 0; i < -viewsToCreate; i++) {
6652
- this.viewContainerRef.remove(this.viewContainerRef.length - 1);
6653
- }
6654
- views.splice(viewsToCreate);
6655
- }
6656
- return views;
6657
- } });
6658
- // Ugly but needed to trigger the linked signal.
6659
- // Otherwise it has no consumers and won't run.
6660
- effect(() => this.views());
6696
+ effect(() => {
6697
+ const count = Math.max(0, this.repeatCount());
6698
+ while (this.viewContainerRef.length < count) {
6699
+ this.viewContainerRef.createEmbeddedView(this.mainTemplateRef);
6700
+ }
6701
+ while (this.viewContainerRef.length > count) {
6702
+ this.viewContainerRef.remove(this.viewContainerRef.length - 1);
6703
+ }
6704
+ });
6661
6705
  }
6662
6706
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: RepeatDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
6663
6707
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: RepeatDirective, isStandalone: true, selector: "[etRepeat]", inputs: { repeatCount: { classPropertyName: "repeatCount", publicName: "etRepeat", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
@@ -6727,11 +6771,15 @@ class ScrollObserverDirective {
6727
6771
  this.isAtEnd = computed(() => this._endIntersection()[0]?.isIntersecting ?? false, /* @ts-ignore */
6728
6772
  ...(ngDevMode ? [{ debugName: "isAtEnd" }] : /* istanbul ignore next */ []));
6729
6773
  }
6730
- _registerStart(el) {
6774
+ /** @internal */
6775
+ registerStart(el) {
6731
6776
  this._startEl.set(el);
6777
+ return () => this._startEl.update((current) => (current === el ? null : current));
6732
6778
  }
6733
- _registerEnd(el) {
6779
+ /** @internal */
6780
+ registerEnd(el) {
6734
6781
  this._endEl.set(el);
6782
+ return () => this._endEl.update((current) => (current === el ? null : current));
6735
6783
  }
6736
6784
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ScrollObserverDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
6737
6785
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: ScrollObserverDirective, isStandalone: true, selector: "[etScrollObserver]", inputs: { enabled: { classPropertyName: "enabled", publicName: "enabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { enabled: "enabledChange" }, exportAs: ["etScrollObserver"], ngImport: i0 }); }
@@ -6748,7 +6796,7 @@ class ScrollObserverEndDirective {
6748
6796
  constructor() {
6749
6797
  this.elementRef = inject(ElementRef);
6750
6798
  this.host = inject(ScrollObserverDirective);
6751
- this.host._registerEnd(this.elementRef);
6799
+ inject(DestroyRef).onDestroy(this.host.registerEnd(this.elementRef));
6752
6800
  }
6753
6801
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ScrollObserverEndDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
6754
6802
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: ScrollObserverEndDirective, isStandalone: true, selector: "[etScrollObserverEnd]", ngImport: i0 }); }
@@ -6764,7 +6812,7 @@ class ScrollObserverStartDirective {
6764
6812
  constructor() {
6765
6813
  this.elementRef = inject(ElementRef);
6766
6814
  this.host = inject(ScrollObserverDirective);
6767
- this.host._registerStart(this.elementRef);
6815
+ inject(DestroyRef).onDestroy(this.host.registerStart(this.elementRef));
6768
6816
  }
6769
6817
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ScrollObserverStartDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
6770
6818
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: ScrollObserverStartDirective, isStandalone: true, selector: "[etScrollObserverStart]", ngImport: i0 }); }
@@ -6788,6 +6836,7 @@ const capturePointer = (el, pointerId) => {
6788
6836
  };
6789
6837
  const setupDragObservable = (startEvent, el, commitThreshold) => {
6790
6838
  const { pointerId, clientX: startX, clientY: startY } = startEvent;
6839
+ const document = el.ownerDocument;
6791
6840
  let cancelled = false;
6792
6841
  let endX = startX;
6793
6842
  let endY = startY;
@@ -7198,7 +7247,12 @@ const applyInitialFocus = (paneElement, autoFocus, document) => {
7198
7247
  focusElement(getFocusableElements(paneElement, document)[0] ?? paneElement);
7199
7248
  return;
7200
7249
  }
7201
- focusElement(paneElement.querySelector(autoFocus) ?? paneElement);
7250
+ try {
7251
+ focusElement(paneElement.querySelector(autoFocus) ?? paneElement);
7252
+ }
7253
+ catch {
7254
+ focusElement(paneElement);
7255
+ }
7202
7256
  };
7203
7257
  const setupFocusTrap = (paneElement, overlayRef, enabled, isTopMost, document) => {
7204
7258
  if (!enabled) {
@@ -7217,6 +7271,11 @@ const setupFocusTrap = (paneElement, overlayRef, enabled, isTopMost, document) =
7217
7271
  const firstElement = focusableElements[0];
7218
7272
  const lastElement = focusableElements[focusableElements.length - 1];
7219
7273
  const activeElement = document.activeElement;
7274
+ if (!activeElement || !paneElement.contains(activeElement)) {
7275
+ event.preventDefault();
7276
+ focusElement(event.shiftKey ? (lastElement ?? null) : (firstElement ?? null));
7277
+ return;
7278
+ }
7220
7279
  if (event.shiftKey && activeElement === firstElement) {
7221
7280
  event.preventDefault();
7222
7281
  focusElement(lastElement ?? null);
@@ -7227,9 +7286,9 @@ const setupFocusTrap = (paneElement, overlayRef, enabled, isTopMost, document) =
7227
7286
  focusElement(firstElement ?? null);
7228
7287
  }
7229
7288
  };
7230
- paneElement.addEventListener('keydown', onKeyDown);
7289
+ document.addEventListener('keydown', onKeyDown, true);
7231
7290
  return () => {
7232
- paneElement.removeEventListener('keydown', onKeyDown);
7291
+ document.removeEventListener('keydown', onKeyDown, true);
7233
7292
  };
7234
7293
  };
7235
7294
 
@@ -7417,6 +7476,9 @@ const resetPositioningStyles = (config, hostElement, paneElement, renderer) => {
7417
7476
  '--et-overlay-anchored-y': null,
7418
7477
  });
7419
7478
  renderer.removeAttribute(paneElement, 'data-overlay-placement');
7479
+ const arrowElement = paneElement.querySelector('[et-floating-arrow]');
7480
+ if (arrowElement)
7481
+ renderer.setCssProperty(arrowElement, '--et-floating-arrow-translate', null);
7420
7482
  setBaseElementStyles(config, hostElement, paneElement, renderer);
7421
7483
  };
7422
7484
  let anchoredPositionSetup = null;
@@ -7570,7 +7632,10 @@ const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, render
7570
7632
  renderer.setStyle(paneElement, { visibility: 'hidden' });
7571
7633
  }
7572
7634
  };
7635
+ let updateId = 0;
7636
+ let destroyed = false;
7573
7637
  const update = () => {
7638
+ const currentUpdateId = ++updateId;
7574
7639
  // Checked here rather than left to the `hide` middleware, which is only in the list when `autoHide`
7575
7640
  // or `autoCloseIfReferenceHidden` asked for it: a trigger destroyed while its overlay is open (a
7576
7641
  // menu item that removes the button it was opened from) would otherwise fly to the corner for the
@@ -7588,7 +7653,7 @@ const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, render
7588
7653
  ? flip({
7589
7654
  fallbackPlacements: strategy.fallbackPlacements ?? undefined,
7590
7655
  fallbackAxisSideDirection: 'start',
7591
- padding: insets,
7656
+ padding: viewportPadding,
7592
7657
  boundary: strategy.boundary,
7593
7658
  })
7594
7659
  : preferredSide({
@@ -7651,6 +7716,8 @@ const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, render
7651
7716
  strategy: 'absolute',
7652
7717
  middleware,
7653
7718
  }).then(({ x, y, placement, middlewareData }) => {
7719
+ if (destroyed || currentUpdateId !== updateId)
7720
+ return;
7654
7721
  if (middlewareData.hide?.referenceHidden) {
7655
7722
  handleUnusableReference();
7656
7723
  return;
@@ -7676,6 +7743,8 @@ const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, render
7676
7743
  // scrolling anything `autoUpdate` watches.
7677
7744
  const stopInsetUpdates = onOverlayViewportInsetsChange(update);
7678
7745
  return () => {
7746
+ destroyed = true;
7747
+ updateId++;
7679
7748
  cleanup();
7680
7749
  stopInsetUpdates();
7681
7750
  };
@@ -7711,6 +7780,7 @@ const createOverlayRuntimeRef = (id, config, elements, requestClose) => {
7711
7780
  const _componentInstance = signal(null, /* @ts-ignore */
7712
7781
  ...(ngDevMode ? [{ debugName: "_componentInstance" }] : /* istanbul ignore next */ []));
7713
7782
  let positionUpdater = null;
7783
+ let backdropUpdater = null;
7714
7784
  const beforeOpenedSubject = new Subject();
7715
7785
  const afterOpenedSubject = new Subject();
7716
7786
  const beforeClosedSubject = new Subject();
@@ -7722,7 +7792,7 @@ const createOverlayRuntimeRef = (id, config, elements, requestClose) => {
7722
7792
  elements,
7723
7793
  state: _state.asReadonly(),
7724
7794
  componentInstance: _componentInstance.asReadonly(),
7725
- // Internal - driven by overlay-runtime.ts
7795
+ /** @internal */
7726
7796
  beforeOpenedSubject,
7727
7797
  close(result, source = 'api') {
7728
7798
  if (_state() === 'closing' || _state() === 'closed') {
@@ -7763,6 +7833,7 @@ const createOverlayRuntimeRef = (id, config, elements, requestClose) => {
7763
7833
  afterClosed() {
7764
7834
  return afterClosedSubject.asObservable();
7765
7835
  },
7836
+ /** @internal */
7766
7837
  attachComponentRef(componentRef) {
7767
7838
  _componentInstance.set(componentRef.instance);
7768
7839
  },
@@ -7776,6 +7847,21 @@ const createOverlayRuntimeRef = (id, config, elements, requestClose) => {
7776
7847
  }
7777
7848
  positionUpdater?.(strategy);
7778
7849
  },
7850
+ /** @internal */
7851
+ attachBackdropUpdater(updater) {
7852
+ backdropUpdater = updater;
7853
+ },
7854
+ /**
7855
+ * Adds or removes the backdrop of an open overlay. `elements.backdropElement` follows.
7856
+ * A closing overlay keeps the backdrop it has, so its leave transition stays intact.
7857
+ */
7858
+ updateBackdrop(hasBackdrop) {
7859
+ if (_state() === 'closing' || _state() === 'closed') {
7860
+ return;
7861
+ }
7862
+ backdropUpdater?.(hasBackdrop);
7863
+ },
7864
+ /** @internal */
7779
7865
  markOpened() {
7780
7866
  if (_state() !== 'mounting') {
7781
7867
  return;
@@ -7784,6 +7870,7 @@ const createOverlayRuntimeRef = (id, config, elements, requestClose) => {
7784
7870
  afterOpenedSubject.next();
7785
7871
  afterOpenedSubject.complete();
7786
7872
  },
7873
+ /** @internal */
7787
7874
  beginClose(closeEvent) {
7788
7875
  if (_state() === 'closing' || _state() === 'closed') {
7789
7876
  return false;
@@ -7793,6 +7880,7 @@ const createOverlayRuntimeRef = (id, config, elements, requestClose) => {
7793
7880
  beforeClosedSubject.complete();
7794
7881
  return true;
7795
7882
  },
7883
+ /** @internal */
7796
7884
  finishClose(closeEvent) {
7797
7885
  if (_state() === 'closed') {
7798
7886
  return;
@@ -7813,8 +7901,7 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
7813
7901
  const renderer = injectRenderer();
7814
7902
  const openEntriesState = signal([], /* @ts-ignore */
7815
7903
  ...(ngDevMode ? [{ debugName: "openEntriesState" }] : /* istanbul ignore next */ []));
7816
- const openEntries = computed(() => openEntriesState(), /* @ts-ignore */
7817
- ...(ngDevMode ? [{ debugName: "openEntries" }] : /* istanbul ignore next */ []));
7904
+ const openEntries = openEntriesState.asReadonly();
7818
7905
  // One runtime root per document and stacking level: overlays usually all mount into the app's
7819
7906
  // document at the default level, but an overlay anchored inside a same-origin pop-up window
7820
7907
  // (config.document) needs a root over there, and one opened from inside something that paints
@@ -7826,12 +7913,6 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
7826
7913
  const getRootElement = (targetDocument, zIndex) => {
7827
7914
  let documentRoots = rootElements.get(targetDocument);
7828
7915
  if (!documentRoots) {
7829
- // A previous Angular app (e.g. the one that existed before a Storybook HMR update or story
7830
- // switch) may have left its runtime root orphaned in <body> if it was torn down mid-animation.
7831
- // Such a node keeps a backdrop/pane on screen and blocks pointer events, so clear any stragglers
7832
- // before creating ours. Only on the document's first root - a second level must not remove the
7833
- // first one's still-mounted overlays.
7834
- targetDocument.querySelectorAll('.et-overlay-runtime-root').forEach((el) => el.remove());
7835
7916
  documentRoots = new Map();
7836
7917
  rootElements.set(targetDocument, documentRoots);
7837
7918
  }
@@ -7877,7 +7958,13 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
7877
7958
  }
7878
7959
  };
7879
7960
  const isTopMost = (overlayRef) => {
7880
- return openEntriesState().at(-1) === overlayRef;
7961
+ const entries = openEntriesState();
7962
+ for (let index = entries.length - 1; index >= 0; index--) {
7963
+ const entry = entries[index];
7964
+ if (entry && entry.state() !== 'closing' && entry.state() !== 'closed')
7965
+ return entry === overlayRef;
7966
+ }
7967
+ return false;
7881
7968
  };
7882
7969
  const getAnimatedLifecycle = (componentRef) => {
7883
7970
  const componentLifecycle = componentRef.instance.animatedLifecycle?.();
@@ -7892,11 +7979,27 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
7892
7979
  const root = getRootElement(targetDocument, layer);
7893
7980
  const hostElement = renderer.createElement('div');
7894
7981
  const paneElement = renderer.createElement('div');
7895
- const backdropElement = config.hasBackdrop === false ? null : renderer.createElement('div');
7982
+ const backdropElement = signal(null, /* @ts-ignore */
7983
+ ...(ngDevMode ? [{ debugName: "backdropElement" }] : /* istanbul ignore next */ []));
7896
7984
  const previousFocusedElement = isHTMLElement(targetDocument.activeElement) ? targetDocument.activeElement : null;
7897
7985
  const autoFocus = config.autoFocus ?? 'first-tabbable';
7986
+ let currentHasBackdrop = config.hasBackdrop !== false;
7987
+ let currentPositionStrategy = config.positionStrategy;
7988
+ const activeConfig = () => ({
7989
+ ...config,
7990
+ positionStrategy: currentPositionStrategy,
7991
+ hasBackdrop: currentHasBackdrop,
7992
+ });
7993
+ const createBackdropElement = () => {
7994
+ const element = renderer.createElement('div');
7995
+ renderer.addClass(element, 'et-overlay-runtime-backdrop');
7996
+ setBackdropStyles(element, renderer);
7997
+ renderer.setAttribute(element, 'data-overlay-id', config.id);
7998
+ (config.backdropClass ?? []).forEach((className) => renderer.addClass(element, className));
7999
+ return element;
8000
+ };
7898
8001
  renderer.addClass(hostElement, 'et-overlay-runtime-entry');
7899
- setBaseElementStyles(config, hostElement, paneElement, renderer);
8002
+ setBaseElementStyles(activeConfig(), hostElement, paneElement, renderer);
7900
8003
  renderer.setAttributes(hostElement, {
7901
8004
  'data-overlay-id': config.id,
7902
8005
  role: config.role ?? null,
@@ -7907,19 +8010,17 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
7907
8010
  'aria-label': config.ariaLabel ?? null,
7908
8011
  });
7909
8012
  renderer.addClass(hostElement, ...(config.hostClass ?? []));
7910
- if (backdropElement) {
7911
- renderer.addClass(backdropElement, 'et-overlay-runtime-backdrop');
7912
- setBackdropStyles(backdropElement, renderer);
7913
- renderer.setAttribute(backdropElement, 'data-overlay-id', config.id);
7914
- (config.backdropClass ?? []).forEach((className) => renderer.addClass(backdropElement, className));
7915
- renderer.appendChild(hostElement, backdropElement);
8013
+ if (currentHasBackdrop) {
8014
+ const element = createBackdropElement();
8015
+ renderer.appendChild(hostElement, element);
8016
+ backdropElement.set(element);
7916
8017
  }
7917
8018
  renderer.appendChild(hostElement, paneElement);
7918
8019
  renderer.appendChild(root, hostElement);
7919
8020
  const overlayRef = createOverlayRuntimeRef(config.id, { ...config }, {
7920
8021
  rootElement: root,
7921
8022
  hostElement,
7922
- backdropElement,
8023
+ backdropElement: backdropElement.asReadonly(),
7923
8024
  paneElement,
7924
8025
  }, (result, source) => beginClose({ result, source }));
7925
8026
  animationDebugLog(`runtime ${config.id}`, 'mount');
@@ -7928,12 +8029,14 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
7928
8029
  let interactiveCloseReady = false;
7929
8030
  const cleanupFns = [];
7930
8031
  const parentInjector = config.injector ?? config.viewContainerRef?.injector ?? environmentInjector;
8032
+ const parentEnvironmentInjector = parentInjector.get(EnvironmentInjector, environmentInjector);
8033
+ const overlayEnvironmentInjector = createEnvironmentInjector(config.providers ?? [], parentEnvironmentInjector);
7931
8034
  const elementInjector = Injector.create({
7932
8035
  parent: parentInjector,
7933
- providers: config.providers ?? [],
8036
+ providers: [],
7934
8037
  });
7935
8038
  const componentRef = createComponent(config.component, {
7936
- environmentInjector,
8039
+ environmentInjector: overlayEnvironmentInjector,
7937
8040
  elementInjector,
7938
8041
  hostElement: paneElement,
7939
8042
  bindings: config.bindings ?? [],
@@ -7946,23 +8049,47 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
7946
8049
  overlayRef.beforeOpenedSubject.next();
7947
8050
  overlayRef.beforeOpenedSubject.complete();
7948
8051
  openEntriesState.update((entries) => [...entries, overlayRef]);
7949
- let positionCleanup = setupPositioning(config, hostElement, paneElement, overlayRef, renderer);
8052
+ let positionCleanup = setupPositioning(activeConfig(), hostElement, paneElement, overlayRef, renderer);
7950
8053
  cleanupFns.push(() => positionCleanup());
7951
- let currentPositionStrategy = config.positionStrategy;
7952
8054
  const getOriginElement = () => currentPositionStrategy?.kind === 'anchored' && isHTMLElement(currentPositionStrategy.referenceElement)
7953
8055
  ? currentPositionStrategy.referenceElement
7954
8056
  : null;
7955
8057
  overlayRef.attachPositionUpdater((strategy) => {
7956
8058
  currentPositionStrategy = strategy;
7957
8059
  positionCleanup();
7958
- resetPositioningStyles(config, hostElement, paneElement, renderer);
7959
- positionCleanup = setupPositioning({ ...config, positionStrategy: strategy }, hostElement, paneElement, overlayRef, renderer);
8060
+ resetPositioningStyles(activeConfig(), hostElement, paneElement, renderer);
8061
+ positionCleanup = setupPositioning(activeConfig(), hostElement, paneElement, overlayRef, renderer);
8062
+ });
8063
+ overlayRef.attachBackdropUpdater((hasBackdrop) => {
8064
+ if (hasBackdrop === currentHasBackdrop) {
8065
+ return;
8066
+ }
8067
+ currentHasBackdrop = hasBackdrop;
8068
+ if (hasBackdrop) {
8069
+ const element = createBackdropElement();
8070
+ renderer.insertBefore(hostElement, element, paneElement);
8071
+ backdropElement.set(element);
8072
+ }
8073
+ else {
8074
+ const element = backdropElement();
8075
+ if (element) {
8076
+ renderer.removeChild(hostElement, element);
8077
+ backdropElement.set(null);
8078
+ }
8079
+ }
8080
+ renderer.setStyle(hostElement, { pointerEvents: hasBackdrop ? 'auto' : 'none' });
7960
8081
  });
7961
8082
  const destroyMountedOverlay = (closeEvent) => {
7962
8083
  animationDebugLog(`runtime ${config.id}`, `destroy (source "${closeEvent.source}")`);
7963
8084
  cleanupFns.forEach((cleanup) => cleanup());
7964
8085
  appRef.detachView(componentRef.hostView);
7965
8086
  componentRef.destroy();
8087
+ // Angular does not own this injector, so nothing else tears down what the overlay's own
8088
+ // providers registered on it - their `DestroyRef` hooks and effects would outlive the overlay.
8089
+ if (!elementInjector.destroyed) {
8090
+ elementInjector.destroy();
8091
+ }
8092
+ overlayEnvironmentInjector.destroy();
7966
8093
  const parentNode = renderer.parentNode(hostElement);
7967
8094
  if (parentNode) {
7968
8095
  renderer.removeChild(parentNode, hostElement);
@@ -7976,7 +8103,11 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
7976
8103
  };
7977
8104
  // Allows the runtime to synchronously destroy this overlay on app teardown, bypassing the
7978
8105
  // async leave animation (whose completion callback would never fire once the app is gone).
7979
- const forceTeardown = () => destroyMountedOverlay({ result: undefined, source: 'api' });
8106
+ const forceTeardown = () => {
8107
+ const closeEvent = { result: undefined, source: 'api' };
8108
+ overlayRef.beginClose(closeEvent);
8109
+ destroyMountedOverlay(closeEvent);
8110
+ };
7980
8111
  mountedTeardowns.add(forceTeardown);
7981
8112
  cleanupFns.push(() => mountedTeardowns.delete(forceTeardown));
7982
8113
  const beginClose = (closeEvent) => {
@@ -8111,7 +8242,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
8111
8242
  type: Pipe,
8112
8243
  args: [{ name: 'etNormalizeGameResultType' }]
8113
8244
  }] });
8114
- // TODO(TRB): Add correct type once provided by API
8115
8245
  const normalizeGameResultType = (type) => {
8116
8246
  if (!type) {
8117
8247
  return null;
@@ -8157,81 +8287,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
8157
8287
  args: [{ name: 'etNormalizeMatchState' }]
8158
8288
  }] });
8159
8289
  const normalizeMatchState = (match) => {
8290
+ if (!match) {
8291
+ return null;
8292
+ }
8160
8293
  if (match?.isCompletedByReferee) {
8161
- return "autoWin" /* MatchStateType.AUTO_WIN */;
8294
+ return MatchStateType.AUTO_WIN;
8162
8295
  }
8163
8296
  else if (match?.status === 'preparing') {
8164
- return "preMatch" /* MatchStateType.PRE_MATCH */;
8297
+ return MatchStateType.PRE_MATCH;
8165
8298
  }
8166
8299
  else if (match?.status === 'started') {
8167
- return "live" /* MatchStateType.LIVE */;
8300
+ return MatchStateType.LIVE;
8168
8301
  }
8169
8302
  else if (match?.status === 'published' || match?.status === 'finished') {
8170
- return "postMatch" /* MatchStateType.POST_MATCH */;
8303
+ return MatchStateType.POST_MATCH;
8171
8304
  }
8172
- else if (match?.round.state !== 'preparing') {
8173
- return "preparingRound" /* MatchStateType.PREPARING_ROUND */;
8305
+ else if (match.round.state === 'preparing') {
8306
+ return MatchStateType.PREPARING_ROUND;
8174
8307
  }
8175
8308
  return null;
8176
8309
  };
8177
8310
 
8178
- class NormalizeMatchParticipantsPipe {
8179
- constructor() {
8180
- this.transform = normalizeMatchParticipants;
8181
- }
8182
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: NormalizeMatchParticipantsPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
8183
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: NormalizeMatchParticipantsPipe, isStandalone: true, name: "etNormalizeMatchParticipants" }); }
8184
- }
8185
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: NormalizeMatchParticipantsPipe, decorators: [{
8186
- type: Pipe,
8187
- args: [{ name: 'etNormalizeMatchParticipants' }]
8188
- }] });
8189
- const normalizeMatchParticipants = (match) => {
8190
- const matchState = normalizeMatchState(match);
8191
- if (!match || !matchState) {
8192
- return null;
8193
- }
8194
- return {
8195
- home: normalizeMatchParticipant(match, 'home'),
8196
- away: normalizeMatchParticipant(match, 'away'),
8197
- };
8198
- };
8199
- const normalizeMatchParticipant = (match, side) => {
8200
- const matchState = normalizeMatchState(match);
8201
- if (!match || !matchState) {
8202
- return null;
8203
- }
8204
- const participant = match[side];
8205
- const participantType = match.home?.type ?? match.away?.type ?? 'unknown';
8206
- if (!participant) {
8207
- if (matchState === "postMatch" /* MatchStateType.POST_MATCH */ || matchState === "autoWin" /* MatchStateType.AUTO_WIN */) {
8208
- return {
8209
- participantType,
8210
- type: 'none',
8211
- i18n: 'match-participant.none',
8212
- text: 'No opponent',
8213
- data: participant,
8214
- };
8215
- }
8216
- else {
8217
- return {
8218
- participantType,
8219
- type: 'tbd',
8220
- i18n: 'match-participant.tbd',
8221
- text: 'TBD',
8222
- data: participant,
8223
- };
8224
- }
8225
- }
8226
- else {
8227
- return {
8228
- participantType,
8229
- type: 'participant',
8230
- data: participant,
8231
- };
8232
- }
8233
- };
8234
-
8235
8311
  class NormalizeMatchScorePipe {
8236
8312
  constructor() {
8237
8313
  this.transform = normalizeMatchScore;
@@ -8243,6 +8319,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
8243
8319
  type: Pipe,
8244
8320
  args: [{ name: 'etNormalizeMatchScore' }]
8245
8321
  }] });
8322
+ const MatchStateType = {
8323
+ PREPARING_ROUND: 'preparingRound',
8324
+ PRE_MATCH: 'preMatch',
8325
+ LIVE: 'live',
8326
+ POST_MATCH: 'postMatch',
8327
+ AUTO_WIN: 'autoWin',
8328
+ };
8246
8329
  const EMPTY_SCORE = {
8247
8330
  home: { score: 'match-score.placeholder', isWinner: false },
8248
8331
  away: { score: 'match-score.placeholder', isWinner: false },
@@ -8259,7 +8342,7 @@ const normalizeMatchScore = (match) => {
8259
8342
  return { ...EMPTY_SCORE, subLine, isNumeric: false };
8260
8343
  }
8261
8344
  if (isKnockoutMatch(match)) {
8262
- if (matchState === "preMatch" /* MatchStateType.PRE_MATCH */ || matchState === "live" /* MatchStateType.LIVE */) {
8345
+ if (matchState === MatchStateType.PRE_MATCH || matchState === MatchStateType.LIVE) {
8263
8346
  return { ...EMPTY_SCORE, subLine, isNumeric: false };
8264
8347
  }
8265
8348
  return {
@@ -8277,7 +8360,6 @@ const normalizeMatchScore = (match) => {
8277
8360
  }
8278
8361
  else if (isGroupMatch(match)) {
8279
8362
  if (match.games.length === 1) {
8280
- // Return the score if only one game has been played
8281
8363
  return {
8282
8364
  ...getGroupMatchScore(match),
8283
8365
  subLine,
@@ -8368,6 +8450,63 @@ const getGroupMatchPoints = (match) => {
8368
8450
  };
8369
8451
  };
8370
8452
 
8453
+ class NormalizeMatchParticipantsPipe {
8454
+ constructor() {
8455
+ this.transform = normalizeMatchParticipants;
8456
+ }
8457
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: NormalizeMatchParticipantsPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
8458
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.7", ngImport: i0, type: NormalizeMatchParticipantsPipe, isStandalone: true, name: "etNormalizeMatchParticipants" }); }
8459
+ }
8460
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: NormalizeMatchParticipantsPipe, decorators: [{
8461
+ type: Pipe,
8462
+ args: [{ name: 'etNormalizeMatchParticipants' }]
8463
+ }] });
8464
+ const normalizeMatchParticipants = (match) => {
8465
+ const matchState = normalizeMatchState(match);
8466
+ if (!match || !matchState) {
8467
+ return null;
8468
+ }
8469
+ return {
8470
+ home: normalizeMatchParticipant(match, 'home'),
8471
+ away: normalizeMatchParticipant(match, 'away'),
8472
+ };
8473
+ };
8474
+ const normalizeMatchParticipant = (match, side) => {
8475
+ const matchState = normalizeMatchState(match);
8476
+ if (!match || !matchState) {
8477
+ return null;
8478
+ }
8479
+ const participant = match[side];
8480
+ const participantType = match.home?.type ?? match.away?.type ?? 'unknown';
8481
+ if (!participant) {
8482
+ if (matchState === MatchStateType.POST_MATCH || matchState === MatchStateType.AUTO_WIN) {
8483
+ return {
8484
+ participantType,
8485
+ type: 'none',
8486
+ i18n: 'match-participant.none',
8487
+ text: 'No opponent',
8488
+ data: participant,
8489
+ };
8490
+ }
8491
+ else {
8492
+ return {
8493
+ participantType,
8494
+ type: 'tbd',
8495
+ i18n: 'match-participant.tbd',
8496
+ text: 'TBD',
8497
+ data: participant,
8498
+ };
8499
+ }
8500
+ }
8501
+ else {
8502
+ return {
8503
+ participantType,
8504
+ type: 'participant',
8505
+ data: participant,
8506
+ };
8507
+ }
8508
+ };
8509
+
8371
8510
  class NormalizeMatchTypePipe {
8372
8511
  constructor() {
8373
8512
  this.transform = normalizeMatchType;
@@ -8468,14 +8607,9 @@ const inferMimeType = (srcset) => {
8468
8607
  }
8469
8608
  const cleanedUrl = urlParts.join(' ');
8470
8609
  const queryPart = cleanedUrl.split('?')[1] ?? '';
8471
- const containsFm = queryPart.startsWith('fm=') || queryPart.includes('&fm=');
8472
8610
  let fileExtension = null;
8473
- if (containsFm) {
8474
- const fmIndex = queryPart.indexOf('fm=');
8475
- const fmValue = queryPart
8476
- .substring(fmIndex + 3)
8477
- .split('&')[0]
8478
- ?.toLowerCase();
8611
+ if (queryPart) {
8612
+ const fmValue = new URLSearchParams(queryPart).get('fm')?.toLowerCase();
8479
8613
  if (fmValue) {
8480
8614
  fileExtension = fmValue;
8481
8615
  }
@@ -8496,7 +8630,7 @@ const inferMimeType = (srcset) => {
8496
8630
  case 'gif':
8497
8631
  return 'image/gif';
8498
8632
  case 'ico':
8499
- return 'image/vdn.microsoft.icon';
8633
+ return 'image/vnd.microsoft.icon';
8500
8634
  case 'jpg':
8501
8635
  case 'jpeg':
8502
8636
  return 'image/jpeg';
@@ -8568,7 +8702,7 @@ const inferMimeType = (srcset) => {
8568
8702
  case 'mpeg':
8569
8703
  return 'video/mpeg';
8570
8704
  case 'mpkg':
8571
- return 'tapplication/vnd.apple.installer+xml';
8705
+ return 'application/vnd.apple.installer+xml';
8572
8706
  case 'odp':
8573
8707
  return 'application/vnd.oasis.opendocument.presentation';
8574
8708
  case 'ods':
@@ -8825,7 +8959,9 @@ const bindProps = (config) => {
8825
8959
  }
8826
8960
  else if (single) {
8827
8961
  const firstAttachedRefElement = attachedElements.first();
8828
- console.error(`[${name}] These props can only be attached to a single element at a time.\n\n Already attached to \n`, firstAttachedRefElement, '\n Trying to attach to \n', el);
8962
+ if (isDevMode()) {
8963
+ console.error(`[${name}] These props can only be attached to a single element at a time.\n\n Already attached to \n`, firstAttachedRefElement, '\n Trying to attach to \n', el);
8964
+ }
8829
8965
  return;
8830
8966
  }
8831
8967
  }
@@ -8920,13 +9056,15 @@ const createHostProps = (props) => {
8920
9056
  const createSetup = (config) => {
8921
9057
  let didCallSetup = false;
8922
9058
  afterNextRender(() => {
8923
- if (!didCallSetup) {
9059
+ if (!didCallSetup && isDevMode()) {
8924
9060
  console.error('The setup() function was not called. Please call it inside your constructor.', config.this);
8925
9061
  return;
8926
9062
  }
8927
9063
  });
8928
9064
  return (params) => {
8929
9065
  if (didCallSetup) {
9066
+ if (!isDevMode())
9067
+ return;
8930
9068
  console.error('The setup() function was already called. Please call it only once. \n\n', 'Instance containing the setup() call \n', config.this, '\n\n Setup was called with\n', params);
8931
9069
  return;
8932
9070
  }
@@ -8959,19 +9097,23 @@ class PropsDirective {
8959
9097
  this.destroyRef = inject(DestroyRef);
8960
9098
  this.props = input.required({ ...(ngDevMode ? { debugName: "props" } : /* istanbul ignore next */ {}), alias: 'etProps', transform: (d) => d });
8961
9099
  this.propHandlers = createPropHandlers();
8962
- afterNextRender({
8963
- write: () => {
9100
+ let boundProps = null;
9101
+ effect(() => {
9102
+ const props = this.props();
9103
+ untracked(() => {
9104
+ if (boundProps) {
9105
+ unbindProps({ handlers: this.propHandlers, props: boundProps });
9106
+ }
8964
9107
  bindProps({
8965
9108
  handlers: this.propHandlers,
8966
- props: this.props(),
9109
+ props,
8967
9110
  });
8968
- },
9111
+ boundProps = props;
9112
+ });
8969
9113
  });
8970
9114
  this.destroyRef.onDestroy(() => {
8971
- unbindProps({
8972
- handlers: this.propHandlers,
8973
- props: this.props(),
8974
- });
9115
+ if (boundProps)
9116
+ unbindProps({ handlers: this.propHandlers, props: boundProps });
8975
9117
  });
8976
9118
  }
8977
9119
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: PropsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
@@ -8986,7 +9128,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
8986
9128
 
8987
9129
  const templateComputed = (templateSignal) => computed(() => {
8988
9130
  const content = templateSignal();
8989
- if (!content)
9131
+ if (content === null)
8990
9132
  return null;
8991
9133
  if (typeof content === 'string') {
8992
9134
  return {
@@ -9039,12 +9181,12 @@ const setupResizeObservable = (startEvent, edge, doc) => {
9039
9181
  const startX = startEvent.clientX;
9040
9182
  const startY = startEvent.clientY;
9041
9183
  let cancelled = false;
9042
- const end$ = merge(fromEvent(document, 'pointerup'), fromEvent(document, 'pointercancel')).pipe(filter((e) => e.pointerId === pointerId), take(1),
9184
+ const end$ = merge(fromEvent(doc, 'pointerup'), fromEvent(doc, 'pointercancel')).pipe(filter((e) => e.pointerId === pointerId), take(1),
9043
9185
  // Read below by the terminating `defer`, which only runs once this has completed the moves.
9044
9186
  tap((e) => (cancelled = e.type === 'pointercancel')));
9045
9187
  return defer(() => {
9046
9188
  const releaseSelection = suppressTextSelection(doc);
9047
- return concat(of({ type: 'start', edge }), fromEvent(document, 'pointermove').pipe(filter((e) => e.pointerId === pointerId), map((e) => ({
9189
+ return concat(of({ type: 'start', edge }), fromEvent(doc, 'pointermove').pipe(filter((e) => e.pointerId === pointerId), map((e) => ({
9048
9190
  type: 'move',
9049
9191
  data: { edge, dx: e.clientX - startX, dy: e.clientY - startY, clientX: e.clientX, clientY: e.clientY },
9050
9192
  })), takeUntil(end$)), defer(() => of({ type: cancelled ? 'cancelled' : 'end' }))).pipe(finalize(releaseSelection));
@@ -9092,7 +9234,7 @@ class ResizeHandlesComponent {
9092
9234
  class="et-resize-handle et-resize-handle--{{ edge }}"
9093
9235
  ></div>
9094
9236
  }
9095
- `, isInline: true, styles: ["@property --et-resize-handles-z-index{syntax: \"<integer>\"; inherits: true; initial-value: 10;}@property --et-resize-handles-edge-size{syntax: \"<length>\"; inherits: true; initial-value: 6px;}@property --et-resize-handles-corner-size{syntax: \"<length>\"; inherits: true; initial-value: 12px;}@property --et-resize-handles-edge-inset{syntax: \"<length>\"; inherits: true; initial-value: 8px;}@property --et-resize-handles-outset{syntax: \"<length>\"; inherits: true; initial-value: 0px;}@property --et-resize-handles-side-top{syntax: \"<length>\"; inherits: true; initial-value: 0px;}@property --et-resize-handles-side-bottom{syntax: \"<length>\"; inherits: true; initial-value: 8px;}@property --et-resize-handles-touch-edge-size{syntax: \"<length>\"; inherits: true; initial-value: 20px;}@property --et-resize-handles-touch-corner-size{syntax: \"<length>\"; inherits: true; initial-value: 28px;}et-resize-handles{position:absolute;inset:calc(-1 * var(--et-resize-handles-outset));pointer-events:none}.et-resize-handle{--et-resize-handle-thickness: calc(var(--et-resize-handles-edge-size) + var(--et-resize-handles-outset));--et-resize-handle-corner: calc(var(--et-resize-handles-corner-size) + var(--et-resize-handles-outset));position:absolute;z-index:var(--et-resize-handles-z-index);touch-action:none;pointer-events:auto}.et-resize-handle--n{left:var(--et-resize-handles-edge-inset);right:var(--et-resize-handles-edge-inset);height:var(--et-resize-handle-thickness);top:0}.et-resize-handle--s{left:var(--et-resize-handles-edge-inset);right:var(--et-resize-handles-edge-inset);height:var(--et-resize-handle-thickness);bottom:0}.et-resize-handle--e,.et-resize-handle--w{top:var(--et-resize-handles-side-top);bottom:var(--et-resize-handles-side-bottom);width:var(--et-resize-handle-thickness)}.et-resize-handle--e{right:0}.et-resize-handle--w{left:0}.et-resize-handle--ne,.et-resize-handle--nw{top:0;width:var(--et-resize-handle-corner);height:var(--et-resize-handle-corner)}.et-resize-handle--ne{right:0}.et-resize-handle--nw{left:0}.et-resize-handle--se,.et-resize-handle--sw{bottom:0;width:var(--et-resize-handle-corner);height:var(--et-resize-handle-corner)}.et-resize-handle--se{right:0}.et-resize-handle--sw{left:0}@media(any-pointer:coarse){.et-resize-handle{--et-resize-handle-thickness: calc(var(--et-resize-handles-touch-edge-size) + var(--et-resize-handles-outset));--et-resize-handle-corner: calc(var(--et-resize-handles-touch-corner-size) + var(--et-resize-handles-outset))}}\n"], encapsulation: i0.ViewEncapsulation.None }); }
9237
+ `, isInline: true, styles: ["@layer components{@property --et-resize-handles-z-index{syntax: \"<integer>\"; inherits: true; initial-value: 10;}@property --et-resize-handles-edge-size{syntax: \"<length>\"; inherits: true; initial-value: 6px;}@property --et-resize-handles-corner-size{syntax: \"<length>\"; inherits: true; initial-value: 12px;}@property --et-resize-handles-edge-inset{syntax: \"<length>\"; inherits: true; initial-value: 8px;}@property --et-resize-handles-outset{syntax: \"<length>\"; inherits: true; initial-value: 0px;}@property --et-resize-handles-side-top{syntax: \"<length>\"; inherits: true; initial-value: 0px;}@property --et-resize-handles-side-bottom{syntax: \"<length>\"; inherits: true; initial-value: 8px;}@property --et-resize-handles-touch-edge-size{syntax: \"<length>\"; inherits: true; initial-value: 20px;}@property --et-resize-handles-touch-corner-size{syntax: \"<length>\"; inherits: true; initial-value: 28px;}.et-resize-handles{position:absolute;inset:calc(-1 * var(--et-resize-handles-outset));pointer-events:none}.et-resize-handle{--et-resize-handle-thickness: calc(var(--et-resize-handles-edge-size) + var(--et-resize-handles-outset));--et-resize-handle-corner: calc(var(--et-resize-handles-corner-size) + var(--et-resize-handles-outset));position:absolute;z-index:var(--et-resize-handles-z-index);touch-action:none;pointer-events:auto}.et-resize-handle--n{top:0;right:var(--et-resize-handles-edge-inset);left:var(--et-resize-handles-edge-inset);height:var(--et-resize-handle-thickness)}.et-resize-handle--s{right:var(--et-resize-handles-edge-inset);bottom:0;left:var(--et-resize-handles-edge-inset);height:var(--et-resize-handle-thickness)}.et-resize-handle--e,.et-resize-handle--w{top:var(--et-resize-handles-side-top);bottom:var(--et-resize-handles-side-bottom);width:var(--et-resize-handle-thickness)}.et-resize-handle--e{right:0}.et-resize-handle--w{left:0}.et-resize-handle--ne,.et-resize-handle--nw{top:0;width:var(--et-resize-handle-corner);height:var(--et-resize-handle-corner)}.et-resize-handle--ne{right:0}.et-resize-handle--nw{left:0}.et-resize-handle--se,.et-resize-handle--sw{bottom:0;width:var(--et-resize-handle-corner);height:var(--et-resize-handle-corner)}.et-resize-handle--se{right:0}.et-resize-handle--sw{left:0}@media(any-pointer:coarse){.et-resize-handle{--et-resize-handle-thickness: calc(var(--et-resize-handles-touch-edge-size) + var(--et-resize-handles-outset));--et-resize-handle-corner: calc(var(--et-resize-handles-touch-corner-size) + var(--et-resize-handles-outset))}}}\n"], encapsulation: i0.ViewEncapsulation.None }); }
9096
9238
  }
9097
9239
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ResizeHandlesComponent, decorators: [{
9098
9240
  type: Component,
@@ -9108,16 +9250,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
9108
9250
  class: 'et-resize-handles',
9109
9251
  '[attr.inert]': 'disabled() ? "" : null',
9110
9252
  '[attr.data-active-edge]': 'activeEdge()',
9111
- }, styles: ["@property --et-resize-handles-z-index{syntax: \"<integer>\"; inherits: true; initial-value: 10;}@property --et-resize-handles-edge-size{syntax: \"<length>\"; inherits: true; initial-value: 6px;}@property --et-resize-handles-corner-size{syntax: \"<length>\"; inherits: true; initial-value: 12px;}@property --et-resize-handles-edge-inset{syntax: \"<length>\"; inherits: true; initial-value: 8px;}@property --et-resize-handles-outset{syntax: \"<length>\"; inherits: true; initial-value: 0px;}@property --et-resize-handles-side-top{syntax: \"<length>\"; inherits: true; initial-value: 0px;}@property --et-resize-handles-side-bottom{syntax: \"<length>\"; inherits: true; initial-value: 8px;}@property --et-resize-handles-touch-edge-size{syntax: \"<length>\"; inherits: true; initial-value: 20px;}@property --et-resize-handles-touch-corner-size{syntax: \"<length>\"; inherits: true; initial-value: 28px;}et-resize-handles{position:absolute;inset:calc(-1 * var(--et-resize-handles-outset));pointer-events:none}.et-resize-handle{--et-resize-handle-thickness: calc(var(--et-resize-handles-edge-size) + var(--et-resize-handles-outset));--et-resize-handle-corner: calc(var(--et-resize-handles-corner-size) + var(--et-resize-handles-outset));position:absolute;z-index:var(--et-resize-handles-z-index);touch-action:none;pointer-events:auto}.et-resize-handle--n{left:var(--et-resize-handles-edge-inset);right:var(--et-resize-handles-edge-inset);height:var(--et-resize-handle-thickness);top:0}.et-resize-handle--s{left:var(--et-resize-handles-edge-inset);right:var(--et-resize-handles-edge-inset);height:var(--et-resize-handle-thickness);bottom:0}.et-resize-handle--e,.et-resize-handle--w{top:var(--et-resize-handles-side-top);bottom:var(--et-resize-handles-side-bottom);width:var(--et-resize-handle-thickness)}.et-resize-handle--e{right:0}.et-resize-handle--w{left:0}.et-resize-handle--ne,.et-resize-handle--nw{top:0;width:var(--et-resize-handle-corner);height:var(--et-resize-handle-corner)}.et-resize-handle--ne{right:0}.et-resize-handle--nw{left:0}.et-resize-handle--se,.et-resize-handle--sw{bottom:0;width:var(--et-resize-handle-corner);height:var(--et-resize-handle-corner)}.et-resize-handle--se{right:0}.et-resize-handle--sw{left:0}@media(any-pointer:coarse){.et-resize-handle{--et-resize-handle-thickness: calc(var(--et-resize-handles-touch-edge-size) + var(--et-resize-handles-outset));--et-resize-handle-corner: calc(var(--et-resize-handles-touch-corner-size) + var(--et-resize-handles-outset))}}\n"] }]
9253
+ }, styles: ["@layer components{@property --et-resize-handles-z-index{syntax: \"<integer>\"; inherits: true; initial-value: 10;}@property --et-resize-handles-edge-size{syntax: \"<length>\"; inherits: true; initial-value: 6px;}@property --et-resize-handles-corner-size{syntax: \"<length>\"; inherits: true; initial-value: 12px;}@property --et-resize-handles-edge-inset{syntax: \"<length>\"; inherits: true; initial-value: 8px;}@property --et-resize-handles-outset{syntax: \"<length>\"; inherits: true; initial-value: 0px;}@property --et-resize-handles-side-top{syntax: \"<length>\"; inherits: true; initial-value: 0px;}@property --et-resize-handles-side-bottom{syntax: \"<length>\"; inherits: true; initial-value: 8px;}@property --et-resize-handles-touch-edge-size{syntax: \"<length>\"; inherits: true; initial-value: 20px;}@property --et-resize-handles-touch-corner-size{syntax: \"<length>\"; inherits: true; initial-value: 28px;}.et-resize-handles{position:absolute;inset:calc(-1 * var(--et-resize-handles-outset));pointer-events:none}.et-resize-handle{--et-resize-handle-thickness: calc(var(--et-resize-handles-edge-size) + var(--et-resize-handles-outset));--et-resize-handle-corner: calc(var(--et-resize-handles-corner-size) + var(--et-resize-handles-outset));position:absolute;z-index:var(--et-resize-handles-z-index);touch-action:none;pointer-events:auto}.et-resize-handle--n{top:0;right:var(--et-resize-handles-edge-inset);left:var(--et-resize-handles-edge-inset);height:var(--et-resize-handle-thickness)}.et-resize-handle--s{right:var(--et-resize-handles-edge-inset);bottom:0;left:var(--et-resize-handles-edge-inset);height:var(--et-resize-handle-thickness)}.et-resize-handle--e,.et-resize-handle--w{top:var(--et-resize-handles-side-top);bottom:var(--et-resize-handles-side-bottom);width:var(--et-resize-handle-thickness)}.et-resize-handle--e{right:0}.et-resize-handle--w{left:0}.et-resize-handle--ne,.et-resize-handle--nw{top:0;width:var(--et-resize-handle-corner);height:var(--et-resize-handle-corner)}.et-resize-handle--ne{right:0}.et-resize-handle--nw{left:0}.et-resize-handle--se,.et-resize-handle--sw{bottom:0;width:var(--et-resize-handle-corner);height:var(--et-resize-handle-corner)}.et-resize-handle--se{right:0}.et-resize-handle--sw{left:0}@media(any-pointer:coarse){.et-resize-handle{--et-resize-handle-thickness: calc(var(--et-resize-handles-touch-edge-size) + var(--et-resize-handles-outset));--et-resize-handle-corner: calc(var(--et-resize-handles-touch-corner-size) + var(--et-resize-handles-outset))}}}\n"] }]
9112
9254
  }], propDecorators: { edges: [{ type: i0.Input, args: [{ isSignal: true, alias: "edges", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], resizeStarted: [{ type: i0.Output, args: ["resizeStarted"] }], resizeMoved: [{ type: i0.Output, args: ["resizeMoved"] }], resizeEnded: [{ type: i0.Output, args: ["resizeEnded"] }], resizeCancelled: [{ type: i0.Output, args: ["resizeCancelled"] }] } });
9113
9255
 
9114
9256
  class ColorInteractiveStylesComponent {
9115
9257
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ColorInteractiveStylesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9116
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.7", type: ColorInteractiveStylesComponent, isStandalone: true, selector: "et-color-interactive-styles", ngImport: i0, template: '', isInline: true, styles: [":where(.et-color-interactive){--et-theme-color-primary-rgb: var(--et-color-primary);--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var(--et-color-on-primary);--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var(--et-color-primary-ink, var(--et-color-primary));--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}@media(hover:hover){:where(.et-color-interactive:hover:not(:has(.et-color-interactive-exclude:hover))),:where(.et-color-interactive-container:hover) :where(.et-color-interactive){--et-theme-color-primary-rgb: var(--et-color-primary-hover, var(--et-color-primary));--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var(--et-color-on-primary-hover, var(--et-color-on-primary));--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var( --et-color-primary-ink-hover, var(--et-color-primary-ink, var(--et-color-primary-hover, var(--et-color-primary))) );--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}}:where(.et-color-interactive:focus-visible){--et-theme-color-primary-rgb: var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary)));--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var( --et-color-on-primary-focus, var(--et-color-on-primary-hover, var(--et-color-on-primary)) );--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var( --et-color-primary-ink-focus, var( --et-color-primary-ink-hover, var(--et-color-primary-ink, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary)))) ) );--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}:where(.et-color-interactive:active:not(:has(.et-color-interactive-exclude:hover))),:where(.et-color-interactive-container:active) :where(.et-color-interactive){--et-theme-color-primary-rgb: var( --et-color-primary-active, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) );--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var( --et-color-on-primary-active, var(--et-color-on-primary-focus, var(--et-color-on-primary-hover, var(--et-color-on-primary))) );--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var( --et-color-primary-ink-active, var( --et-color-primary-ink-focus, var( --et-color-primary-ink-hover, var( --et-color-primary-ink, var( --et-color-primary-active, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) ) ) ) ) );--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}:where(.et-color-interactive--has-focus:has(:focus-visible)){--et-theme-color-primary-rgb: var(--et-color-primary);--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var(--et-color-on-primary);--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var(--et-color-primary-ink, var(--et-color-primary));--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}:where(.et-color-interactive[aria-readonly=true]){--et-theme-color-primary-rgb: var(--et-color-primary);--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var(--et-color-on-primary);--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var(--et-color-primary-ink, var(--et-color-primary));--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}:where(.et-color-interactive[disabled]),:where(.et-color-interactive[aria-disabled=true]){--et-theme-color-primary-rgb: var( --et-color-primary-disabled, var( --et-color-primary-active, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) ) );--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var( --et-color-on-primary-disabled, var( --et-color-on-primary-active, var(--et-color-on-primary-focus, var(--et-color-on-primary-hover, var(--et-color-on-primary))) ) );--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var( --et-color-primary-ink-disabled, var( --et-color-primary-ink-active, var( --et-color-primary-ink-focus, var( --et-color-primary-ink-hover, var( --et-color-primary-ink, var( --et-color-primary-disabled, var( --et-color-primary-active, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) ) ) ) ) ) ) );--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}\n"], encapsulation: i0.ViewEncapsulation.None }); }
9258
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.7", type: ColorInteractiveStylesComponent, isStandalone: true, selector: "et-color-interactive-styles", ngImport: i0, template: '', isInline: true, styles: ["@layer components{:where(.et-color-interactive){--et-theme-color-primary-rgb: var(--et-color-primary);--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var(--et-color-on-primary);--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var(--et-color-primary-ink, var(--et-color-primary));--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}@media(hover:hover){:where(.et-color-interactive:hover:not(:has(.et-color-interactive-exclude:hover))),:where(.et-color-interactive-container:hover) :where(.et-color-interactive){--et-theme-color-primary-rgb: var(--et-color-primary-hover, var(--et-color-primary));--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var(--et-color-on-primary-hover, var(--et-color-on-primary));--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var( --et-color-primary-ink-hover, var(--et-color-primary-ink, var(--et-color-primary-hover, var(--et-color-primary))) );--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}}:where(.et-color-interactive:focus-visible){--et-theme-color-primary-rgb: var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary)));--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var( --et-color-on-primary-focus, var(--et-color-on-primary-hover, var(--et-color-on-primary)) );--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var( --et-color-primary-ink-focus, var( --et-color-primary-ink-hover, var( --et-color-primary-ink, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) ) ) );--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}:where(.et-color-interactive:active:not(:has(.et-color-interactive-exclude:hover))),:where(.et-color-interactive-container:active) :where(.et-color-interactive){--et-theme-color-primary-rgb: var( --et-color-primary-active, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) );--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var( --et-color-on-primary-active, var(--et-color-on-primary-focus, var(--et-color-on-primary-hover, var(--et-color-on-primary))) );--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var( --et-color-primary-ink-active, var( --et-color-primary-ink-focus, var( --et-color-primary-ink-hover, var( --et-color-primary-ink, var( --et-color-primary-active, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) ) ) ) ) );--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}:where(.et-color-interactive--has-focus:has(:focus-visible)){--et-theme-color-primary-rgb: var(--et-color-primary);--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var(--et-color-on-primary);--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var(--et-color-primary-ink, var(--et-color-primary));--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}:where(.et-color-interactive[aria-readonly=true]){--et-theme-color-primary-rgb: var(--et-color-primary);--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var(--et-color-on-primary);--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var(--et-color-primary-ink, var(--et-color-primary));--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}:where(.et-color-interactive[disabled]),:where(.et-color-interactive[aria-disabled=true]){--et-theme-color-primary-rgb: var( --et-color-primary-disabled, var( --et-color-primary-active, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) ) );--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var( --et-color-on-primary-disabled, var( --et-color-on-primary-active, var(--et-color-on-primary-focus, var(--et-color-on-primary-hover, var(--et-color-on-primary))) ) );--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var( --et-color-primary-ink-disabled, var( --et-color-primary-ink-active, var( --et-color-primary-ink-focus, var( --et-color-primary-ink-hover, var( --et-color-primary-ink, var( --et-color-primary-disabled, var( --et-color-primary-active, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) ) ) ) ) ) ) );--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}}\n"], encapsulation: i0.ViewEncapsulation.None }); }
9117
9259
  }
9118
9260
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ColorInteractiveStylesComponent, decorators: [{
9119
9261
  type: Component,
9120
- args: [{ selector: 'et-color-interactive-styles', template: '', encapsulation: ViewEncapsulation.None, styles: [":where(.et-color-interactive){--et-theme-color-primary-rgb: var(--et-color-primary);--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var(--et-color-on-primary);--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var(--et-color-primary-ink, var(--et-color-primary));--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}@media(hover:hover){:where(.et-color-interactive:hover:not(:has(.et-color-interactive-exclude:hover))),:where(.et-color-interactive-container:hover) :where(.et-color-interactive){--et-theme-color-primary-rgb: var(--et-color-primary-hover, var(--et-color-primary));--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var(--et-color-on-primary-hover, var(--et-color-on-primary));--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var( --et-color-primary-ink-hover, var(--et-color-primary-ink, var(--et-color-primary-hover, var(--et-color-primary))) );--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}}:where(.et-color-interactive:focus-visible){--et-theme-color-primary-rgb: var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary)));--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var( --et-color-on-primary-focus, var(--et-color-on-primary-hover, var(--et-color-on-primary)) );--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var( --et-color-primary-ink-focus, var( --et-color-primary-ink-hover, var(--et-color-primary-ink, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary)))) ) );--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}:where(.et-color-interactive:active:not(:has(.et-color-interactive-exclude:hover))),:where(.et-color-interactive-container:active) :where(.et-color-interactive){--et-theme-color-primary-rgb: var( --et-color-primary-active, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) );--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var( --et-color-on-primary-active, var(--et-color-on-primary-focus, var(--et-color-on-primary-hover, var(--et-color-on-primary))) );--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var( --et-color-primary-ink-active, var( --et-color-primary-ink-focus, var( --et-color-primary-ink-hover, var( --et-color-primary-ink, var( --et-color-primary-active, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) ) ) ) ) );--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}:where(.et-color-interactive--has-focus:has(:focus-visible)){--et-theme-color-primary-rgb: var(--et-color-primary);--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var(--et-color-on-primary);--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var(--et-color-primary-ink, var(--et-color-primary));--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}:where(.et-color-interactive[aria-readonly=true]){--et-theme-color-primary-rgb: var(--et-color-primary);--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var(--et-color-on-primary);--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var(--et-color-primary-ink, var(--et-color-primary));--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}:where(.et-color-interactive[disabled]),:where(.et-color-interactive[aria-disabled=true]){--et-theme-color-primary-rgb: var( --et-color-primary-disabled, var( --et-color-primary-active, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) ) );--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var( --et-color-on-primary-disabled, var( --et-color-on-primary-active, var(--et-color-on-primary-focus, var(--et-color-on-primary-hover, var(--et-color-on-primary))) ) );--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var( --et-color-primary-ink-disabled, var( --et-color-primary-ink-active, var( --et-color-primary-ink-focus, var( --et-color-primary-ink-hover, var( --et-color-primary-ink, var( --et-color-primary-disabled, var( --et-color-primary-active, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) ) ) ) ) ) ) );--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}\n"] }]
9262
+ args: [{ selector: 'et-color-interactive-styles', template: '', encapsulation: ViewEncapsulation.None, styles: ["@layer components{:where(.et-color-interactive){--et-theme-color-primary-rgb: var(--et-color-primary);--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var(--et-color-on-primary);--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var(--et-color-primary-ink, var(--et-color-primary));--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}@media(hover:hover){:where(.et-color-interactive:hover:not(:has(.et-color-interactive-exclude:hover))),:where(.et-color-interactive-container:hover) :where(.et-color-interactive){--et-theme-color-primary-rgb: var(--et-color-primary-hover, var(--et-color-primary));--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var(--et-color-on-primary-hover, var(--et-color-on-primary));--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var( --et-color-primary-ink-hover, var(--et-color-primary-ink, var(--et-color-primary-hover, var(--et-color-primary))) );--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}}:where(.et-color-interactive:focus-visible){--et-theme-color-primary-rgb: var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary)));--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var( --et-color-on-primary-focus, var(--et-color-on-primary-hover, var(--et-color-on-primary)) );--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var( --et-color-primary-ink-focus, var( --et-color-primary-ink-hover, var( --et-color-primary-ink, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) ) ) );--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}:where(.et-color-interactive:active:not(:has(.et-color-interactive-exclude:hover))),:where(.et-color-interactive-container:active) :where(.et-color-interactive){--et-theme-color-primary-rgb: var( --et-color-primary-active, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) );--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var( --et-color-on-primary-active, var(--et-color-on-primary-focus, var(--et-color-on-primary-hover, var(--et-color-on-primary))) );--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var( --et-color-primary-ink-active, var( --et-color-primary-ink-focus, var( --et-color-primary-ink-hover, var( --et-color-primary-ink, var( --et-color-primary-active, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) ) ) ) ) );--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}:where(.et-color-interactive--has-focus:has(:focus-visible)){--et-theme-color-primary-rgb: var(--et-color-primary);--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var(--et-color-on-primary);--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var(--et-color-primary-ink, var(--et-color-primary));--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}:where(.et-color-interactive[aria-readonly=true]){--et-theme-color-primary-rgb: var(--et-color-primary);--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var(--et-color-on-primary);--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var(--et-color-primary-ink, var(--et-color-primary));--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}:where(.et-color-interactive[disabled]),:where(.et-color-interactive[aria-disabled=true]){--et-theme-color-primary-rgb: var( --et-color-primary-disabled, var( --et-color-primary-active, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) ) );--et-theme-color-primary-solid: rgb(var(--et-theme-color-primary-rgb));--et-theme-color-on-primary-rgb: var( --et-color-on-primary-disabled, var( --et-color-on-primary-active, var(--et-color-on-primary-focus, var(--et-color-on-primary-hover, var(--et-color-on-primary))) ) );--et-theme-color-on-primary-solid: rgb(var(--et-theme-color-on-primary-rgb));--et-theme-color-ink-rgb: var( --et-color-primary-ink-disabled, var( --et-color-primary-ink-active, var( --et-color-primary-ink-focus, var( --et-color-primary-ink-hover, var( --et-color-primary-ink, var( --et-color-primary-disabled, var( --et-color-primary-active, var(--et-color-primary-focus, var(--et-color-primary-hover, var(--et-color-primary))) ) ) ) ) ) ) );--et-theme-color-ink-solid: rgb(var(--et-theme-color-ink-rgb))}}\n"] }]
9121
9263
  }] });
9122
9264
 
9123
9265
  /**
@@ -9343,7 +9485,7 @@ class ProvideSurfaceDirective {
9343
9485
  this.currentProviderSync?.destroy();
9344
9486
  runInInjectionContext(this.injector, () => {
9345
9487
  this.currentProviderSync = effect(() => {
9346
- const provideSurface = provider.effectiveSurface();
9488
+ const provideSurface = provider.activeTheme()?.name;
9347
9489
  untracked(() => {
9348
9490
  if (provideSurface === undefined) {
9349
9491
  this.clearForcedSurface();
@@ -9393,7 +9535,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
9393
9535
  */
9394
9536
  const injectSurfaceType = () => {
9395
9537
  const provider = inject(SURFACE_PROVIDER, { optional: true, skipSelf: true });
9396
- const defaultType = injectDefaultSurfaceTheme()?.type ?? SURFACE_TYPE.DARK;
9538
+ const defaultType = injectDefaultSurfaceTheme()?.type ?? null;
9397
9539
  return computed(() => provider?.surfaceType() ?? defaultType);
9398
9540
  };
9399
9541
  /**
@@ -9619,7 +9761,7 @@ const provideColorThemesWithTailwind4 = (themes, prefix = 'et') => {
9619
9761
  return [ɵProvideColorThemes(themes), ɵProvideColorThemesPrefix(prefix)];
9620
9762
  };
9621
9763
  const injectColorThemeByType = (type) => {
9622
- const themes = injectColorThemes();
9764
+ const themes = injectColorThemes({ optional: true });
9623
9765
  if (!themes) {
9624
9766
  throw new Error(`[injectColorThemeByType] No color themes provided. Call provideColorThemesWithTailwind4() in your app config.`);
9625
9767
  }
@@ -9639,7 +9781,7 @@ const injectErrorTheme = () => injectColorThemeByType('error');
9639
9781
  const injectWarningTheme = () => injectColorThemeByType('warning');
9640
9782
  const injectSuccessTheme = () => injectColorThemeByType('success');
9641
9783
  const injectDefaultColorTheme = () => {
9642
- const themes = injectColorThemes();
9784
+ const themes = injectColorThemes({ optional: true });
9643
9785
  if (!themes) {
9644
9786
  throw new Error(`[injectDefaultColorTheme] No color themes provided. Call provideColorThemesWithTailwind4() in your app config.`);
9645
9787
  }
@@ -9691,6 +9833,8 @@ const createSwatchCss = (swatch, isAlt, data) => {
9691
9833
  * @deprecated Migrate to Tailwind v4. Intent to remove in v6.
9692
9834
  */
9693
9835
  const createRootThemeCss = (themes) => {
9836
+ if (typeof document === 'undefined')
9837
+ return;
9694
9838
  const createVars = (name, swatch) => {
9695
9839
  const inkDefault = swatch.inkColor?.default || swatch.color.default;
9696
9840
  const inkHover = swatch.inkColor?.hover || inkDefault;
@@ -9738,6 +9882,7 @@ const createRootThemeCss = (themes) => {
9738
9882
  ${vars.join('\n')}
9739
9883
  }
9740
9884
  `;
9885
+ document.getElementById('et-root-themes')?.remove();
9741
9886
  const style = document.createElement('style');
9742
9887
  style.id = `et-root-themes`;
9743
9888
  style.appendChild(document.createTextNode(css));
@@ -9747,6 +9892,8 @@ const createRootThemeCss = (themes) => {
9747
9892
  * @deprecated Migrate to Tailwind v4. Intent to remove in v6.
9748
9893
  */
9749
9894
  const createThemeStyle = (theme, isAlt) => {
9895
+ if (typeof document === 'undefined')
9896
+ return;
9750
9897
  const cssThemeName = createCssColorThemeName(theme.name);
9751
9898
  const classPrefix = isAlt ? 'et-color-alt' : 'et-color';
9752
9899
  const selectors = [
@@ -9762,6 +9909,7 @@ const createThemeStyle = (theme, isAlt) => {
9762
9909
  ${theme.tertiary ? createSwatchCss('tertiary', isAlt, theme.tertiary) : ''}
9763
9910
  }
9764
9911
  `;
9912
+ document.getElementById(`${classPrefix}--${cssThemeName}`)?.remove();
9765
9913
  const style = document.createElement('style');
9766
9914
  style.id = `${classPrefix}--${cssThemeName}`;
9767
9915
  style.appendChild(document.createTextNode(css));
@@ -9970,11 +10118,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
9970
10118
 
9971
10119
  class SurfaceInteractiveStylesComponent {
9972
10120
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SurfaceInteractiveStylesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
9973
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.7", type: SurfaceInteractiveStylesComponent, isStandalone: true, selector: "et-surface-interactive-styles", ngImport: i0, template: '', isInline: true, styles: [":where(.et-surface-interactive){--et-surface-interaction-rgb: var(--et-surface-interaction);--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}@media(hover:hover){:where(.et-surface-interactive:hover){--et-surface-interaction-rgb: var(--et-surface-interaction-hover, var(--et-surface-interaction));--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}}:where(.et-surface-interactive:focus-visible){--et-surface-interaction-rgb: var( --et-surface-interaction-focus, var(--et-surface-interaction-hover, var(--et-surface-interaction)) );--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}:where(.et-surface-interactive:active){--et-surface-interaction-rgb: var( --et-surface-interaction-active, var(--et-surface-interaction-focus, var(--et-surface-interaction-hover, var(--et-surface-interaction))) );--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}:where(.et-surface-interactive[disabled]),:where(.et-surface-interactive[aria-disabled=true]){--et-surface-interaction-rgb: var( --et-surface-interaction-disabled, var( --et-surface-interaction-active, var(--et-surface-interaction-focus, var(--et-surface-interaction-hover, var(--et-surface-interaction))) ) );--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}\n"], encapsulation: i0.ViewEncapsulation.None }); }
10121
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.7", type: SurfaceInteractiveStylesComponent, isStandalone: true, selector: "et-surface-interactive-styles", ngImport: i0, template: '', isInline: true, styles: ["@layer components{:where(.et-surface-interactive){--et-surface-interaction-rgb: var(--et-surface-interaction);--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}@media(hover:hover){:where(.et-surface-interactive:hover){--et-surface-interaction-rgb: var(--et-surface-interaction-hover, var(--et-surface-interaction));--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}}:where(.et-surface-interactive:focus-visible){--et-surface-interaction-rgb: var( --et-surface-interaction-focus, var(--et-surface-interaction-hover, var(--et-surface-interaction)) );--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}:where(.et-surface-interactive:active){--et-surface-interaction-rgb: var( --et-surface-interaction-active, var(--et-surface-interaction-focus, var(--et-surface-interaction-hover, var(--et-surface-interaction))) );--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}:where(.et-surface-interactive[disabled]),:where(.et-surface-interactive[aria-disabled=true]){--et-surface-interaction-rgb: var( --et-surface-interaction-disabled, var( --et-surface-interaction-active, var(--et-surface-interaction-focus, var(--et-surface-interaction-hover, var(--et-surface-interaction))) ) );--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}}\n"], encapsulation: i0.ViewEncapsulation.None }); }
9974
10122
  }
9975
10123
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SurfaceInteractiveStylesComponent, decorators: [{
9976
10124
  type: Component,
9977
- args: [{ selector: 'et-surface-interactive-styles', template: '', encapsulation: ViewEncapsulation.None, styles: [":where(.et-surface-interactive){--et-surface-interaction-rgb: var(--et-surface-interaction);--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}@media(hover:hover){:where(.et-surface-interactive:hover){--et-surface-interaction-rgb: var(--et-surface-interaction-hover, var(--et-surface-interaction));--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}}:where(.et-surface-interactive:focus-visible){--et-surface-interaction-rgb: var( --et-surface-interaction-focus, var(--et-surface-interaction-hover, var(--et-surface-interaction)) );--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}:where(.et-surface-interactive:active){--et-surface-interaction-rgb: var( --et-surface-interaction-active, var(--et-surface-interaction-focus, var(--et-surface-interaction-hover, var(--et-surface-interaction))) );--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}:where(.et-surface-interactive[disabled]),:where(.et-surface-interactive[aria-disabled=true]){--et-surface-interaction-rgb: var( --et-surface-interaction-disabled, var( --et-surface-interaction-active, var(--et-surface-interaction-focus, var(--et-surface-interaction-hover, var(--et-surface-interaction))) ) );--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}\n"] }]
10125
+ args: [{ selector: 'et-surface-interactive-styles', template: '', encapsulation: ViewEncapsulation.None, styles: ["@layer components{:where(.et-surface-interactive){--et-surface-interaction-rgb: var(--et-surface-interaction);--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}@media(hover:hover){:where(.et-surface-interactive:hover){--et-surface-interaction-rgb: var(--et-surface-interaction-hover, var(--et-surface-interaction));--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}}:where(.et-surface-interactive:focus-visible){--et-surface-interaction-rgb: var( --et-surface-interaction-focus, var(--et-surface-interaction-hover, var(--et-surface-interaction)) );--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}:where(.et-surface-interactive:active){--et-surface-interaction-rgb: var( --et-surface-interaction-active, var(--et-surface-interaction-focus, var(--et-surface-interaction-hover, var(--et-surface-interaction))) );--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}:where(.et-surface-interactive[disabled]),:where(.et-surface-interactive[aria-disabled=true]){--et-surface-interaction-rgb: var( --et-surface-interaction-disabled, var( --et-surface-interaction-active, var(--et-surface-interaction-focus, var(--et-surface-interaction-hover, var(--et-surface-interaction))) ) );--et-surface-interaction-solid: rgb(var(--et-surface-interaction-rgb))}}\n"] }]
9978
10126
  }] });
9979
10127
 
9980
10128
  /**
@@ -10008,11 +10156,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
10008
10156
 
10009
10157
  // Generated from package.json by tools/scripts/generate-version.js - do not edit.
10010
10158
  /** The version of `@ethlete/core` this build was cut from. */
10011
- const CORE_VERSION = '5.0.0-next.52';
10159
+ const CORE_VERSION = '5.0.0-next.54';
10012
10160
 
10013
10161
  /**
10014
10162
  * Generated bundle index. Do not edit.
10015
10163
  */
10016
10164
 
10017
- export { ANIMATABLE_TOKEN, ANIMATED_IF_TOKEN, ANIMATED_LIFECYCLE_TOKEN, ANIMATION_DEBUG_STORAGE_KEY, AT_LEAST_ONE_REQUIRED, AnimatableDirective, AnimatedIfDirective, AnimatedLifecycleDirective, AutoSurfaceDirective, BOUNDARY_ELEMENT_TOKEN, BREAKPOINT_INSTANCE_TOKEN, BREAKPOINT_ORDER, COLOR_PALETTE, COLOR_PROVIDER, CORE_VERSION, ClickOutsideDirective, ColorInteractiveContainerDirective, ColorInteractiveDirective, ColorInteractiveExcludeDirective, ColorInteractiveHasFocusDirective, DEFAULT_MULTI_INSTANCE_RELS, DEFAULT_MULTI_INSTANCE_TAGS, DEFAULT_OVERLAY_LAYER, DEFAULT_VIEWPORT_CONFIG, DISABLE_LOGGER_PARAM, DragHandleDirective, ET_DISABLE_SCROLL_TOP, ET_DISABLE_SCROLL_TOP_AS_RETURN_ROUTE, ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE, ET_PROPERTY_REMOVED, ET_RESTORE_SCROLL, FOCUSABLE_SELECTOR, FOCUS_VISIBLE_TRACKER_TOKEN, HtmlToMarkdownPipe, IS_ARRAY_NOT_EMPTY, IS_EMAIL, InferMimeTypePipe, InitialsPipe, IsArrayNotEmpty, IsEmail, jsonLd as JsonLD, KeyPressManager, MUST_MATCH, MarkdownToHtmlPipe, MustMatch, NOTIFICATION_CLICK_MESSAGE_TYPE, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, OVERLAY_LAYER_ATTRIBUTE, PropsDirective, ProvideColorDirective, ProvideSurfaceDirective, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeHandlesComponent, RestoreScrollDirective, RuntimeError, SURFACE_COLOR, SURFACE_PROVIDER, SURFACE_TYPE, SWIPE_VELOCITY_WINDOW_MS, ScrollObserverDirective, ScrollObserverEndDirective, ScrollObserverStartDirective, SlugifyPipe, StructuredDataComponent, SurfaceInteractiveDirective, ToArrayPipe, TypedQueryList, UNSAVED_CHANGES_TITLE_MARKER, ValidateAtLeastOneRequired, Validators, anchoredOverlayPosition, animationDebugLog, applyAlternateBinding, applyAlternateLanguagesBindings, applyArticleBindings, applyAuthorBinding, applyCanonicalBinding, applyCenteredPosition, applyDescriptionBinding, applyFaviconOverlay, applyGlobalPosition, applyHeadBinding, applyHeadTitleBinding, applyHeadTitleMarker, applyHostListener, applyHostListeners, applyInitialFocus, applyKeywordsBinding, applyLinkBinding, applyMetaBinding, applyNextBinding, applyOgBinding, applyOpenGraphBindings, applyPrevBinding, applyResourceHintsBindings, applyRobotsBinding, applySocialMediaBindings, applyStructuredDataBinding, applyTwitterCardBindings, areScrollStatesEqual, bindProps, boolBreakpointTransform, booleanBreakpointAttribute, boundingClientRectToElementRect, breakpointTransformBase, buildElementSignal, buildSignalEffects, canUseSessionMemory, clamp, clone, cloneFormGroup, computedTillFalsy, computedTillTruthy, controlValueSignal, controlValueSignalWithPrevious, copyToClipboard, createAnchoredPositionCleanup, createArrayPropertyBinding, createAutoSessionMemoryKey, createBulkPropertyBinding, createCanAnimateSignal, createComponentId, createCssColorThemeName, createCssSurfaceName, createDependencyStash, createDestroy, createDocumentElementSignal, createElementDictionary, createElementDimensions, createEmptyElementSignal, createFlipAnimation, createFlipAnimationGroup, createHostProps, createIsRenderedSignal, createLogger, createObjectUrlHandle, createOverlayRuntimeRef, createPropHandlers, createPropertyBinding, createProps, createRootThemeCss, createRoute, createRouterState, createRxHostListener, createSessionMemory, createSetup, createSwatchCss, createSwipeTracker, createTailwindColorThemes, createTailwindCssVar, createTailwindRgbVar, createThemeStyle, createUnsavedChangesGuard, createUnsavedChangesTabLock, createUnsavedChangesTracker, createUserConsentProvider, deferredSignal, defineLabels, defineProvider, defineRootProvider, defineStaticProvider, defineStaticRootProvider, deleteCookie, dragGestureFrom, easeElastic, easeIn, easeInOut, easeLinear, easeOut, easeOutBack, easeOutBackStrong, elementCanScroll, enableAnchoredOverlayPositionExtras, equal, fetchDeployedBuildFingerprint, firstElementSignal, focusElement, forceReflow, formatRuntimeError, fromNextFrame, getCookie, getDomain, getElementScrollCoordinates, getFocusableElements, getFormGroupValue, getGroupMatchPoints, getGroupMatchScore, getHeadingElement, getKnockoutMatchScore, getMatchScoreSubLine, getObjectProperty, getScrollContainerTarget, getScrollItemTarget, getScrollSnapTarget, hasCookie, holdScrollRestoration, htmlToMarkdown, inferMimeType, initials, injectAngularRootElement, injectAnimatedBlockSize, injectAppUpdates, injectAppUpdatesConfig, injectBoundaryElement, injectBreakpointInput, injectBreakpointIsMatched, injectBreakpointObserver, injectCanHover, injectColorPalette, injectColorThemes, injectColorThemesPrefix, injectCurrentBreakpoint, injectDefaultColorTheme, injectDefaultSurfaceTheme, injectDeviceInputType, injectDisplayOrientation, injectErrorTheme, injectFaviconStore, injectFileDownload, injectFocusVisibleTracker, injectFragment, injectHasPrecisionInput, injectHasTouchInput, injectHostElement, injectIs2Xl, injectIsDocumentVisible, injectIsLandscape, injectIsLg, injectIsMd, injectIsPortrait, injectIsRouterInitialized, injectIsSm, injectIsXl, injectIsXs, injectLinkStore, injectLinkStoreConfig, injectLocale, injectMediaQueryIsMatched, injectMetaConfig, injectMetaStore, injectNotifications, injectObserveBreakpoint, injectObserveMediaQuery, injectOverlayRuntime, injectParentSurface, injectPathParam, injectPathParamChanges, injectPathParams, injectPrefersReducedMotion, injectQueryParam, injectQueryParamChanges, injectQueryParams, injectRenderer, injectRoute, injectRouteData, injectRouteDataItem, injectRouteTitle, injectRouterEvent, injectRouterNavigationState, injectRouterState, injectScrollbarDimensions, injectStructuredDataConfig, injectStructuredDataStore, injectStyleManager, injectSuccessTheme, injectSurfaceContextTracker, injectSurfaceThemes, injectSurfaceThemesPrefix, injectSurfaceType, injectTemplateRef, injectTitleConfig, injectTitleStore, injectUnsavedChangesCoordinator, injectUrl, injectViewportConfig, injectViewportDimensions, injectViewportSize, injectWarningTheme, isAnimationDebugEnabled, isArray, isElementSignal, isElementVisible, isFocusable, isGroupMatch, isHTMLElement, isKnockoutMatch, isObject, isOnHigherOverlayLayer, isStaleBuildError, markdownToHtml, matchesReducedMotion, maybeSignalValue, memoizeSignal, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, normalizeUnsavedChangesSource, numberBreakpointAttribute, numberBreakpointTransform, onOverlayViewportInsetsChange, overlayViewportInsets, overlayViewportInsetsFor, previousSignalValue, provideAppUpdates, provideAppUpdatesConfig, provideAppUpdatesInstance, provideBoundaryElement, provideBreakpointInstance, provideBreakpointObserver, provideColorPalette, provideColorThemes, provideColorThemesWithTailwind4, provideFaviconStore, provideFocusVisibleTracker, provideLinkStore, provideLinkStoreConfig, provideLocale, provideMetaConfig, provideMetaStore, provideNotifications, provideOverlayRuntime, provideRenderer, provideStructuredDataConfig, provideStructuredDataStore, provideStyleManager, provideSurfaceContextTracker, provideSurfaceThemesWithTailwind4, provideTitleConfig, provideTitleStore, provideUnsavedChangesCoordinator, provideViewportConfig, randomId, readBuildFingerprint, readFromClipboard, registerAnchoredPositionMiddlewareExtras, registerAnchoredPositionSetup, reserveOverlayViewportSpace, resetPositioningStyles, resolveAppRootColorProvider, resolveOverlayLayer, resolveSurfaceByElevation, round, routerDisableScrollTop, routerRestoreScroll, scrollToElement, setBackdropStyles, setBaseElementStyles, setCookie, setInputSignal, setupFocusTrap, setupPositioning, setupScrollRestoration, signalAnimatedNumber, signalAttributes, signalClasses, signalDeferredLoading, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementLastScrollDirection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementLastScrollDirection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, slugify, suppressTextSelection, switchQueryListChanges, syncSignal, templateComputed, toArray, toArrayTrackByFn, toInjectFn, toProvideFn, toStringBinding, toToken, transformOrReturn, typedBreakpointTransform, unbindProps, useCursorDragScroll, writeScrollbarSizeToCssVariables, writeViewportSizeToCssVariables, ɵProvideColorThemes, ɵProvideColorThemesPrefix, ɵProvideSurfaceThemes, ɵProvideSurfaceThemesPrefix };
10165
+ export { ANIMATABLE_TOKEN, ANIMATED_IF_TOKEN, ANIMATED_LIFECYCLE_TOKEN, ANIMATION_DEBUG_STORAGE_KEY, AT_LEAST_ONE_REQUIRED, AnimatableDirective, AnimatedIfDirective, AnimatedLifecycleDirective, AutoSurfaceDirective, BOUNDARY_ELEMENT_TOKEN, BREAKPOINT_INSTANCE_TOKEN, BREAKPOINT_ORDER, COLOR_PALETTE, COLOR_PROVIDER, CORE_VERSION, ClickOutsideDirective, ColorInteractiveContainerDirective, ColorInteractiveDirective, ColorInteractiveExcludeDirective, ColorInteractiveHasFocusDirective, DEFAULT_MULTI_INSTANCE_RELS, DEFAULT_MULTI_INSTANCE_TAGS, DEFAULT_OVERLAY_LAYER, DEFAULT_VIEWPORT_CONFIG, DISABLE_LOGGER_PARAM, DragHandleDirective, ET_DISABLE_SCROLL_TOP, ET_DISABLE_SCROLL_TOP_AS_RETURN_ROUTE, ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE, ET_PROPERTY_REMOVED, ET_RESTORE_SCROLL, EthleteValidators, FOCUSABLE_SELECTOR, FOCUS_VISIBLE_TRACKER_TOKEN, HtmlToMarkdownPipe, IS_ARRAY_NOT_EMPTY, IS_EMAIL, InferMimeTypePipe, InitialsPipe, IsArrayNotEmpty, IsEmail, jsonLd as JsonLD, KeyPressManager, MUST_MATCH, MarkdownToHtmlPipe, MatchStateType, MustMatch, NOTIFICATION_CLICK_MESSAGE_TYPE, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, OVERLAY_LAYER_ATTRIBUTE, PropsDirective, ProvideColorDirective, ProvideSurfaceDirective, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeHandlesComponent, RestoreScrollDirective, RuntimeError, SURFACE_COLOR, SURFACE_PROVIDER, SURFACE_TYPE, SWIPE_VELOCITY_WINDOW_MS, ScrollObserverDirective, ScrollObserverEndDirective, ScrollObserverStartDirective, SlugifyPipe, StructuredDataComponent, SurfaceInteractiveDirective, ToArrayPipe, TypedQueryList, UNSAVED_CHANGES_TITLE_MARKER, ValidateAtLeastOneRequired, anchoredOverlayPosition, animationDebugLog, applyAlternateBinding, applyAlternateLanguagesBindings, applyArticleBindings, applyAuthorBinding, applyCanonicalBinding, applyCenteredPosition, applyDescriptionBinding, applyFaviconOverlay, applyGlobalPosition, applyHeadBinding, applyHeadTitleBinding, applyHeadTitleMarker, applyHostListener, applyHostListeners, applyInitialFocus, applyKeywordsBinding, applyLinkBinding, applyMetaBinding, applyNextBinding, applyOgBinding, applyOpenGraphBindings, applyPrevBinding, applyResourceHintsBindings, applyRobotsBinding, applySocialMediaBindings, applyStructuredDataBinding, applyTwitterCardBindings, bindProps, boolBreakpointTransform, boundingClientRectToElementRect, breakpointTransformBase, buildElementSignal, buildSignalEffects, canUseSessionMemory, clamp, clone, cloneFormGroup, computedTillFalsy, computedTillTruthy, controlValueSignal, controlValueSignalWithPrevious, copyToClipboard, createAnchoredPositionCleanup, createArrayPropertyBinding, createAutoSessionMemoryKey, createCanAnimateSignal, createComponentId, createCssColorThemeName, createCssSurfaceName, createDependencyStash, createDestroy, createDocumentElementSignal, createElementDictionary, createElementDimensions, createEmptyElementSignal, createFlipAnimation, createFlipAnimationGroup, createHostProps, createIsRenderedSignal, createLogger, createObjectUrlHandle, createOverlayRuntimeRef, createPropHandlers, createPropertyBinding, createProps, createRootThemeCss, createRoute, createRouterState, createRxHostListener, createSessionMemory, createSetup, createSwatchCss, createSwipeTracker, createTailwindColorThemes, createTailwindCssVar, createTailwindRgbVar, createThemeStyle, createUnsavedChangesGuard, createUnsavedChangesTabLock, createUnsavedChangesTracker, createUserConsentProvider, deferredSignal, defineLabels, defineProvider, defineRootProvider, defineStaticProvider, defineStaticRootProvider, deleteCookie, dragGestureFrom, easeElastic, easeIn, easeInOut, easeLinear, easeOut, easeOutBack, easeOutBackStrong, elementCanScroll, enableAnchoredOverlayPositionExtras, equal, fetchDeployedBuildFingerprint, firstElementSignal, focusElement, forceReflow, formatRuntimeError, fromNextFrame, getCookie, getDomain, getElementScrollCoordinates, getFocusableElements, getFormGroupValue, getGroupMatchPoints, getGroupMatchScore, getHeadingElement, getKnockoutMatchScore, getMatchScoreSubLine, getObjectProperty, getScrollContainerTarget, getScrollItemTarget, getScrollSnapTarget, hasCookie, holdScrollRestoration, htmlToMarkdown, inferMimeType, initials, injectAngularRootElement, injectAnimatedBlockSize, injectAppUpdates, injectAppUpdatesConfig, injectBoundaryElement, injectBreakpointInput, injectBreakpointIsMatched, injectBreakpointObserver, injectCanHover, injectColorPalette, injectColorThemes, injectColorThemesPrefix, injectCurrentBreakpoint, injectDefaultColorTheme, injectDefaultSurfaceTheme, injectDeviceInputType, injectDisplayOrientation, injectErrorTheme, injectFaviconStore, injectFileDownload, injectFocusVisibleTracker, injectFragment, injectHasPrecisionInput, injectHasTouchInput, injectHostElement, injectIs2Xl, injectIsDocumentVisible, injectIsLandscape, injectIsLg, injectIsMd, injectIsPortrait, injectIsRouterInitialized, injectIsSm, injectIsXl, injectIsXs, injectLinkStore, injectLinkStoreConfig, injectLocale, injectMediaQueryIsMatched, injectMetaConfig, injectMetaStore, injectNotifications, injectObserveBreakpoint, injectObserveMediaQuery, injectOverlayRuntime, injectParentSurface, injectPathParam, injectPathParamChanges, injectPathParams, injectPrefersReducedMotion, injectQueryParam, injectQueryParamChanges, injectQueryParams, injectRenderer, injectRoute, injectRouteData, injectRouteDataItem, injectRouteTitle, injectRouterEvent, injectRouterNavigationState, injectRouterState, injectScrollbarDimensions, injectStructuredDataConfig, injectStructuredDataStore, injectStyleManager, injectSuccessTheme, injectSurfaceContextTracker, injectSurfaceThemes, injectSurfaceThemesPrefix, injectSurfaceType, injectTemplateRef, injectTitleConfig, injectTitleStore, injectUnsavedChangesCoordinator, injectUrl, injectViewportConfig, injectViewportDimensions, injectViewportSize, injectWarningTheme, isAnimationDebugEnabled, isArray, isElementSignal, isElementVisible, isFocusable, isGroupMatch, isHTMLElement, isKnockoutMatch, isObject, isOnHigherOverlayLayer, isStaleBuildError, markdownToHtml, matchesReducedMotion, maybeSignalValue, memoizeSignal, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, normalizeUnsavedChangesSource, numberBreakpointTransform, onOverlayViewportInsetsChange, overlayViewportInsets, overlayViewportInsetsFor, previousSignalValue, provideAppUpdates, provideAppUpdatesConfig, provideAppUpdatesInstance, provideBoundaryElement, provideBreakpointInstance, provideBreakpointObserver, provideColorPalette, provideColorThemes, provideColorThemesWithTailwind4, provideFaviconStore, provideFocusVisibleTracker, provideLinkStore, provideLinkStoreConfig, provideLocale, provideMetaConfig, provideMetaStore, provideNotifications, provideOverlayRuntime, provideRenderer, provideStructuredDataConfig, provideStructuredDataStore, provideStyleManager, provideSurfaceContextTracker, provideSurfaceThemesWithTailwind4, provideTitleConfig, provideTitleStore, provideUnsavedChangesCoordinator, provideViewportConfig, randomId, readBuildFingerprint, readFromClipboard, registerAnchoredPositionMiddlewareExtras, registerAnchoredPositionSetup, reserveOverlayViewportSpace, resetPositioningStyles, resolveAppRootColorProvider, resolveOverlayLayer, resolveSurfaceByElevation, round, routerDisableScrollTop, routerRestoreScroll, scrollToElement, setBackdropStyles, setBaseElementStyles, setCookie, setInputSignal, setupFocusTrap, setupPositioning, setupScrollRestoration, signalAnimatedNumber, signalAttributes, signalClasses, signalDeferredLoading, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementLastScrollDirection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementLastScrollDirection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, slugify, suppressTextSelection, switchQueryListChanges, syncSignal, templateComputed, toArray, toArrayTrackByFn, toInjectFn, toProvideFn, toStringBinding, toToken, transformOrReturn, typedBreakpointTransform, unbindProps, useCursorDragScroll, writeScrollbarSizeToCssVariables, writeViewportSizeToCssVariables, ɵProvideColorThemes, ɵProvideColorThemesPrefix, ɵProvideSurfaceThemes, ɵProvideSurfaceThemesPrefix };
10018
10166
  //# sourceMappingURL=ethlete-core.mjs.map