@ethlete/core 5.0.0-next.60 → 5.0.0-next.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/fesm2022/ethlete-core.mjs +269 -203
- package/fesm2022/ethlete-core.mjs.map +1 -1
- package/generators/migrate-to-v5/apply-replacements.js +14 -0
- package/generators/migrate-to-v5/color-naming.js +11 -57
- package/generators/migrate-to-v5/create-provider.js +56 -44
- package/generators/migrate-to-v5/migration-files.js +13 -0
- package/generators/migrate-to-v5/migration.js +31 -27
- package/generators/migrate-to-v5/removed-exports.js +7 -27
- package/generators/migrate-to-v5/router-state-service.js +118 -350
- package/generators/migrate-to-v5/schema.json +12 -0
- package/generators/migrate-to-v5/service-classes.js +108 -0
- package/generators/migrate-to-v5/viewport-service.js +195 -443
- package/generators/tailwind-4-color-theme/generator.js +71 -85
- package/package.json +1 -1
- package/types/ethlete-core.d.ts +41 -34
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { assertInInjectionContext, inject, DestroyRef, ElementRef, TemplateRef, InjectionToken, QueryList, RendererFactory2, RendererStyleFlags2, isSignal, DOCUMENT, signal, linkedSignal, isDevMode, computed, afterNextRender, effect, untracked, ApplicationRef, runInInjectionContext, NgZone, Injector, booleanAttribute, numberAttribute, PLATFORM_ID, EnvironmentInjector, createComponent, ViewEncapsulation, Component, Directive, model, ViewContainerRef, input, CSP_NONCE, provideEnvironmentInitializer, output, createEnvironmentInjector, Pipe, afterEveryRender } from '@angular/core';
|
|
3
3
|
import { takeUntilDestroyed, toSignal, toObservable, outputFromObservable } from '@angular/core/rxjs-interop';
|
|
4
|
-
import { Subject, fromEvent, switchMap, startWith, of, defer, from, map, catchError, timer, takeUntil, pairwise, debounceTime, merge, distinctUntilChanged, EMPTY, expand, skip,
|
|
4
|
+
import { Subject, fromEvent, switchMap, startWith, of, defer, from, map, catchError, timer, takeUntil, tap, pairwise, debounceTime, merge, distinctUntilChanged, EMPTY, expand, skip, take, filter, BehaviorSubject, combineLatest, 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
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
|
-
import { offset, flip, shift, limitShift, computePosition, autoUpdate, hide, arrow, size } from '@floating-ui/dom';
|
|
10
|
+
import { platform, 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;
|
|
@@ -660,8 +660,8 @@ class KeyPressManager {
|
|
|
660
660
|
this.keyPressCount++;
|
|
661
661
|
this._stopTimeout$.next();
|
|
662
662
|
timer(100)
|
|
663
|
-
.pipe(takeUntil(this._stopTimeout$))
|
|
664
|
-
.subscribe(
|
|
663
|
+
.pipe(takeUntil(this._stopTimeout$), tap(() => this.clear()))
|
|
664
|
+
.subscribe();
|
|
665
665
|
}
|
|
666
666
|
else {
|
|
667
667
|
this.clear();
|
|
@@ -1693,6 +1693,7 @@ const resolveFromMap = (map, bp, defaultValue) => {
|
|
|
1693
1693
|
}
|
|
1694
1694
|
return defaultValue;
|
|
1695
1695
|
};
|
|
1696
|
+
/** Builds an input transform that coerces a value or a per-breakpoint map to `T` for the current breakpoint. */
|
|
1696
1697
|
const breakpointTransformBase = (coerce, defaultValue) => {
|
|
1697
1698
|
const currentBp = injectCurrentBreakpoint();
|
|
1698
1699
|
const injector = inject(Injector);
|
|
@@ -1852,8 +1853,8 @@ const signalCountdown = (deadline) => {
|
|
|
1852
1853
|
const remainingMs = endsAt - Date.now();
|
|
1853
1854
|
return remainingMs <= 0 ? EMPTY : timer(remainingMs % SECOND_MS || SECOND_MS);
|
|
1854
1855
|
}), skip(1));
|
|
1855
|
-
}), takeUntilDestroyed())
|
|
1856
|
-
.subscribe(
|
|
1856
|
+
}), tap(() => tick.update((count) => count + 1)), takeUntilDestroyed())
|
|
1857
|
+
.subscribe();
|
|
1857
1858
|
}
|
|
1858
1859
|
return computed(() => {
|
|
1859
1860
|
tick();
|
|
@@ -1897,13 +1898,13 @@ const signalDeferredLoading = (source, options) => {
|
|
|
1897
1898
|
}
|
|
1898
1899
|
const remaining = minDuration - (performance.now() - shownAt);
|
|
1899
1900
|
return remaining <= 0 ? of(false) : timer(remaining).pipe(map(() => false));
|
|
1900
|
-
}),
|
|
1901
|
-
.subscribe((isVisible) => {
|
|
1901
|
+
}), tap((isVisible) => {
|
|
1902
1902
|
if (isVisible) {
|
|
1903
1903
|
shownAt = performance.now();
|
|
1904
1904
|
}
|
|
1905
1905
|
visible.set(isVisible);
|
|
1906
|
-
})
|
|
1906
|
+
}), takeUntilDestroyed())
|
|
1907
|
+
.subscribe();
|
|
1907
1908
|
return visible.asReadonly();
|
|
1908
1909
|
};
|
|
1909
1910
|
|
|
@@ -1948,8 +1949,6 @@ const signalElementChildren = (el, options) => {
|
|
|
1948
1949
|
if (!isRendered())
|
|
1949
1950
|
return [];
|
|
1950
1951
|
const els = firstEl();
|
|
1951
|
-
// We are not interested what the mutation is, just that there is one.
|
|
1952
|
-
// Changes to the DOM may affect the children of the element.
|
|
1953
1952
|
elementMutations();
|
|
1954
1953
|
if (!els.currentElement)
|
|
1955
1954
|
return [];
|
|
@@ -2099,8 +2098,6 @@ const signalStyles = (el, styleMap) => {
|
|
|
2099
2098
|
const signalHostStyles = (styleMap) => signalStyles(inject(ElementRef), styleMap);
|
|
2100
2099
|
|
|
2101
2100
|
const elementCanScroll = (element, direction) => {
|
|
2102
|
-
// Omitting the element means "the document scroller". Resolved lazily and guarded so a call on the
|
|
2103
|
-
// server answers "cannot scroll" instead of throwing on a missing `document`.
|
|
2104
2101
|
const el = element || (typeof document === 'undefined' ? null : document.documentElement);
|
|
2105
2102
|
if (!el) {
|
|
2106
2103
|
return false;
|
|
@@ -2115,9 +2112,6 @@ const elementCanScroll = (element, direction) => {
|
|
|
2115
2112
|
return scrollHeight > clientHeight || scrollWidth > clientWidth;
|
|
2116
2113
|
};
|
|
2117
2114
|
const createViewportRect = () => {
|
|
2118
|
-
// Collapses to a zero rect where there is no window (server). `isElementVisible` never reaches the
|
|
2119
|
-
// intersection math there anyway - `elementCanScroll` already reports the document as unscrollable
|
|
2120
|
-
// - so the rect only has to be a valid shape.
|
|
2121
2115
|
const hasWindow = typeof window !== 'undefined';
|
|
2122
2116
|
const width = hasWindow ? window.innerWidth : 0;
|
|
2123
2117
|
const height = hasWindow ? window.innerHeight : 0;
|
|
@@ -2212,13 +2206,13 @@ const getElementScrollCoordinates = (options) => {
|
|
|
2212
2206
|
scrollTopTo = scrollTop + relativeTop - conHeight / 2 + elHeight / 2;
|
|
2213
2207
|
};
|
|
2214
2208
|
const calculateScrollToNearest = () => {
|
|
2215
|
-
const isAbove = elBottom
|
|
2209
|
+
const isAbove = elBottom <= conTop;
|
|
2216
2210
|
const isPartialAbove = elTop < conTop && elBottom > conTop;
|
|
2217
|
-
const isBelow = elTop
|
|
2211
|
+
const isBelow = elTop >= conBottom;
|
|
2218
2212
|
const isPartialBelow = elTop < conBottom && elBottom > conBottom;
|
|
2219
|
-
const isLeft = elRight
|
|
2213
|
+
const isLeft = elRight <= conLeft;
|
|
2220
2214
|
const isPartialLeft = elLeft < conLeft && elRight > conLeft;
|
|
2221
|
-
const isRight = elLeft
|
|
2215
|
+
const isRight = elLeft >= conRight;
|
|
2222
2216
|
const isPartialRight = elLeft < conRight && elRight > conRight;
|
|
2223
2217
|
if (isAbove || isPartialAbove || isLeft || isPartialLeft) {
|
|
2224
2218
|
calculateScrollToStart();
|
|
@@ -2252,6 +2246,7 @@ const scrollToElement = (options) => {
|
|
|
2252
2246
|
};
|
|
2253
2247
|
|
|
2254
2248
|
const MIN_SNAP_DELTA_PX = 1;
|
|
2249
|
+
const FULLY_VISIBLE_RATIO = 0.99;
|
|
2255
2250
|
const getScrollSnapTarget = (items, container, direction, origin, margin = 0) => {
|
|
2256
2251
|
if (!items.length)
|
|
2257
2252
|
return null;
|
|
@@ -2371,7 +2366,7 @@ const getScrollItemTarget = (entries, container, direction, scrollOrigin, axisDi
|
|
|
2371
2366
|
}
|
|
2372
2367
|
const entry = direction === 'start' ? firstVisible : lastVisible;
|
|
2373
2368
|
const entryIndex = direction === 'start' ? firstIndex : lastIndex;
|
|
2374
|
-
if (
|
|
2369
|
+
if (entry.intersectionRatio >= FULLY_VISIBLE_RATIO) {
|
|
2375
2370
|
if (direction === 'start' && entryIndex === 0)
|
|
2376
2371
|
return null;
|
|
2377
2372
|
if (direction === 'end' && entryIndex === entries.length - 1)
|
|
@@ -2623,8 +2618,6 @@ const signalElementScrollState = (el, options) => {
|
|
|
2623
2618
|
return computed(() => {
|
|
2624
2619
|
const element = observedEl().currentElement;
|
|
2625
2620
|
const dimensions = elementDimensions();
|
|
2626
|
-
// We are not interested what the mutation is, just that there is one.
|
|
2627
|
-
// Changes to the DOM can affect the scroll state of the element.
|
|
2628
2621
|
elementMutations();
|
|
2629
2622
|
if (!element || !isRendered())
|
|
2630
2623
|
return notScrollable(dimensions);
|
|
@@ -2745,14 +2738,12 @@ const useCursorDragScroll = (el, options) => {
|
|
|
2745
2738
|
// A host destroyed mid-drag never re-runs the styling effect, so the grabbing cursor it wrote on
|
|
2746
2739
|
// `<html>` would outlive the page it was dragged on.
|
|
2747
2740
|
destroyRef.onDestroy(() => renderer.removeStyle(document.documentElement, 'cursor'));
|
|
2748
|
-
// Cleanup if the element the cursor drag scroll is bound to gets changed
|
|
2749
2741
|
effect(() => {
|
|
2750
2742
|
const { previousElement } = element();
|
|
2751
2743
|
if (previousElement) {
|
|
2752
2744
|
renderer.removeStyle(previousElement, 'cursor');
|
|
2753
2745
|
}
|
|
2754
2746
|
});
|
|
2755
|
-
// Conditionally apply styles/classes to the element and the document
|
|
2756
2747
|
effect(() => {
|
|
2757
2748
|
const currCanScroll = canScroll();
|
|
2758
2749
|
const isEnabled = enabled();
|
|
@@ -2792,7 +2783,6 @@ const useCursorDragScroll = (el, options) => {
|
|
|
2792
2783
|
}
|
|
2793
2784
|
});
|
|
2794
2785
|
});
|
|
2795
|
-
// Update the element's scroll position when the user drags
|
|
2796
2786
|
effect(() => {
|
|
2797
2787
|
const currDragAmount = dragAmount();
|
|
2798
2788
|
untracked(() => {
|
|
@@ -3425,14 +3415,14 @@ const setupScrollRestoration = (config = {}) => {
|
|
|
3425
3415
|
}
|
|
3426
3416
|
};
|
|
3427
3417
|
router.events
|
|
3428
|
-
.pipe(filter((e) => e instanceof NavigationStart || e instanceof NavigationEnd || e instanceof NavigationSkipped),
|
|
3429
|
-
.subscribe((event) => {
|
|
3418
|
+
.pipe(filter((e) => e instanceof NavigationStart || e instanceof NavigationEnd || e instanceof NavigationSkipped), tap((event) => {
|
|
3430
3419
|
if (event instanceof NavigationStart) {
|
|
3431
3420
|
onNavigationStart(event);
|
|
3432
3421
|
return;
|
|
3433
3422
|
}
|
|
3434
3423
|
onNavigationEnd(event);
|
|
3435
|
-
})
|
|
3424
|
+
}), takeUntilDestroyed())
|
|
3425
|
+
.subscribe();
|
|
3436
3426
|
destroyRef.onDestroy(() => {
|
|
3437
3427
|
cancelPendingRestore();
|
|
3438
3428
|
if (restoreEnabled && previousScrollRestoration !== null) {
|
|
@@ -3470,15 +3460,30 @@ const escapeHtmlPreservingEntities = (str) => str
|
|
|
3470
3460
|
.replace(/</g, '<')
|
|
3471
3461
|
.replace(/>/g, '>')
|
|
3472
3462
|
.replace(/"/g, '"');
|
|
3463
|
+
/** Attribute that makes `htmlToMarkdown` write an element's text verbatim, without Markdown escaping:
|
|
3464
|
+
* `<span data-markdown-verbatim>{{user:_x}}</span>` becomes `{{user:_x}}`. The element must hold
|
|
3465
|
+
* text only. */
|
|
3466
|
+
const MARKDOWN_VERBATIM_ATTR = 'data-markdown-verbatim';
|
|
3467
|
+
const VERBATIM_RE = /* @__PURE__ */ new RegExp(`<span\\b[^>]*\\b${MARKDOWN_VERBATIM_ATTR}\\b[^>]*>([^<]*)<\\/span>`, 'gi');
|
|
3473
3468
|
const decodeUrlCharacterReferences = (url) => url
|
|
3474
3469
|
.replace(/&#(\d+);?/g, (_, value) => String.fromCodePoint(Number(value)))
|
|
3475
3470
|
.replace(/&#x([0-9a-f]+);?/gi, (_, value) => String.fromCodePoint(Number.parseInt(value, 16)))
|
|
3476
3471
|
.replace(/&(colon|tab|newline);/gi, (_, entity) => entity.toLowerCase() === 'colon' ? ':' : entity.toLowerCase() === 'tab' ? '\t' : '\n');
|
|
3472
|
+
/** Whether `url` may be embedded as an image `src`: everything except `javascript:` and `vbscript:`
|
|
3473
|
+
* URLs and non-image `data:` URLs, however they are cased, spaced or entity-encoded. */
|
|
3477
3474
|
const isSafeUrl = (url) => {
|
|
3478
3475
|
// eslint-disable-next-line no-control-regex -- URL parsers ignore these characters inside schemes.
|
|
3479
3476
|
const normalized = decodeUrlCharacterReferences(url).replace(/[\s\u0000-\u001f]/g, '');
|
|
3480
3477
|
return (!/^(javascript|vbscript):/i.test(normalized) && !/^data:(?!image\/(?:avif|gif|jpeg|png|webp);)/i.test(normalized));
|
|
3481
3478
|
};
|
|
3479
|
+
/** Whether `url` may become a link: `http:`, `https:`, `mailto:` and `tel:` URLs, relative paths and
|
|
3480
|
+
* fragments pass; any other scheme (`javascript:`, `data:`, `vbscript:`, ...) is refused, however
|
|
3481
|
+
* it is cased, spaced or entity-encoded. */
|
|
3482
|
+
const isSafeLinkUrl = (url) => {
|
|
3483
|
+
// eslint-disable-next-line no-control-regex -- URL parsers ignore these characters inside schemes.
|
|
3484
|
+
const normalized = decodeUrlCharacterReferences(url).replace(/[\s\u0000-\u001f]/g, '');
|
|
3485
|
+
return !/^[a-z][a-z0-9+.-]*:/i.test(normalized) || /^(?:https?|mailto|tel):/i.test(normalized);
|
|
3486
|
+
};
|
|
3482
3487
|
const unescapeHtml = (str) => str
|
|
3483
3488
|
.replace(/&/g, '&')
|
|
3484
3489
|
.replace(/</g, '<')
|
|
@@ -3527,7 +3532,7 @@ const sanitizeInlineHtml = (html) => {
|
|
|
3527
3532
|
const name = tag.toLowerCase();
|
|
3528
3533
|
if (name === 'a') {
|
|
3529
3534
|
const href = closing ? null : /\bhref\s*=\s*"([^"]*)"/i.exec(full)?.[1];
|
|
3530
|
-
const anchor = closing ? '</a>' : href &&
|
|
3535
|
+
const anchor = closing ? '</a>' : href && isSafeLinkUrl(href) ? `<a href="${href}">` : '<a>';
|
|
3531
3536
|
return makePlaceholder('TAG', kept.push(anchor) - 1);
|
|
3532
3537
|
}
|
|
3533
3538
|
if (!SAFE_INLINE_TAGS.has(name))
|
|
@@ -3538,10 +3543,10 @@ const sanitizeInlineHtml = (html) => {
|
|
|
3538
3543
|
};
|
|
3539
3544
|
const processInline = (text) => {
|
|
3540
3545
|
const inlineCodes = [];
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3546
|
+
const escapes = [];
|
|
3547
|
+
text = text.replace(/\\([!-/:-@[-`{-~])|`([^`]+)`/g, (_, escaped, code) => escaped !== undefined
|
|
3548
|
+
? makePlaceholder('ESC', escapes.push(escapeHtml(escaped)) - 1)
|
|
3549
|
+
: makePlaceholder('IC', inlineCodes.push(`<code>${escapeHtml(code ?? '')}</code>`) - 1));
|
|
3545
3550
|
// "Open in new tab" links round-trip as raw HTML because Markdown has no `target` syntax. Extract
|
|
3546
3551
|
// them before the raw-HTML escape below, keeping only a safe href, `target="_blank"` and a forced
|
|
3547
3552
|
// `rel="noopener noreferrer"` (any other attribute - including event handlers - is dropped); their
|
|
@@ -3550,9 +3555,11 @@ const processInline = (text) => {
|
|
|
3550
3555
|
text = text.replace(/<a\b([^>]*)>([\s\S]*?)<\/a>/gi, (full, attrs, inner) => {
|
|
3551
3556
|
const href = /\bhref\s*=\s*"([^"]*)"/i.exec(attrs)?.[1];
|
|
3552
3557
|
const newTab = /\btarget\s*=\s*"_blank"/i.test(attrs);
|
|
3553
|
-
if (!newTab || !href
|
|
3558
|
+
if (!newTab || !href)
|
|
3554
3559
|
return full;
|
|
3555
|
-
const anchor =
|
|
3560
|
+
const anchor = isSafeLinkUrl(href)
|
|
3561
|
+
? `<a href="${href}" target="_blank" rel="noopener noreferrer">${processInline(inner)}</a>`
|
|
3562
|
+
: processInline(inner);
|
|
3556
3563
|
return makePlaceholder('NTLINK', newTabLinks.push(anchor) - 1);
|
|
3557
3564
|
});
|
|
3558
3565
|
// Raw HTML in Markdown text is escaped, not rendered - the editor writes this HTML straight
|
|
@@ -3570,10 +3577,12 @@ const processInline = (text) => {
|
|
|
3570
3577
|
text = text.replace(/~~([^\s~](?:.*?[^\s~])?)~~/g, '<del>$1</del>');
|
|
3571
3578
|
// Images before links (order matters); URLs with script-running schemes stay literal text
|
|
3572
3579
|
text = text.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (match, alt, src) => isSafeUrl(src) ? `<img src="${src}" alt="${alt}">` : match);
|
|
3573
|
-
text = text.replace(
|
|
3580
|
+
text = text.replace(/(?<!!)\[([^\]]+)\]\(([^)]+)\)/g, (_match, label, href) => isSafeLinkUrl(href) ? `<a href="${href}">${label}</a>` : label);
|
|
3581
|
+
// New-tab links first: their inner markup still holds this call's code and escape placeholders.
|
|
3574
3582
|
return text
|
|
3575
|
-
.replace(placeholderRe('
|
|
3576
|
-
.replace(placeholderRe('
|
|
3583
|
+
.replace(placeholderRe('NTLINK'), (_, i) => newTabLinks[+i] ?? '')
|
|
3584
|
+
.replace(placeholderRe('IC'), (match, i) => inlineCodes[+i] ?? match)
|
|
3585
|
+
.replace(placeholderRe('ESC'), (match, i) => escapes[+i] ?? match);
|
|
3577
3586
|
};
|
|
3578
3587
|
/** The first top-level `<ul>`/`<ol>` in `html`, matched with balanced nesting. */
|
|
3579
3588
|
const findList = (html) => {
|
|
@@ -3737,15 +3746,49 @@ const buildListHtml = (lines, start, baseIndent) => {
|
|
|
3737
3746
|
const tag = ordered ? 'ol' : 'ul';
|
|
3738
3747
|
return { html: `<${tag}>${items}</${tag}>`, next: i };
|
|
3739
3748
|
};
|
|
3749
|
+
const escapeMarkdownText = (text) => text
|
|
3750
|
+
.replace(/[\\`[\]]/g, '\\$&')
|
|
3751
|
+
.replace(/(?<!\s)\*|\*(?!\s)/g, '\\*')
|
|
3752
|
+
.replace(/_+/g, (run, offset, whole) => run.length === 1 && /[a-z0-9]/i.test(whole[offset - 1] ?? '') && /[a-z0-9]/i.test(whole[offset + 1] ?? '')
|
|
3753
|
+
? run
|
|
3754
|
+
: run.replace(/_/g, '\\_'))
|
|
3755
|
+
.replace(/~{2,}/g, (run) => run.replace(/~/g, '\\~'))
|
|
3756
|
+
.replace(/<(?=\/?(?:u|a|p|h[1-6]|div)\b)/gi, '\\<')
|
|
3757
|
+
.replace(/(^|\n)([ \t]*)(?=[-+*#|:]|>|\d+\.)/g, '$1$2\u{E002}');
|
|
3758
|
+
const escapeMarkdownAlt = (alt) => alt.replace(/[\\[\]]/g, '\\$&');
|
|
3759
|
+
const escapeTextNodes = (html) => {
|
|
3760
|
+
let codeDepth = 0;
|
|
3761
|
+
return html.replace(/(<[^>]*>)|([^<]+)/g, (_, tag, text) => {
|
|
3762
|
+
if (tag) {
|
|
3763
|
+
const code = /^<(\/?)(?:pre|code)\b/i.exec(tag);
|
|
3764
|
+
if (code)
|
|
3765
|
+
codeDepth = Math.max(0, codeDepth + (code[1] ? -1 : 1));
|
|
3766
|
+
return tag;
|
|
3767
|
+
}
|
|
3768
|
+
return codeDepth > 0 ? (text ?? '') : escapeMarkdownText(text ?? '');
|
|
3769
|
+
});
|
|
3770
|
+
};
|
|
3771
|
+
const escapeLineStarts = (md) => md
|
|
3772
|
+
.replace(/^([ \t]*(?:>[ \t]?)*)\u{E002}(?:([-+*])(?=[ \t]|$|--[ \t]*$)|(#{1,6})(?=[ \t]|$)|([>|])|(\d+)\.(?=[ \t]|$)|(?=[-:| \t]*\|[-:| \t]*$)(?=.*-))/gmu, (_, prefix, bullet, hashes, marker, digits) => digits !== undefined ? `${prefix}${digits}\\.` : `${prefix}\\${bullet ?? hashes ?? marker ?? ''}`)
|
|
3773
|
+
.replace(/\u{E002}/gu, '');
|
|
3740
3774
|
/**
|
|
3741
3775
|
* Converts a markdown string to HTML.
|
|
3742
3776
|
* Covers headings, bold, italic, strikethrough, inline code, fenced code blocks,
|
|
3743
3777
|
* links, images, block quotes, unordered/ordered (and nested) lists, tables, horizontal rules, and paragraphs.
|
|
3778
|
+
* A backslash before a punctuation character keeps that character literal.
|
|
3779
|
+
* Text matching `options.verbatim` is emitted as plain text, untouched by any Markdown syntax:
|
|
3780
|
+
* `markdownToHtml('{{field:__x__}}', { verbatim: /\{\{[^}]+\}\}/ })` returns `<p>{{field:__x__}}</p>`.
|
|
3744
3781
|
*/
|
|
3745
|
-
const markdownToHtml = (markdown) => {
|
|
3782
|
+
const markdownToHtml = (markdown, options = {}) => {
|
|
3746
3783
|
if (!markdown)
|
|
3747
3784
|
return '';
|
|
3748
3785
|
let text = markdown.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
3786
|
+
const verbatims = [];
|
|
3787
|
+
const { verbatim } = options;
|
|
3788
|
+
if (verbatim) {
|
|
3789
|
+
const pattern = new RegExp(verbatim.source, verbatim.flags.includes('g') ? verbatim.flags : `${verbatim.flags}g`);
|
|
3790
|
+
text = text.replace(pattern, (match) => match ? makePlaceholder('VERB', verbatims.push(escapeHtmlPreservingEntities(match)) - 1) : match);
|
|
3791
|
+
}
|
|
3749
3792
|
// Extract fenced code blocks before any other processing
|
|
3750
3793
|
const codeBlocks = [];
|
|
3751
3794
|
text = text.replace(/```(\w*)\n([\s\S]*?)```/g, (_, lang, code) => {
|
|
@@ -3822,17 +3865,23 @@ const markdownToHtml = (markdown) => {
|
|
|
3822
3865
|
})
|
|
3823
3866
|
.filter(Boolean)
|
|
3824
3867
|
.join('\n');
|
|
3825
|
-
return html
|
|
3868
|
+
return html
|
|
3869
|
+
.replace(placeholderRe('CODE'), (_, i) => codeBlocks[+i] ?? '')
|
|
3870
|
+
.replace(placeholderRe('VERB'), (match, i) => verbatims[+i] ?? match);
|
|
3826
3871
|
};
|
|
3827
3872
|
/**
|
|
3828
3873
|
* Converts an HTML string to markdown.
|
|
3829
3874
|
* Covers headings, bold, italic, strikethrough, inline code, fenced code blocks,
|
|
3830
3875
|
* links, images, block quotes, unordered/ordered lists, tables, horizontal rules, and paragraphs.
|
|
3876
|
+
* Text that would read as Markdown is backslash-escaped (code and {@link MARKDOWN_VERBATIM_ATTR}
|
|
3877
|
+
* elements are left as is), and a link whose URL
|
|
3878
|
+
* fails {@link isSafeLinkUrl} keeps only its text.
|
|
3831
3879
|
*/
|
|
3832
3880
|
const htmlToMarkdown = (html) => {
|
|
3833
3881
|
if (!html)
|
|
3834
3882
|
return '';
|
|
3835
|
-
|
|
3883
|
+
const verbatims = [];
|
|
3884
|
+
let md = html.replace(VERBATIM_RE, (_, text) => makePlaceholder('VERB', verbatims.push(unescapeHtml(text)) - 1));
|
|
3836
3885
|
// Aligned blocks: text-align has no Markdown form, so preserve them as HTML (their inner markup
|
|
3837
3886
|
// stays HTML) and round-trip via a placeholder - extracted before the block passes below rewrite
|
|
3838
3887
|
// them, restored after the final tag-strip.
|
|
@@ -3841,6 +3890,7 @@ const htmlToMarkdown = (html) => {
|
|
|
3841
3890
|
const name = tag.toLowerCase();
|
|
3842
3891
|
return makePlaceholder('ALIGN', alignedBlocks.push(`<${name}${alignClass(alignOf(attrs))}>${inner}</${name}>`) - 1);
|
|
3843
3892
|
});
|
|
3893
|
+
md = escapeTextNodes(md);
|
|
3844
3894
|
// Code blocks - process before inline code
|
|
3845
3895
|
md = md.replace(/<pre[^>]*><code[^>]*class="language-([^"]+)"[^>]*>([\s\S]*?)<\/code><\/pre>/gi, (_, lang, code) => `\n\`\`\`${lang}\n${unescapeHtml(code.trim())}\n\`\`\`\n`);
|
|
3846
3896
|
md = md.replace(/<pre[^>]*><code[^>]*>([\s\S]*?)<\/code><\/pre>/gi, (_, code) => `\n\`\`\`\n${unescapeHtml(code.trim())}\n\`\`\`\n`);
|
|
@@ -3865,14 +3915,16 @@ const htmlToMarkdown = (html) => {
|
|
|
3865
3915
|
const newTabLinks = [];
|
|
3866
3916
|
md = md.replace(/<a\b([^>]*)>([\s\S]*?)<\/a>/gi, (_, attrs, inner) => {
|
|
3867
3917
|
const href = /\bhref\s*=\s*"([^"]*)"/i.exec(attrs)?.[1] ?? '';
|
|
3918
|
+
if (!isSafeLinkUrl(href))
|
|
3919
|
+
return inner;
|
|
3868
3920
|
if (/\btarget\s*=\s*"_blank"/i.test(attrs) && href) {
|
|
3869
3921
|
const anchor = `<a href="${href}" target="_blank" rel="noopener noreferrer">${inner}</a>`;
|
|
3870
3922
|
return makePlaceholder('NTLINK', newTabLinks.push(anchor) - 1);
|
|
3871
3923
|
}
|
|
3872
3924
|
return href ? `[${inner}](${href})` : inner;
|
|
3873
3925
|
});
|
|
3874
|
-
md = md.replace(/<img[^>]+src="([^"]*)"[^>]*alt="([^"]*)"[^>]*\/?>/gi,
|
|
3875
|
-
md = md.replace(/<img[^>]+alt="([^"]*)"[^>]*src="([^"]*)"[^>]*\/?>/gi,
|
|
3926
|
+
md = md.replace(/<img[^>]+src="([^"]*)"[^>]*alt="([^"]*)"[^>]*\/?>/gi, (_, src, alt) => ``);
|
|
3927
|
+
md = md.replace(/<img[^>]+alt="([^"]*)"[^>]*src="([^"]*)"[^>]*\/?>/gi, (_, alt, src) => ``);
|
|
3876
3928
|
md = md.replace(/<img[^>]+src="([^"]*)"[^>]*\/?>/gi, '');
|
|
3877
3929
|
// Underline has no Markdown form - preserve it as raw <u> so it round-trips. Extract it now (its
|
|
3878
3930
|
// inner markup is already converted above) so the block passes below don't strip the tag; the
|
|
@@ -3926,7 +3978,7 @@ const htmlToMarkdown = (html) => {
|
|
|
3926
3978
|
// aligned blocks are block-level, so pad with blank lines before collapsing so they survive as
|
|
3927
3979
|
// their own Markdown block
|
|
3928
3980
|
md = md.replace(placeholderRe('ALIGN'), (_, i) => `\n\n${alignedBlocks[+i] ?? ''}\n\n`);
|
|
3929
|
-
return md.replace(/\n{3,}/g, '\n\n').trim();
|
|
3981
|
+
return escapeLineStarts(md.replace(/\n{3,}/g, '\n\n').trim()).replace(placeholderRe('VERB'), (_, i) => verbatims[+i] ?? '');
|
|
3930
3982
|
};
|
|
3931
3983
|
|
|
3932
3984
|
const clamp = (value, min = 0, max = 100) => {
|
|
@@ -4197,8 +4249,15 @@ const suppressTextSelection = (doc) => {
|
|
|
4197
4249
|
existing.count++;
|
|
4198
4250
|
}
|
|
4199
4251
|
else {
|
|
4200
|
-
|
|
4201
|
-
doc
|
|
4252
|
+
const style = doc.documentElement.style;
|
|
4253
|
+
suppressions.set(doc, {
|
|
4254
|
+
count: 1,
|
|
4255
|
+
previousUserSelect: style.userSelect,
|
|
4256
|
+
previousWebkitUserSelect: style.webkitUserSelect,
|
|
4257
|
+
});
|
|
4258
|
+
style.userSelect = 'none';
|
|
4259
|
+
// Safari and WebKitGTK ignore the unprefixed `user-select`.
|
|
4260
|
+
style.webkitUserSelect = 'none';
|
|
4202
4261
|
}
|
|
4203
4262
|
let released = false;
|
|
4204
4263
|
return () => {
|
|
@@ -4210,7 +4269,8 @@ const suppressTextSelection = (doc) => {
|
|
|
4210
4269
|
if (state.count > 0)
|
|
4211
4270
|
return;
|
|
4212
4271
|
suppressions.delete(doc);
|
|
4213
|
-
doc.documentElement.style.userSelect = state.
|
|
4272
|
+
doc.documentElement.style.userSelect = state.previousUserSelect;
|
|
4273
|
+
doc.documentElement.style.webkitUserSelect = state.previousWebkitUserSelect;
|
|
4214
4274
|
};
|
|
4215
4275
|
};
|
|
4216
4276
|
|
|
@@ -4610,25 +4670,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
|
|
|
4610
4670
|
}]
|
|
4611
4671
|
}], ctorParameters: () => [] });
|
|
4612
4672
|
|
|
4673
|
+
/** Runs `cb` two frames from now. Returns a function that cancels it if it has not run yet. */
|
|
4613
4674
|
const nextFrame = (cb) => {
|
|
4614
4675
|
if (typeof requestAnimationFrame === 'undefined') {
|
|
4615
|
-
return;
|
|
4676
|
+
return () => undefined;
|
|
4616
4677
|
}
|
|
4617
|
-
requestAnimationFrame(() => {
|
|
4618
|
-
requestAnimationFrame(cb);
|
|
4678
|
+
let id = requestAnimationFrame(() => {
|
|
4679
|
+
id = requestAnimationFrame(cb);
|
|
4619
4680
|
});
|
|
4681
|
+
return () => cancelAnimationFrame(id);
|
|
4620
4682
|
};
|
|
4621
4683
|
const fromNextFrame = () => {
|
|
4622
|
-
return new Observable((observer) => {
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
});
|
|
4627
|
-
});
|
|
4684
|
+
return new Observable((observer) => nextFrame(() => {
|
|
4685
|
+
observer.next();
|
|
4686
|
+
observer.complete();
|
|
4687
|
+
}));
|
|
4628
4688
|
};
|
|
4629
4689
|
const forceReflow = (element) => {
|
|
4630
|
-
// The `document.body` fallback is resolved lazily and guarded: there is nothing to reflow on the
|
|
4631
|
-
// server, so this becomes a no-op instead of throwing on a missing `document`.
|
|
4632
4690
|
const el = element ?? (typeof document === 'undefined' ? null : document.body);
|
|
4633
4691
|
return el?.offsetHeight ?? 0;
|
|
4634
4692
|
};
|
|
@@ -5030,14 +5088,16 @@ const createFlipAnimationGroup = (config) => {
|
|
|
5030
5088
|
}
|
|
5031
5089
|
};
|
|
5032
5090
|
flips.forEach((animation) => {
|
|
5033
|
-
animation.onStart
|
|
5091
|
+
animation.onStart$
|
|
5092
|
+
.pipe(tap(() => {
|
|
5034
5093
|
startedCount++;
|
|
5035
5094
|
if (startedCount === flips.length) {
|
|
5036
5095
|
onStart$.next();
|
|
5037
5096
|
}
|
|
5038
|
-
})
|
|
5039
|
-
|
|
5040
|
-
animation.
|
|
5097
|
+
}))
|
|
5098
|
+
.subscribe();
|
|
5099
|
+
animation.onFinish$.pipe(tap(() => settle(false))).subscribe();
|
|
5100
|
+
animation.onCancel$.pipe(tap(() => settle(true))).subscribe();
|
|
5041
5101
|
});
|
|
5042
5102
|
const updateInit = () => {
|
|
5043
5103
|
flips.forEach((animation) => animation.updateInit());
|
|
@@ -5155,7 +5215,7 @@ const UNSAVED_CHANGES_COORDINATOR_DEF = /* @__PURE__ */ defineRootProvider(() =>
|
|
|
5155
5215
|
const hasUnsavedChanges = computed(() => _registrations().some((registration) => registration.hasChanges()), /* @ts-ignore */
|
|
5156
5216
|
...(ngDevMode ? [{ debugName: "hasUnsavedChanges" }] : /* istanbul ignore next */ []));
|
|
5157
5217
|
let pending = null;
|
|
5158
|
-
/**
|
|
5218
|
+
/** Runs a tracker's confirm under the single-flight + abandon regime. */
|
|
5159
5219
|
const runCheck = (runner) => {
|
|
5160
5220
|
// A confirm is already on screen - adopt its answer rather than opening a second dialog.
|
|
5161
5221
|
if (pending) {
|
|
@@ -5183,7 +5243,6 @@ const UNSAVED_CHANGES_COORDINATOR_DEF = /* @__PURE__ */ defineRootProvider(() =>
|
|
|
5183
5243
|
_isCheckPending.set(true);
|
|
5184
5244
|
return promise;
|
|
5185
5245
|
};
|
|
5186
|
-
/** @internal */
|
|
5187
5246
|
const register = (registration) => {
|
|
5188
5247
|
_registrations.update((current) => [...current, registration]);
|
|
5189
5248
|
return () => _registrations.update((current) => current.filter((entry) => entry !== registration));
|
|
@@ -5670,6 +5729,9 @@ const LINK_STORE_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
5670
5729
|
}, { name: 'Link Store' });
|
|
5671
5730
|
const provideLinkStore = /* @__PURE__ */ toProvideFn(LINK_STORE_DEF);
|
|
5672
5731
|
const injectLinkStore = /* @__PURE__ */ toInjectFn(LINK_STORE_DEF);
|
|
5732
|
+
/**
|
|
5733
|
+
* Binds a link tag. Only removes the elements it created; pre-existing links are left in place, unlike meta bindings.
|
|
5734
|
+
*/
|
|
5673
5735
|
const applyLinkBinding = (binding) => {
|
|
5674
5736
|
const linkStore = injectLinkStore();
|
|
5675
5737
|
const linkId = Symbol('link-tag');
|
|
@@ -5814,7 +5876,6 @@ const applyHeadTitleMarker = (binding) => {
|
|
|
5814
5876
|
};
|
|
5815
5877
|
|
|
5816
5878
|
const DEFAULT_MULTI_INSTANCE_TAGS = /* @__PURE__ */ new Set([
|
|
5817
|
-
// Open Graph - Media
|
|
5818
5879
|
'property="og:image"',
|
|
5819
5880
|
'property="og:image:url"',
|
|
5820
5881
|
'property="og:image:secure_url"',
|
|
@@ -5824,32 +5885,23 @@ const DEFAULT_MULTI_INSTANCE_TAGS = /* @__PURE__ */ new Set([
|
|
|
5824
5885
|
'property="og:audio"',
|
|
5825
5886
|
'property="og:audio:url"',
|
|
5826
5887
|
'property="og:audio:secure_url"',
|
|
5827
|
-
// Open Graph - Locale alternatives
|
|
5828
5888
|
'property="og:locale:alternate"',
|
|
5829
|
-
// Twitter Card
|
|
5830
5889
|
'name="twitter:image"',
|
|
5831
5890
|
'name="twitter:player"',
|
|
5832
|
-
// Article tags (arrays)
|
|
5833
5891
|
'property="article:author"',
|
|
5834
5892
|
'property="article:tag"',
|
|
5835
|
-
// Music tags (arrays)
|
|
5836
5893
|
'property="music:song"',
|
|
5837
5894
|
'property="music:musician"',
|
|
5838
5895
|
'property="music:album"',
|
|
5839
|
-
// Video tags (arrays)
|
|
5840
5896
|
'property="video:actor"',
|
|
5841
5897
|
'property="video:director"',
|
|
5842
5898
|
'property="video:writer"',
|
|
5843
5899
|
'property="video:tag"',
|
|
5844
|
-
// Book tags (arrays)
|
|
5845
5900
|
'property="book:author"',
|
|
5846
5901
|
'property="book:tag"',
|
|
5847
|
-
// Profile (arrays)
|
|
5848
5902
|
'property="profile:username"',
|
|
5849
|
-
// Product tags (arrays)
|
|
5850
5903
|
'property="product:category"',
|
|
5851
5904
|
'property="product:retailer_item_id"',
|
|
5852
|
-
// App Links (multiple platforms)
|
|
5853
5905
|
'property="al:ios:url"',
|
|
5854
5906
|
'property="al:ios:app_store_id"',
|
|
5855
5907
|
'property="al:ios:app_name"',
|
|
@@ -5866,16 +5918,12 @@ const DEFAULT_MULTI_INSTANCE_TAGS = /* @__PURE__ */ new Set([
|
|
|
5866
5918
|
'property="al:windows_universal:url"',
|
|
5867
5919
|
'property="al:windows_universal:app_id"',
|
|
5868
5920
|
'property="al:windows_universal:app_name"',
|
|
5869
|
-
// Dublin Core (can have multiple)
|
|
5870
5921
|
'name="DC.creator"',
|
|
5871
5922
|
'name="DC.contributor"',
|
|
5872
5923
|
'name="DC.subject"',
|
|
5873
|
-
// Schema.org (via meta tags - though JSON-LD is preferred)
|
|
5874
5924
|
'itemprop="image"',
|
|
5875
5925
|
'itemprop="author"',
|
|
5876
|
-
// Apple iOS
|
|
5877
5926
|
'name="apple-itunes-app"', // Can have multiple app arguments
|
|
5878
|
-
// Verification tags (multiple services)
|
|
5879
5927
|
'name="google-site-verification"',
|
|
5880
5928
|
'name="msvalidate.01"',
|
|
5881
5929
|
'name="yandex-verification"',
|
|
@@ -6004,6 +6052,9 @@ const META_STORE_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
6004
6052
|
}, { name: 'Meta Store' });
|
|
6005
6053
|
const provideMetaStore = /* @__PURE__ */ toProvideFn(META_STORE_DEF);
|
|
6006
6054
|
const injectMetaStore = /* @__PURE__ */ toInjectFn(META_STORE_DEF);
|
|
6055
|
+
/**
|
|
6056
|
+
* Binds a meta tag. Removes any pre-existing tags matching the same selector, unlike link bindings, which leave pre-existing links alone.
|
|
6057
|
+
*/
|
|
6007
6058
|
const applyMetaBinding = (binding) => {
|
|
6008
6059
|
const metaStore = injectMetaStore();
|
|
6009
6060
|
const tagId = Symbol('meta-tag');
|
|
@@ -6199,7 +6250,7 @@ const STRUCTURED_DATA_STORE_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
6199
6250
|
renderer.setAttributes(script, { type: 'application/ld+json' });
|
|
6200
6251
|
if (nonce)
|
|
6201
6252
|
renderer.setAttribute(script, 'nonce', nonce);
|
|
6202
|
-
renderer.setTextContent(script, JSON.stringify(data));
|
|
6253
|
+
renderer.setTextContent(script, JSON.stringify(data).replace(/</g, '\\u003C'));
|
|
6203
6254
|
const target = getTargetElement();
|
|
6204
6255
|
renderer.appendChild(target, script);
|
|
6205
6256
|
newScripts.set(id, script);
|
|
@@ -6550,6 +6601,26 @@ const createUnsavedChangesGuard = (config) => {
|
|
|
6550
6601
|
};
|
|
6551
6602
|
|
|
6552
6603
|
const isCrossOrigin = (source) => /^(https?:)?\/\//.test(source);
|
|
6604
|
+
const HTML_COMMENT = /<!--[\s\S]*?-->/g;
|
|
6605
|
+
const SCRIPT_SRC = /<script\b[^>]*?\ssrc\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+))/gi;
|
|
6606
|
+
const CHARACTER_REFERENCE = /&(?:#(\d+)|#[xX]([\da-fA-F]+)|(amp|quot|apos|lt|gt));/g;
|
|
6607
|
+
const NAMED_REFERENCES = { amp: '&', quot: '"', apos: "'", lt: '<', gt: '>' };
|
|
6608
|
+
const decodeCharacterReferences = (value) => value.replace(CHARACTER_REFERENCE, (_match, decimal, hex, name) => decimal
|
|
6609
|
+
? String.fromCodePoint(Number(decimal))
|
|
6610
|
+
: hex
|
|
6611
|
+
? String.fromCodePoint(parseInt(hex, 16))
|
|
6612
|
+
: (NAMED_REFERENCES[name ?? ''] ?? ''));
|
|
6613
|
+
const toFingerprint = (sources) => sources
|
|
6614
|
+
.filter((source) => !!source && !isCrossOrigin(source))
|
|
6615
|
+
.sort()
|
|
6616
|
+
.join('|');
|
|
6617
|
+
/**
|
|
6618
|
+
* Must decode what `getAttribute('src')` decodes, or every check reports an update.
|
|
6619
|
+
*
|
|
6620
|
+
* Not `DOMParser`: its document inherits the page's CSP, and under a nonce `style-src` each `<style>`
|
|
6621
|
+
* in the fetched document, with its fresh nonce, logs a violation.
|
|
6622
|
+
*/
|
|
6623
|
+
const readBuildFingerprintFromHtml = (html) => toFingerprint(Array.from(html.replace(HTML_COMMENT, '').matchAll(SCRIPT_SRC), ([, doubleQuoted, singleQuoted, unquoted]) => decodeCharacterReferences(doubleQuoted ?? singleQuoted ?? unquoted ?? '')));
|
|
6553
6624
|
/**
|
|
6554
6625
|
* Identifies the build a document boots from, by its entry script filenames. Those carry a content
|
|
6555
6626
|
* hash in any production build, so two documents share a fingerprint exactly when reloading one would
|
|
@@ -6559,32 +6630,17 @@ const isCrossOrigin = (source) => /^(https?:)?\/\//.test(source);
|
|
|
6559
6630
|
* Cross-origin scripts are left out: an analytics tag with a cache-busting query would otherwise read
|
|
6560
6631
|
* as a new deploy on every check.
|
|
6561
6632
|
*/
|
|
6562
|
-
const readBuildFingerprint = (document) => Array.from(document.querySelectorAll('script[src]'))
|
|
6563
|
-
.map((script) => script.getAttribute('src') ?? '')
|
|
6564
|
-
.filter((source) => !!source && !isCrossOrigin(source))
|
|
6565
|
-
.sort()
|
|
6566
|
-
.join('|');
|
|
6633
|
+
const readBuildFingerprint = (document) => toFingerprint(Array.from(document.querySelectorAll('script[src]'), (script) => script.getAttribute('src') ?? ''));
|
|
6567
6634
|
/**
|
|
6568
|
-
* Reads the currently deployed build's fingerprint from the app's entry document.
|
|
6635
|
+
* Reads the currently deployed build's fingerprint from the app's entry document. Cold: nothing is fetched
|
|
6636
|
+
* until it is subscribed.
|
|
6569
6637
|
*
|
|
6570
6638
|
* `null` for anything that is not a usable answer - a network failure, a non-2xx response, or a body
|
|
6571
6639
|
* with no entry scripts in it. Callers must treat that as "no information" rather than as a change:
|
|
6572
6640
|
* an error page parses perfectly well as HTML, and acting on its empty fingerprint would reload the
|
|
6573
6641
|
* app in a loop.
|
|
6574
6642
|
*/
|
|
6575
|
-
const fetchDeployedBuildFingerprint =
|
|
6576
|
-
try {
|
|
6577
|
-
const response = await fetch(url, { cache: 'no-store', headers: { accept: 'text/html' } });
|
|
6578
|
-
if (!response.ok) {
|
|
6579
|
-
return null;
|
|
6580
|
-
}
|
|
6581
|
-
const parsed = new DOMParser().parseFromString(await response.text(), 'text/html');
|
|
6582
|
-
return readBuildFingerprint(parsed) || null;
|
|
6583
|
-
}
|
|
6584
|
-
catch {
|
|
6585
|
-
return null;
|
|
6586
|
-
}
|
|
6587
|
-
};
|
|
6643
|
+
const fetchDeployedBuildFingerprint$ = (url) => defer(() => fetch(url, { cache: 'no-store', headers: { accept: 'text/html' } })).pipe(switchMap((response) => (response.ok ? response.text() : of(null))), map((html) => (html === null ? null : readBuildFingerprintFromHtml(html) || null)), catchError(() => of(null)));
|
|
6588
6644
|
|
|
6589
6645
|
/**
|
|
6590
6646
|
* How each engine words a lazy chunk that could not be loaded. There is no error code and no shared
|
|
@@ -6668,19 +6724,15 @@ const APP_UPDATES_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
6668
6724
|
}, /* @ts-ignore */
|
|
6669
6725
|
...(ngDevMode ? [{ debugName: "isAvailable" }] : /* istanbul ignore next */ []));
|
|
6670
6726
|
let lastCheckAt = 0;
|
|
6671
|
-
const check =
|
|
6727
|
+
const check$ = () => defer(() => {
|
|
6672
6728
|
lastCheckAt = Date.now();
|
|
6673
|
-
|
|
6729
|
+
return fetchDeployedBuildFingerprint$(config.entryUrl);
|
|
6730
|
+
}).pipe(tap((deployed) => {
|
|
6674
6731
|
if (deployed) {
|
|
6675
6732
|
_deployedBuild.set(deployed);
|
|
6676
6733
|
}
|
|
6677
|
-
};
|
|
6678
|
-
const checkIfDue =
|
|
6679
|
-
if (Date.now() - lastCheckAt < config.minCheckInterval) {
|
|
6680
|
-
return;
|
|
6681
|
-
}
|
|
6682
|
-
await check();
|
|
6683
|
-
};
|
|
6734
|
+
}), map(() => undefined));
|
|
6735
|
+
const checkIfDue$ = () => defer(() => (Date.now() - lastCheckAt < config.minCheckInterval ? EMPTY : check$()));
|
|
6684
6736
|
const reload = () => {
|
|
6685
6737
|
// The reload is deliberate and the user has already answered for it, so release every
|
|
6686
6738
|
// beforeunload lock rather than have the browser ask the same question again.
|
|
@@ -6728,7 +6780,7 @@ const APP_UPDATES_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
6728
6780
|
if (config.pollInterval > 0) {
|
|
6729
6781
|
const isDocumentVisible = injectIsDocumentVisible();
|
|
6730
6782
|
toObservable(isDocumentVisible)
|
|
6731
|
-
.pipe(switchMap((isVisible) => (isVisible ? timer(0, config.pollInterval) : EMPTY)), switchMap(() =>
|
|
6783
|
+
.pipe(switchMap((isVisible) => (isVisible ? timer(0, config.pollInterval) : EMPTY)), switchMap(() => checkIfDue$()), takeUntilDestroyed(destroyRef))
|
|
6732
6784
|
.subscribe();
|
|
6733
6785
|
}
|
|
6734
6786
|
}
|
|
@@ -6736,7 +6788,7 @@ const APP_UPDATES_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
6736
6788
|
isAvailable,
|
|
6737
6789
|
isRequired: _isRequired.asReadonly(),
|
|
6738
6790
|
wouldDiscardChanges: coordinator.hasUnsavedChanges,
|
|
6739
|
-
check
|
|
6791
|
+
check$,
|
|
6740
6792
|
reload,
|
|
6741
6793
|
};
|
|
6742
6794
|
}, { name: 'App Updates' });
|
|
@@ -6931,12 +6983,10 @@ class ScrollObserverDirective {
|
|
|
6931
6983
|
this.isAtEnd = computed(() => this._endIntersection()[0]?.isIntersecting ?? false, /* @ts-ignore */
|
|
6932
6984
|
...(ngDevMode ? [{ debugName: "isAtEnd" }] : /* istanbul ignore next */ []));
|
|
6933
6985
|
}
|
|
6934
|
-
/** @internal */
|
|
6935
6986
|
registerStart(el) {
|
|
6936
6987
|
this._startEl.set(el);
|
|
6937
6988
|
return () => this._startEl.update((current) => (current === el ? null : current));
|
|
6938
6989
|
}
|
|
6939
|
-
/** @internal */
|
|
6940
6990
|
registerEnd(el) {
|
|
6941
6991
|
this._endEl.set(el);
|
|
6942
6992
|
return () => this._endEl.update((current) => (current === el ? null : current));
|
|
@@ -7229,6 +7279,7 @@ const NOTIFICATIONS_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
7229
7279
|
}).pipe(tap((state) => permission.set(state)));
|
|
7230
7280
|
let nextTagId = 0;
|
|
7231
7281
|
const clickHandlers = new Map();
|
|
7282
|
+
const confirmedTags = new Set();
|
|
7232
7283
|
const openCloseFns = new Set();
|
|
7233
7284
|
let isClickRelayAttached = false;
|
|
7234
7285
|
const attachClickRelay = () => {
|
|
@@ -7250,6 +7301,18 @@ const NOTIFICATIONS_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
7250
7301
|
? // Firefox rejects getNotifications() when the worker is not the one that showed them.
|
|
7251
7302
|
from(registration.getNotifications(tag ? { tag } : undefined)).pipe(catchError(() => of([])))
|
|
7252
7303
|
: of([])), tap((notifications) => notifications.forEach((notification) => notification.close())));
|
|
7304
|
+
const pruneDismissedHandlers = (registration) => from(registration.getNotifications()).pipe(catchError(() => of(null)), map((shown) => {
|
|
7305
|
+
if (!shown) {
|
|
7306
|
+
return;
|
|
7307
|
+
}
|
|
7308
|
+
const shownTags = new Set(shown.map((notification) => notification.tag));
|
|
7309
|
+
for (const tag of confirmedTags) {
|
|
7310
|
+
if (!shownTags.has(tag)) {
|
|
7311
|
+
confirmedTags.delete(tag);
|
|
7312
|
+
clickHandlers.delete(tag);
|
|
7313
|
+
}
|
|
7314
|
+
}
|
|
7315
|
+
}));
|
|
7253
7316
|
const show = (config) => {
|
|
7254
7317
|
const tag = config.tag ?? `et-notification-${++nextTagId}`;
|
|
7255
7318
|
const options = toNotificationOptions(config, tag);
|
|
@@ -7268,6 +7331,7 @@ const NOTIFICATIONS_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
7268
7331
|
closed$.next();
|
|
7269
7332
|
closed$.complete();
|
|
7270
7333
|
clickHandlers.delete(tag);
|
|
7334
|
+
confirmedTags.delete(tag);
|
|
7271
7335
|
openCloseFns.delete(close);
|
|
7272
7336
|
pageNotification?.close();
|
|
7273
7337
|
// A no-op unless this notification took the persistent path.
|
|
@@ -7301,16 +7365,27 @@ const NOTIFICATIONS_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
7301
7365
|
if (!registration || isClosed) {
|
|
7302
7366
|
return of('unavailable');
|
|
7303
7367
|
}
|
|
7304
|
-
|
|
7305
|
-
|
|
7306
|
-
|
|
7307
|
-
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7368
|
+
return pruneDismissedHandlers(registration).pipe(switchMap(() => {
|
|
7369
|
+
if (isClosed) {
|
|
7370
|
+
return of('unavailable');
|
|
7371
|
+
}
|
|
7372
|
+
if (config.onClick) {
|
|
7373
|
+
clickHandlers.set(tag, config.onClick);
|
|
7374
|
+
attachClickRelay();
|
|
7375
|
+
}
|
|
7376
|
+
return from(registration.showNotification(config.title, options)).pipe(switchMap(() => {
|
|
7377
|
+
if (isClosed) {
|
|
7378
|
+
// Closed while the worker was still putting it up - take back what just appeared.
|
|
7379
|
+
return closePersistentNotifications(tag).pipe(map(() => 'unavailable'));
|
|
7380
|
+
}
|
|
7381
|
+
if (config.onClick) {
|
|
7382
|
+
confirmedTags.add(tag);
|
|
7383
|
+
}
|
|
7384
|
+
return of('service-worker');
|
|
7385
|
+
}), catchError(() => {
|
|
7386
|
+
clickHandlers.delete(tag);
|
|
7387
|
+
return of('unavailable');
|
|
7388
|
+
}));
|
|
7314
7389
|
}));
|
|
7315
7390
|
}));
|
|
7316
7391
|
const shown$ = defer(() => {
|
|
@@ -7556,8 +7631,6 @@ const overlayViewportInsetsFor = (element) => overlayViewportInsets(resolveOverl
|
|
|
7556
7631
|
/**
|
|
7557
7632
|
* Runs `listener` whenever a reservation is made or released, so an already positioned overlay can be
|
|
7558
7633
|
* laid out again. Returns the unsubscribe callback.
|
|
7559
|
-
*
|
|
7560
|
-
* @internal
|
|
7561
7634
|
*/
|
|
7562
7635
|
const onOverlayViewportInsetsChange = (listener) => {
|
|
7563
7636
|
listeners.add(listener);
|
|
@@ -7566,10 +7639,6 @@ const onOverlayViewportInsetsChange = (listener) => {
|
|
|
7566
7639
|
};
|
|
7567
7640
|
};
|
|
7568
7641
|
|
|
7569
|
-
/**
|
|
7570
|
-
* Shrinks the host box to the part of the viewport nothing above this overlay has reserved, so a
|
|
7571
|
-
* centered or globally placed pane is laid out inside it instead of under a docked panel.
|
|
7572
|
-
*/
|
|
7573
7642
|
const applyViewportInsets = (hostElement, renderer) => {
|
|
7574
7643
|
const insets = overlayViewportInsetsFor(hostElement);
|
|
7575
7644
|
renderer.setStyle(hostElement, {
|
|
@@ -7667,8 +7736,6 @@ let anchoredPositionSetup = null;
|
|
|
7667
7736
|
* Installs the anchored positioning implementation. Called by `anchoredOverlayPosition()`, which is
|
|
7668
7737
|
* the only thing that pulls `@floating-ui/dom` into the bundle - apps that never anchor an overlay
|
|
7669
7738
|
* do not ship it.
|
|
7670
|
-
*
|
|
7671
|
-
* @internal
|
|
7672
7739
|
*/
|
|
7673
7740
|
const registerAnchoredPositionSetup = (setup) => {
|
|
7674
7741
|
anchoredPositionSetup = setup;
|
|
@@ -7700,8 +7767,6 @@ let middlewareExtras = null;
|
|
|
7700
7767
|
/**
|
|
7701
7768
|
* Installs the `size` / `arrow` / `hide` middleware. Called by
|
|
7702
7769
|
* `enableAnchoredOverlayPositionExtras()`.
|
|
7703
|
-
*
|
|
7704
|
-
* @internal
|
|
7705
7770
|
*/
|
|
7706
7771
|
const registerAnchoredPositionMiddlewareExtras = (extras) => {
|
|
7707
7772
|
middlewareExtras = extras;
|
|
@@ -7773,10 +7838,6 @@ const toSideObject = (padding) => typeof padding === 'number'
|
|
|
7773
7838
|
bottom: padding.bottom ?? 0,
|
|
7774
7839
|
left: padding.left ?? 0,
|
|
7775
7840
|
};
|
|
7776
|
-
/**
|
|
7777
|
-
* The strategy's own viewport padding plus the space reserved on each edge. Every middleware that
|
|
7778
|
-
* measures overflow gets it, so an edge a docked panel covers is as unavailable as the viewport edge.
|
|
7779
|
-
*/
|
|
7780
7841
|
const paddingWithInsets = (padding, insets) => {
|
|
7781
7842
|
const own = toSideObject(padding);
|
|
7782
7843
|
return {
|
|
@@ -7786,6 +7847,43 @@ const paddingWithInsets = (padding, insets) => {
|
|
|
7786
7847
|
left: own.left + insets.left,
|
|
7787
7848
|
};
|
|
7788
7849
|
};
|
|
7850
|
+
/**
|
|
7851
|
+
* A platform whose first measurement of the pane, in each `computePosition` run, ignores the cap
|
|
7852
|
+
* `size` set in the previous run. `flip` reads that first measurement: against a capped pane, the side
|
|
7853
|
+
* the pane was squeezed onto always fits, so a pane whose content grows after it opened never flips
|
|
7854
|
+
* to the roomier side. Later measurements in the same run see the cap, and `size` resets with them,
|
|
7855
|
+
* so the final position is computed from the pane as it renders.
|
|
7856
|
+
*/
|
|
7857
|
+
const platformMeasuringUncappedPaneFirst = (paneElement, renderer) => {
|
|
7858
|
+
let measuredUncapped = false;
|
|
7859
|
+
return {
|
|
7860
|
+
...platform,
|
|
7861
|
+
getDimensions: (element) => {
|
|
7862
|
+
if (element !== paneElement || measuredUncapped)
|
|
7863
|
+
return platform.getDimensions(element);
|
|
7864
|
+
measuredUncapped = true;
|
|
7865
|
+
const maxWidth = paneElement.style.getPropertyValue('--et-overlay-max-width');
|
|
7866
|
+
const maxHeight = paneElement.style.getPropertyValue('--et-overlay-max-height');
|
|
7867
|
+
if (!maxWidth && !maxHeight)
|
|
7868
|
+
return platform.getDimensions(element);
|
|
7869
|
+
// The uncapped layout clamps the scroll offset of every scroller the cap made scrollable.
|
|
7870
|
+
const scrolled = [...paneElement.querySelectorAll('*')]
|
|
7871
|
+
.filter((el) => el.scrollTop || el.scrollLeft)
|
|
7872
|
+
.map((el) => ({ el, top: el.scrollTop, left: el.scrollLeft }));
|
|
7873
|
+
renderer.setCssProperties(paneElement, { '--et-overlay-max-width': null, '--et-overlay-max-height': null });
|
|
7874
|
+
const dimensions = platform.getDimensions(element);
|
|
7875
|
+
renderer.setCssProperties(paneElement, {
|
|
7876
|
+
'--et-overlay-max-width': maxWidth || null,
|
|
7877
|
+
'--et-overlay-max-height': maxHeight || null,
|
|
7878
|
+
});
|
|
7879
|
+
for (const { el, top, left } of scrolled) {
|
|
7880
|
+
el.scrollTop = top;
|
|
7881
|
+
el.scrollLeft = left;
|
|
7882
|
+
}
|
|
7883
|
+
return dimensions;
|
|
7884
|
+
},
|
|
7885
|
+
};
|
|
7886
|
+
};
|
|
7789
7887
|
const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, renderer) => {
|
|
7790
7888
|
// mirrorWidth needs a real element to measure; virtual references fall back to max-content
|
|
7791
7889
|
const mirrorWidthElement = strategy.mirrorWidth && isHTMLElement(strategy.referenceElement) ? strategy.referenceElement : null;
|
|
@@ -7898,6 +7996,9 @@ const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, render
|
|
|
7898
7996
|
placement: strategy.placement ?? 'bottom',
|
|
7899
7997
|
strategy: 'absolute',
|
|
7900
7998
|
middleware,
|
|
7999
|
+
platform: strategy.autoResize && strategy.minAvailableSpace === undefined
|
|
8000
|
+
? platformMeasuringUncappedPaneFirst(paneElement, renderer)
|
|
8001
|
+
: platform,
|
|
7901
8002
|
}).then(({ x, y, placement, middlewareData }) => {
|
|
7902
8003
|
if (destroyed || currentUpdateId !== updateId)
|
|
7903
8004
|
return;
|
|
@@ -7975,7 +8076,6 @@ const createOverlayRuntimeRef = (id, config, elements, requestClose) => {
|
|
|
7975
8076
|
elements,
|
|
7976
8077
|
state: _state.asReadonly(),
|
|
7977
8078
|
componentInstance: _componentInstance.asReadonly(),
|
|
7978
|
-
/** @internal */
|
|
7979
8079
|
beforeOpenedSubject,
|
|
7980
8080
|
close(result, source = 'api') {
|
|
7981
8081
|
if (_state() === 'closing' || _state() === 'closed') {
|
|
@@ -8016,11 +8116,9 @@ const createOverlayRuntimeRef = (id, config, elements, requestClose) => {
|
|
|
8016
8116
|
afterClosed() {
|
|
8017
8117
|
return afterClosedSubject.asObservable();
|
|
8018
8118
|
},
|
|
8019
|
-
/** @internal */
|
|
8020
8119
|
attachComponentRef(componentRef) {
|
|
8021
8120
|
_componentInstance.set(componentRef.instance);
|
|
8022
8121
|
},
|
|
8023
|
-
/** @internal */
|
|
8024
8122
|
attachPositionUpdater(updater) {
|
|
8025
8123
|
positionUpdater = updater;
|
|
8026
8124
|
},
|
|
@@ -8030,7 +8128,6 @@ const createOverlayRuntimeRef = (id, config, elements, requestClose) => {
|
|
|
8030
8128
|
}
|
|
8031
8129
|
positionUpdater?.(strategy);
|
|
8032
8130
|
},
|
|
8033
|
-
/** @internal */
|
|
8034
8131
|
attachBackdropUpdater(updater) {
|
|
8035
8132
|
backdropUpdater = updater;
|
|
8036
8133
|
},
|
|
@@ -8044,7 +8141,6 @@ const createOverlayRuntimeRef = (id, config, elements, requestClose) => {
|
|
|
8044
8141
|
}
|
|
8045
8142
|
backdropUpdater?.(hasBackdrop);
|
|
8046
8143
|
},
|
|
8047
|
-
/** @internal */
|
|
8048
8144
|
markOpened() {
|
|
8049
8145
|
if (_state() !== 'mounting') {
|
|
8050
8146
|
return;
|
|
@@ -8053,7 +8149,6 @@ const createOverlayRuntimeRef = (id, config, elements, requestClose) => {
|
|
|
8053
8149
|
afterOpenedSubject.next();
|
|
8054
8150
|
afterOpenedSubject.complete();
|
|
8055
8151
|
},
|
|
8056
|
-
/** @internal */
|
|
8057
8152
|
beginClose(closeEvent) {
|
|
8058
8153
|
if (_state() === 'closing' || _state() === 'closed') {
|
|
8059
8154
|
return false;
|
|
@@ -8063,7 +8158,6 @@ const createOverlayRuntimeRef = (id, config, elements, requestClose) => {
|
|
|
8063
8158
|
beforeClosedSubject.complete();
|
|
8064
8159
|
return true;
|
|
8065
8160
|
},
|
|
8066
|
-
/** @internal */
|
|
8067
8161
|
finishClose(closeEvent) {
|
|
8068
8162
|
if (_state() === 'closed') {
|
|
8069
8163
|
return;
|
|
@@ -8210,8 +8304,6 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
8210
8304
|
paneElement,
|
|
8211
8305
|
}, (result, source) => beginClose({ result, source }));
|
|
8212
8306
|
animationDebugLog(`runtime ${config.id}`, 'mount');
|
|
8213
|
-
// matches the previous overlay behavior: escape/outside-pointer closes are
|
|
8214
|
-
// ignored until the enter transition has started plus one frame
|
|
8215
8307
|
let interactiveCloseReady = false;
|
|
8216
8308
|
const cleanupFns = [];
|
|
8217
8309
|
const parentInjector = config.injector ?? config.viewContainerRef?.injector ?? environmentInjector;
|
|
@@ -8225,12 +8317,22 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
8225
8317
|
// `config.providers`.
|
|
8226
8318
|
providers: [{ provide: EnvironmentInjector, useValue: overlayEnvironmentInjector }],
|
|
8227
8319
|
});
|
|
8228
|
-
|
|
8229
|
-
|
|
8230
|
-
|
|
8231
|
-
|
|
8232
|
-
|
|
8233
|
-
|
|
8320
|
+
let componentRef;
|
|
8321
|
+
try {
|
|
8322
|
+
componentRef = createComponent(config.component, {
|
|
8323
|
+
environmentInjector: overlayEnvironmentInjector,
|
|
8324
|
+
elementInjector,
|
|
8325
|
+
hostElement: paneElement,
|
|
8326
|
+
bindings: config.bindings ?? [],
|
|
8327
|
+
});
|
|
8328
|
+
}
|
|
8329
|
+
catch (error) {
|
|
8330
|
+
elementInjector.destroy();
|
|
8331
|
+
overlayEnvironmentInjector.destroy();
|
|
8332
|
+
renderer.removeChild(root, hostElement);
|
|
8333
|
+
maybeDestroyRootElements(targetDocument);
|
|
8334
|
+
throw error;
|
|
8335
|
+
}
|
|
8234
8336
|
// pane classes are applied after component creation - Angular replaces the host
|
|
8235
8337
|
// element's class attribute with the component's static host class on creation
|
|
8236
8338
|
renderer.addClass(paneElement, 'et-overlay-runtime-pane', ...(config.paneClass ?? []));
|
|
@@ -8325,10 +8427,8 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
8325
8427
|
lifecycle.leave();
|
|
8326
8428
|
}
|
|
8327
8429
|
lifecycle.state$
|
|
8328
|
-
.pipe(filter((state) => state === 'left'), take(1))
|
|
8329
|
-
.subscribe(
|
|
8330
|
-
destroyMountedOverlay(closeEvent);
|
|
8331
|
-
});
|
|
8430
|
+
.pipe(filter((state) => state === 'left'), take(1), tap(() => destroyMountedOverlay(closeEvent)))
|
|
8431
|
+
.subscribe();
|
|
8332
8432
|
};
|
|
8333
8433
|
const closeOnEscape = config.closeOnEscape ?? true;
|
|
8334
8434
|
if (closeOnEscape) {
|
|
@@ -8396,12 +8496,12 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
8396
8496
|
}
|
|
8397
8497
|
animationDebugLog(`runtime ${config.id}`, `enter (delegate ${config.animationDelegate?.enter ? 'yes' : 'no'}, lifecycle state "${lifecycle.state$.value}")`);
|
|
8398
8498
|
const readySubscription = lifecycle.state$
|
|
8399
|
-
.pipe(filter((state) => state === 'entering' || state === 'entered'), take(1))
|
|
8400
|
-
.subscribe(() => {
|
|
8499
|
+
.pipe(filter((state) => state === 'entering' || state === 'entered'), take(1), tap(() => {
|
|
8401
8500
|
nextFrame(() => {
|
|
8402
8501
|
interactiveCloseReady = true;
|
|
8403
8502
|
});
|
|
8404
|
-
})
|
|
8503
|
+
}))
|
|
8504
|
+
.subscribe();
|
|
8405
8505
|
cleanupFns.push(() => readySubscription.unsubscribe());
|
|
8406
8506
|
if (config.animationDelegate?.enter) {
|
|
8407
8507
|
config.animationDelegate.enter({ lifecycle, elements: overlayRef.elements });
|
|
@@ -8410,11 +8510,11 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
8410
8510
|
lifecycle.enter();
|
|
8411
8511
|
}
|
|
8412
8512
|
lifecycle.state$
|
|
8413
|
-
.pipe(filter((state) => state === 'entered'), take(1))
|
|
8414
|
-
.subscribe(() => {
|
|
8513
|
+
.pipe(filter((state) => state === 'entered'), take(1), tap(() => {
|
|
8415
8514
|
applyInitialFocus(paneElement, autoFocus, targetDocument);
|
|
8416
8515
|
overlayRef.markOpened();
|
|
8417
|
-
})
|
|
8516
|
+
}))
|
|
8517
|
+
.subscribe();
|
|
8418
8518
|
});
|
|
8419
8519
|
return overlayRef;
|
|
8420
8520
|
};
|
|
@@ -9485,11 +9585,9 @@ class ProvideSurfaceDirective {
|
|
|
9485
9585
|
this.clearForcedSurface();
|
|
9486
9586
|
}
|
|
9487
9587
|
}
|
|
9488
|
-
/** @internal */
|
|
9489
9588
|
forceSurface(surface) {
|
|
9490
9589
|
this.forcedSurface.set(surface);
|
|
9491
9590
|
}
|
|
9492
|
-
/** @internal */
|
|
9493
9591
|
clearForcedSurface() {
|
|
9494
9592
|
if (this.forcedSurface() === FORCED_SURFACE_UNSET) {
|
|
9495
9593
|
return;
|
|
@@ -9586,15 +9684,9 @@ class AutoSurfaceDirective {
|
|
|
9586
9684
|
*/
|
|
9587
9685
|
this.surfaceProvider = input(null, /* @ts-ignore */
|
|
9588
9686
|
...(ngDevMode ? [{ debugName: "surfaceProvider" }] : /* istanbul ignore next */ []));
|
|
9589
|
-
// An overlay *panel* that IS its overlay's own painted surface opts in (see
|
|
9590
|
-
// matchOverlaySurface) so it adopts the overlay's registered elevation exactly,
|
|
9591
|
-
// rather than layering one level above a parent surface.
|
|
9592
9687
|
this.isOverlaySurface = signal(false, /* @ts-ignore */
|
|
9593
9688
|
...(ngDevMode ? [{ debugName: "isOverlaySurface" }] : /* istanbul ignore next */ []));
|
|
9594
|
-
//
|
|
9595
|
-
// containment changes. surfaceForElement() below does a non-reactive element.contains() read,
|
|
9596
|
-
// so the computed must be re-triggered when this element is (re)grafted into an overlay pane -
|
|
9597
|
-
// otherwise a value cached from before the graft (one elevation too low) sticks forever.
|
|
9689
|
+
// surfaceForElement() reads the DOM non-reactively; bumping this re-runs resolvedSurface after a re-graft.
|
|
9598
9690
|
this.domSettleTick = signal(0, /* @ts-ignore */
|
|
9599
9691
|
...(ngDevMode ? [{ debugName: "domSettleTick" }] : /* istanbul ignore next */ []));
|
|
9600
9692
|
this.resolvedSurface = computed(() => {
|
|
@@ -9602,40 +9694,25 @@ class AutoSurfaceDirective {
|
|
|
9602
9694
|
if (!themes) {
|
|
9603
9695
|
return null;
|
|
9604
9696
|
}
|
|
9605
|
-
// Establish a dependency on the DOM-settle tick so the non-reactive containment read below
|
|
9606
|
-
// is re-evaluated after the element is grafted into its final overlay pane.
|
|
9607
9697
|
this.domSettleTick();
|
|
9608
9698
|
const explicitProvider = this.surfaceProvider();
|
|
9609
9699
|
const contextTheme = explicitProvider ? explicitProvider.activeTheme() : this.parentSurface();
|
|
9610
9700
|
const contextElevation = contextTheme?.elevation ?? null;
|
|
9611
9701
|
const contextType = contextTheme?.type ?? null;
|
|
9612
|
-
//
|
|
9613
|
-
// *declared* (the trigger location), not the pane it renders into - so the
|
|
9614
|
-
// injector-derived parent surface is one elevation too low. The surface-context
|
|
9615
|
-
// tracker records each open overlay's surface *and* its pane element, so we consult
|
|
9616
|
-
// only the overlay whose pane actually contains this element in the DOM (portaling
|
|
9617
|
-
// moves the DOM into the pane even though the injector stays at the trigger). An
|
|
9618
|
-
// auto-surface on the base page therefore stays put when an overlay opens elsewhere.
|
|
9702
|
+
// Portaled content keeps the trigger's injector, so only the pane that contains this element in the DOM counts.
|
|
9619
9703
|
const overlaySurface = this.surfaceContextTracker.surfaceForElement(this.elementRef.nativeElement);
|
|
9620
9704
|
const overlayElevation = overlaySurface?.elevation ?? null;
|
|
9621
9705
|
const overlayType = overlaySurface?.type ?? null;
|
|
9622
|
-
//
|
|
9623
|
-
// overlay's elevation: the overlay container already resolved it (one above the trigger) and
|
|
9624
|
-
// registered it in the tracker. It must NOT re-derive from its declaration injector - that
|
|
9625
|
-
// points back at the trigger location and disagrees with the pane whenever the trigger itself
|
|
9626
|
-
// sits on a surface, which would double-elevate the panel relative to its own pane.
|
|
9706
|
+
// Must not re-derive from the declaration injector: it points at the trigger and would double-elevate the panel.
|
|
9627
9707
|
if (this.isOverlaySurface()) {
|
|
9628
9708
|
if (overlayElevation !== null) {
|
|
9629
9709
|
return resolveSurfaceByElevation(themes, overlayType ?? contextType ?? 'dark', overlayElevation)?.name ?? null;
|
|
9630
9710
|
}
|
|
9631
|
-
// Rendered outside any tracked overlay: fall back to the injector context unchanged.
|
|
9632
9711
|
if (contextElevation !== null) {
|
|
9633
9712
|
return resolveSurfaceByElevation(themes, contextType ?? 'dark', contextElevation)?.name ?? null;
|
|
9634
9713
|
}
|
|
9635
9714
|
return null;
|
|
9636
9715
|
}
|
|
9637
|
-
// A regular auto-surface sits one elevation *above* the deeper of its injector context and the
|
|
9638
|
-
// overlay pane it renders into (content painted onto the surface it lives on).
|
|
9639
9716
|
let parentElevation;
|
|
9640
9717
|
let parentType;
|
|
9641
9718
|
if (overlayElevation !== null && (contextElevation === null || overlayElevation > contextElevation)) {
|
|
@@ -9652,14 +9729,8 @@ class AutoSurfaceDirective {
|
|
|
9652
9729
|
return resolveSurfaceByElevation(themes, parentType, parentElevation + 1)?.name ?? null;
|
|
9653
9730
|
}, /* @ts-ignore */
|
|
9654
9731
|
...(ngDevMode ? [{ debugName: "resolvedSurface" }] : /* istanbul ignore next */ []));
|
|
9655
|
-
//
|
|
9656
|
-
//
|
|
9657
|
-
// in - or while it is briefly mounted in an off-pane measuring container, as windowed lists do.
|
|
9658
|
-
// surfaceForElement()'s element.contains() check then returns the wrong (or no) overlay, so it
|
|
9659
|
-
// resolves off the declaration injector (the trigger location) one elevation too low. That check
|
|
9660
|
-
// is a plain DOM read, not a signal, so nothing re-runs the computed once the element reaches its
|
|
9661
|
-
// final pane. Watch the tracker result across renders and re-trigger the computed whenever the
|
|
9662
|
-
// element's overlay containment changes, settling (and unsubscribing) once it stops moving.
|
|
9732
|
+
// The containment check is a plain DOM read, so nothing re-runs resolvedSurface once the element
|
|
9733
|
+
// reaches its final pane (windowed lists mount it in an off-pane container first). Watch it across renders.
|
|
9663
9734
|
let lastElevation = this.surfaceContextTracker.surfaceForElement(this.elementRef.nativeElement)?.elevation ?? null;
|
|
9664
9735
|
let stableRenders = 0;
|
|
9665
9736
|
const settleWatcher = afterEveryRender(() => {
|
|
@@ -9671,7 +9742,6 @@ class AutoSurfaceDirective {
|
|
|
9671
9742
|
this.domSettleTick.update((v) => v + 1);
|
|
9672
9743
|
}
|
|
9673
9744
|
else if (el.isConnected && ++stableRenders >= 2) {
|
|
9674
|
-
// containment has held for a couple of renders and the element is in the DOM - done moving
|
|
9675
9745
|
settleWatcher.destroy();
|
|
9676
9746
|
}
|
|
9677
9747
|
});
|
|
@@ -9986,8 +10056,6 @@ const COLOR_PROVIDER = new InjectionToken('ColorProvider');
|
|
|
9986
10056
|
* it through element DI, so overlay containers fall back to this when resolving the provider to
|
|
9987
10057
|
* `syncWithProvider()` - resolve at sync time, not at injection time, since root components only
|
|
9988
10058
|
* register with `ApplicationRef` once bootstrap completes.
|
|
9989
|
-
*
|
|
9990
|
-
* @internal
|
|
9991
10059
|
*/
|
|
9992
10060
|
const resolveAppRootColorProvider = (appRef) => {
|
|
9993
10061
|
for (const componentRef of appRef.components) {
|
|
@@ -10040,7 +10108,7 @@ class ProvideColorDirective {
|
|
|
10040
10108
|
return SURFACE_COLOR;
|
|
10041
10109
|
if (!this.themes || !value)
|
|
10042
10110
|
return;
|
|
10043
|
-
if (isDevMode() && !this.themes.some((theme) => theme.name === value)
|
|
10111
|
+
if (isDevMode() && !this.themes.some((theme) => theme.name === value)) {
|
|
10044
10112
|
console.error(`Theme ${value} does not exist. Please make sure to add it to provideColorThemesWithTailwind4()`);
|
|
10045
10113
|
}
|
|
10046
10114
|
return createCssColorThemeName(value);
|
|
@@ -10079,11 +10147,9 @@ class ProvideColorDirective {
|
|
|
10079
10147
|
this.clearForcedColor();
|
|
10080
10148
|
}
|
|
10081
10149
|
}
|
|
10082
|
-
/** @internal */
|
|
10083
10150
|
forceColor(color) {
|
|
10084
10151
|
this.forcedColor.set(color);
|
|
10085
10152
|
}
|
|
10086
|
-
/** @internal */
|
|
10087
10153
|
clearForcedColor() {
|
|
10088
10154
|
if (this.forcedColor() === FORCED_COLOR_UNSET) {
|
|
10089
10155
|
return;
|
|
@@ -10144,11 +10210,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
|
|
|
10144
10210
|
|
|
10145
10211
|
// Generated from package.json by tools/scripts/generate-version.js - do not edit.
|
|
10146
10212
|
/** The version of `@ethlete/core` this build was cut from. */
|
|
10147
|
-
const CORE_VERSION = '5.0.0-next.
|
|
10213
|
+
const CORE_VERSION = '5.0.0-next.61';
|
|
10148
10214
|
|
|
10149
10215
|
/**
|
|
10150
10216
|
* Generated bundle index. Do not edit.
|
|
10151
10217
|
*/
|
|
10152
10218
|
|
|
10153
|
-
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, EasingTokensStylesComponent, 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, 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, boolBreakpointTransform, boundingClientRectToElementRect, breakpointTransformBase, buildElementSignal, buildSignalEffects, canUseSessionMemory, clamp, clone, cloneFormGroup, computedTillFalsy, computedTillTruthy, controlValueSignal, controlValueSignalWithPrevious, copyToClipboard, createAnchoredPositionCleanup, createArrayPropertyBinding, createAutoSessionMemoryKey, createCanAnimateSignal, createComponentId, createCssColorThemeName, createCssSurfaceName, createDestroy, createDocumentElementSignal, createElementDimensions, createEmptyElementSignal, createFlipAnimation, createFlipAnimationGroup, createIsRenderedSignal, createLogger, createObjectUrlHandle, createOverlayRuntimeRef, createPropertyBinding, createRootThemeCss, createRoute, createRouterState, createRxHostListener, createSessionMemory, 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
|
|
10219
|
+
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, EasingTokensStylesComponent, EthleteValidators, FOCUSABLE_SELECTOR, FOCUS_VISIBLE_TRACKER_TOKEN, HtmlToMarkdownPipe, IS_ARRAY_NOT_EMPTY, IS_EMAIL, InferMimeTypePipe, InitialsPipe, IsArrayNotEmpty, IsEmail, jsonLd as JsonLD, KeyPressManager, MARKDOWN_VERBATIM_ATTR, MUST_MATCH, MarkdownToHtmlPipe, MatchStateType, MustMatch, NOTIFICATION_CLICK_MESSAGE_TYPE, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, OVERLAY_LAYER_ATTRIBUTE, 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, boolBreakpointTransform, boundingClientRectToElementRect, breakpointTransformBase, buildElementSignal, buildSignalEffects, canUseSessionMemory, clamp, clone, cloneFormGroup, computedTillFalsy, computedTillTruthy, controlValueSignal, controlValueSignalWithPrevious, copyToClipboard, createAnchoredPositionCleanup, createArrayPropertyBinding, createAutoSessionMemoryKey, createCanAnimateSignal, createComponentId, createCssColorThemeName, createCssSurfaceName, createDestroy, createDocumentElementSignal, createElementDimensions, createEmptyElementSignal, createFlipAnimation, createFlipAnimationGroup, createIsRenderedSignal, createLogger, createObjectUrlHandle, createOverlayRuntimeRef, createPropertyBinding, createRootThemeCss, createRoute, createRouterState, createRxHostListener, createSessionMemory, 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, isElement, isElementSignal, isElementVisible, isFocusable, isGroupMatch, isHTMLElement, isHTMLOrSVGElement, isKnockoutMatch, isObject, isOnHigherOverlayLayer, isSafeLinkUrl, isSafeUrl, isStaleBuildError, markdownToHtml, matchesReducedMotion, maybeSignalValue, memoizeSignal, mountEasingTokens, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, normalizeUnsavedChangesSource, numberBreakpointTransform, onOverlayViewportInsetsChange, overlayViewportInsets, overlayViewportInsetsFor, ownsActiveElement, 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, signalCountdown, signalDeferredLoading, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementLastScrollDirection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementLastScrollDirection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, slugify, suppressTextSelection, switchQueryListChanges, syncSignal, toArray, toArrayTrackByFn, toInjectFn, toProvideFn, toStringBinding, toToken, transformOrReturn, typedBreakpointTransform, useCursorDragScroll, writeScrollbarSizeToCssVariables, writeViewportSizeToCssVariables, ɵProvideColorThemes, ɵProvideColorThemesPrefix, ɵProvideSurfaceThemes, ɵProvideSurfaceThemesPrefix };
|
|
10154
10220
|
//# sourceMappingURL=ethlete-core.mjs.map
|