@ethlete/core 5.0.0-next.51 → 5.0.0-next.53

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.
@@ -7,7 +7,7 @@ import { SIGNAL, signalSetFn } from '@angular/core/primitives/signals';
7
7
  import { DOCUMENT as DOCUMENT$1, isPlatformBrowser } 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
- import { autoUpdate, offset, flip, shift, limitShift, computePosition, hide, arrow, size } from '@floating-ui/dom';
10
+ import { offset, flip, shift, limitShift, computePosition, autoUpdate, hide, arrow, size } from '@floating-ui/dom';
11
11
 
12
12
  const ANIMATION_DEBUG_STORAGE_KEY = 'et-overlay-debug';
13
13
  let cachedEnabled = null;
@@ -42,7 +42,6 @@ class AnimatableDirective {
42
42
  this.animationEndSubject$ = new Subject();
43
43
  this.activeAnimationCount = 0;
44
44
  this.hostActiveAnimationCount$ = new BehaviorSubject(0);
45
- this.pendingTransitionIds = [];
46
45
  this.animationStart$ = this.animationStartSubject$.asObservable().pipe(debounceTime(0));
47
46
  this.animationEnd$ = this.animationEndSubject$.asObservable().pipe(debounceTime(0));
48
47
  this.totalActiveAnimationCount$ = this.parent
@@ -58,9 +57,10 @@ class AnimatableDirective {
58
57
  const startingNewBatch = this.activeAnimationCount === 0;
59
58
  this.updateActiveAnimationCount(1);
60
59
  if (startingNewBatch) {
61
- this.activeBatchTransitionId = this.pendingTransitionIds.shift();
60
+ this.activeBatchTransitionId = this.pendingTransitionId;
61
+ this.pendingTransitionId = undefined;
62
62
  }
63
- animationDebugLog(`animatable ${el.tagName.toLowerCase()}`, `start (count ${this.activeAnimationCount}, batch "${this.activeBatchTransitionId}", pending [${this.pendingTransitionIds.join(', ')}])`);
63
+ animationDebugLog(`animatable ${el.tagName.toLowerCase()}`, `start (count ${this.activeAnimationCount}, batch "${this.activeBatchTransitionId}", pending "${this.pendingTransitionId ?? 'none'}")`);
64
64
  if (!didEmitStart) {
65
65
  didEmitStart = true;
66
66
  this.animationStartSubject$.next();
@@ -91,8 +91,33 @@ class AnimatableDirective {
91
91
  }), takeUntilDestroyed())
92
92
  .subscribe();
93
93
  }
94
+ /**
95
+ * Labels the next batch of animations that starts on this element. Only the most recent id is
96
+ * kept: a call whose animations never start must not leave an id behind for a later batch.
97
+ */
94
98
  setTransitionId(id) {
95
- this.pendingTransitionIds.push(id);
99
+ this.pendingTransitionId = id;
100
+ }
101
+ /**
102
+ * The animations running on this element right now, without the endless and pseudo-element ones.
103
+ *
104
+ * Reading this flushes pending style changes, so an animation a class change started in the same
105
+ * task is already listed here. `isAnimating$` cannot answer that: it turns true only once the
106
+ * browser dispatches `transitionrun`, a frame after the style change is committed.
107
+ */
108
+ getRunningAnimations() {
109
+ const el = this.elementRef.nativeElement;
110
+ if (typeof el.getAnimations !== 'function')
111
+ return [];
112
+ return el.getAnimations().filter((animation) => {
113
+ if (animation.playState !== 'running')
114
+ return false;
115
+ const effect = animation.effect;
116
+ if (!effect || effect.pseudoElement)
117
+ return false;
118
+ // An endless animation never resolves `finished`, so awaiting one would strand the transition.
119
+ return effect.getComputedTiming().iterations !== Infinity;
120
+ });
96
121
  }
