@ethlete/core 5.0.0-next.41 → 5.0.0-next.43

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 CHANGED
@@ -1,5 +1,21 @@
1
1
  # @ethlete/core
2
2
 
3
+ ## 5.0.0-next.43
4
+
5
+ ### Minor Changes
6
+
7
+ - [#3048](https://github.com/ethlete-io/ethdk/pull/3048) [`6bd6057`](https://github.com/ethlete-io/ethdk/commit/6bd6057398465ecd24a2f187321934e12430d127) Thanks [@github-actions](https://github.com/apps/github-actions)! - New `injectFileDownload()` and `createObjectUrlHandle()` in core replace four hand-rolled object URLs. The query devtools exports now append their anchor before clicking it, which Firefox ignored.
8
+
9
+ - [#3048](https://github.com/ethlete-io/ethdk/pull/3048) [`6c95aa0`](https://github.com/ethlete-io/ethdk/commit/6c95aa00bb0df0aa4c3638453a35c4f14a9364eb) Thanks [@github-actions](https://github.com/apps/github-actions)! - A gesture the browser takes away mid-drag now emits `dragCancelled` / `resizeCancelled` instead of `dragEnded`. Grid moves and resizes, table column reorder and column resize revert instead of committing a drop the user never made.
10
+
11
+ - [#3048](https://github.com/ethlete-io/ethdk/pull/3048) [`5008c81`](https://github.com/ethlete-io/ethdk/commit/5008c81d726021d078e87ecb37cfb1d5d4eee6cb) Thanks [@github-actions](https://github.com/apps/github-actions)! - Grid resize strips grow into the gap - a 14px target at the default gap, with the marker unmoved - via the new `--et-resize-handles-outset`. Touch sizes now key on `any-pointer: coarse`, so a touchscreen laptop gets them too.
12
+
13
+ ## 5.0.0-next.42
14
+
15
+ ### Minor Changes
16
+
17
+ - [#3047](https://github.com/ethlete-io/ethdk/pull/3047) [`309dc57`](https://github.com/ethlete-io/ethdk/commit/309dc576d296efe39d9ff85030102c10db834b9b) Thanks [@github-actions](https://github.com/apps/github-actions)! - Scroll restoration: mark a "back to the overview" link with `etRestoreScroll` (or `routerRestoreScroll()` in the navigation state) and it restores that page's last offset instead of scrolling to top.
18
+
3
19
  ## 5.0.0-next.41
4
20
 
5
21
  ### Major Changes
@@ -5,7 +5,7 @@ import { Subject, BehaviorSubject, debounceTime, combineLatest, map, merge, from
5
5
  import { FormGroup, FormArray, FormControl } from '@angular/forms';
6
6
  import { SIGNAL, signalSetFn } from '@angular/core/primitives/signals';
7
7
  import { DOCUMENT as DOCUMENT$1, isPlatformBrowser } from '@angular/common';
8
- import { Router, NavigationEnd, NavigationSkipped, NavigationStart } from '@angular/router';
8
+ import { Router, NavigationEnd, NavigationSkipped, NavigationStart, RouterLink } from '@angular/router';
9
9
  import { autoUpdate, offset, flip, shift, limitShift, computePosition, hide, arrow, size } from '@floating-ui/dom';
10
10
  import { Title, Meta, DomSanitizer } from '@angular/platform-browser';
11
11
 
@@ -3076,6 +3076,20 @@ const routerDisableScrollTop = (config = {}) => {
3076
3076
  ...(config.onPathParamChange ? { [ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE]: true } : {}),
3077
3077
  };
3078
3078
  };
3079
+ const ET_RESTORE_SCROLL = /* @__PURE__ */ Symbol('ET_RESTORE_SCROLL');
3080
+ /**
3081
+ * Marks a navigation as a return to a page the user has already seen, so it restores that page's last
3082
+ * scroll offset instead of scrolling to top - what a "back to the overview" link means, as opposed to
3083
+ * a link that opens the overview fresh. Spread into `NavigationExtras.state`; for a `routerLink`, use
3084
+ * {@link RestoreScrollDirective} instead.
3085
+ *
3086
+ * Needs `restore.enabled` on {@link setupScrollRestoration}, and only ever restores an offset the
3087
+ * session actually recorded - the first visit to a page has none, so it scrolls to top as usual.
3088
+ *
3089
+ * @example
3090
+ * router.navigate(['/teams'], { state: routerRestoreScroll() });
3091
+ */
3092
+ const routerRestoreScroll = () => ({ [ET_RESTORE_SCROLL]: true });
3079
3093
  const SCROLL_RESTORATION_HOLDS_DEF = /* @__PURE__ */ defineRootProvider(() => {
3080
3094
  const holds = new Set();
3081
3095
  return {
@@ -3119,6 +3133,11 @@ const DEFAULT_RESTORE_TIMEOUT = 1000;
3119
3133
  const DEFAULT_RESTORE_MAX_TIMEOUT = 10_000;
3120
3134
  /** Events that mean the user took over scrolling, so a pending restoration must be abandoned. */
3121
3135
  const INTERACTION_EVENTS = ['wheel', 'touchmove', 'keydown'];
3136
+ /** Key order is navigation order, not declaration order, so two spellings of one URL compare equal. */
3137
+ const serializeQueryParams = (queryParams) => Object.keys(queryParams)
3138
+ .sort()
3139
+ .map((key) => `${key}=${queryParams[key]}`)
3140
+ .join('&');
3122
3141
  const setupScrollRestoration = (config = {}) => {
3123
3142
  if (!isPlatformBrowser(inject(PLATFORM_ID))) {
3124
3143
  return;
@@ -3140,13 +3159,14 @@ const setupScrollRestoration = (config = {}) => {
3140
3159
  if (restoreEnabled && 'scrollRestoration' in history) {
3141
3160
  history.scrollRestoration = 'manual';
3142
3161
  }
3143
- /** Saved offsets keyed by the router's per-history-entry `navigationId`. */
3162
+ /** Saved offsets keyed by the router's per-history-entry `navigationId`, in least-recent-first order. */
3144
3163
  const positions = new Map();
3145
3164
  // Mirrors Angular's own `RouterScroller`: the offset of the currently displayed page belongs to
3146
3165
  // the navigation that produced it, and a popstate reports the id of the entry it moves to.
3147
3166
  let lastNavigationId = 0;
3148
3167
  let restoredNavigationId = 0;
3149
3168
  let isPopstate = false;
3169
+ let wantsRestore = false;
3150
3170
  let prev = { state: createRouterState(router), route: createRoute(router) };
3151
3171
  let pendingRestore = null;
3152
3172
  const cancelPendingRestore = () => {
@@ -3215,12 +3235,36 @@ const setupScrollRestoration = (config = {}) => {
3215
3235
  }
3216
3236
  };
3217
3237
  };
3238
+ /**
3239
+ * The offset the most recently left entry for this page had. A target without query params means
3240
+ * "that page", whichever query state it was last in - the crumb linking to an overview does not
3241
+ * know, and should not have to reproduce, the filter the user left it under.
3242
+ */
3243
+ const findLastVisitedOffset = (route, search) => {
3244
+ const entries = [...positions.values()];
3245
+ for (let i = entries.length - 1; i >= 0; i--) {
3246
+ const entry = entries[i];
3247
+ if (!entry || entry.route !== route)
3248
+ continue;
3249
+ if (search && entry.search !== search)
3250
+ continue;
3251
+ return entry.top;
3252
+ }
3253
+ return undefined;
3254
+ };
3218
3255
  const onNavigationStart = (event) => {
3219
3256
  // A new navigation supersedes a restoration that has not committed yet.
3220
3257
  cancelPendingRestore();
3221
3258
  if (!restoreEnabled)
3222
3259
  return;
3223
- positions.set(lastNavigationId, resolveScrollElement().scrollTop);
3260
+ // Re-inserted rather than overwritten so map order stays least-recently-left first, which is both
3261
+ // what `findLastVisitedOffset` walks backwards and what the cap below evicts from.
3262
+ positions.delete(lastNavigationId);
3263
+ positions.set(lastNavigationId, {
3264
+ top: resolveScrollElement().scrollTop,
3265
+ route: prev.route,
3266
+ search: serializeQueryParams(prev.state.queryParams),
3267
+ });
3224
3268
  if (positions.size > MAX_STORED_POSITIONS) {
3225
3269
  const oldest = positions.keys().next();
3226
3270
  if (!oldest.done)
@@ -3228,6 +3272,11 @@ const setupScrollRestoration = (config = {}) => {
3228
3272
  }
3229
3273
  isPopstate = event.navigationTrigger === 'popstate';
3230
3274
  restoredNavigationId = event.restoredState?.navigationId ?? 0;
3275
+ // Read off the navigation rather than `history.state`: a symbol key does not survive being
3276
+ // structured-cloned into the history entry, which is what keeps the mark from outliving this
3277
+ // navigation and re-firing when the user later pops back to the entry it created.
3278
+ const navigationState = router.getCurrentNavigation()?.extras.state;
3279
+ wantsRestore = !isPopstate && navigationState?.[ET_RESTORE_SCROLL] === true;
3231
3280
  };
3232
3281
  const onNavigationEnd = (event) => {
3233
3282
  const curr = { state: createRouterState(router), route: createRoute(router) };
@@ -3236,6 +3285,8 @@ const setupScrollRestoration = (config = {}) => {
3236
3285
  const sameUrlNavigation = prev.route === curr.route;
3237
3286
  const didFragmentChange = prevState.fragment !== currState.fragment;
3238
3287
  prev = curr;
3288
+ const wasMarkedAsReturn = wantsRestore;
3289
+ wantsRestore = false;
3239
3290
  if (event instanceof NavigationEnd) {
3240
3291
  lastNavigationId = event.id;
3241
3292
  }
@@ -3248,6 +3299,13 @@ const setupScrollRestoration = (config = {}) => {
3248
3299
  const target = positions.get(restoredNavigationId);
3249
3300
  // The saved offset wins over both scroll to top and fragment scrolling: the user may well have
3250
3301
  // scrolled away from the anchor before leaving the page.
3302
+ if (target !== undefined) {
3303
+ scheduleRestore(target.top);
3304
+ return;
3305
+ }
3306
+ }
3307
+ if (restoreEnabled && wasMarkedAsReturn) {
3308
+ const target = findLastVisitedOffset(curr.route, serializeQueryParams(currState.queryParams));
3251
3309
  if (target !== undefined) {
3252
3310
  scheduleRestore(target);
3253
3311
  return;
@@ -3810,6 +3868,33 @@ const getObjectProperty = (obj, prop) => {
3810
3868
  return value;
3811
3869
  };
3812
3870
 
3871
+ /**
3872
+ * Creates an object URL for a `Blob`/`File` and hands back a handle that owns it. Keep the handle
3873
+ * for as long as the URL is on screen and call `revoke()` when it is not - the browser holds the
3874
+ * blob in memory until then.
3875
+ *
3876
+ * A handle rather than a bare string, so the URL and the call that frees it cannot drift apart. Use
3877
+ * `injectFileDownload()` instead when the URL only has to survive a single click.
3878
+ *
3879
+ * @example
3880
+ * const preview = createObjectUrlHandle(file);
3881
+ * // later
3882
+ * preview.revoke();
3883
+ */
3884
+ const createObjectUrlHandle = (object) => {
3885
+ const url = typeof URL === 'undefined' || !URL.createObjectURL ? null : URL.createObjectURL(object);
3886
+ let revoked = false;
3887
+ return {
3888
+ url,
3889
+ revoke: () => {
3890
+ if (!url || revoked)
3891
+ return;
3892
+ revoked = true;
3893
+ URL.revokeObjectURL(url);
3894
+ },
3895
+ };
3896
+ };
3897
+
3813
3898
  const RUNTIME_ERROR_NO_DATA = '__ET_NO_DATA__';
3814
3899
  class RuntimeError extends Error {
3815
3900
  constructor(code, message, data = RUNTIME_ERROR_NO_DATA) {
@@ -4059,6 +4144,44 @@ const provideBoundaryElement = /* @__PURE__ */ toProvideFn(BOUNDARY_ELEMENT_DEF)
4059
4144
  const injectBoundaryElement = /* @__PURE__ */ toInjectFn(BOUNDARY_ELEMENT_DEF);
4060
4145
  const BOUNDARY_ELEMENT_TOKEN = /* @__PURE__ */ toToken(BOUNDARY_ELEMENT_DEF);
4061
4146
 
4147
+ /**
4148
+ * Hands the user a file the browser downloads. Call it once from an injection context - a field
4149
+ * initializer - and the function it hands back can then be called from anywhere, including a click
4150
+ * handler.
4151
+ *
4152
+ * A no-op where there is no browser (server-side rendering), so a toolbar button needs no platform
4153
+ * check of its own. Use {@link createObjectUrlHandle} instead when the URL has to outlive the call.
4154
+ *
4155
+ * @example
4156
+ * private download = injectFileDownload();
4157
+ *
4158
+ * protected save() {
4159
+ * this.download({ content: json, filename: 'session.json', type: 'application/json' });
4160
+ * }
4161
+ */
4162
+ const injectFileDownload = () => {
4163
+ const document = inject(DOCUMENT);
4164
+ const renderer = injectRenderer();
4165
+ return (options) => {
4166
+ // No window means no browser: server-side there is nothing to hand a file to.
4167
+ const view = document.defaultView;
4168
+ if (!view)
4169
+ return;
4170
+ const { content, filename, type } = options;
4171
+ const parts = Array.isArray(content) ? content : [content];
4172
+ const url = view.URL.createObjectURL(new view.Blob(parts, type ? { type } : undefined));
4173
+ const link = renderer.createElement('a');
4174
+ renderer.setProperties(link, { href: url, download: filename, rel: 'noopener' });
4175
+ renderer.setStyle(link, { display: 'none' });
4176
+ // Firefox only follows the click of an anchor that is in the document.
4177
+ renderer.appendChild(document.body, link);
4178
+ link.click();
4179
+ renderer.removeChild(document.body, link);
4180
+ // The blob would otherwise be held until the tab closes; the click has already read it.
4181
+ view.URL.revokeObjectURL(url);
4182
+ };
4183
+ };
4184
+
4062
4185
  const FOCUS_VISIBLE_TRACKER_DEF = /* @__PURE__ */ defineRootProvider(() => {
4063
4186
  const document = inject(DOCUMENT);
4064
4187
  const destroyRef = inject(DestroyRef);
@@ -4825,6 +4948,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
4825
4948
  }]
4826
4949
  }], ctorParameters: () => [], propDecorators: { repeatCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "etRepeat", required: false }] }] } });
4827
4950
 
4951
+ /**
4952
+ * Marks a `routerLink` as a return to a page the user has already seen - a "back to the overview"
4953
+ * link - so it restores that page's last scroll offset instead of scrolling to top.
4954
+ *
4955
+ * Needs `restore.enabled` on `setupScrollRestoration`. A page the session has no offset for (the
4956
+ * first visit, or a reload since) scrolls to top as usual.
4957
+ *
4958
+ * @example
4959
+ * <a routerLink="/teams" etRestoreScroll>Teams</a>
4960
+ */
4961
+ class RestoreScrollDirective {
4962
+ constructor() {
4963
+ this.routerLink = inject(RouterLink);
4964
+ this.elementRef = inject(ElementRef);
4965
+ // Capture, so the mark is on `state` before `RouterLink`'s own click handler reads it. Applied
4966
+ // per click rather than once, because a `[state]` binding on the same element would overwrite it
4967
+ // on any later change detection run.
4968
+ this.elementRef.nativeElement.addEventListener('click', () => (this.routerLink.state = { ...this.routerLink.state, ...routerRestoreScroll() }), { capture: true });
4969
+ }
4970
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: RestoreScrollDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4971
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.7", type: RestoreScrollDirective, isStandalone: true, selector: "[routerLink][etRestoreScroll]", ngImport: i0 }); }
4972
+ }
4973
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: RestoreScrollDirective, decorators: [{
4974
+ type: Directive,
4975
+ args: [{
4976
+ selector: '[routerLink][etRestoreScroll]',
4977
+ }]
4978
+ }], ctorParameters: () => [] });
4979
+
4828
4980
  class ScrollObserverDirective {
4829
4981
  constructor() {
4830
4982
  this.elementRef = inject(ElementRef);
@@ -4905,7 +5057,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
4905
5057
 
4906
5058
  const setupDragObservable = (startEvent, el, commitThreshold) => {
4907
5059
  const { pointerId, clientX: startX, clientY: startY } = startEvent;
4908
- const end$ = merge(fromEvent(document, 'pointerup'), fromEvent(document, 'pointercancel')).pipe(filter((e) => e.pointerId === pointerId), take(1));
5060
+ let cancelled = false;
5061
+ const end$ = merge(fromEvent(document, 'pointerup'), fromEvent(document, 'pointercancel')).pipe(filter((e) => e.pointerId === pointerId), take(1),
5062
+ // Read below by the terminating `defer`, which only runs once this has completed the moves.
5063
+ tap((e) => (cancelled = e.type === 'pointercancel')));
4909
5064
  let lastX = startX;
4910
5065
  let lastY = startY;
4911
5066
  let committed = false;
@@ -4950,7 +5105,11 @@ const setupDragObservable = (startEvent, el, commitThreshold) => {
4950
5105
  },
4951
5106
  });
4952
5107
  }), takeUntil(end$));
4953
- return concat(moves$, defer(() => of(committed ? { type: 'end' } : { type: 'tapped' })));
5108
+ return concat(moves$, defer(() => {
5109
+ if (cancelled)
5110
+ return of({ type: 'cancelled' });
5111
+ return of(committed ? { type: 'end' } : { type: 'tapped' });
5112
+ }));
4954
5113
  };
4955
5114
  /**
4956
5115
  * Observe one drag gesture, starting from a `pointerdown` on `element`.
@@ -4960,6 +5119,10 @@ const setupDragObservable = (startEvent, el, commitThreshold) => {
4960
5119
  * pointer released before crossing the threshold emits a single `tapped` instead. The stream
4961
5120
  * completes with the gesture, so there is nothing to unsubscribe on the happy path.
4962
5121
  *
5122
+ * A gesture the browser takes away - a `pointercancel` from a system gesture, an incoming call, the
5123
+ * tab going to the background - ends on `cancelled` rather than `end` or `tapped`. Treat it as
5124
+ * "revert", not "drop here": the user never let go, so there is no position they chose.
5125
+ *
4963
5126
  * This is the primitive behind {@link DragHandleDirective}. Prefer the directive; reach for this when
4964
5127
  * the draggable element belongs to someone else's template (e.g. a table feature attaching a drag to
4965
5128
  * header cells the table itself renders) and you can only work from a delegated `pointerdown`.
@@ -4978,6 +5141,12 @@ class DragHandleDirective {
4978
5141
  this.dragStarted = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'start'), map((e) => e.data)));
4979
5142
  this.dragMoved = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'move'), map((e) => e.data)));
4980
5143
  this.dragEnded = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'end'), map(() => undefined)));
5144
+ /**
5145
+ * The browser took the gesture away mid-drag (a system gesture, an incoming call, the tab going to
5146
+ * the background). Revert to where the drag started - the user never chose a drop position. A
5147
+ * consumer that does not handle this leaves the item wherever the pointer happened to be.
5148
+ */
5149
+ this.dragCancelled = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'cancelled'), map(() => undefined)));
4981
5150
  this.isDragging = toSignal(this.gesture$.pipe(map((e) => e.type === 'start' || e.type === 'move'), distinctUntilChanged()), { initialValue: false });