97
122
  updateActiveAnimationCount(delta) {
98
123
  const newVal = this.activeAnimationCount + delta;
@@ -4696,73 +4721,39 @@ class AnimatedLifecycleDirective {
4696
4721
  this.removeClass(fromClass);
4697
4722
  this.addClass(toClass);
4698
4723
  }
4699
- }), switchMap(() => this.animatable.isAnimating$), take(1), switchMap((isAnimating) => {
4700
- if (isAnimating)
4701
- return of(true);
4702
- // Nothing started yet on the first check - give a transition with a delay one more
4703
- // frame before concluding none is coming (mirrors handleInterruptedTransition).
4704
- return fromNextFrame().pipe(switchMap(() => this.animatable.isAnimating$), take(1));
4705
- }), switchMap((isAnimating) => {
4706
- if (!isAnimating) {
4707
- // No transition ever started - e.g. `prefers-reduced-motion` collapsed every
4708
- // transition-duration to 0, which per spec never fires transitionrun/transitionend.
4709
- // Waiting on animationEnd$ here would hang forever, so treat it as settled.
4710
- this.debugLog(`${transitionId}: completes via fallback (no transition started)`);
4711
- return of(true);
4712
- }
4713
- return this.animatable.animationEnd$.pipe(filter(() => this.state$.value === expectedState), switchMap((e) => {
4714
- if (!e.cancelled && e.transitionId === transitionId) {
4715
- return of(true);
4716
- }
4717
- // The batch ended cancelled or under a different id - e.g. the browser cancelled and
4718
- // restarted a running transition mid-flight (an anchored overlay whose ancestor pane got
4719
- // destroyed) or a foreign transition on the same element finished. If nothing is
4720
- // animating anymore the expected end event can never arrive, so treat the transition as
4721
- // settled instead of waiting forever (mirrors the fallback in handleInterruptedTransition).
4722
- return this.animatable.isAnimating$.pipe(take(1), tap((stillAnimating) => {
4723
- if (!stillAnimating) {
4724
- this.debugLog(`${transitionId}: completes via fallback (batch id "${e.transitionId ?? 'none'}", cancelled ${e.cancelled})`);
4725
- }
4726
- }), map((stillAnimating) => !stillAnimating));
4727
- }));
4728
- }), filter((settled) => settled && this.state$.value === expectedState), tap(onComplete), take(1), takeUntil(cancelSignal), takeUntilDestroyed(this.destroyRef))
4724
+ }), switchMap(() => this.whenAnimationsSettled()), tap(() => this.debugLog(`${transitionId}: settled`)), filter(() => this.state$.value === expectedState), tap(onComplete), take(1), takeUntil(cancelSignal), takeUntilDestroyed(this.destroyRef))
4729
4725
  .subscribe();
4730
4726
  }
4731
4727
  handleInterruptedTransition(config) {
4732
4728
  const { removeClasses, addClasses, expectedState, transitionId, onComplete, cancelSignal } = config;
4733
4729
  this.removeClasses(...removeClasses);
4734
4730
  addClasses.forEach((cls) => this.addClass(cls));
4735
- fromNextFrame()
4736
- .pipe(switchMap(() => this.animatable.isAnimating$), take(1), switchMap((isAnimating) => {
4737
- if (isAnimating) {
4738
- return of(true);
4739
- }
4740
- this.debugLog(`${transitionId}: interrupt found no running transition, re-checking next frame`);
4741
- return fromNextFrame().pipe(switchMap(() => this.animatable.isAnimating$), take(1));
4742
- }), take(1), switchMap((isAnimating) => {
4743
- if (!isAnimating && this.state$.value === expectedState) {
4744
- this.debugLog(`${transitionId}: interrupt completes INSTANTLY (no transition running after class swap)`);
4745
- return of({ cancelled: false, transitionId });
4746
- }
4747
- this.debugLog(`${transitionId}: interrupt waiting for animation end`, { isAnimating });
4748
- return this.animatable.animationEnd$.pipe(switchMap((e) => {
4749
- if (e.transitionId === transitionId) {
4750
- return of(e);
4751
- }
4752
- return this.animatable.isAnimating$.pipe(take(1), switchMap((stillAnimating) => {
4753
- if (!stillAnimating && this.state$.value === expectedState) {
4754
- this.debugLog(`${transitionId}: interrupt completes via foreign animation end (batch id was "${e.transitionId}")`, { stillAnimating });
4755
- return of({ cancelled: false, transitionId });
4756
- }
4757
- return of(null);
4758
- }));
4759
- }), filter((e) => e !== null && e.transitionId === transitionId));
4760
- }), filter((e) => this.state$.value === expectedState && !e.cancelled), tap(() => {
4761
- this.debugLog(`${transitionId}: interrupt complete`);
4762
- onComplete();
4763
- }), take(1), takeUntil(cancelSignal), takeUntilDestroyed(this.destroyRef))
4731
+ this.whenAnimationsSettled()
4732
+ .pipe(tap(() => this.debugLog(`${transitionId}: interrupt settled`)), filter(() => this.state$.value === expectedState), tap(onComplete), take(1), takeUntil(cancelSignal), takeUntilDestroyed(this.destroyRef))
4764
4733
  .subscribe();
4765
4734
  }
4735
+ /**
4736
+ * Emits once every animation the class change started on this element has finished, or right away
4737
+ * when the change starts none - a `transition-duration` of 0 (`prefers-reduced-motion`) or a
4738
+ * property whose value did not change.
4739
+ *
4740
+ * `isAnimating$` cannot replace the reading here: it turns true a frame after the browser commits
4741
+ * the style change, so a slow commit reads as "nothing will animate" and ends the transition
4742
+ * before its animation starts.
4743
+ */
4744
+ whenAnimationsSettled(isFirstRead = true) {
4745
+ return defer(() => {
4746
+ const running = this.animatable.getRunningAnimations();
4747
+ if (!running.length) {
4748
+ // Settling on the first read means nothing was ever awaited, so emitting here would reenter
4749
+ // the enter()/leave() call still on the stack. Every later read already runs off a promise.
4750
+ return isFirstRead ? fromNextFrame() : of(undefined);
4751
+ }
4752
+ // A running animation may be replaced rather than finished - the browser retargets a transition
4753
+ // whose end value changes - so re-read instead of settling on the first batch.
4754
+ return from(Promise.allSettled(running.map((animation) => animation.finished))).pipe(switchMap(() => this.whenAnimationsSettled(false)));
4755
+ });
4756
+ }
4766
4757
  addClass(className) {
4767
4758
  this.renderer.addClass(this.element, className);
4768
4759
  }
@@ -7242,6 +7233,112 @@ const setupFocusTrap = (paneElement, overlayRef, enabled, isTopMost, document) =
7242
7233
  };
7243
7234
  };
7244
7235
 
7236
+ const NO_INSET = { top: 0, right: 0, bottom: 0, left: 0 };
7237
+ const reservations = /* @__PURE__ */ new Set();
7238
+ const listeners = /* @__PURE__ */ new Set();
7239
+ /**
7240
+ * The custom property each edge is published as on the document root, so page chrome that overlays
7241
+ * cannot move for you - a sticky action bar, a floating button - can keep out of the same space:
7242
+ * `inset-block-end: calc(1.6rem + var(--et-viewport-inset-bottom, 0px))`.
7243
+ */
7244
+ const INSET_PROPERTIES = {
7245
+ top: '--et-viewport-inset-top',
7246
+ right: '--et-viewport-inset-right',
7247
+ bottom: '--et-viewport-inset-bottom',
7248
+ left: '--et-viewport-inset-left',
7249
+ };
7250
+ /**
7251
+ * Page content paints below every reserving surface, so - unlike an overlay - it keeps out of every
7252
+ * reservation, whichever level it was made on.
7253
+ */
7254
+ const publishInsetProperties = () => {
7255
+ const root = globalThis.document?.documentElement;
7256
+ if (!root)
7257
+ return;
7258
+ const insets = overlayViewportInsets(Number.NEGATIVE_INFINITY);
7259
+ Object.entries(INSET_PROPERTIES).forEach(([edge, property]) => {
7260
+ if (!reservations.size) {
7261
+ root.style.removeProperty(property);
7262
+ return;
7263
+ }
7264
+ root.style.setProperty(property, `${insets[edge]}px`);
7265
+ });
7266
+ };
7267
+ const notify = () => {
7268
+ publishInsetProperties();
7269
+ listeners.forEach((listener) => listener());
7270
+ };
7271
+ /**
7272
+ * Reserves an edge of the viewport, so overlays keep out of it. Returns the release callback.
7273
+ *
7274
+ * Meant for a surface an application paints over its own content and above the overlay layer - a
7275
+ * docked devtools panel, an always-on-top widget. A centered or globally positioned overlay is laid
7276
+ * out inside what is left of the viewport, and an anchored one avoids the reserved edge the same way
7277
+ * it avoids the viewport edge. Page chrome that nothing can move for you - a sticky action bar, a
7278
+ * floating button - reads the published `--et-viewport-inset-*` custom properties instead.
7279
+ */
7280
+ const reserveOverlayViewportSpace = (reservation) => {
7281
+ const entry = {
7282
+ top: reservation.top ?? 0,
7283
+ right: reservation.right ?? 0,
7284
+ bottom: reservation.bottom ?? 0,
7285
+ left: reservation.left ?? 0,
7286
+ layer: reservation.layer ?? DEFAULT_OVERLAY_LAYER + 1,
7287
+ };
7288
+ reservations.add(entry);
7289
+ notify();
7290
+ return () => {
7291
+ if (!reservations.delete(entry))
7292
+ return;
7293
+ notify();
7294
+ };
7295
+ };
7296
+ /**
7297
+ * What an overlay on this stacking level must keep out of: the largest reservation per edge made by a
7298
+ * surface that paints above it. Reservations on or below the level are ignored - they cannot cover it.
7299
+ */
7300
+ const overlayViewportInsets = (layer = DEFAULT_OVERLAY_LAYER) => {
7301
+ let insets = NO_INSET;
7302
+ reservations.forEach((reservation) => {
7303
+ if (reservation.layer <= layer)
7304
+ return;
7305
+ insets = {
7306
+ top: Math.max(insets.top, reservation.top),
7307
+ right: Math.max(insets.right, reservation.right),
7308
+ bottom: Math.max(insets.bottom, reservation.bottom),
7309
+ left: Math.max(insets.left, reservation.left),
7310
+ };
7311
+ });
7312
+ return insets;
7313
+ };
7314
+ /** {@link overlayViewportInsets} for the stacking level `element` is rendered on. */
7315
+ const overlayViewportInsetsFor = (element) => overlayViewportInsets(resolveOverlayLayer(element));
7316
+ /**
7317
+ * Runs `listener` whenever a reservation is made or released, so an already positioned overlay can be
7318
+ * laid out again. Returns the unsubscribe callback.
7319
+ *
7320
+ * @internal
7321
+ */
7322
+ const onOverlayViewportInsetsChange = (listener) => {
7323
+ listeners.add(listener);
7324
+ return () => {
7325
+ listeners.delete(listener);
7326
+ };
7327
+ };
7328
+
7329
+ /**
7330
+ * Shrinks the host box to the part of the viewport nothing above this overlay has reserved, so a
7331
+ * centered or globally placed pane is laid out inside it instead of under a docked panel.
7332
+ */
7333
+ const applyViewportInsets = (hostElement, renderer) => {
7334
+ const insets = overlayViewportInsetsFor(hostElement);
7335
+ renderer.setStyle(hostElement, {
7336
+ top: `${insets.top}px`,
7337
+ right: `${insets.right}px`,
7338
+ bottom: `${insets.bottom}px`,
7339
+ left: `${insets.left}px`,
7340
+ });
7341
+ };
7245
7342
  const setBaseElementStyles = (config, hostElement, paneElement, renderer) => {
7246
7343
  renderer.setStyle(hostElement, {
7247
7344
  position: 'fixed',
@@ -7273,6 +7370,7 @@ const applyCenteredPosition = (hostElement, paneElement, renderer, _config) => {
7273
7370
  padding: '16px',
7274
7371
  overflow: 'auto',
7275
7372
  });
7373
+ applyViewportInsets(hostElement, renderer);
7276
7374
  renderer.setStyle(paneElement, {
7277
7375
  position: 'relative',
7278
7376
  });
@@ -7287,6 +7385,7 @@ const applyGlobalPosition = (hostElement, paneElement, renderer, config) => {
7287
7385
  placeItems: `${config.vertical ?? 'center'} ${config.horizontal ?? 'center'}`,
7288
7386
  padding: config.padding ?? '0',
7289
7387
  });
7388
+ applyViewportInsets(hostElement, renderer);
7290
7389
  renderer.setStyle(paneElement, {
7291
7390
  position: 'relative',
7292
7391
  });
@@ -7348,10 +7447,10 @@ const setupPositioning = (config, hostElement, paneElement, overlayRef, renderer
7348
7447
  }
7349
7448
  if (strategy.kind === 'global') {
7350
7449
  applyGlobalPosition(hostElement, paneElement, renderer, strategy);
7351
- return () => undefined;
7450
+ return onOverlayViewportInsetsChange(() => applyViewportInsets(hostElement, renderer));
7352
7451
  }
7353
7452
  applyCenteredPosition(hostElement, paneElement, renderer, strategy);
7354
- return () => undefined;
7453
+ return onOverlayViewportInsetsChange(() => applyViewportInsets(hostElement, renderer));
7355
7454
  };