4982
5151
  applyHostListener('pointerdown', (e) => this.startGesture(e));
4983
5152
  }
@@ -4988,7 +5157,7 @@ class DragHandleDirective {
4988
5157
  this.gestureStart$.next(event);
4989
5158
  }
4990
5159
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: DragHandleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
4991
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: DragHandleDirective, isStandalone: true, selector: "[etDragHandle]", inputs: { commitThreshold: { classPropertyName: "commitThreshold", publicName: "commitThreshold", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dragTapped: "dragTapped", dragStarted: "dragStarted", dragMoved: "dragMoved", dragEnded: "dragEnded" }, host: { properties: { "style.touch-action": "disabled() ? null : 'none'" } }, ngImport: i0 }); }
5160
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: DragHandleDirective, isStandalone: true, selector: "[etDragHandle]", inputs: { commitThreshold: { classPropertyName: "commitThreshold", publicName: "commitThreshold", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dragTapped: "dragTapped", dragStarted: "dragStarted", dragMoved: "dragMoved", dragEnded: "dragEnded", dragCancelled: "dragCancelled" }, host: { properties: { "style.touch-action": "disabled() ? null : 'none'" } }, ngImport: i0 }); }
4992
5161
  }
4993
5162
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: DragHandleDirective, decorators: [{
4994
5163
  type: Directive,
@@ -5001,7 +5170,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
5001
5170
  '[style.touch-action]': "disabled() ? null : 'none'",
5002
5171
  },
5003
5172
  }]