7356
7455
 
7357
7456
  let middlewareExtras = null;
@@ -7423,6 +7522,27 @@ const preferredSide = (options) => ({
7423
7522
  : { data: { availableSpace }, reset: { placement: toOppositeSidePlacement(placement) } };
7424
7523
  },
7425
7524
  });
7525
+ const toSideObject = (padding) => typeof padding === 'number'
7526
+ ? { top: padding, right: padding, bottom: padding, left: padding }
7527
+ : {
7528
+ top: padding.top ?? 0,
7529
+ right: padding.right ?? 0,
7530
+ bottom: padding.bottom ?? 0,
7531
+ left: padding.left ?? 0,
7532
+ };
7533
+ /**
7534
+ * The strategy's own viewport padding plus the space reserved on each edge. Every middleware that
7535
+ * measures overflow gets it, so an edge a docked panel covers is as unavailable as the viewport edge.
7536
+ */
7537
+ const paddingWithInsets = (padding, insets) => {
7538
+ const own = toSideObject(padding);
7539
+ return {
7540
+ top: own.top + insets.top,
7541
+ right: own.right + insets.right,
7542
+ bottom: own.bottom + insets.bottom,
7543
+ left: own.left + insets.left,
7544
+ };
7545
+ };
7426
7546
  const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, renderer) => {
7427
7547
  // mirrorWidth needs a real element to measure; virtual references fall back to max-content
7428
7548
  const mirrorWidthElement = strategy.mirrorWidth && isHTMLElement(strategy.referenceElement) ? strategy.referenceElement : null;
@@ -7450,7 +7570,7 @@ const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, render
7450
7570
  renderer.setStyle(paneElement, { visibility: 'hidden' });
7451
7571
  }
7452
7572
  };
7453
- const cleanup = autoUpdate(strategy.referenceElement, paneElement, () => {
7573
+ const update = () => {
7454
7574
  // Checked here rather than left to the `hide` middleware, which is only in the list when `autoHide`
7455
7575
  // or `autoCloseIfReferenceHidden` asked for it: a trigger destroyed while its overlay is open (a
7456
7576
  // menu item that removes the button it was opened from) would otherwise fly to the corner for the
@@ -7460,19 +7580,22 @@ const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, render
7460
7580
  return;
7461
7581
  }
7462
7582
  const arrowElement = paneElement.querySelector('[et-floating-arrow]');
7583
+ const insets = overlayViewportInsetsFor(paneElement);
7584
+ const viewportPadding = paddingWithInsets(strategy.viewportPadding ?? 8, insets);
7463
7585
  const middleware = [];
7464
7586
  middleware.push(offset(strategy.offset ?? 8));
7465
7587
  middleware.push(strategy.minAvailableSpace === undefined
7466
7588
  ? flip({
7467
7589
  fallbackPlacements: strategy.fallbackPlacements ?? undefined,
7468
7590
  fallbackAxisSideDirection: 'start',
7591
+ padding: insets,
7469
7592
  boundary: strategy.boundary,
7470
7593
  })
7471
7594
  : preferredSide({
7472
7595
  minAvailableSpace: strategy.minAvailableSpace,
7473
7596
  // must stay the padding `size` measures with: the threshold is then compared against the
7474
7597
  // very height the pane ends up capped to
7475
- padding: strategy.viewportPadding ?? 8,
7598
+ padding: viewportPadding,
7476
7599
  boundary: strategy.boundary,
7477
7600
  }));
7478
7601
  if (strategy.shift !== false) {
@@ -7483,7 +7606,7 @@ const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, render
7483
7606
  crossAxis: strategy.minAvailableSpace === undefined &&
7484
7607
  (typeof strategy.shift === 'object' ? (strategy.shift.crossAxis ?? false) : false),
7485
7608
  limiter: limitShift(),
7486
- padding: strategy.viewportPadding ?? 8,
7609
+ padding: viewportPadding,
7487
7610
  boundary: strategy.boundary,
7488
7611
  }));
7489
7612
  }
@@ -7493,7 +7616,7 @@ const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, render
7493
7616
  const extras = requireMiddlewareExtras('autoResize');
7494
7617
  if (extras) {
7495
7618
  middleware.push(extras.size({
7496
- padding: strategy.viewportPadding ?? 8,
7619
+ padding: viewportPadding,
7497
7620
  apply({ availableHeight, availableWidth }) {
7498
7621
  renderer.setCssProperties(paneElement, {
7499
7622
  '--et-overlay-max-width': `${availableWidth}px`,
@@ -7547,9 +7670,14 @@ const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, render
7547
7670
  renderer.setCssProperty(arrowElement, '--et-floating-arrow-translate', `translate3d(${middlewareData.arrow.x ?? 0}px, ${middlewareData.arrow.y ?? 0}px, 0)`);
7548
7671
  }
7549
7672
  });
7550
- });
7673
+ };
7674
+ const cleanup = autoUpdate(strategy.referenceElement, paneElement, update);
7675
+ // A panel docked over the page changes how much room the pane has without moving, resizing or
7676
+ // scrolling anything `autoUpdate` watches.
7677
+ const stopInsetUpdates = onOverlayViewportInsetsChange(update);
7551
7678
  return () => {
7552
7679
  cleanup();
7680
+ stopInsetUpdates();
7553
7681
  };
7554
7682
  };
7555
7683
  /**
@@ -7583,6 +7711,7 @@ const createOverlayRuntimeRef = (id, config, elements, requestClose) => {
7583
7711
  const _componentInstance = signal(null, /* @ts-ignore */
7584
7712
  ...(ngDevMode ? [{ debugName: "_componentInstance" }] : /* istanbul ignore next */ []));
7585
7713
  let positionUpdater = null;
7714
+ let backdropUpdater = null;
7586
7715
  const beforeOpenedSubject = new Subject();
7587
7716
  const afterOpenedSubject = new Subject();
7588
7717
  const beforeClosedSubject = new Subject();
@@ -7648,6 +7777,20 @@ const createOverlayRuntimeRef = (id, config, elements, requestClose) => {
7648
7777
  }
7649
7778
  positionUpdater?.(strategy);
7650
7779
  },