5004
- }], ctorParameters: () => [], propDecorators: { commitThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "commitThreshold", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], dragTapped: [{ type: i0.Output, args: ["dragTapped"] }], dragStarted: [{ type: i0.Output, args: ["dragStarted"] }], dragMoved: [{ type: i0.Output, args: ["dragMoved"] }], dragEnded: [{ type: i0.Output, args: ["dragEnded"] }] } });
5173
+ }], ctorParameters: () => [], propDecorators: { commitThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "commitThreshold", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], dragTapped: [{ type: i0.Output, args: ["dragTapped"] }], dragStarted: [{ type: i0.Output, args: ["dragStarted"] }], dragMoved: [{ type: i0.Output, args: ["dragMoved"] }], dragEnded: [{ type: i0.Output, args: ["dragEnded"] }], dragCancelled: [{ type: i0.Output, args: ["dragCancelled"] }] } });
5005
5174
 
5006
5175
  /**
5007
5176
  * The `message` type a service worker must post for `onClick` to fire on the service-worker path,
@@ -6944,11 +7113,14 @@ const setupResizeObservable = (startEvent, edge) => {
6944
7113
  const pointerId = startEvent.pointerId;
6945
7114
  const startX = startEvent.clientX;
6946
7115
  const startY = startEvent.clientY;
6947
- const end$ = merge(fromEvent(document, 'pointerup'), fromEvent(document, 'pointercancel')).pipe(filter((e) => e.pointerId === pointerId), take(1));
7116
+ let cancelled = false;
7117
+ const end$ = merge(fromEvent(document, 'pointerup'), fromEvent(document, 'pointercancel')).pipe(filter((e) => e.pointerId === pointerId), take(1),
7118
+ // Read below by the terminating `defer`, which only runs once this has completed the moves.
7119
+ tap((e) => (cancelled = e.type === 'pointercancel')));
6948
7120
  return concat(of({ type: 'start', edge }), fromEvent(document, 'pointermove').pipe(filter((e) => e.pointerId === pointerId), map((e) => ({
6949
7121
  type: 'move',
6950
7122
  data: { edge, dx: e.clientX - startX, dy: e.clientY - startY, clientX: e.clientX, clientY: e.clientY },
6951
- })), takeUntil(end$)), of({ type: 'end' }));
7123
+ })), takeUntil(end$)), defer(() => of({ type: cancelled ? 'cancelled' : 'end' })));
6952
7124
  };
6953
7125
  class ResizeHandlesComponent {
6954
7126
  constructor() {
@@ -6960,13 +7132,19 @@ class ResizeHandlesComponent {
6960
7132
  this.resizeStarted = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'start'), map((e) => e.edge)));
6961
7133
  this.resizeMoved = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'move'), map((e) => e.data)));
6962
7134
  this.resizeEnded = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'end'), map(() => undefined)));
6963
- this.isResizing = toSignal(this.gesture$.pipe(map((e) => e.type !== 'end'), distinctUntilChanged()), { initialValue: false });
7135
+ /**
7136
+ * The browser took the gesture away mid-resize (a system gesture, an incoming call, the tab going
7137
+ * to the background). Revert to the size the resize started from - the user never let go, so there
7138
+ * is no size they chose.
7139
+ */
7140
+ this.resizeCancelled = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'cancelled'), map(() => undefined)));
7141
+ this.isResizing = toSignal(this.gesture$.pipe(map((e) => e.type === 'start' || e.type === 'move'), distinctUntilChanged()), { initialValue: false });
6964
7142
  this.activeEdge = toSignal(this.gesture$.pipe(map((e) => {
6965
- if (e.type === 'end')
6966
- return null;
6967
7143
  if (e.type === 'start')
6968
7144
  return e.edge;
6969
- return e.data.edge;
7145
+ if (e.type === 'move')
7146
+ return e.data.edge;
7147
+ return null;
6970
7148
  }), distinctUntilChanged()), { initialValue: null });