7780
+ /** @internal */
7781
+ attachBackdropUpdater(updater) {
7782
+ backdropUpdater = updater;
7783
+ },
7784
+ /**
7785
+ * Adds or removes the backdrop of an open overlay. `elements.backdropElement` follows.
7786
+ * A closing overlay keeps the backdrop it has, so its leave transition stays intact.
7787
+ */
7788
+ updateBackdrop(hasBackdrop) {
7789
+ if (_state() === 'closing' || _state() === 'closed') {
7790
+ return;
7791
+ }
7792
+ backdropUpdater?.(hasBackdrop);
7793
+ },
7651
7794
  markOpened() {
7652
7795
  if (_state() !== 'mounting') {
7653
7796
  return;
@@ -7764,11 +7907,27 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
7764
7907
  const root = getRootElement(targetDocument, layer);
7765
7908
  const hostElement = renderer.createElement('div');
7766
7909
  const paneElement = renderer.createElement('div');
7767
- const backdropElement = config.hasBackdrop === false ? null : renderer.createElement('div');
7910
+ const backdropElement = signal(null, /* @ts-ignore */
7911
+ ...(ngDevMode ? [{ debugName: "backdropElement" }] : /* istanbul ignore next */ []));
7768
7912
  const previousFocusedElement = isHTMLElement(targetDocument.activeElement) ? targetDocument.activeElement : null;
7769
7913
  const autoFocus = config.autoFocus ?? 'first-tabbable';
7914
+ let currentHasBackdrop = config.hasBackdrop !== false;
7915
+ let currentPositionStrategy = config.positionStrategy;
7916
+ const activeConfig = () => ({
7917
+ ...config,
7918
+ positionStrategy: currentPositionStrategy,
7919
+ hasBackdrop: currentHasBackdrop,
7920
+ });
7921
+ const createBackdropElement = () => {
7922
+ const element = renderer.createElement('div');
7923
+ renderer.addClass(element, 'et-overlay-runtime-backdrop');
7924
+ setBackdropStyles(element, renderer);
7925
+ renderer.setAttribute(element, 'data-overlay-id', config.id);
7926
+ (config.backdropClass ?? []).forEach((className) => renderer.addClass(element, className));
7927
+ return element;
7928
+ };
7770
7929
  renderer.addClass(hostElement, 'et-overlay-runtime-entry');
7771
- setBaseElementStyles(config, hostElement, paneElement, renderer);
7930
+ setBaseElementStyles(activeConfig(), hostElement, paneElement, renderer);
7772
7931
  renderer.setAttributes(hostElement, {
7773
7932
  'data-overlay-id': config.id,
7774
7933
  role: config.role ?? null,
@@ -7779,19 +7938,17 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
7779
7938
  'aria-label': config.ariaLabel ?? null,
7780
7939
  });
7781
7940
  renderer.addClass(hostElement, ...(config.hostClass ?? []));
7782
- if (backdropElement) {
7783
- renderer.addClass(backdropElement, 'et-overlay-runtime-backdrop');
7784
- setBackdropStyles(backdropElement, renderer);
7785
- renderer.setAttribute(backdropElement, 'data-overlay-id', config.id);
7786
- (config.backdropClass ?? []).forEach((className) => renderer.addClass(backdropElement, className));
7787
- renderer.appendChild(hostElement, backdropElement);
7941
+ if (currentHasBackdrop) {
7942
+ const element = createBackdropElement();
7943
+ renderer.appendChild(hostElement, element);
7944
+ backdropElement.set(element);
7788
7945
  }
7789
7946
  renderer.appendChild(hostElement, paneElement);
7790
7947
  renderer.appendChild(root, hostElement);
7791
7948
  const overlayRef = createOverlayRuntimeRef(config.id, { ...config }, {
7792
7949
  rootElement: root,
7793
7950
  hostElement,
7794
- backdropElement,
7951
+ backdropElement: backdropElement.asReadonly(),
7795
7952
  paneElement,
7796
7953
  }, (result, source) => beginClose({ result, source }));
7797
7954
  animationDebugLog(`runtime ${config.id}`, 'mount');
@@ -7818,23 +7975,46 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
7818
7975
  overlayRef.beforeOpenedSubject.next();
7819
7976
  overlayRef.beforeOpenedSubject.complete();
7820
7977
  openEntriesState.update((entries) => [...entries, overlayRef]);
7821
- let positionCleanup = setupPositioning(config, hostElement, paneElement, overlayRef, renderer);
7978
+ let positionCleanup = setupPositioning(activeConfig(), hostElement, paneElement, overlayRef, renderer);
7822
7979
  cleanupFns.push(() => positionCleanup());
7823
- let currentPositionStrategy = config.positionStrategy;
7824
7980
  const getOriginElement = () => currentPositionStrategy?.kind === 'anchored' && isHTMLElement(currentPositionStrategy.referenceElement)
7825
7981
  ? currentPositionStrategy.referenceElement
7826
7982
  : null;
7827
7983
  overlayRef.attachPositionUpdater((strategy) => {
7828
7984
  currentPositionStrategy = strategy;
7829
7985
  positionCleanup();
7830
- resetPositioningStyles(config, hostElement, paneElement, renderer);
7831
- positionCleanup = setupPositioning({ ...config, positionStrategy: strategy }, hostElement, paneElement, overlayRef, renderer);
7986
+ resetPositioningStyles(activeConfig(), hostElement, paneElement, renderer);
7987
+ positionCleanup = setupPositioning(activeConfig(), hostElement, paneElement, overlayRef, renderer);
7988
+ });
7989
+ overlayRef.attachBackdropUpdater((hasBackdrop) => {
7990
+ if (hasBackdrop === currentHasBackdrop) {
7991
+ return;
7992
+ }
7993
+ currentHasBackdrop = hasBackdrop;
7994
+ if (hasBackdrop) {
7995
+ const element = createBackdropElement();
7996
+ renderer.insertBefore(hostElement, element, paneElement);
7997
+ backdropElement.set(element);
7998
+ }
7999
+ else {
8000
+ const element = backdropElement();
8001
+ if (element) {
8002
+ renderer.removeChild(hostElement, element);
8003
+ backdropElement.set(null);
8004
+ }
8005
+ }
8006
+ renderer.setStyle(hostElement, { pointerEvents: hasBackdrop ? 'auto' : 'none' });
7832
8007
  });
7833
8008
  const destroyMountedOverlay = (closeEvent) => {
7834
8009
  animationDebugLog(`runtime ${config.id}`, `destroy (source "${closeEvent.source}")`);
7835
8010
  cleanupFns.forEach((cleanup) => cleanup());
7836
8011
  appRef.detachView(componentRef.hostView);
7837
8012
  componentRef.destroy();
8013
+ // Angular does not own this injector, so nothing else tears down what the overlay's own
8014
+ // providers registered on it - their `DestroyRef` hooks and effects would outlive the overlay.
8015
+ if (!elementInjector.destroyed) {
8016
+ elementInjector.destroy();
8017
+ }
7838
8018
  const parentNode = renderer.parentNode(hostElement);
7839
8019
  if (parentNode) {
7840
8020
  renderer.removeChild(parentNode, hostElement);
@@ -9184,9 +9364,16 @@ class ProvideSurfaceDirective {
9184
9364
  return theme;
9185
9365
  }, /* @ts-ignore */
9186
9366
  ...(ngDevMode ? [{ debugName: "resolvedTheme" }] : /* istanbul ignore next */ []));
9187
- this.elevation = computed(() => this.resolvedTheme()?.elevation ?? 0, /* @ts-ignore */
9367
+ /**
9368
+ * The surface theme in effect on this element - the theme this provider resolves itself, or,
9369
+ * where it is left unset, the one it inherits from the closest ancestor provider. The outermost
9370
+ * provider resolves the app default, so the chain ends there.
9371
+ */
9372
+ this.activeTheme = computed(() => this.resolvedTheme() ?? this.parentProvider?.activeTheme() ?? null, /* @ts-ignore */
9373
+ ...(ngDevMode ? [{ debugName: "activeTheme" }] : /* istanbul ignore next */ []));
9374
+ this.elevation = computed(() => this.activeTheme()?.elevation ?? 0, /* @ts-ignore */
9188
9375
  ...(ngDevMode ? [{ debugName: "elevation" }] : /* istanbul ignore next */ []));
9189
- this.surfaceType = computed(() => this.resolvedTheme()?.type ?? null, /* @ts-ignore */
9376
+ this.surfaceType = computed(() => this.activeTheme()?.type ?? null, /* @ts-ignore */
9190
9377
  ...(ngDevMode ? [{ debugName: "surfaceType" }] : /* istanbul ignore next */ []));
9191
9378
  this.surfaceName = computed(() => {
9192
9379
  const value = this.effectiveSurface();
@@ -9261,20 +9448,25 @@ const injectSurfaceType = () => {
9261
9448
  const defaultType = injectDefaultSurfaceTheme()?.type ?? SURFACE_TYPE.DARK;
9262
9449
  return computed(() => provider?.surfaceType() ?? defaultType);
9263
9450
  };
9451
+ /**
9452
+ * Inject a signal containing the surface theme the current subtree renders on - the theme in
9453
+ * effect on the surrounding surface provider, or the app's default surface where nothing provides
9454
+ * one. Use it to derive an elevation relative to the surrounding surface.
9455
+ *
9456
+ * `null` where the app registers no surface themes, or registers a default per surface type -
9457
+ * which of those two `:root` paints is a `prefers-color-scheme` decision, so it cannot be
9458
+ * resolved at runtime.
9459
+ */
9460
+ const injectParentSurface = () => {
9461
+ const provider = inject(SURFACE_PROVIDER, { optional: true, skipSelf: true });
9462
+ const defaultTheme = injectDefaultSurfaceTheme();
9463
+ return computed(() => provider?.activeTheme() ?? defaultTheme);
9464
+ };
9264
9465
 
9265
9466
  let uniqueId = 0;
9266
9467
  const SURFACE_CONTEXT_TRACKER_DEF = /* @__PURE__ */ defineRootProvider(() => {
9267
9468
  const entries = signal([], /* @ts-ignore */
9268
9469
  ...(ngDevMode ? [{ debugName: "entries" }] : /* istanbul ignore next */ []));
9269
- const topEntry = computed(() => {
9270
- const stack = entries();
9271
- return stack.length > 0 ? (stack[stack.length - 1] ?? null) : null;
9272
- }, /* @ts-ignore */
9273
- ...(ngDevMode ? [{ debugName: "topEntry" }] : /* istanbul ignore next */ []));
9274
- const topType = computed(() => topEntry()?.type ?? null, /* @ts-ignore */
9275
- ...(ngDevMode ? [{ debugName: "topType" }] : /* istanbul ignore next */ []));
9276
- const topElevation = computed(() => topEntry()?.elevation ?? 0, /* @ts-ignore */
9277
- ...(ngDevMode ? [{ debugName: "topElevation" }] : /* istanbul ignore next */ []));
9278
9470
  const register = (type, elevation, element) => {
9279
9471
  const id = `surface-ctx-${uniqueId++}`;
9280
9472
  const entry = { id, type, elevation, element };
@@ -9294,7 +9486,7 @@ const SURFACE_CONTEXT_TRACKER_DEF = /* @__PURE__ */ defineRootProvider(() => {
9294
9486
  }
9295
9487
  return null;
9296
9488
  };
9297
- return { topType, topElevation, register, surfaceForElement };
9489
+ return { register, surfaceForElement };
9298
9490
  }, { name: 'SurfaceContextTracker' });
9299
9491
  const provideSurfaceContextTracker = /* @__PURE__ */ toProvideFn(SURFACE_CONTEXT_TRACKER_DEF);
9300
9492
  const injectSurfaceContextTracker = /* @__PURE__ */ toInjectFn(SURFACE_CONTEXT_TRACKER_DEF);
@@ -9314,9 +9506,9 @@ class AutoSurfaceDirective {
9314
9506
  }
9315
9507
  constructor() {
9316
9508
  this.ownSurfaceProvider = inject(ProvideSurfaceDirective);
9317
- this.contextSurfaceProvider = inject(SURFACE_PROVIDER, { optional: true, skipSelf: true });
9318
9509
  this.surfaceThemes = injectSurfaceThemes({ optional: true });
9319
9510
  this.surfaceContextTracker = injectSurfaceContextTracker();
9511
+ this.parentSurface = injectParentSurface();
9320
9512
  this.elementRef = inject(ElementRef);
9321
9513
  /**
9322
9514
  * Explicit surface provider to resolve the surface relative to. Falls back to the
@@ -9343,9 +9535,10 @@ class AutoSurfaceDirective {
9343
9535
  // Establish a dependency on the DOM-settle tick so the non-reactive containment read below
9344
9536
  // is re-evaluated after the element is grafted into its final overlay pane.
9345
9537
  this.domSettleTick();
9346
- const contextProvider = this.surfaceProvider() ?? this.contextSurfaceProvider ?? null;
9347
- const contextElevation = contextProvider?.elevation() ?? null;
9348
- const contextType = contextProvider?.surfaceType() ?? null;
9538
+ const explicitProvider = this.surfaceProvider();
9539
+ const contextTheme = explicitProvider ? explicitProvider.activeTheme() : this.parentSurface();
9540
+ const contextElevation = contextTheme?.elevation ?? null;
9541
+ const contextType = contextTheme?.type ?? null;
9349
9542
  // An overlay's projected/portaled content keeps the injector of where it was
9350
9543
  // *declared* (the trigger location), not the pane it renders into - so the
9351
9544
  // injector-derived parent surface is one elevation too low. The surface-context
@@ -9867,11 +10060,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
9867
10060
 
9868
10061
  // Generated from package.json by tools/scripts/generate-version.js - do not edit.
9869
10062
  /** The version of `@ethlete/core` this build was cut from. */
9870
- const CORE_VERSION = '5.0.0-next.51';
10063
+ const CORE_VERSION = '5.0.0-next.53';
9871
10064
 
9872
10065
  /**
9873
10066
  * Generated bundle index. Do not edit.
9874
10067
  */
9875
10068
 
9876
- 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, 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, 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, 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 };
10069
+ 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 };
9877
10070
  //# sourceMappingURL=ethlete-core.mjs.map