6971
7149
  this.edgeCursors = EDGE_CURSORS;
6972
7150
  }
@@ -6977,7 +7155,7 @@ class ResizeHandlesComponent {
6977
7155
  this.gestureStart$.next({ event, edge });
6978
7156
  }
6979
7157
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ResizeHandlesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6980
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: ResizeHandlesComponent, isStandalone: true, selector: "et-resize-handles", inputs: { edges: { classPropertyName: "edges", publicName: "edges", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { resizeStarted: "resizeStarted", resizeMoved: "resizeMoved", resizeEnded: "resizeEnded" }, host: { properties: { "attr.inert": "disabled() ? \"\" : null", "attr.data-active-edge": "activeEdge()" }, classAttribute: "et-resize-handles" }, ngImport: i0, template: `
7158
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: ResizeHandlesComponent, isStandalone: true, selector: "et-resize-handles", inputs: { edges: { classPropertyName: "edges", publicName: "edges", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { resizeStarted: "resizeStarted", resizeMoved: "resizeMoved", resizeEnded: "resizeEnded", resizeCancelled: "resizeCancelled" }, host: { properties: { "attr.inert": "disabled() ? \"\" : null", "attr.data-active-edge": "activeEdge()" }, classAttribute: "et-resize-handles" }, ngImport: i0, template: `
6981
7159
  @for (edge of edges(); track edge) {
6982
7160
  <div
6983
7161
  [style.cursor]="edgeCursors[edge]"
@@ -6985,7 +7163,7 @@ class ResizeHandlesComponent {
6985
7163
  class="et-resize-handle et-resize-handle--{{ edge }}"
6986
7164
  ></div>
6987
7165
  }
6988
- `, isInline: true, styles: ["@property --et-resize-handles-z-index{syntax: \"<integer>\"; inherits: true; initial-value: 10;}@property --et-resize-handles-edge-size{syntax: \"<length>\"; inherits: true; initial-value: 6px;}@property --et-resize-handles-corner-size{syntax: \"<length>\"; inherits: true; initial-value: 12px;}@property --et-resize-handles-edge-inset{syntax: \"<length>\"; inherits: true; initial-value: 8px;}@property --et-resize-handles-side-top{syntax: \"<length>\"; inherits: true; initial-value: 0px;}@property --et-resize-handles-side-bottom{syntax: \"<length>\"; inherits: true; initial-value: 8px;}@property --et-resize-handles-touch-edge-size{syntax: \"<length>\"; inherits: true; initial-value: 20px;}@property --et-resize-handles-touch-corner-size{syntax: \"<length>\"; inherits: true; initial-value: 28px;}et-resize-handles{position:absolute;inset:0;pointer-events:none}.et-resize-handle{position:absolute;z-index:var(--et-resize-handles-z-index);touch-action:none;pointer-events:auto}.et-resize-handle--n{left:var(--et-resize-handles-edge-inset);right:var(--et-resize-handles-edge-inset);height:var(--et-resize-handles-edge-size);top:0}.et-resize-handle--s{left:var(--et-resize-handles-edge-inset);right:var(--et-resize-handles-edge-inset);height:var(--et-resize-handles-edge-size);bottom:0}.et-resize-handle--e,.et-resize-handle--w{top:var(--et-resize-handles-side-top);bottom:var(--et-resize-handles-side-bottom);width:var(--et-resize-handles-edge-size)}.et-resize-handle--e{right:0}.et-resize-handle--w{left:0}.et-resize-handle--ne,.et-resize-handle--nw{top:0;width:var(--et-resize-handles-corner-size);height:var(--et-resize-handles-corner-size)}.et-resize-handle--ne{right:0}.et-resize-handle--nw{left:0}.et-resize-handle--se,.et-resize-handle--sw{bottom:0;width:var(--et-resize-handles-corner-size);height:var(--et-resize-handles-corner-size)}.et-resize-handle--se{right:0}.et-resize-handle--sw{left:0}@media(hover:none){.et-resize-handle--n,.et-resize-handle--s{height:var(--et-resize-handles-touch-edge-size)}.et-resize-handle--e,.et-resize-handle--w{width:var(--et-resize-handles-touch-edge-size)}.et-resize-handle--ne,.et-resize-handle--nw,.et-resize-handle--se,.et-resize-handle--sw{width:var(--et-resize-handles-touch-corner-size);height:var(--et-resize-handles-touch-corner-size)}}\n"], encapsulation: i0.ViewEncapsulation.None }); }
7166
+ `, isInline: true, styles: ["@property --et-resize-handles-z-index{syntax: \"<integer>\"; inherits: true; initial-value: 10;}@property --et-resize-handles-edge-size{syntax: \"<length>\"; inherits: true; initial-value: 6px;}@property --et-resize-handles-corner-size{syntax: \"<length>\"; inherits: true; initial-value: 12px;}@property --et-resize-handles-edge-inset{syntax: \"<length>\"; inherits: true; initial-value: 8px;}@property --et-resize-handles-outset{syntax: \"<length>\"; inherits: true; initial-value: 0px;}@property --et-resize-handles-side-top{syntax: \"<length>\"; inherits: true; initial-value: 0px;}@property --et-resize-handles-side-bottom{syntax: \"<length>\"; inherits: true; initial-value: 8px;}@property --et-resize-handles-touch-edge-size{syntax: \"<length>\"; inherits: true; initial-value: 20px;}@property --et-resize-handles-touch-corner-size{syntax: \"<length>\"; inherits: true; initial-value: 28px;}et-resize-handles{position:absolute;inset:calc(-1 * var(--et-resize-handles-outset));pointer-events:none}.et-resize-handle{--et-resize-handle-thickness: calc(var(--et-resize-handles-edge-size) + var(--et-resize-handles-outset));--et-resize-handle-corner: calc(var(--et-resize-handles-corner-size) + var(--et-resize-handles-outset));position:absolute;z-index:var(--et-resize-handles-z-index);touch-action:none;pointer-events:auto}.et-resize-handle--n{left:var(--et-resize-handles-edge-inset);right:var(--et-resize-handles-edge-inset);height:var(--et-resize-handle-thickness);top:0}.et-resize-handle--s{left:var(--et-resize-handles-edge-inset);right:var(--et-resize-handles-edge-inset);height:var(--et-resize-handle-thickness);bottom:0}.et-resize-handle--e,.et-resize-handle--w{top:var(--et-resize-handles-side-top);bottom:var(--et-resize-handles-side-bottom);width:var(--et-resize-handle-thickness)}.et-resize-handle--e{right:0}.et-resize-handle--w{left:0}.et-resize-handle--ne,.et-resize-handle--nw{top:0;width:var(--et-resize-handle-corner);height:var(--et-resize-handle-corner)}.et-resize-handle--ne{right:0}.et-resize-handle--nw{left:0}.et-resize-handle--se,.et-resize-handle--sw{bottom:0;width:var(--et-resize-handle-corner);height:var(--et-resize-handle-corner)}.et-resize-handle--se{right:0}.et-resize-handle--sw{left:0}@media(any-pointer:coarse){.et-resize-handle{--et-resize-handle-thickness: calc(var(--et-resize-handles-touch-edge-size) + var(--et-resize-handles-outset));--et-resize-handle-corner: calc(var(--et-resize-handles-touch-corner-size) + var(--et-resize-handles-outset))}}\n"], encapsulation: i0.ViewEncapsulation.None }); }
6989
7167
  }
6990
7168
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: ResizeHandlesComponent, decorators: [{
6991
7169
  type: Component,
@@ -7001,8 +7179,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
7001
7179
  class: 'et-resize-handles',
7002
7180
  '[attr.inert]': 'disabled() ? "" : null',
7003
7181
  '[attr.data-active-edge]': 'activeEdge()',
7004
- }, styles: ["@property --et-resize-handles-z-index{syntax: \"<integer>\"; inherits: true; initial-value: 10;}@property --et-resize-handles-edge-size{syntax: \"<length>\"; inherits: true; initial-value: 6px;}@property --et-resize-handles-corner-size{syntax: \"<length>\"; inherits: true; initial-value: 12px;}@property --et-resize-handles-edge-inset{syntax: \"<length>\"; inherits: true; initial-value: 8px;}@property --et-resize-handles-side-top{syntax: \"<length>\"; inherits: true; initial-value: 0px;}@property --et-resize-handles-side-bottom{syntax: \"<length>\"; inherits: true; initial-value: 8px;}@property --et-resize-handles-touch-edge-size{syntax: \"<length>\"; inherits: true; initial-value: 20px;}@property --et-resize-handles-touch-corner-size{syntax: \"<length>\"; inherits: true; initial-value: 28px;}et-resize-handles{position:absolute;inset:0;pointer-events:none}.et-resize-handle{position:absolute;z-index:var(--et-resize-handles-z-index);touch-action:none;pointer-events:auto}.et-resize-handle--n{left:var(--et-resize-handles-edge-inset);right:var(--et-resize-handles-edge-inset);height:var(--et-resize-handles-edge-size);top:0}.et-resize-handle--s{left:var(--et-resize-handles-edge-inset);right:var(--et-resize-handles-edge-inset);height:var(--et-resize-handles-edge-size);bottom:0}.et-resize-handle--e,.et-resize-handle--w{top:var(--et-resize-handles-side-top);bottom:var(--et-resize-handles-side-bottom);width:var(--et-resize-handles-edge-size)}.et-resize-handle--e{right:0}.et-resize-handle--w{left:0}.et-resize-handle--ne,.et-resize-handle--nw{top:0;width:var(--et-resize-handles-corner-size);height:var(--et-resize-handles-corner-size)}.et-resize-handle--ne{right:0}.et-resize-handle--nw{left:0}.et-resize-handle--se,.et-resize-handle--sw{bottom:0;width:var(--et-resize-handles-corner-size);height:var(--et-resize-handles-corner-size)}.et-resize-handle--se{right:0}.et-resize-handle--sw{left:0}@media(hover:none){.et-resize-handle--n,.et-resize-handle--s{height:var(--et-resize-handles-touch-edge-size)}.et-resize-handle--e,.et-resize-handle--w{width:var(--et-resize-handles-touch-edge-size)}.et-resize-handle--ne,.et-resize-handle--nw,.et-resize-handle--se,.et-resize-handle--sw{width:var(--et-resize-handles-touch-corner-size);height:var(--et-resize-handles-touch-corner-size)}}\n"] }]
7005
- }], propDecorators: { edges: [{ type: i0.Input, args: [{ isSignal: true, alias: "edges", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], resizeStarted: [{ type: i0.Output, args: ["resizeStarted"] }], resizeMoved: [{ type: i0.Output, args: ["resizeMoved"] }], resizeEnded: [{ type: i0.Output, args: ["resizeEnded"] }] } });
7182
+ }, styles: ["@property --et-resize-handles-z-index{syntax: \"<integer>\"; inherits: true; initial-value: 10;}@property --et-resize-handles-edge-size{syntax: \"<length>\"; inherits: true; initial-value: 6px;}@property --et-resize-handles-corner-size{syntax: \"<length>\"; inherits: true; initial-value: 12px;}@property --et-resize-handles-edge-inset{syntax: \"<length>\"; inherits: true; initial-value: 8px;}@property --et-resize-handles-outset{syntax: \"<length>\"; inherits: true; initial-value: 0px;}@property --et-resize-handles-side-top{syntax: \"<length>\"; inherits: true; initial-value: 0px;}@property --et-resize-handles-side-bottom{syntax: \"<length>\"; inherits: true; initial-value: 8px;}@property --et-resize-handles-touch-edge-size{syntax: \"<length>\"; inherits: true; initial-value: 20px;}@property --et-resize-handles-touch-corner-size{syntax: \"<length>\"; inherits: true; initial-value: 28px;}et-resize-handles{position:absolute;inset:calc(-1 * var(--et-resize-handles-outset));pointer-events:none}.et-resize-handle{--et-resize-handle-thickness: calc(var(--et-resize-handles-edge-size) + var(--et-resize-handles-outset));--et-resize-handle-corner: calc(var(--et-resize-handles-corner-size) + var(--et-resize-handles-outset));position:absolute;z-index:var(--et-resize-handles-z-index);touch-action:none;pointer-events:auto}.et-resize-handle--n{left:var(--et-resize-handles-edge-inset);right:var(--et-resize-handles-edge-inset);height:var(--et-resize-handle-thickness);top:0}.et-resize-handle--s{left:var(--et-resize-handles-edge-inset);right:var(--et-resize-handles-edge-inset);height:var(--et-resize-handle-thickness);bottom:0}.et-resize-handle--e,.et-resize-handle--w{top:var(--et-resize-handles-side-top);bottom:var(--et-resize-handles-side-bottom);width:var(--et-resize-handle-thickness)}.et-resize-handle--e{right:0}.et-resize-handle--w{left:0}.et-resize-handle--ne,.et-resize-handle--nw{top:0;width:var(--et-resize-handle-corner);height:var(--et-resize-handle-corner)}.et-resize-handle--ne{right:0}.et-resize-handle--nw{left:0}.et-resize-handle--se,.et-resize-handle--sw{bottom:0;width:var(--et-resize-handle-corner);height:var(--et-resize-handle-corner)}.et-resize-handle--se{right:0}.et-resize-handle--sw{left:0}@media(any-pointer:coarse){.et-resize-handle{--et-resize-handle-thickness: calc(var(--et-resize-handles-touch-edge-size) + var(--et-resize-handles-outset));--et-resize-handle-corner: calc(var(--et-resize-handles-touch-corner-size) + var(--et-resize-handles-outset))}}\n"] }]
7183
+ }], propDecorators: { edges: [{ type: i0.Input, args: [{ isSignal: true, alias: "edges", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], resizeStarted: [{ type: i0.Output, args: ["resizeStarted"] }], resizeMoved: [{ type: i0.Output, args: ["resizeMoved"] }], resizeEnded: [{ type: i0.Output, args: ["resizeEnded"] }], resizeCancelled: [{ type: i0.Output, args: ["resizeCancelled"] }] } });
7006
7184
 
7007
7185
  const applyHeadBinding = (binding, applyFn, removeFn, isValid) => {
7008
7186
  const destroyRef = inject(DestroyRef);
@@ -9203,5 +9381,5 @@ const createUnsavedChangesGuard = (config) => {
9203
9381
  * Generated bundle index. Do not edit.
9204
9382
  */
9205
9383
 
9206
- 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_PROVIDER, ClickOutsideDirective, ColorInteractiveContainerDirective, ColorInteractiveDirective, ColorInteractiveExcludeDirective, ColorInteractiveHasFocusDirective, DEFAULT_MULTI_INSTANCE_RELS, DEFAULT_MULTI_INSTANCE_TAGS, 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, 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, PropsDirective, ProvideColorDirective, ProvideSurfaceDirective, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeHandlesComponent, RuntimeError, 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, 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, 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, injectBoundaryElement, injectBreakpointInput, injectBreakpointIsMatched, injectBreakpointObserver, injectCanHover, injectColorThemes, injectColorThemesPrefix, injectCurrentBreakpoint, injectDefaultColorTheme, injectDeviceInputType, injectDisplayOrientation, injectErrorTheme, injectFaviconStore, 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, injectTemplateRef, injectTitleConfig, injectTitleStore, injectUnsavedChangesCoordinator, injectUrl, injectViewportConfig, injectViewportDimensions, injectViewportSize, injectWarningTheme, isAnimationDebugEnabled, isArray, isElementSignal, isElementVisible, isFocusable, isGroupMatch, isHTMLElement, isKnockoutMatch, isObject, markdownToHtml, matchesReducedMotion, maybeSignalValue, memoizeSignal, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, normalizeUnsavedChangesSource, numberBreakpointAttribute, numberBreakpointTransform, previousSignalValue, provideBoundaryElement, provideBreakpointInstance, provideBreakpointObserver, provideColorThemes, provideColorThemesWithTailwind4, provideFaviconStore, provideFocusVisibleTracker, provideLinkStore, provideLinkStoreConfig, provideLocale, provideMetaConfig, provideMetaStore, provideNotifications, provideOverlayRuntime, provideRenderer, provideStructuredDataConfig, provideStructuredDataStore, provideStyleManager, provideSurfaceContextTracker, provideSurfaceThemesWithTailwind4, provideTitleConfig, provideTitleStore, provideUnsavedChangesCoordinator, provideViewportConfig, randomId, readFromClipboard, registerAnchoredPositionMiddlewareExtras, registerAnchoredPositionSetup, resetPositioningStyles, resolveAppRootColorProvider, resolveSurfaceByElevation, round, routerDisableScrollTop, scrollToElement, setBackdropStyles, setBaseElementStyles, setCookie, setInputSignal, setupFocusTrap, setupPositioning, setupScrollRestoration, signalAnimatedNumber, signalAttributes, signalClasses, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementLastScrollDirection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementLastScrollDirection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, slugify, switchQueryListChanges, syncSignal, templateComputed, toArray, toArrayTrackByFn, toInjectFn, toProvideFn, toStringBinding, toToken, transformOrReturn, typedBreakpointTransform, unbindProps, useCursorDragScroll, writeScrollbarSizeToCssVariables, writeViewportSizeToCssVariables, ɵProvideColorThemes, ɵProvideColorThemesPrefix, ɵProvideSurfaceThemes, ɵProvideSurfaceThemesPrefix };
9384
+ 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_PROVIDER, ClickOutsideDirective, ColorInteractiveContainerDirective, ColorInteractiveDirective, ColorInteractiveExcludeDirective, ColorInteractiveHasFocusDirective, DEFAULT_MULTI_INSTANCE_RELS, DEFAULT_MULTI_INSTANCE_TAGS, 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, PropsDirective, ProvideColorDirective, ProvideSurfaceDirective, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeHandlesComponent, RestoreScrollDirective, RuntimeError, 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, 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, injectBoundaryElement, injectBreakpointInput, injectBreakpointIsMatched, injectBreakpointObserver, injectCanHover, injectColorThemes, injectColorThemesPrefix, injectCurrentBreakpoint, injectDefaultColorTheme, 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, injectTemplateRef, injectTitleConfig, injectTitleStore, injectUnsavedChangesCoordinator, injectUrl, injectViewportConfig, injectViewportDimensions, injectViewportSize, injectWarningTheme, isAnimationDebugEnabled, isArray, isElementSignal, isElementVisible, isFocusable, isGroupMatch, isHTMLElement, isKnockoutMatch, isObject, markdownToHtml, matchesReducedMotion, maybeSignalValue, memoizeSignal, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, normalizeUnsavedChangesSource, numberBreakpointAttribute, numberBreakpointTransform, previousSignalValue, provideBoundaryElement, provideBreakpointInstance, provideBreakpointObserver, provideColorThemes, provideColorThemesWithTailwind4, provideFaviconStore, provideFocusVisibleTracker, provideLinkStore, provideLinkStoreConfig, provideLocale, provideMetaConfig, provideMetaStore, provideNotifications, provideOverlayRuntime, provideRenderer, provideStructuredDataConfig, provideStructuredDataStore, provideStyleManager, provideSurfaceContextTracker, provideSurfaceThemesWithTailwind4, provideTitleConfig, provideTitleStore, provideUnsavedChangesCoordinator, provideViewportConfig, randomId, readFromClipboard, registerAnchoredPositionMiddlewareExtras, registerAnchoredPositionSetup, resetPositioningStyles, resolveAppRootColorProvider, resolveSurfaceByElevation, round, routerDisableScrollTop, routerRestoreScroll, scrollToElement, setBackdropStyles, setBaseElementStyles, setCookie, setInputSignal, setupFocusTrap, setupPositioning, setupScrollRestoration, signalAnimatedNumber, signalAttributes, signalClasses, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementLastScrollDirection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementLastScrollDirection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, slugify, switchQueryListChanges, syncSignal, templateComputed, toArray, toArrayTrackByFn, toInjectFn, toProvideFn, toStringBinding, toToken, transformOrReturn, typedBreakpointTransform, unbindProps, useCursorDragScroll, writeScrollbarSizeToCssVariables, writeViewportSizeToCssVariables, ɵProvideColorThemes, ɵProvideColorThemesPrefix, ɵProvideSurfaceThemes, ɵProvideSurfaceThemesPrefix };
9207
9385
  //# sourceMappingURL=ethlete-core.mjs.map