@angular/core 21.0.0-next.7 → 21.0.0-next.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/fesm2022/_attribute-chunk.mjs +1 -1
  2. package/fesm2022/_attribute-chunk.mjs.map +1 -1
  3. package/fesm2022/_debug_node-chunk.mjs +722 -569
  4. package/fesm2022/_debug_node-chunk.mjs.map +1 -1
  5. package/fesm2022/_effect-chunk.mjs +512 -48
  6. package/fesm2022/_effect-chunk.mjs.map +1 -1
  7. package/fesm2022/{_root_effect_scheduler-chunk.mjs → _effect-chunk2.mjs} +202 -19
  8. package/fesm2022/_effect-chunk2.mjs.map +1 -0
  9. package/fesm2022/_not_found-chunk.mjs +1 -1
  10. package/fesm2022/_not_found-chunk.mjs.map +1 -1
  11. package/fesm2022/_resource-chunk.mjs +5 -173
  12. package/fesm2022/_resource-chunk.mjs.map +1 -1
  13. package/fesm2022/_untracked-chunk.mjs +117 -0
  14. package/fesm2022/_untracked-chunk.mjs.map +1 -0
  15. package/fesm2022/_weak_ref-chunk.mjs +1 -1
  16. package/fesm2022/_weak_ref-chunk.mjs.map +1 -1
  17. package/fesm2022/core.mjs +15 -18
  18. package/fesm2022/core.mjs.map +1 -1
  19. package/fesm2022/primitives-di.mjs +1 -1
  20. package/fesm2022/primitives-di.mjs.map +1 -1
  21. package/fesm2022/primitives-event-dispatch.mjs +1 -1
  22. package/fesm2022/primitives-event-dispatch.mjs.map +1 -1
  23. package/fesm2022/primitives-signals.mjs +4 -4
  24. package/fesm2022/primitives-signals.mjs.map +1 -1
  25. package/fesm2022/rxjs-interop.mjs +5 -5
  26. package/fesm2022/rxjs-interop.mjs.map +1 -1
  27. package/fesm2022/testing.mjs +3 -3
  28. package/fesm2022/testing.mjs.map +1 -1
  29. package/package.json +2 -2
  30. package/schematics/bundles/add-bootstrap-context-to-server-main.cjs +5 -5
  31. package/schematics/bundles/application-config-core.cjs +5 -5
  32. package/schematics/bundles/{apply_import_manager-D_4NSuRa.cjs → apply_import_manager-CoeTX_Ob.cjs} +3 -3
  33. package/schematics/bundles/bootstrap-options-migration.cjs +5 -5
  34. package/schematics/bundles/cleanup-unused-imports.cjs +5 -5
  35. package/schematics/bundles/common-to-standalone-migration.cjs +385 -0
  36. package/schematics/bundles/{compiler_host-C1KRWoxv.cjs → compiler_host-emLDwK2U.cjs} +2 -2
  37. package/schematics/bundles/control-flow-migration.cjs +4 -4
  38. package/schematics/bundles/imports-DwPXlGFl.cjs +1 -1
  39. package/schematics/bundles/{index-DYqR8Lpq.cjs → index-CLxYZ09c.cjs} +4 -4
  40. package/schematics/bundles/{index-BFENxhdR.cjs → index-Dvqnp6JS.cjs} +391 -152
  41. package/schematics/bundles/inject-migration.cjs +3 -3
  42. package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
  43. package/schematics/bundles/{migrate_ts_type_references-CemH7A8e.cjs → migrate_ts_type_references-CpM5FPGa.cjs} +47 -5
  44. package/schematics/bundles/{ng_component_template-AYs8YXuT.cjs → ng_component_template-BRbBIAUX.cjs} +2 -2
  45. package/schematics/bundles/ng_decorators-BI0uV7KI.cjs +1 -1
  46. package/schematics/bundles/ngclass-to-class-migration.cjs +7 -7
  47. package/schematics/bundles/ngstyle-to-style-migration.cjs +7 -7
  48. package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
  49. package/schematics/bundles/output-migration.cjs +6 -6
  50. package/schematics/bundles/{parse_html-6-AB4O-A.cjs → parse_html-CPWfkfhR.cjs} +2 -2
  51. package/schematics/bundles/{project_paths-EiOrjlNS.cjs → project_paths-C8H7KDJ3.cjs} +3 -3
  52. package/schematics/bundles/{project_tsconfig_paths-BbVhi4fG.cjs → project_tsconfig_paths-CiBzGSIa.cjs} +335 -47
  53. package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
  54. package/schematics/bundles/route-lazy-loading.cjs +3 -3
  55. package/schematics/bundles/router-current-navigation.cjs +4 -4
  56. package/schematics/bundles/router-last-successful-navigation.cjs +4 -4
  57. package/schematics/bundles/router-testing-module-migration.cjs +513 -0
  58. package/schematics/bundles/self-closing-tags-migration.cjs +6 -6
  59. package/schematics/bundles/signal-input-migration.cjs +7 -7
  60. package/schematics/bundles/signal-queries-migration.cjs +7 -7
  61. package/schematics/bundles/signals.cjs +7 -7
  62. package/schematics/bundles/standalone-migration.cjs +4 -4
  63. package/schematics/bundles/symbol-BObKoqes.cjs +1 -1
  64. package/schematics/collection.json +11 -0
  65. package/schematics/migrations/common-to-standalone-migration/schema.json +14 -0
  66. package/schematics/migrations/router-testing-module-migration/schema.json +14 -0
  67. package/types/_api-chunk.d.ts +1 -1
  68. package/types/_chrome_dev_tools_performance-chunk.d.ts +22 -12
  69. package/types/_discovery-chunk.d.ts +58 -10
  70. package/types/_effect-chunk.d.ts +1 -1
  71. package/types/_event_dispatcher-chunk.d.ts +1 -1
  72. package/types/_formatter-chunk.d.ts +4 -3
  73. package/types/_weak_ref-chunk.d.ts +1 -1
  74. package/types/core.d.ts +68 -33
  75. package/types/primitives-di.d.ts +1 -1
  76. package/types/primitives-event-dispatch.d.ts +1 -1
  77. package/types/primitives-signals.d.ts +2 -2
  78. package/types/rxjs-interop.d.ts +1 -1
  79. package/types/testing.d.ts +1 -1
  80. package/fesm2022/_root_effect_scheduler-chunk.mjs.map +0 -1
  81. package/fesm2022/_signal-chunk.mjs +0 -581
  82. package/fesm2022/_signal-chunk.mjs.map +0 -1
@@ -1,11 +1,11 @@
1
1
  /**
2
- * @license Angular v21.0.0-next.7
2
+ * @license Angular v21.0.0-next.9
3
3
  * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
6
6
 
7
- import { attachInjectFlag, _global, ɵɵdefineInjectable as __defineInjectable, ɵɵdefineInjector as __defineInjector, ɵɵinject as __inject, ɵɵinvalidFactoryDep as __invalidFactoryDep, resolveForwardRef, newArray, EMPTY_OBJ, assertString, assertNotEqual, FLAGS, assertEqual, isInCheckNoChangesMode, PREORDER_HOOK_FLAGS, assertFirstCreatePass, assertDefined, throwError, assertNumber, assertGreaterThan, HEADER_OFFSET, DECLARATION_VIEW, NG_FACTORY_DEF, isForwardRef, getFactoryDef, assertIndexInRange, assertTNodeForLView, enterDI, runInInjectorProfilerContext, getCurrentTNode, getLView, emitInjectorToCreateInstanceEvent, emitInstanceCreatedByInjectorEvent, throwProviderNotFoundError, leaveDI, assertNodeInjector, stringifyForError, cyclicDependencyErrorWithDetails, cyclicDependencyError, setInjectorProfilerContext, setInjectImplementation, assertDirectiveDef, NG_ELEMENT_ID, convertToBitFlags, isRootView, T_HOST, TVIEW, injectRootLimpMode, isComponentDef, EMBEDDED_VIEW_INJECTOR, INJECTOR$1 as INJECTOR, DECLARATION_COMPONENT_VIEW, isComponentHost, RuntimeError, NG_PROV_DEF, getClosureSafeProperty, getNativeByTNode, flatten, arrayEquals, ID, isLView, assertDomNode, unwrapRNode, getComponentLViewByIndex, CONTEXT, EMPTY_ARRAY, assertLView, HOST, CHILD_HEAD, NEXT, isLContainer, getLViewParent, Injector, CLEANUP, getComponentDef, getDirectiveDef, InjectionToken, ENVIRONMENT_INITIALIZER, inject, isInSkipHydrationBlock as isInSkipHydrationBlock$1, HYDRATION, isContentQueryHost, setCurrentQueryIndex, XSS_SECURITY_URL, renderStringify, ENVIRONMENT, makeEnvironmentProviders, isDirectiveHost, formatRuntimeError, resetPreOrderHookFlags, PARENT, RENDERER, CHILD_TAIL, assertSame, assertFirstUpdatePass, getSelectedIndex, getTView, assertIndexInDeclRange, setSelectedIndex, assertLContainer, MOVED_VIEWS, isDestroyed, REACTIVE_TEMPLATE_CONSUMER, DECLARATION_LCONTAINER, QUERIES, assertNotReactive, ON_DESTROY_HOOKS, assertFunction, EFFECTS, assertProjectionSlots, NATIVE, assertParentView, CONTAINER_HEADER_OFFSET, ANIMATIONS, assertNotSame, setCurrentDirectiveIndex, setCurrentTNode, getElementDepthCount, increaseElementDepthCount, wasLastNodeCreated, isCurrentTNodeParent, setCurrentTNodeAsNotParent, assertHasParent, INTERNAL_APPLICATION_ERROR_HANDLER, stringify, getCurrentDirectiveIndex, unwrapLView, isCreationMode, enterView, leaveView, AFTER_RENDER_SEQUENCES_TO_ADD, markAncestorsForTraversal, markViewForRefresh, setIsRefreshingViews, isExhaustiveCheckNoChanges, requiresRefreshOrTraversal, setIsInCheckNoChangesMode, CheckNoChangesMode, setBindingIndex, EFFECTS_TO_SCHEDULE, viewAttachedToChangeDetector, setBindingRootForHostBindings, isRefreshingViews, removeFromArray, addToArray, updateAncestorTraversalFlagsOnAttach, storeLViewOnDestroy, VIEW_REFS, assertGreaterThanOrEqual, isInI18nBlock, assertTNodeForTView, getCurrentParentTNode, getCurrentTNodePlaceholderOk, assertTNode, assertTIcu, assertNumberInRange, DEHYDRATED_VIEWS, getNgModuleDef, getPipeDef as getPipeDef$1, getNgModuleDefOrThrow, isStandalone, concatStringsWithSpace, assertInjectImplementationNotEqual, emitInjectEvent, getConstant, assertLessThan, getOrCreateTViewCleanup, getOrCreateLViewCleanup, assertNotDefined, nextBindingIndex, getSelectedTNode, getDirectiveDefOrThrow, getTNode, assertComponentType, debugStringifyTypeForError, ChangeDetectionScheduler, EnvironmentInjector, SVG_NAMESPACE, MATH_ML_NAMESPACE, viewAttachedToContainer, storeCleanupWithContext, signal, createInjectorWithoutInjectorInstances, R3Injector, getNullInjector, internalImportProvidersFrom, initNgDevMode, fillProperties, getBindingsEnabled, lastNodeWasCreated, NgZone, ErrorHandler, assertNotInReactiveContext, assertInInjectionContext, DestroyRef, ViewContext, removeLViewOnDestroy, walkUpViews, getNativeByIndex, assertElement, arrayInsert2, arraySplice, setInjectorProfiler, NullInjector, INJECTOR_DEF_TYPES, walkProviderTree, getInjectorDef, deepForEach, isTypeProvider, isSignal, isInInjectionContext, runInInjectionContext, ZONELESS_ENABLED, EffectScheduler, PendingTasksInternal, PendingTasks, assertTNodeCreationIndex, isSkipHydrationRootTNode, leaveSkipHydrationBlock, decreaseElementDepthCount, getNamespace, enterSkipHydrationBlock, getCurrentDirectiveDef, assertIndexInExpandoRange, getBindingIndex, assertOneOf, setInI18nBlock, nextContextImpl, getCurrentQueryIndex, getContextLView, load, keyValueArrayIndexOf, keyValueArraySet, keyValueArrayGet, incrementBindingIndex, isWritableSignal, store, providerToFactory, emitProviderConfiguredEvent, isClassProvider, getBindingRoot, NG_COMP_DEF, ɵɵresetView as __resetView, ɵɵnamespaceHTML as __namespaceHTML, ɵɵnamespaceMathML as __namespaceMathML, ɵɵnamespaceSVG as __namespaceSVG, ɵɵenableBindings as __enableBindings, ɵɵdisableBindings as __disableBindings, ɵɵrestoreView as __restoreView, forwardRef, NG_MOD_DEF, NG_INJ_DEF, NG_DIR_DEF, NG_PIPE_DEF, angularZoneInstanceIdProperty, SCHEDULE_IN_ROOT_ZONE, scheduleCallbackWithMicrotask, PROVIDED_ZONELESS, NoopNgZone, scheduleCallbackWithRafRace, getNativeByTNodeOrNull } from './_root_effect_scheduler-chunk.mjs';
8
- import { setActiveConsumer, SIGNAL, consumerDestroy, REACTIVE_NODE, consumerPollProducersForChange, consumerBeforeComputation, getActiveConsumer, consumerAfterComputation, createComputed, setThrowInvalidWriteToSignalError } from './_signal-chunk.mjs';
7
+ import { attachInjectFlag, _global, ɵɵdefineInjectable as __defineInjectable, ɵɵdefineInjector as __defineInjector, ɵɵinject as __inject, ɵɵinvalidFactoryDep as __invalidFactoryDep, resolveForwardRef, newArray, EMPTY_OBJ, assertString, assertNotEqual, FLAGS, assertEqual, isInCheckNoChangesMode, PREORDER_HOOK_FLAGS, assertFirstCreatePass, assertDefined, throwError, assertNumber, assertGreaterThan, HEADER_OFFSET, DECLARATION_VIEW, NG_FACTORY_DEF, isForwardRef, getFactoryDef, assertIndexInRange, assertTNodeForLView, enterDI, runInInjectorProfilerContext, getCurrentTNode, getLView, emitInjectorToCreateInstanceEvent, emitInstanceCreatedByInjectorEvent, throwProviderNotFoundError, leaveDI, assertNodeInjector, stringifyForError, cyclicDependencyErrorWithDetails, cyclicDependencyError, setInjectorProfilerContext, setInjectImplementation, assertDirectiveDef, NG_ELEMENT_ID, convertToBitFlags, isRootView, T_HOST, TVIEW, injectRootLimpMode, isComponentDef, EMBEDDED_VIEW_INJECTOR, INJECTOR$1 as INJECTOR, DECLARATION_COMPONENT_VIEW, isComponentHost, RuntimeError, NG_PROV_DEF, getClosureSafeProperty, getNativeByTNode, flatten, arrayEquals, ID, isLView, assertDomNode, unwrapRNode, getComponentLViewByIndex, CONTEXT, EMPTY_ARRAY, assertLView, HOST, CHILD_HEAD, NEXT, isLContainer, getLViewParent, Injector, CLEANUP, getComponentDef, getDirectiveDef, InjectionToken, ENVIRONMENT_INITIALIZER, inject, formatRuntimeError, isInSkipHydrationBlock as isInSkipHydrationBlock$1, HYDRATION, isContentQueryHost, setCurrentQueryIndex, XSS_SECURITY_URL, renderStringify, ENVIRONMENT, makeEnvironmentProviders, isDirectiveHost, resetPreOrderHookFlags, PARENT, RENDERER, CHILD_TAIL, assertSame, assertFirstUpdatePass, getSelectedIndex, getTView, assertIndexInDeclRange, setSelectedIndex, NgZone, ChangeDetectionScheduler, ErrorHandler, AFTER_RENDER_SEQUENCES_TO_ADD, markAncestorsForTraversal, assertNotInReactiveContext, assertInInjectionContext, DestroyRef, ViewContext, assertLContainer, MOVED_VIEWS, isDestroyed, REACTIVE_TEMPLATE_CONSUMER, DECLARATION_LCONTAINER, QUERIES, assertNotReactive, ON_DESTROY_HOOKS, assertFunction, EFFECTS, assertProjectionSlots, NATIVE, ANIMATIONS, assertParentView, CONTAINER_HEADER_OFFSET, assertNotSame, setCurrentDirectiveIndex, setCurrentTNode, getElementDepthCount, increaseElementDepthCount, wasLastNodeCreated, isCurrentTNodeParent, setCurrentTNodeAsNotParent, assertHasParent, INTERNAL_APPLICATION_ERROR_HANDLER, stringify, getCurrentDirectiveIndex, unwrapLView, isCreationMode, enterView, leaveView, markViewForRefresh, setIsRefreshingViews, isExhaustiveCheckNoChanges, requiresRefreshOrTraversal, setIsInCheckNoChangesMode, CheckNoChangesMode, setBindingIndex, EFFECTS_TO_SCHEDULE, viewAttachedToChangeDetector, setBindingRootForHostBindings, isRefreshingViews, removeFromArray, addToArray, updateAncestorTraversalFlagsOnAttach, storeLViewOnDestroy, VIEW_REFS, assertGreaterThanOrEqual, isInI18nBlock, assertTNodeForTView, getCurrentParentTNode, getCurrentTNodePlaceholderOk, assertTNode, assertTIcu, assertNumberInRange, DEHYDRATED_VIEWS, getNgModuleDef, getPipeDef as getPipeDef$1, getNgModuleDefOrThrow, isStandalone, concatStringsWithSpace, assertInjectImplementationNotEqual, emitInjectEvent, getConstant, assertLessThan, getOrCreateTViewCleanup, getOrCreateLViewCleanup, assertNotDefined, nextBindingIndex, getSelectedTNode, getDirectiveDefOrThrow, getTNode, assertComponentType, debugStringifyTypeForError, EnvironmentInjector, SVG_NAMESPACE, MATH_ML_NAMESPACE, viewAttachedToContainer, storeCleanupWithContext, signal, createInjectorWithoutInjectorInstances, R3Injector, getNullInjector, internalImportProvidersFrom, initNgDevMode, fillProperties, getBindingsEnabled, lastNodeWasCreated, removeLViewOnDestroy, walkUpViews, getNativeByIndex, assertElement, arrayInsert2, arraySplice, setInjectorProfiler, NullInjector, INJECTOR_DEF_TYPES, walkProviderTree, getInjectorDef, deepForEach, EffectRefImpl, isTypeProvider, isSignal, isInInjectionContext, runInInjectionContext, ZONELESS_ENABLED, EffectScheduler, PendingTasksInternal, PendingTasks, assertTNodeCreationIndex, isSkipHydrationRootTNode, leaveSkipHydrationBlock, decreaseElementDepthCount, getNamespace, enterSkipHydrationBlock, getCurrentDirectiveDef, assertIndexInExpandoRange, getBindingIndex, assertOneOf, setInI18nBlock, nextContextImpl, getCurrentQueryIndex, getContextLView, load, keyValueArrayIndexOf, keyValueArraySet, keyValueArrayGet, incrementBindingIndex, isWritableSignal, store, providerToFactory, emitProviderConfiguredEvent, isClassProvider, getBindingRoot, NG_COMP_DEF, ɵɵresetView as __resetView, ɵɵnamespaceHTML as __namespaceHTML, ɵɵnamespaceMathML as __namespaceMathML, ɵɵnamespaceSVG as __namespaceSVG, ɵɵenableBindings as __enableBindings, ɵɵdisableBindings as __disableBindings, ɵɵrestoreView as __restoreView, forwardRef, NG_MOD_DEF, NG_INJ_DEF, NG_DIR_DEF, NG_PIPE_DEF, angularZoneInstanceIdProperty, SCHEDULE_IN_ROOT_ZONE, scheduleCallbackWithMicrotask, PROVIDED_ZONELESS, NoopNgZone, scheduleCallbackWithRafRace, getNativeByTNodeOrNull } from './_effect-chunk2.mjs';
8
+ import { setActiveConsumer, SIGNAL, consumerDestroy, REACTIVE_NODE, consumerPollProducersForChange, consumerBeforeComputation, getActiveConsumer, consumerAfterComputation, createComputed, setThrowInvalidWriteToSignalError } from './_effect-chunk.mjs';
9
9
  import { Subject, Subscription } from 'rxjs';
10
10
  import { setActiveConsumer as setActiveConsumer$1 } from '@angular/core/primitives/signals';
11
11
  import { map } from 'rxjs/operators';
@@ -494,6 +494,15 @@ function getParentCtor(ctor) {
494
494
  return parentCtor || Object;
495
495
  }
496
496
 
497
+ function applyValueToInputField(instance, inputSignalNode, privateName, value) {
498
+ if (inputSignalNode !== null) {
499
+ inputSignalNode.applyValueToInputSignal(inputSignalNode, value);
500
+ }
501
+ else {
502
+ instance[privateName] = value;
503
+ }
504
+ }
505
+
497
506
  /**
498
507
  * Represents a basic change from a previous to a new value for a single
499
508
  * property on a directive instance. Passed as a value in a
@@ -520,15 +529,6 @@ class SimpleChange {
520
529
  }
521
530
  }
522
531
 
523
- function applyValueToInputField(instance, inputSignalNode, privateName, value) {
524
- if (inputSignalNode !== null) {
525
- inputSignalNode.applyValueToInputSignal(inputSignalNode, value);
526
- }
527
- else {
528
- instance[privateName] = value;
529
- }
530
- }
531
-
532
532
  /**
533
533
  * The NgOnChangesFeature decorates a component with support for the ngOnChanges
534
534
  * lifecycle hook, so it should be included in any component that implements
@@ -3880,9 +3880,7 @@ const interactionEventNames = ['click', 'keydown'];
3880
3880
  /** Names of the events considered as hover events. */
3881
3881
  const hoverEventNames = ['mouseenter', 'mouseover', 'focusin'];
3882
3882
  /** `IntersectionObserver` used to observe `viewport` triggers. */
3883
- let intersectionObserver = null;
3884
- /** Number of elements currently observed with `viewport` triggers. */
3885
- let observedViewportElements = 0;
3883
+ const intersectionObservers = new Map();
3886
3884
  /** Object keeping track of registered callbacks for a deferred block trigger. */
3887
3885
  class DeferEventEntry {
3888
3886
  callbacks = new Set();
@@ -3965,14 +3963,15 @@ function onHover(trigger, callback) {
3965
3963
  * Used to create an IntersectionObserver instance.
3966
3964
  * @return IntersectionObserver that is used by onViewport
3967
3965
  */
3968
- function createIntersectionObserver() {
3966
+ function createIntersectionObserver(options) {
3967
+ const key = getIntersectionObserverKey(options);
3969
3968
  return new IntersectionObserver((entries) => {
3970
3969
  for (const current of entries) {
3971
3970
  if (current.isIntersecting && viewportTriggers.has(current.target)) {
3972
- viewportTriggers.get(current.target).listener();
3971
+ viewportTriggers.get(current.target)?.get(key)?.listener();
3973
3972
  }
3974
3973
  }
3975
- });
3974
+ }, options);
3976
3975
  }
3977
3976
  /**
3978
3977
  * Registers a viewport trigger.
@@ -3983,32 +3982,57 @@ function createIntersectionObserver() {
3983
3982
  * and tells the intersection observer to stop observing trigger Element and set
3984
3983
  * intersectionObserver to null if there are no more Elements to observe
3985
3984
  */
3986
- function onViewport(trigger, callback, observerFactoryFn) {
3987
- let entry = viewportTriggers.get(trigger);
3988
- intersectionObserver = intersectionObserver || observerFactoryFn();
3985
+ function onViewport(trigger, callback, observerFactoryFn, options) {
3986
+ const key = getIntersectionObserverKey(options);
3987
+ let entry = viewportTriggers.get(trigger)?.get(key);
3988
+ if (!intersectionObservers.has(key)) {
3989
+ intersectionObservers.set(key, { observer: observerFactoryFn(options), count: 0 });
3990
+ }
3991
+ const config = intersectionObservers.get(key);
3989
3992
  if (!entry) {
3990
3993
  entry = new DeferEventEntry();
3991
- intersectionObserver.observe(trigger);
3992
- viewportTriggers.set(trigger, entry);
3993
- observedViewportElements++;
3994
+ config.observer.observe(trigger);
3995
+ let triggerConfig = viewportTriggers.get(trigger);
3996
+ if (triggerConfig) {
3997
+ triggerConfig.set(key, entry);
3998
+ }
3999
+ else {
4000
+ triggerConfig = new Map();
4001
+ viewportTriggers.set(trigger, triggerConfig);
4002
+ }
4003
+ triggerConfig.set(key, entry);
4004
+ config.count++;
3994
4005
  }
3995
4006
  entry.callbacks.add(callback);
3996
4007
  return () => {
3997
- if (!viewportTriggers.has(trigger)) {
4008
+ if (!viewportTriggers.get(trigger)?.has(key)) {
3998
4009
  return;
3999
4010
  }
4000
4011
  entry.callbacks.delete(callback);
4001
4012
  if (entry.callbacks.size === 0) {
4002
- intersectionObserver?.unobserve(trigger);
4003
- viewportTriggers.delete(trigger);
4004
- observedViewportElements--;
4013
+ config.observer.unobserve(trigger);
4014
+ config.count--;
4015
+ const triggerConfig = viewportTriggers.get(trigger);
4016
+ if (triggerConfig) {
4017
+ triggerConfig.delete(key);
4018
+ if (triggerConfig.size === 0) {
4019
+ viewportTriggers.delete(trigger);
4020
+ }
4021
+ }
4005
4022
  }
4006
- if (observedViewportElements === 0) {
4007
- intersectionObserver?.disconnect();
4008
- intersectionObserver = null;
4023
+ if (config.count === 0) {
4024
+ config.observer.disconnect();
4025
+ intersectionObservers.delete(key);
4009
4026
  }
4010
4027
  };
4011
4028
  }
4029
+ /** Generates a string that can be used to find identical intersection observer option objects. */
4030
+ function getIntersectionObserverKey(options) {
4031
+ if (!options) {
4032
+ return '';
4033
+ }
4034
+ return `${options.rootMargin}/${typeof options.threshold === 'number' ? options.threshold : options.threshold?.join('\n')}`;
4035
+ }
4012
4036
 
4013
4037
  const DEFER_BLOCK_SSR_ID_ATTRIBUTE = 'ngb';
4014
4038
  function setJSActionAttributes(nativeElement, eventTypes, parentDeferBlockId = null) {
@@ -4498,13 +4522,18 @@ function isIncrementalHydrationEnabled(injector) {
4498
4522
  optional: true,
4499
4523
  });
4500
4524
  }
4525
+ let incrementalHydrationEnabledWarned = false;
4526
+ function resetIncrementalHydrationEnabledWarnedForTests() {
4527
+ incrementalHydrationEnabledWarned = false;
4528
+ }
4501
4529
  /** Throws an error if the incremental hydration is not enabled */
4502
- function assertIncrementalHydrationIsConfigured(injector) {
4503
- if (!isIncrementalHydrationEnabled(injector)) {
4504
- throw new RuntimeError(508 /* RuntimeErrorCode.MISCONFIGURED_INCREMENTAL_HYDRATION */, 'Angular has detected that some `@defer` blocks use `hydrate` triggers, ' +
4530
+ function warnIncrementalHydrationNotConfigured() {
4531
+ if (!incrementalHydrationEnabledWarned) {
4532
+ incrementalHydrationEnabledWarned = true;
4533
+ console.warn(formatRuntimeError(508 /* RuntimeErrorCode.MISCONFIGURED_INCREMENTAL_HYDRATION */, 'Angular has detected that some `@defer` blocks use `hydrate` triggers, ' +
4505
4534
  'but incremental hydration was not enabled. Please ensure that the `withIncrementalHydration()` ' +
4506
4535
  'call is added as an argument for the `provideClientHydration()` function call ' +
4507
- 'in your application config.');
4536
+ 'in your application config.'));
4508
4537
  }
4509
4538
  }
4510
4539
  /** Throws an error if the ssrUniqueId on the LDeferBlockDetails is not present */
@@ -4727,6 +4756,20 @@ function getHydrateTimerTrigger(blockData) {
4727
4756
  const trigger = blockData[DEFER_HYDRATE_TRIGGERS]?.find((t) => isTimerTrigger(t));
4728
4757
  return trigger?.delay ?? null;
4729
4758
  }
4759
+ function getHydrateViewportTrigger(blockData) {
4760
+ const details = blockData[DEFER_HYDRATE_TRIGGERS];
4761
+ if (details) {
4762
+ for (const current of details) {
4763
+ if (current === 2 /* DeferBlockTrigger.Viewport */) {
4764
+ return true;
4765
+ }
4766
+ else if (typeof current === 'object' && current.trigger === 2 /* DeferBlockTrigger.Viewport */) {
4767
+ return current.intersectionObserverOptions || true;
4768
+ }
4769
+ }
4770
+ }
4771
+ return null;
4772
+ }
4730
4773
  function hasHydrateTrigger(blockData, trigger) {
4731
4774
  return blockData[DEFER_HYDRATE_TRIGGERS]?.includes(trigger) ?? false;
4732
4775
  }
@@ -4741,7 +4784,7 @@ function createBlockSummary(blockInfo) {
4741
4784
  idle: hasHydrateTrigger(blockInfo, 0 /* DeferBlockTrigger.Idle */),
4742
4785
  immediate: hasHydrateTrigger(blockInfo, 1 /* DeferBlockTrigger.Immediate */),
4743
4786
  timer: getHydrateTimerTrigger(blockInfo),
4744
- viewport: hasHydrateTrigger(blockInfo, 2 /* DeferBlockTrigger.Viewport */),
4787
+ viewport: getHydrateViewportTrigger(blockInfo),
4745
4788
  },
4746
4789
  };
4747
4790
  }
@@ -7337,117 +7380,380 @@ function determineLongestAnimationFromElementAnimations(el, animationsMap, anima
7337
7380
  }
7338
7381
  const allLeavingAnimations = new Set();
7339
7382
 
7383
+ /** Actions that are supported by the tracing framework. */
7384
+ var TracingAction;
7385
+ (function (TracingAction) {
7386
+ TracingAction[TracingAction["CHANGE_DETECTION"] = 0] = "CHANGE_DETECTION";
7387
+ TracingAction[TracingAction["AFTER_NEXT_RENDER"] = 1] = "AFTER_NEXT_RENDER";
7388
+ })(TracingAction || (TracingAction = {}));
7340
7389
  /**
7341
- * A [DI token](api/core/InjectionToken) that enables or disables all enter and leave animations.
7342
- */
7343
- const ANIMATIONS_DISABLED = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'AnimationsDisabled' : '', {
7344
- providedIn: 'root',
7345
- factory: () => false,
7346
- });
7347
- /**
7348
- * A [DI token](api/core/InjectionToken) for the queue of all animations.
7390
+ * Injection token for a `TracingService`, optionally provided.
7349
7391
  */
7350
- const ANIMATION_QUEUE = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'AnimationQueue' : '', {
7351
- providedIn: 'root',
7352
- factory: () => {
7353
- return {
7354
- queue: new Set(),
7355
- isScheduled: false,
7356
- };
7357
- },
7358
- });
7392
+ const TracingService = new InjectionToken(typeof ngDevMode !== undefined && ngDevMode ? 'TracingService' : '');
7393
+
7394
+ const markedFeatures = new Set();
7395
+ // tslint:disable:ban
7359
7396
  /**
7360
- * A [DI token](api/core/InjectionToken) that configures the maximum animation timeout
7361
- * before element removal. The default value mirrors from Chrome's cross document
7362
- * navigation view transition timeout. It's intended to prevent people from accidentally
7363
- * forgetting to call the removal function in their callback. Also serves as a delay
7364
- * for when stylesheets are pruned.
7397
+ * A guarded `performance.mark` for feature marking.
7365
7398
  *
7366
- * @publicApi 20.2
7399
+ * This method exists because while all supported browser and node.js version supported by Angular
7400
+ * support performance.mark API. This is not the case for other environments such as JSDOM and
7401
+ * Cloudflare workers.
7367
7402
  */
7368
- const MAX_ANIMATION_TIMEOUT = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'MaxAnimationTimeout' : '', {
7369
- providedIn: 'root',
7370
- factory: () => MAX_ANIMATION_TIMEOUT_DEFAULT,
7371
- });
7372
- const MAX_ANIMATION_TIMEOUT_DEFAULT = 4000;
7403
+ function performanceMarkFeature(feature) {
7404
+ if (markedFeatures.has(feature)) {
7405
+ return;
7406
+ }
7407
+ markedFeatures.add(feature);
7408
+ performance?.mark?.('mark_feature_usage', { detail: { feature } });
7409
+ }
7373
7410
 
7374
- function maybeQueueEnterAnimation(parentLView, parent, tNode, injector) {
7375
- const enterAnimations = parentLView?.[ANIMATIONS]?.enter;
7376
- if (parent !== null && enterAnimations && enterAnimations.has(tNode.index)) {
7377
- const animationQueue = injector.get(ANIMATION_QUEUE);
7378
- for (const animateFn of enterAnimations.get(tNode.index).animateFns) {
7379
- animationQueue.queue.add(animateFn);
7380
- }
7411
+ class AfterRenderManager {
7412
+ impl = null;
7413
+ execute() {
7414
+ this.impl?.execute();
7381
7415
  }
7416
+ /** @nocollapse */
7417
+ static ɵprov = /** @pureOrBreakMyCode */ /* @__PURE__ */ __defineInjectable({
7418
+ token: AfterRenderManager,
7419
+ providedIn: 'root',
7420
+ factory: () => new AfterRenderManager(),
7421
+ });
7382
7422
  }
7383
- /**
7384
- * NOTE: for performance reasons, the possible actions are inlined within the function instead of
7385
- * being passed as an argument.
7386
- */
7387
- function applyToElementOrContainer(action, renderer, injector, parent, lNodeToHandle, tNode, beforeNode, parentLView) {
7388
- // If this slot was allocated for a text node dynamically created by i18n, the text node itself
7389
- // won't be created until i18nApply() in the update block, so this node should be skipped.
7390
- // For more info, see "ICU expressions should work inside an ngTemplateOutlet inside an ngFor"
7391
- // in `i18n_spec.ts`.
7392
- if (lNodeToHandle != null) {
7393
- let lContainer;
7394
- let isComponent = false;
7395
- // We are expecting an RNode, but in the case of a component or LContainer the `RNode` is
7396
- // wrapped in an array which needs to be unwrapped. We need to know if it is a component and if
7397
- // it has LContainer so that we can process all of those cases appropriately.
7398
- if (isLContainer(lNodeToHandle)) {
7399
- lContainer = lNodeToHandle;
7400
- }
7401
- else if (isLView(lNodeToHandle)) {
7402
- isComponent = true;
7403
- ngDevMode && assertDefined(lNodeToHandle[HOST], 'HOST must be defined for a component LView');
7404
- lNodeToHandle = lNodeToHandle[HOST];
7423
+ const AFTER_RENDER_PHASES = /* @__PURE__ **/ (() => [
7424
+ 0 /* AfterRenderPhase.EarlyRead */,
7425
+ 1 /* AfterRenderPhase.Write */,
7426
+ 2 /* AfterRenderPhase.MixedReadWrite */,
7427
+ 3 /* AfterRenderPhase.Read */,
7428
+ ])();
7429
+ class AfterRenderImpl {
7430
+ ngZone = inject(NgZone);
7431
+ scheduler = inject(ChangeDetectionScheduler);
7432
+ errorHandler = inject(ErrorHandler, { optional: true });
7433
+ /** Current set of active sequences. */
7434
+ sequences = new Set();
7435
+ /** Tracks registrations made during the current set of executions. */
7436
+ deferredRegistrations = new Set();
7437
+ /** Whether the `AfterRenderManager` is currently executing hooks. */
7438
+ executing = false;
7439
+ constructor() {
7440
+ // Inject the tracing service to make sure it's initialized.
7441
+ inject(TracingService, { optional: true });
7442
+ }
7443
+ /**
7444
+ * Run the sequence of phases of hooks, once through. As a result of executing some hooks, more
7445
+ * might be scheduled.
7446
+ */
7447
+ execute() {
7448
+ const hasSequencesToExecute = this.sequences.size > 0;
7449
+ if (hasSequencesToExecute) {
7450
+ profiler(16 /* ProfilerEvent.AfterRenderHooksStart */);
7405
7451
  }
7406
- const rNode = unwrapRNode(lNodeToHandle);
7407
- if (action === 0 /* WalkTNodeTreeAction.Create */ && parent !== null) {
7408
- maybeQueueEnterAnimation(parentLView, parent, tNode, injector);
7409
- if (beforeNode == null) {
7410
- nativeAppendChild(renderer, parent, rNode);
7452
+ this.executing = true;
7453
+ for (const phase of AFTER_RENDER_PHASES) {
7454
+ for (const sequence of this.sequences) {
7455
+ if (sequence.erroredOrDestroyed || !sequence.hooks[phase]) {
7456
+ continue;
7457
+ }
7458
+ try {
7459
+ sequence.pipelinedValue = this.ngZone.runOutsideAngular(() => this.maybeTrace(() => {
7460
+ const hookFn = sequence.hooks[phase];
7461
+ const value = hookFn(sequence.pipelinedValue);
7462
+ return value;
7463
+ }, sequence.snapshot));
7464
+ }
7465
+ catch (err) {
7466
+ sequence.erroredOrDestroyed = true;
7467
+ this.errorHandler?.handleError(err);
7468
+ }
7411
7469
  }
7412
- else {
7413
- nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);
7470
+ }
7471
+ this.executing = false;
7472
+ // Cleanup step to reset sequence state and also collect one-shot sequences for removal.
7473
+ for (const sequence of this.sequences) {
7474
+ sequence.afterRun();
7475
+ if (sequence.once) {
7476
+ this.sequences.delete(sequence);
7477
+ // Destroy the sequence so its on destroy callbacks can be cleaned up
7478
+ // immediately, instead of waiting until the injector is destroyed.
7479
+ sequence.destroy();
7414
7480
  }
7415
7481
  }
7416
- else if (action === 1 /* WalkTNodeTreeAction.Insert */ && parent !== null) {
7417
- maybeQueueEnterAnimation(parentLView, parent, tNode, injector);
7418
- nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);
7482
+ for (const sequence of this.deferredRegistrations) {
7483
+ this.sequences.add(sequence);
7419
7484
  }
7420
- else if (action === 2 /* WalkTNodeTreeAction.Detach */) {
7421
- runLeaveAnimationsWithCallback(parentLView, tNode, injector, (nodeHasLeaveAnimations) => {
7422
- // the nodeHasLeaveAnimations indicates to the renderer that the element needs to
7423
- // be removed synchronously and sets the requireSynchronousElementRemoval flag in
7424
- // the renderer.
7425
- nativeRemoveNode(renderer, rNode, isComponent, nodeHasLeaveAnimations);
7426
- });
7485
+ if (this.deferredRegistrations.size > 0) {
7486
+ this.scheduler.notify(7 /* NotificationSource.RenderHook */);
7427
7487
  }
7428
- else if (action === 3 /* WalkTNodeTreeAction.Destroy */) {
7429
- runLeaveAnimationsWithCallback(parentLView, tNode, injector, () => {
7430
- renderer.destroyNode(rNode);
7431
- });
7488
+ this.deferredRegistrations.clear();
7489
+ if (hasSequencesToExecute) {
7490
+ profiler(17 /* ProfilerEvent.AfterRenderHooksEnd */);
7432
7491
  }
7433
- if (lContainer != null) {
7434
- applyContainer(renderer, action, injector, lContainer, tNode, parent, beforeNode);
7492
+ }
7493
+ register(sequence) {
7494
+ const { view } = sequence;
7495
+ if (view !== undefined) {
7496
+ // Delay adding it to the manager, add it to the view instead.
7497
+ (view[AFTER_RENDER_SEQUENCES_TO_ADD] ??= []).push(sequence);
7498
+ // Mark the view for traversal to ensure we eventually schedule the afterNextRender.
7499
+ markAncestorsForTraversal(view);
7500
+ view[FLAGS] |= 8192 /* LViewFlags.HasChildViewsToRefresh */;
7501
+ }
7502
+ else if (!this.executing) {
7503
+ this.addSequence(sequence);
7504
+ }
7505
+ else {
7506
+ this.deferredRegistrations.add(sequence);
7435
7507
  }
7436
7508
  }
7437
- }
7438
- function addToAnimationQueue(injector, animationFns) {
7439
- const animationQueue = injector.get(ANIMATION_QUEUE);
7440
- if (Array.isArray(animationFns)) {
7441
- for (const animateFn of animationFns) {
7442
- animationQueue.queue.add(animateFn);
7509
+ addSequence(sequence) {
7510
+ this.sequences.add(sequence);
7511
+ // Trigger an `ApplicationRef.tick()` if one is not already pending/running, because we have a
7512
+ // new render hook that needs to run.
7513
+ this.scheduler.notify(7 /* NotificationSource.RenderHook */);
7514
+ }
7515
+ unregister(sequence) {
7516
+ if (this.executing && this.sequences.has(sequence)) {
7517
+ // We can't remove an `AfterRenderSequence` in the middle of iteration.
7518
+ // Instead, mark it as destroyed so it doesn't run any more, and mark it as one-shot so it'll
7519
+ // be removed at the end of the current execution.
7520
+ sequence.erroredOrDestroyed = true;
7521
+ sequence.pipelinedValue = undefined;
7522
+ sequence.once = true;
7523
+ }
7524
+ else {
7525
+ // It's safe to directly remove this sequence.
7526
+ this.sequences.delete(sequence);
7527
+ this.deferredRegistrations.delete(sequence);
7443
7528
  }
7444
7529
  }
7445
- else {
7446
- animationQueue.queue.add(animationFns);
7530
+ maybeTrace(fn, snapshot) {
7531
+ // Only trace the execution if the snapshot is defined.
7532
+ return snapshot ? snapshot.run(TracingAction.AFTER_NEXT_RENDER, fn) : fn();
7447
7533
  }
7448
- }
7449
- /**
7450
- * Removes all DOM elements associated with a view.
7534
+ /** @nocollapse */
7535
+ static ɵprov = /** @pureOrBreakMyCode */ /* @__PURE__ */ __defineInjectable({
7536
+ token: AfterRenderImpl,
7537
+ providedIn: 'root',
7538
+ factory: () => new AfterRenderImpl(),
7539
+ });
7540
+ }
7541
+ class AfterRenderSequence {
7542
+ impl;
7543
+ hooks;
7544
+ view;
7545
+ once;
7546
+ snapshot;
7547
+ /**
7548
+ * Whether this sequence errored or was destroyed during this execution, and hooks should no
7549
+ * longer run for it.
7550
+ */
7551
+ erroredOrDestroyed = false;
7552
+ /**
7553
+ * The value returned by the last hook execution (if any), ready to be pipelined into the next
7554
+ * one.
7555
+ */
7556
+ pipelinedValue = undefined;
7557
+ unregisterOnDestroy;
7558
+ constructor(impl, hooks, view, once, destroyRef, snapshot = null) {
7559
+ this.impl = impl;
7560
+ this.hooks = hooks;
7561
+ this.view = view;
7562
+ this.once = once;
7563
+ this.snapshot = snapshot;
7564
+ this.unregisterOnDestroy = destroyRef?.onDestroy(() => this.destroy());
7565
+ }
7566
+ afterRun() {
7567
+ this.erroredOrDestroyed = false;
7568
+ this.pipelinedValue = undefined;
7569
+ // Clear the tracing snapshot after the initial run. This snapshot only
7570
+ // associates the initial run of the hook with the context that created it.
7571
+ // Follow-up runs are independent of that initial context and have different
7572
+ // triggers.
7573
+ this.snapshot?.dispose();
7574
+ this.snapshot = null;
7575
+ }
7576
+ destroy() {
7577
+ this.impl.unregister(this);
7578
+ this.unregisterOnDestroy?.();
7579
+ const scheduled = this.view?.[AFTER_RENDER_SEQUENCES_TO_ADD];
7580
+ if (scheduled) {
7581
+ this.view[AFTER_RENDER_SEQUENCES_TO_ADD] = scheduled.filter((s) => s !== this);
7582
+ }
7583
+ }
7584
+ }
7585
+
7586
+ function afterEveryRender(callbackOrSpec, options) {
7587
+ ngDevMode &&
7588
+ assertNotInReactiveContext(afterEveryRender, 'Call `afterEveryRender` outside of a reactive context. For example, schedule the render ' +
7589
+ 'callback inside the component constructor`.');
7590
+ if (ngDevMode && !options?.injector) {
7591
+ assertInInjectionContext(afterEveryRender);
7592
+ }
7593
+ const injector = options?.injector ?? inject(Injector);
7594
+ if (typeof ngServerMode !== 'undefined' && ngServerMode) {
7595
+ return NOOP_AFTER_RENDER_REF;
7596
+ }
7597
+ performanceMarkFeature('NgAfterRender');
7598
+ return afterEveryRenderImpl(callbackOrSpec, injector, options, /* once */ false);
7599
+ }
7600
+ function afterNextRender(callbackOrSpec, options) {
7601
+ if (ngDevMode && !options?.injector) {
7602
+ assertInInjectionContext(afterNextRender);
7603
+ }
7604
+ const injector = options?.injector ?? inject(Injector);
7605
+ if (typeof ngServerMode !== 'undefined' && ngServerMode) {
7606
+ return NOOP_AFTER_RENDER_REF;
7607
+ }
7608
+ performanceMarkFeature('NgAfterNextRender');
7609
+ return afterEveryRenderImpl(callbackOrSpec, injector, options, /* once */ true);
7610
+ }
7611
+ function getHooks(callbackOrSpec) {
7612
+ if (callbackOrSpec instanceof Function) {
7613
+ return [undefined, undefined, /* MixedReadWrite */ callbackOrSpec, undefined];
7614
+ }
7615
+ else {
7616
+ return [
7617
+ callbackOrSpec.earlyRead,
7618
+ callbackOrSpec.write,
7619
+ callbackOrSpec.mixedReadWrite,
7620
+ callbackOrSpec.read,
7621
+ ];
7622
+ }
7623
+ }
7624
+ /**
7625
+ * Shared implementation for `afterEveryRender` and `afterNextRender`.
7626
+ */
7627
+ function afterEveryRenderImpl(callbackOrSpec, injector, options, once) {
7628
+ const manager = injector.get(AfterRenderManager);
7629
+ // Lazily initialize the handler implementation, if necessary. This is so that it can be
7630
+ // tree-shaken if `afterEveryRender` and `afterNextRender` aren't used.
7631
+ manager.impl ??= injector.get(AfterRenderImpl);
7632
+ const tracing = injector.get(TracingService, null, { optional: true });
7633
+ const destroyRef = options?.manualCleanup !== true ? injector.get(DestroyRef) : null;
7634
+ const viewContext = injector.get(ViewContext, null, { optional: true });
7635
+ const sequence = new AfterRenderSequence(manager.impl, getHooks(callbackOrSpec), viewContext?.view, once, destroyRef, tracing?.snapshot(null));
7636
+ manager.impl.register(sequence);
7637
+ return sequence;
7638
+ }
7639
+ /** `AfterRenderRef` that does nothing. */
7640
+ const NOOP_AFTER_RENDER_REF = {
7641
+ destroy() { },
7642
+ };
7643
+
7644
+ /**
7645
+ * A [DI token](api/core/InjectionToken) for the queue of all animations.
7646
+ */
7647
+ const ANIMATION_QUEUE = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'AnimationQueue' : '', {
7648
+ providedIn: 'root',
7649
+ factory: () => {
7650
+ return {
7651
+ queue: new Set(),
7652
+ isScheduled: false,
7653
+ scheduler: null,
7654
+ };
7655
+ },
7656
+ });
7657
+ function addToAnimationQueue(injector, animationFns) {
7658
+ const animationQueue = injector.get(ANIMATION_QUEUE);
7659
+ if (Array.isArray(animationFns)) {
7660
+ for (const animateFn of animationFns) {
7661
+ animationQueue.queue.add(animateFn);
7662
+ }
7663
+ }
7664
+ else {
7665
+ animationQueue.queue.add(animationFns);
7666
+ }
7667
+ animationQueue.scheduler && animationQueue.scheduler(injector);
7668
+ }
7669
+ function scheduleAnimationQueue(injector) {
7670
+ const animationQueue = injector.get(ANIMATION_QUEUE);
7671
+ // We only want to schedule the animation queue if it hasn't already been scheduled.
7672
+ if (!animationQueue.isScheduled) {
7673
+ afterNextRender(() => {
7674
+ animationQueue.isScheduled = false;
7675
+ for (let animateFn of animationQueue.queue) {
7676
+ animateFn();
7677
+ }
7678
+ animationQueue.queue.clear();
7679
+ }, { injector });
7680
+ animationQueue.isScheduled = true;
7681
+ }
7682
+ }
7683
+ function initializeAnimationQueueScheduler(injector) {
7684
+ const animationQueue = injector.get(ANIMATION_QUEUE);
7685
+ animationQueue.scheduler = scheduleAnimationQueue;
7686
+ animationQueue.scheduler(injector);
7687
+ }
7688
+ function queueEnterAnimations(injector, enterAnimations) {
7689
+ for (const [_, nodeAnimations] of enterAnimations) {
7690
+ addToAnimationQueue(injector, nodeAnimations.animateFns);
7691
+ }
7692
+ }
7693
+
7694
+ function maybeQueueEnterAnimation(parentLView, parent, tNode, injector) {
7695
+ const enterAnimations = parentLView?.[ANIMATIONS]?.enter;
7696
+ if (parent !== null && enterAnimations && enterAnimations.has(tNode.index)) {
7697
+ queueEnterAnimations(injector, enterAnimations);
7698
+ }
7699
+ }
7700
+ /**
7701
+ * NOTE: for performance reasons, the possible actions are inlined within the function instead of
7702
+ * being passed as an argument.
7703
+ */
7704
+ function applyToElementOrContainer(action, renderer, injector, parent, lNodeToHandle, tNode, beforeNode, parentLView) {
7705
+ // If this slot was allocated for a text node dynamically created by i18n, the text node itself
7706
+ // won't be created until i18nApply() in the update block, so this node should be skipped.
7707
+ // For more info, see "ICU expressions should work inside an ngTemplateOutlet inside an ngFor"
7708
+ // in `i18n_spec.ts`.
7709
+ if (lNodeToHandle != null) {
7710
+ let lContainer;
7711
+ let isComponent = false;
7712
+ // We are expecting an RNode, but in the case of a component or LContainer the `RNode` is
7713
+ // wrapped in an array which needs to be unwrapped. We need to know if it is a component and if
7714
+ // it has LContainer so that we can process all of those cases appropriately.
7715
+ if (isLContainer(lNodeToHandle)) {
7716
+ lContainer = lNodeToHandle;
7717
+ }
7718
+ else if (isLView(lNodeToHandle)) {
7719
+ isComponent = true;
7720
+ ngDevMode && assertDefined(lNodeToHandle[HOST], 'HOST must be defined for a component LView');
7721
+ lNodeToHandle = lNodeToHandle[HOST];
7722
+ }
7723
+ const rNode = unwrapRNode(lNodeToHandle);
7724
+ if (action === 0 /* WalkTNodeTreeAction.Create */ && parent !== null) {
7725
+ maybeQueueEnterAnimation(parentLView, parent, tNode, injector);
7726
+ if (beforeNode == null) {
7727
+ nativeAppendChild(renderer, parent, rNode);
7728
+ }
7729
+ else {
7730
+ nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);
7731
+ }
7732
+ }
7733
+ else if (action === 1 /* WalkTNodeTreeAction.Insert */ && parent !== null) {
7734
+ maybeQueueEnterAnimation(parentLView, parent, tNode, injector);
7735
+ nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);
7736
+ }
7737
+ else if (action === 2 /* WalkTNodeTreeAction.Detach */) {
7738
+ runLeaveAnimationsWithCallback(parentLView, tNode, injector, (nodeHasLeaveAnimations) => {
7739
+ // the nodeHasLeaveAnimations indicates to the renderer that the element needs to
7740
+ // be removed synchronously and sets the requireSynchronousElementRemoval flag in
7741
+ // the renderer.
7742
+ nativeRemoveNode(renderer, rNode, isComponent, nodeHasLeaveAnimations);
7743
+ });
7744
+ }
7745
+ else if (action === 3 /* WalkTNodeTreeAction.Destroy */) {
7746
+ runLeaveAnimationsWithCallback(parentLView, tNode, injector, () => {
7747
+ renderer.destroyNode(rNode);
7748
+ });
7749
+ }
7750
+ if (lContainer != null) {
7751
+ applyContainer(renderer, action, injector, lContainer, tNode, parent, beforeNode);
7752
+ }
7753
+ }
7754
+ }
7755
+ /**
7756
+ * Removes all DOM elements associated with a view.
7451
7757
  *
7452
7758
  * Because some root nodes of the view may be containers, we sometimes need
7453
7759
  * to propagate deeply into the nested containers to remove all elements in the
@@ -7629,6 +7935,8 @@ function runLeaveAnimationsWithCallback(lView, tNode, injector, callback) {
7629
7935
  animations.skipLeaveAnimations = false;
7630
7936
  return callback(false);
7631
7937
  }
7938
+ if (lView)
7939
+ allLeavingAnimations.add(lView);
7632
7940
  addToAnimationQueue(injector, () => {
7633
7941
  // it's possible that in the time between when the leave animation was
7634
7942
  // and the time it was executed, the data structure changed. So we need
@@ -13771,7 +14079,7 @@ class ComponentFactory extends ComponentFactory$1 {
13771
14079
  }
13772
14080
  function createRootTView(rootSelectorOrNode, componentDef, componentBindings, directives) {
13773
14081
  const tAttributes = rootSelectorOrNode
13774
- ? ['ng-version', '21.0.0-next.7']
14082
+ ? ['ng-version', '21.0.0-next.9']
13775
14083
  : // Extract attributes and classes from the first selector only to match VE behavior.
13776
14084
  extractAttrsAndClassesFromSelector(componentDef.selectors[0]);
13777
14085
  let creationBindings = null;
@@ -15077,23 +15385,6 @@ function ɵɵvalidateIframeAttribute(attrValue, tagName, attrName) {
15077
15385
  return attrValue;
15078
15386
  }
15079
15387
 
15080
- const markedFeatures = new Set();
15081
- // tslint:disable:ban
15082
- /**
15083
- * A guarded `performance.mark` for feature marking.
15084
- *
15085
- * This method exists because while all supported browser and node.js version supported by Angular
15086
- * support performance.mark API. This is not the case for other environments such as JSDOM and
15087
- * Cloudflare workers.
15088
- */
15089
- function performanceMarkFeature(feature) {
15090
- if (markedFeatures.has(feature)) {
15091
- return;
15092
- }
15093
- markedFeatures.add(feature);
15094
- performance?.mark?.('mark_feature_usage', { detail: { feature } });
15095
- }
15096
-
15097
15388
  /**
15098
15389
  * Represents an instance of an `NgModule` created by an `NgModuleFactory`.
15099
15390
  * Provides access to the `NgModule` instance and related objects.
@@ -16436,258 +16727,14 @@ function getCleanupFnKeyByType(type) {
16436
16727
  return key;
16437
16728
  }
16438
16729
 
16439
- /** Actions that are supported by the tracing framework. */
16440
- var TracingAction;
16441
- (function (TracingAction) {
16442
- TracingAction[TracingAction["CHANGE_DETECTION"] = 0] = "CHANGE_DETECTION";
16443
- TracingAction[TracingAction["AFTER_NEXT_RENDER"] = 1] = "AFTER_NEXT_RENDER";
16444
- })(TracingAction || (TracingAction = {}));
16445
16730
  /**
16446
- * Injection token for a `TracingService`, optionally provided.
16731
+ * Calculates a data slot index for defer block info (either static or
16732
+ * instance-specific), given an index of a defer instruction.
16447
16733
  */
16448
- const TracingService = new InjectionToken(typeof ngDevMode !== undefined && ngDevMode ? 'TracingService' : '');
16449
-
16450
- class AfterRenderManager {
16451
- impl = null;
16452
- execute() {
16453
- this.impl?.execute();
16454
- }
16455
- /** @nocollapse */
16456
- static ɵprov = /** @pureOrBreakMyCode */ /* @__PURE__ */ __defineInjectable({
16457
- token: AfterRenderManager,
16458
- providedIn: 'root',
16459
- factory: () => new AfterRenderManager(),
16460
- });
16461
- }
16462
- const AFTER_RENDER_PHASES = /* @__PURE__ **/ (() => [
16463
- 0 /* AfterRenderPhase.EarlyRead */,
16464
- 1 /* AfterRenderPhase.Write */,
16465
- 2 /* AfterRenderPhase.MixedReadWrite */,
16466
- 3 /* AfterRenderPhase.Read */,
16467
- ])();
16468
- class AfterRenderImpl {
16469
- ngZone = inject(NgZone);
16470
- scheduler = inject(ChangeDetectionScheduler);
16471
- errorHandler = inject(ErrorHandler, { optional: true });
16472
- /** Current set of active sequences. */
16473
- sequences = new Set();
16474
- /** Tracks registrations made during the current set of executions. */
16475
- deferredRegistrations = new Set();
16476
- /** Whether the `AfterRenderManager` is currently executing hooks. */
16477
- executing = false;
16478
- constructor() {
16479
- // Inject the tracing service to make sure it's initialized.
16480
- inject(TracingService, { optional: true });
16481
- }
16482
- /**
16483
- * Run the sequence of phases of hooks, once through. As a result of executing some hooks, more
16484
- * might be scheduled.
16485
- */
16486
- execute() {
16487
- const hasSequencesToExecute = this.sequences.size > 0;
16488
- if (hasSequencesToExecute) {
16489
- profiler(16 /* ProfilerEvent.AfterRenderHooksStart */);
16490
- }
16491
- this.executing = true;
16492
- for (const phase of AFTER_RENDER_PHASES) {
16493
- for (const sequence of this.sequences) {
16494
- if (sequence.erroredOrDestroyed || !sequence.hooks[phase]) {
16495
- continue;
16496
- }
16497
- try {
16498
- sequence.pipelinedValue = this.ngZone.runOutsideAngular(() => this.maybeTrace(() => {
16499
- const hookFn = sequence.hooks[phase];
16500
- const value = hookFn(sequence.pipelinedValue);
16501
- return value;
16502
- }, sequence.snapshot));
16503
- }
16504
- catch (err) {
16505
- sequence.erroredOrDestroyed = true;
16506
- this.errorHandler?.handleError(err);
16507
- }
16508
- }
16509
- }
16510
- this.executing = false;
16511
- // Cleanup step to reset sequence state and also collect one-shot sequences for removal.
16512
- for (const sequence of this.sequences) {
16513
- sequence.afterRun();
16514
- if (sequence.once) {
16515
- this.sequences.delete(sequence);
16516
- // Destroy the sequence so its on destroy callbacks can be cleaned up
16517
- // immediately, instead of waiting until the injector is destroyed.
16518
- sequence.destroy();
16519
- }
16520
- }
16521
- for (const sequence of this.deferredRegistrations) {
16522
- this.sequences.add(sequence);
16523
- }
16524
- if (this.deferredRegistrations.size > 0) {
16525
- this.scheduler.notify(7 /* NotificationSource.RenderHook */);
16526
- }
16527
- this.deferredRegistrations.clear();
16528
- if (hasSequencesToExecute) {
16529
- profiler(17 /* ProfilerEvent.AfterRenderHooksEnd */);
16530
- }
16531
- }
16532
- register(sequence) {
16533
- const { view } = sequence;
16534
- if (view !== undefined) {
16535
- // Delay adding it to the manager, add it to the view instead.
16536
- (view[AFTER_RENDER_SEQUENCES_TO_ADD] ??= []).push(sequence);
16537
- // Mark the view for traversal to ensure we eventually schedule the afterNextRender.
16538
- markAncestorsForTraversal(view);
16539
- view[FLAGS] |= 8192 /* LViewFlags.HasChildViewsToRefresh */;
16540
- }
16541
- else if (!this.executing) {
16542
- this.addSequence(sequence);
16543
- }
16544
- else {
16545
- this.deferredRegistrations.add(sequence);
16546
- }
16547
- }
16548
- addSequence(sequence) {
16549
- this.sequences.add(sequence);
16550
- // Trigger an `ApplicationRef.tick()` if one is not already pending/running, because we have a
16551
- // new render hook that needs to run.
16552
- this.scheduler.notify(7 /* NotificationSource.RenderHook */);
16553
- }
16554
- unregister(sequence) {
16555
- if (this.executing && this.sequences.has(sequence)) {
16556
- // We can't remove an `AfterRenderSequence` in the middle of iteration.
16557
- // Instead, mark it as destroyed so it doesn't run any more, and mark it as one-shot so it'll
16558
- // be removed at the end of the current execution.
16559
- sequence.erroredOrDestroyed = true;
16560
- sequence.pipelinedValue = undefined;
16561
- sequence.once = true;
16562
- }
16563
- else {
16564
- // It's safe to directly remove this sequence.
16565
- this.sequences.delete(sequence);
16566
- this.deferredRegistrations.delete(sequence);
16567
- }
16568
- }
16569
- maybeTrace(fn, snapshot) {
16570
- // Only trace the execution if the snapshot is defined.
16571
- return snapshot ? snapshot.run(TracingAction.AFTER_NEXT_RENDER, fn) : fn();
16572
- }
16573
- /** @nocollapse */
16574
- static ɵprov = /** @pureOrBreakMyCode */ /* @__PURE__ */ __defineInjectable({
16575
- token: AfterRenderImpl,
16576
- providedIn: 'root',
16577
- factory: () => new AfterRenderImpl(),
16578
- });
16579
- }
16580
- class AfterRenderSequence {
16581
- impl;
16582
- hooks;
16583
- view;
16584
- once;
16585
- snapshot;
16586
- /**
16587
- * Whether this sequence errored or was destroyed during this execution, and hooks should no
16588
- * longer run for it.
16589
- */
16590
- erroredOrDestroyed = false;
16591
- /**
16592
- * The value returned by the last hook execution (if any), ready to be pipelined into the next
16593
- * one.
16594
- */
16595
- pipelinedValue = undefined;
16596
- unregisterOnDestroy;
16597
- constructor(impl, hooks, view, once, destroyRef, snapshot = null) {
16598
- this.impl = impl;
16599
- this.hooks = hooks;
16600
- this.view = view;
16601
- this.once = once;
16602
- this.snapshot = snapshot;
16603
- this.unregisterOnDestroy = destroyRef?.onDestroy(() => this.destroy());
16604
- }
16605
- afterRun() {
16606
- this.erroredOrDestroyed = false;
16607
- this.pipelinedValue = undefined;
16608
- // Clear the tracing snapshot after the initial run. This snapshot only
16609
- // associates the initial run of the hook with the context that created it.
16610
- // Follow-up runs are independent of that initial context and have different
16611
- // triggers.
16612
- this.snapshot?.dispose();
16613
- this.snapshot = null;
16614
- }
16615
- destroy() {
16616
- this.impl.unregister(this);
16617
- this.unregisterOnDestroy?.();
16618
- const scheduled = this.view?.[AFTER_RENDER_SEQUENCES_TO_ADD];
16619
- if (scheduled) {
16620
- this.view[AFTER_RENDER_SEQUENCES_TO_ADD] = scheduled.filter((s) => s !== this);
16621
- }
16622
- }
16623
- }
16624
-
16625
- function afterEveryRender(callbackOrSpec, options) {
16626
- ngDevMode &&
16627
- assertNotInReactiveContext(afterEveryRender, 'Call `afterEveryRender` outside of a reactive context. For example, schedule the render ' +
16628
- 'callback inside the component constructor`.');
16629
- if (ngDevMode && !options?.injector) {
16630
- assertInInjectionContext(afterEveryRender);
16631
- }
16632
- const injector = options?.injector ?? inject(Injector);
16633
- if (typeof ngServerMode !== 'undefined' && ngServerMode) {
16634
- return NOOP_AFTER_RENDER_REF;
16635
- }
16636
- performanceMarkFeature('NgAfterRender');
16637
- return afterEveryRenderImpl(callbackOrSpec, injector, options, /* once */ false);
16638
- }
16639
- function afterNextRender(callbackOrSpec, options) {
16640
- if (ngDevMode && !options?.injector) {
16641
- assertInInjectionContext(afterNextRender);
16642
- }
16643
- const injector = options?.injector ?? inject(Injector);
16644
- if (typeof ngServerMode !== 'undefined' && ngServerMode) {
16645
- return NOOP_AFTER_RENDER_REF;
16646
- }
16647
- performanceMarkFeature('NgAfterNextRender');
16648
- return afterEveryRenderImpl(callbackOrSpec, injector, options, /* once */ true);
16649
- }
16650
- function getHooks(callbackOrSpec) {
16651
- if (callbackOrSpec instanceof Function) {
16652
- return [undefined, undefined, /* MixedReadWrite */ callbackOrSpec, undefined];
16653
- }
16654
- else {
16655
- return [
16656
- callbackOrSpec.earlyRead,
16657
- callbackOrSpec.write,
16658
- callbackOrSpec.mixedReadWrite,
16659
- callbackOrSpec.read,
16660
- ];
16661
- }
16662
- }
16663
- /**
16664
- * Shared implementation for `afterEveryRender` and `afterNextRender`.
16665
- */
16666
- function afterEveryRenderImpl(callbackOrSpec, injector, options, once) {
16667
- const manager = injector.get(AfterRenderManager);
16668
- // Lazily initialize the handler implementation, if necessary. This is so that it can be
16669
- // tree-shaken if `afterEveryRender` and `afterNextRender` aren't used.
16670
- manager.impl ??= injector.get(AfterRenderImpl);
16671
- const tracing = injector.get(TracingService, null, { optional: true });
16672
- const destroyRef = options?.manualCleanup !== true ? injector.get(DestroyRef) : null;
16673
- const viewContext = injector.get(ViewContext, null, { optional: true });
16674
- const sequence = new AfterRenderSequence(manager.impl, getHooks(callbackOrSpec), viewContext?.view, once, destroyRef, tracing?.snapshot(null));
16675
- manager.impl.register(sequence);
16676
- return sequence;
16677
- }
16678
- /** `AfterRenderRef` that does nothing. */
16679
- const NOOP_AFTER_RENDER_REF = {
16680
- destroy() { },
16681
- };
16682
-
16683
- /**
16684
- * Calculates a data slot index for defer block info (either static or
16685
- * instance-specific), given an index of a defer instruction.
16686
- */
16687
- function getDeferBlockDataIndex(deferBlockIndex) {
16688
- // Instance state is located at the *next* position
16689
- // after the defer block slot in an LView or TView.data.
16690
- return deferBlockIndex + 1;
16734
+ function getDeferBlockDataIndex(deferBlockIndex) {
16735
+ // Instance state is located at the *next* position
16736
+ // after the defer block slot in an LView or TView.data.
16737
+ return deferBlockIndex + 1;
16691
16738
  }
16692
16739
  /** Retrieves a defer block state from an LView, given a TNode that represents a block. */
16693
16740
  function getLDeferBlockDetails(lView, tNode) {
@@ -16831,9 +16878,9 @@ function trackTriggerForDebugging(tView, tNode, textRepresentation) {
16831
16878
  * @param callback Callback to be invoked when the trigger comes into the viewport.
16832
16879
  * @param injector Injector that can be used by the trigger to resolve DI tokens.
16833
16880
  */
16834
- function onViewportWrapper(trigger, callback, injector) {
16881
+ function onViewportWrapper(trigger, callback, injector, wrapperOptions) {
16835
16882
  const ngZone = injector.get(NgZone);
16836
- return onViewport(trigger, () => ngZone.run(callback), () => ngZone.runOutsideAngular(() => createIntersectionObserver()));
16883
+ return onViewport(trigger, () => ngZone.run(callback), (options) => ngZone.runOutsideAngular(() => createIntersectionObserver(options)), wrapperOptions);
16837
16884
  }
16838
16885
  /**
16839
16886
  * Helper function to get the LView in which a deferred block's trigger is rendered.
@@ -16886,7 +16933,7 @@ function getTriggerElement(triggerLView, triggerIndex) {
16886
16933
  * the deferred block.
16887
16934
  * @param type Trigger type to distinguish between regular and prefetch triggers.
16888
16935
  */
16889
- function registerDomTrigger(initialLView, tNode, triggerIndex, walkUpTimes, registerFn, callback, type) {
16936
+ function registerDomTrigger(initialLView, tNode, triggerIndex, walkUpTimes, registerFn, callback, type, options) {
16890
16937
  const injector = initialLView[INJECTOR];
16891
16938
  const zone = injector.get(NgZone);
16892
16939
  let poll;
@@ -16925,7 +16972,7 @@ function registerDomTrigger(initialLView, tNode, triggerIndex, walkUpTimes, regi
16925
16972
  }
16926
16973
  callback();
16927
16974
  });
16928
- }, injector);
16975
+ }, injector, options);
16929
16976
  // The trigger and deferred block might be in different LViews.
16930
16977
  // For the main LView the cleanup would happen as a part of
16931
16978
  // `storeTriggerCleanupFn` logic. For trigger LView we register
@@ -17744,6 +17791,9 @@ function injectorProfilerEventHandler(injectorProfilerEvent) {
17744
17791
  else if (type === 3 /* InjectorProfilerEventType.EffectCreated */) {
17745
17792
  handleEffectCreatedEvent(context, injectorProfilerEvent.effect);
17746
17793
  }
17794
+ else if (type === 4 /* InjectorProfilerEventType.AfterRenderEffectPhaseCreated */) {
17795
+ handleEffectCreatedEvent(context, injectorProfilerEvent.effectPhase);
17796
+ }
17747
17797
  }
17748
17798
  function handleEffectCreatedEvent(context, effect) {
17749
17799
  const diResolver = getDIResolver(context.injector);
@@ -18754,7 +18804,15 @@ function extractEffectsFromInjector(injector) {
18754
18804
  }
18755
18805
  const resolverToEffects = getFrameworkDIDebugData().resolverToEffects;
18756
18806
  const effects = resolverToEffects.get(diResolver) ?? [];
18757
- return effects.map((effect) => effect[SIGNAL]);
18807
+ return effects.map((effect) => {
18808
+ if (effect instanceof EffectRefImpl) {
18809
+ return effect[SIGNAL];
18810
+ }
18811
+ else {
18812
+ // Narrowing down afterRenderEffect phases
18813
+ return effect.signal[SIGNAL];
18814
+ }
18815
+ });
18758
18816
  }
18759
18817
  function extractSignalNodesAndEdgesFromRoots(nodes, signalDependenciesMap = new Map()) {
18760
18818
  for (const node of nodes) {
@@ -18813,7 +18871,7 @@ function measureEnd(startEvent, entryName, color) {
18813
18871
  }
18814
18872
  const chromeDevToolsInjectorProfiler = (event) => {
18815
18873
  const eventType = event.type;
18816
- if (eventType === 4 /* InjectorProfilerEventType.InjectorToCreateInstanceEvent */) {
18874
+ if (eventType === 5 /* InjectorProfilerEventType.InjectorToCreateInstanceEvent */) {
18817
18875
  measureStart(100 /* ProfilerDIEvent.InjectorToCreateInstanceEvent */);
18818
18876
  }
18819
18877
  else if (eventType === 1 /* InjectorProfilerEventType.InstanceCreatedByInjector */) {
@@ -20196,7 +20254,7 @@ function scheduleDelayedTrigger(scheduleFn) {
20196
20254
  *
20197
20255
  * @param scheduleFn A function that does the scheduling.
20198
20256
  */
20199
- function scheduleDelayedPrefetching(scheduleFn, trigger) {
20257
+ function scheduleDelayedPrefetching(scheduleFn) {
20200
20258
  if (typeof ngServerMode !== 'undefined' && ngServerMode)
20201
20259
  return;
20202
20260
  const lView = getLView();
@@ -20652,6 +20710,9 @@ function processAndInitTriggers(injector, blockData, nodes) {
20652
20710
  timerElements.push(elementTrigger);
20653
20711
  }
20654
20712
  if (blockSummary.hydrate.viewport) {
20713
+ if (typeof blockSummary.hydrate.viewport !== 'boolean') {
20714
+ elementTrigger.intersectionObserverOptions = blockSummary.hydrate.viewport;
20715
+ }
20655
20716
  viewportElements.push(elementTrigger);
20656
20717
  }
20657
20718
  }
@@ -20674,7 +20735,7 @@ function setViewportTriggers(injector, elementTriggers) {
20674
20735
  if (elementTriggers.length > 0) {
20675
20736
  const registry = injector.get(DEHYDRATED_BLOCK_REGISTRY);
20676
20737
  for (let elementTrigger of elementTriggers) {
20677
- const cleanupFn = onViewportWrapper(elementTrigger.el, () => triggerHydrationFromBlockName(injector, elementTrigger.blockName), injector);
20738
+ const cleanupFn = onViewportWrapper(elementTrigger.el, () => triggerHydrationFromBlockName(injector, elementTrigger.blockName), injector, elementTrigger.intersectionObserverOptions);
20678
20739
  registry.addCleanupFn(elementTrigger.blockName, cleanupFn);
20679
20740
  }
20680
20741
  }
@@ -20742,14 +20803,15 @@ function ɵɵdefer(index, primaryTmplIndex, dependencyResolverFn, loadingTmplInd
20742
20803
  const adjustedIndex = index + HEADER_OFFSET;
20743
20804
  const tNode = declareNoDirectiveHostTemplate(lView, tView, index, null, 0, 0);
20744
20805
  const injector = lView[INJECTOR];
20806
+ const incrementalHydrationEnabled = isIncrementalHydrationEnabled(injector);
20745
20807
  if (tView.firstCreatePass) {
20746
20808
  performanceMarkFeature('NgDefer');
20747
20809
  if (ngDevMode) {
20748
20810
  if (typeof ngHmrMode !== 'undefined' && ngHmrMode) {
20749
20811
  logHmrWarning(injector);
20750
20812
  }
20751
- if (hasHydrateTriggers(flags)) {
20752
- assertIncrementalHydrationIsConfigured(injector);
20813
+ if (hasHydrateTriggers(flags) && !incrementalHydrationEnabled) {
20814
+ warnIncrementalHydrationNotConfigured();
20753
20815
  }
20754
20816
  }
20755
20817
  const tDetails = {
@@ -20797,7 +20859,7 @@ function ɵɵdefer(index, primaryTmplIndex, dependencyResolverFn, loadingTmplInd
20797
20859
  ];
20798
20860
  setLDeferBlockDetails(lView, adjustedIndex, lDetails);
20799
20861
  let registry = null;
20800
- if (ssrUniqueId !== null) {
20862
+ if (ssrUniqueId !== null && incrementalHydrationEnabled) {
20801
20863
  // Store this defer block in the registry, to have an access to
20802
20864
  // internal data structures from hydration runtime code.
20803
20865
  registry = injector.get(DEHYDRATED_BLOCK_REGISTRY);
@@ -21097,7 +21159,7 @@ function ɵɵdeferHydrateOnTimer(delay) {
21097
21159
  if (!shouldAttachTrigger(2 /* TriggerType.Hydrate */, lView, tNode))
21098
21160
  return;
21099
21161
  const hydrateTriggers = getHydrateTriggers(getTView(), tNode);
21100
- hydrateTriggers.set(5 /* DeferBlockTrigger.Timer */, { delay });
21162
+ hydrateTriggers.set(5 /* DeferBlockTrigger.Timer */, { type: 5 /* DeferBlockTrigger.Timer */, delay });
21101
21163
  if (typeof ngServerMode !== 'undefined' && ngServerMode) {
21102
21164
  // We are on the server and SSR for defer blocks is enabled.
21103
21165
  triggerDeferBlock(2 /* TriggerType.Hydrate */, lView, tNode);
@@ -21234,18 +21296,25 @@ function ɵɵdeferHydrateOnInteraction() {
21234
21296
  * @param walkUpTimes Number of times to walk up/down the tree hierarchy to find the trigger.
21235
21297
  * @codeGenApi
21236
21298
  */
21237
- function ɵɵdeferOnViewport(triggerIndex, walkUpTimes) {
21299
+ function ɵɵdeferOnViewport(triggerIndex, walkUpTimes, options) {
21238
21300
  const lView = getLView();
21239
21301
  const tNode = getCurrentTNode();
21240
21302
  if (ngDevMode) {
21241
- trackTriggerForDebugging(lView[TVIEW], tNode, `on viewport${walkUpTimes === -1 ? '' : '(<target>)'}`);
21303
+ const args = [];
21304
+ if (walkUpTimes !== undefined && walkUpTimes !== -1) {
21305
+ args.push('<target>');
21306
+ }
21307
+ if (options) {
21308
+ args.push(JSON.stringify(options));
21309
+ }
21310
+ trackTriggerForDebugging(lView[TVIEW], tNode, `on viewport${args.length === 0 ? '' : `(${args.join(', ')})`}`);
21242
21311
  }
21243
21312
  if (!shouldAttachTrigger(0 /* TriggerType.Regular */, lView, tNode))
21244
21313
  return;
21245
21314
  renderPlaceholder(lView, tNode);
21246
21315
  // Avoid adding event listeners when this instruction is invoked on the server.
21247
21316
  if (!(typeof ngServerMode !== 'undefined' && ngServerMode)) {
21248
- registerDomTrigger(lView, tNode, triggerIndex, walkUpTimes, onViewportWrapper, () => triggerDeferBlock(0 /* TriggerType.Regular */, lView, tNode), 0 /* TriggerType.Regular */);
21317
+ registerDomTrigger(lView, tNode, triggerIndex, walkUpTimes, onViewportWrapper, () => triggerDeferBlock(0 /* TriggerType.Regular */, lView, tNode), 0 /* TriggerType.Regular */, options);
21249
21318
  }
21250
21319
  }
21251
21320
  /**
@@ -21254,34 +21323,46 @@ function ɵɵdeferOnViewport(triggerIndex, walkUpTimes) {
21254
21323
  * @param walkUpTimes Number of times to walk up/down the tree hierarchy to find the trigger.
21255
21324
  * @codeGenApi
21256
21325
  */
21257
- function ɵɵdeferPrefetchOnViewport(triggerIndex, walkUpTimes) {
21326
+ function ɵɵdeferPrefetchOnViewport(triggerIndex, walkUpTimes, options) {
21258
21327
  const lView = getLView();
21259
21328
  const tNode = getCurrentTNode();
21260
21329
  if (ngDevMode) {
21261
- trackTriggerForDebugging(lView[TVIEW], tNode, `prefetch on viewport${walkUpTimes === -1 ? '' : '(<target>)'}`);
21330
+ const args = [];
21331
+ if (walkUpTimes !== undefined && walkUpTimes !== -1) {
21332
+ args.push('<target>');
21333
+ }
21334
+ if (options) {
21335
+ args.push(JSON.stringify(options));
21336
+ }
21337
+ trackTriggerForDebugging(lView[TVIEW], tNode, `prefetch on viewport${args.length === 0 ? '' : `(${args.join(', ')})`}`);
21262
21338
  }
21263
21339
  if (!shouldAttachTrigger(1 /* TriggerType.Prefetch */, lView, tNode))
21264
21340
  return;
21265
21341
  const tView = lView[TVIEW];
21266
21342
  const tDetails = getTDeferBlockDetails(tView, tNode);
21267
21343
  if (tDetails.loadingState === DeferDependenciesLoadingState.NOT_STARTED) {
21268
- registerDomTrigger(lView, tNode, triggerIndex, walkUpTimes, onViewportWrapper, () => triggerPrefetching(tDetails, lView, tNode), 1 /* TriggerType.Prefetch */);
21344
+ registerDomTrigger(lView, tNode, triggerIndex, walkUpTimes, onViewportWrapper, () => triggerPrefetching(tDetails, lView, tNode), 1 /* TriggerType.Prefetch */, options);
21269
21345
  }
21270
21346
  }
21271
21347
  /**
21272
21348
  * Creates runtime data structures for the `on viewport` hydrate trigger.
21273
21349
  * @codeGenApi
21274
21350
  */
21275
- function ɵɵdeferHydrateOnViewport() {
21351
+ function ɵɵdeferHydrateOnViewport(options) {
21276
21352
  const lView = getLView();
21277
21353
  const tNode = getCurrentTNode();
21278
21354
  if (ngDevMode) {
21279
- trackTriggerForDebugging(lView[TVIEW], tNode, 'hydrate on viewport');
21355
+ trackTriggerForDebugging(lView[TVIEW], tNode, `hydrate on viewport${options ? `(${JSON.stringify(options)})` : ''}`);
21280
21356
  }
21281
21357
  if (!shouldAttachTrigger(2 /* TriggerType.Hydrate */, lView, tNode))
21282
21358
  return;
21283
21359
  const hydrateTriggers = getHydrateTriggers(getTView(), tNode);
21284
- hydrateTriggers.set(2 /* DeferBlockTrigger.Viewport */, null);
21360
+ hydrateTriggers.set(2 /* DeferBlockTrigger.Viewport */, options
21361
+ ? {
21362
+ type: 2 /* DeferBlockTrigger.Viewport */,
21363
+ intersectionObserverOptions: options,
21364
+ }
21365
+ : null);
21285
21366
  if (typeof ngServerMode !== 'undefined' && ngServerMode) {
21286
21367
  // We are on the server and SSR for defer blocks is enabled.
21287
21368
  triggerDeferBlock(2 /* TriggerType.Hydrate */, lView, tNode);
@@ -21348,6 +21429,28 @@ function ɵɵattribute(name, value, sanitizer, namespace) {
21348
21429
  return ɵɵattribute;
21349
21430
  }
21350
21431
 
21432
+ /**
21433
+ * A [DI token](api/core/InjectionToken) that enables or disables all enter and leave animations.
21434
+ */
21435
+ const ANIMATIONS_DISABLED = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'AnimationsDisabled' : '', {
21436
+ providedIn: 'root',
21437
+ factory: () => false,
21438
+ });
21439
+ /**
21440
+ * A [DI token](api/core/InjectionToken) that configures the maximum animation timeout
21441
+ * before element removal. The default value mirrors from Chrome's cross document
21442
+ * navigation view transition timeout. It's intended to prevent people from accidentally
21443
+ * forgetting to call the removal function in their callback. Also serves as a delay
21444
+ * for when stylesheets are pruned.
21445
+ *
21446
+ * @publicApi 20.2
21447
+ */
21448
+ const MAX_ANIMATION_TIMEOUT = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'MaxAnimationTimeout' : '', {
21449
+ providedIn: 'root',
21450
+ factory: () => MAX_ANIMATION_TIMEOUT_DEFAULT,
21451
+ });
21452
+ const MAX_ANIMATION_TIMEOUT_DEFAULT = 4000;
21453
+
21351
21454
  const DEFAULT_ANIMATIONS_DISABLED = false;
21352
21455
  const areAnimationSupported = (typeof ngServerMode === 'undefined' || !ngServerMode) &&
21353
21456
  typeof document !== 'undefined' &&
@@ -21575,6 +21678,11 @@ function clearLViewNodeAnimationResolvers(lView, tNode) {
21575
21678
  if (nodeAnimations)
21576
21679
  nodeAnimations.resolvers = undefined;
21577
21680
  }
21681
+ function leaveAnimationFunctionCleanup(lView, tNode, nativeElement, resolvers, cleanupFns) {
21682
+ clearLeavingNodes(tNode, nativeElement);
21683
+ cleanupAfterLeaveAnimations(resolvers, cleanupFns);
21684
+ clearLViewNodeAnimationResolvers(lView, tNode);
21685
+ }
21578
21686
 
21579
21687
  /**
21580
21688
  * Instruction to handle the `animate.enter` behavior for class bindings.
@@ -21597,7 +21705,13 @@ function ɵɵanimateEnter(value) {
21597
21705
  const tNode = getCurrentTNode();
21598
21706
  cancelLeavingNodes(tNode, lView);
21599
21707
  addAnimationToLView(getLViewEnterAnimations(lView), tNode, () => runEnterAnimation(lView, tNode, value));
21600
- queueEnterAnimations(lView);
21708
+ initializeAnimationQueueScheduler(lView[INJECTOR]);
21709
+ // We have to queue here due to the animation instruction being invoked after the element
21710
+ // instruction. The DOM node has to exist before we can queue an animation. Any node that
21711
+ // is not inside of control flow needs to get queued here. For nodes inside of control
21712
+ // flow, those are queued in node_manipulation.ts and are deduped by a Set in the animation
21713
+ // queue.
21714
+ queueEnterAnimations(lView[INJECTOR], getLViewEnterAnimations(lView));
21601
21715
  return ɵɵanimateEnter; // For chaining
21602
21716
  }
21603
21717
  function runEnterAnimation(lView, tNode, value) {
@@ -21694,7 +21808,13 @@ function ɵɵanimateEnterListener(value) {
21694
21808
  const tNode = getCurrentTNode();
21695
21809
  cancelLeavingNodes(tNode, lView);
21696
21810
  addAnimationToLView(getLViewEnterAnimations(lView), tNode, () => runEnterAnimationFunction(lView, tNode, value));
21697
- queueEnterAnimations(lView);
21811
+ initializeAnimationQueueScheduler(lView[INJECTOR]);
21812
+ // We have to queue here due to the animation instruction being invoked after the element
21813
+ // instruction. The DOM node has to exist before we can queue an animation. Any node that
21814
+ // is not inside of control flow needs to get queued here. For nodes inside of control
21815
+ // flow, those are queued in node_manipulation.ts and are deduped by a Set in the animation
21816
+ // queue.
21817
+ queueEnterAnimations(lView[INJECTOR], getLViewEnterAnimations(lView));
21698
21818
  return ɵɵanimateEnterListener;
21699
21819
  }
21700
21820
  /**
@@ -21727,8 +21847,9 @@ function ɵɵanimateLeave(value) {
21727
21847
  return ɵɵanimateLeave;
21728
21848
  }
21729
21849
  const tNode = getCurrentTNode();
21850
+ cancelLeavingNodes(tNode, lView);
21730
21851
  addAnimationToLView(getLViewLeaveAnimations(lView), tNode, () => runLeaveAnimations(lView, tNode, value));
21731
- enableAnimationQueueScheduler(lView[INJECTOR]);
21852
+ initializeAnimationQueueScheduler(lView[INJECTOR]);
21732
21853
  return ɵɵanimateLeave; // For chaining
21733
21854
  }
21734
21855
  function runLeaveAnimations(lView, tNode, value) {
@@ -21824,9 +21945,10 @@ function ɵɵanimateLeaveListener(value) {
21824
21945
  // So we don't have an early return here.
21825
21946
  const lView = getLView();
21826
21947
  const tNode = getCurrentTNode();
21948
+ cancelLeavingNodes(tNode, lView);
21827
21949
  allLeavingAnimations.add(lView);
21828
21950
  addAnimationToLView(getLViewLeaveAnimations(lView), tNode, () => runLeaveAnimationFunction(lView, tNode, value));
21829
- enableAnimationQueueScheduler(lView[INJECTOR]);
21951
+ initializeAnimationQueueScheduler(lView[INJECTOR]);
21830
21952
  return ɵɵanimateLeaveListener; // For chaining
21831
21953
  }
21832
21954
  /**
@@ -21836,65 +21958,36 @@ function runLeaveAnimationFunction(lView, tNode, value) {
21836
21958
  const { promise, resolve } = promiseWithResolvers();
21837
21959
  const nativeElement = getNativeByTNode(tNode, lView);
21838
21960
  ngDevMode && assertElementNodes(nativeElement, 'animate.leave');
21961
+ const cleanupFns = [];
21839
21962
  const renderer = lView[RENDERER];
21840
21963
  const animationsDisabled = areAnimationsDisabled(lView);
21841
21964
  const ngZone = lView[INJECTOR].get(NgZone);
21842
21965
  const maxAnimationTimeout = lView[INJECTOR].get(MAX_ANIMATION_TIMEOUT);
21966
+ (getLViewLeaveAnimations(lView).get(tNode.index).resolvers ??= []).push(resolve);
21967
+ const resolvers = getLViewLeaveAnimations(lView).get(tNode.index)?.resolvers;
21843
21968
  if (animationsDisabled) {
21844
- resolve();
21969
+ leaveAnimationFunctionCleanup(lView, tNode, nativeElement, resolvers, cleanupFns);
21845
21970
  }
21846
21971
  else {
21847
- const timeoutId = setTimeout(() => {
21848
- clearLeavingNodes(tNode, nativeElement);
21849
- resolve();
21850
- }, maxAnimationTimeout);
21972
+ const timeoutId = setTimeout(() => leaveAnimationFunctionCleanup(lView, tNode, nativeElement, resolvers, cleanupFns), maxAnimationTimeout);
21851
21973
  const event = {
21852
21974
  target: nativeElement,
21853
21975
  animationComplete: () => {
21854
- clearLeavingNodes(tNode, nativeElement);
21976
+ leaveAnimationFunctionCleanup(lView, tNode, nativeElement, resolvers, cleanupFns);
21855
21977
  clearTimeout(timeoutId);
21856
- resolve();
21857
21978
  },
21858
21979
  };
21859
21980
  trackLeavingNodes(tNode, nativeElement);
21860
21981
  ngZone.runOutsideAngular(() => {
21861
- renderer.listen(nativeElement, 'animationend', () => {
21862
- resolve();
21863
- }, { once: true });
21982
+ cleanupFns.push(renderer.listen(nativeElement, 'animationend', () => {
21983
+ leaveAnimationFunctionCleanup(lView, tNode, nativeElement, resolvers, cleanupFns);
21984
+ clearTimeout(timeoutId);
21985
+ }, { once: true }));
21864
21986
  });
21865
21987
  value.call(lView[CONTEXT], event);
21866
21988
  }
21867
21989
  // Ensure cleanup if the LView is destroyed before the animation runs.
21868
- return promise;
21869
- }
21870
- function queueEnterAnimations(lView) {
21871
- enableAnimationQueueScheduler(lView[INJECTOR]);
21872
- const enterAnimations = lView[ANIMATIONS]?.enter;
21873
- if (enterAnimations) {
21874
- const animationQueue = lView[INJECTOR].get(ANIMATION_QUEUE);
21875
- for (const [_, nodeAnimations] of enterAnimations) {
21876
- for (const animateFn of nodeAnimations.animateFns) {
21877
- animationQueue.queue.add(animateFn);
21878
- }
21879
- }
21880
- }
21881
- }
21882
- function enableAnimationQueueScheduler(injector) {
21883
- const animationQueue = injector.get(ANIMATION_QUEUE);
21884
- // We only need to schedule the animation queue runner once per application.
21885
- if (!animationQueue.isScheduled) {
21886
- afterEveryRender(() => {
21887
- runQueuedAnimations(injector);
21888
- }, { injector });
21889
- animationQueue.isScheduled = true;
21890
- }
21891
- }
21892
- function runQueuedAnimations(injector) {
21893
- const animationQueue = injector.get(ANIMATION_QUEUE);
21894
- for (let animateFn of animationQueue.queue) {
21895
- animateFn();
21896
- }
21897
- animationQueue.queue.clear();
21990
+ return { promise, resolve };
21898
21991
  }
21899
21992
 
21900
21993
  /*!
@@ -21923,44 +22016,38 @@ const ɵCONTROL = Symbol('CONTROL');
21923
22016
  /**
21924
22017
  * Possibly sets up a {@link ɵControl} to manage a native or custom form control.
21925
22018
  *
21926
- * Setup occurs if a `control` input is bound to a {@link ɵControl} directive on the current node,
21927
- * but not to a component. If a `control` input is bound to a component, we assume the component
22019
+ * Setup occurs if a `field` input is bound to a {@link ɵControl} directive on the current node,
22020
+ * but not to a component. If a `field` input is bound to a component, we assume the component
21928
22021
  * will manage the control in its own template.
21929
22022
  *
21930
22023
  * @codeGenApi
21931
22024
  */
21932
22025
  function ɵɵcontrolCreate() {
21933
22026
  const lView = getLView();
22027
+ const tView = getTView();
21934
22028
  const tNode = getCurrentTNode();
21935
- // TODO(https://github.com/orgs/angular/projects/60/views/1?pane=issue&itemId=131712274)
21936
- // * cache the control directive index or instance for reuse.
21937
- const control = getControlDirective(tNode, lView);
22029
+ const control = tView.firstCreatePass
22030
+ ? getControlDirectiveFirstCreatePass(tView, tNode, lView)
22031
+ : getControlDirective(tNode, lView);
21938
22032
  if (!control) {
21939
22033
  return;
21940
22034
  }
21941
- // TODO(https://github.com/orgs/angular/projects/60/views/1?pane=issue&itemId=131712274):
21942
- // * cache the custom control component index or instance for reuse.
21943
- // * cache the control model name for reuse.
21944
- const customControl = getCustomControlComponent(tNode);
21945
- if (customControl) {
21946
- const [componentIndex, modelName] = customControl;
21947
- listenToCustomControl(lView, tNode, control, componentIndex, modelName);
22035
+ if (tNode.flags & 2048 /* TNodeFlags.isFormValueControl */) {
22036
+ listenToCustomControl(lView, tNode, control, 'value');
21948
22037
  }
21949
- else if (isNativeControl(lView, tNode)) {
21950
- listenToNativeControl(lView, tNode, control);
22038
+ else if (tNode.flags & 4096 /* TNodeFlags.isFormCheckboxControl */) {
22039
+ listenToCustomControl(lView, tNode, control, 'checked');
22040
+ }
22041
+ else if (tNode.flags & 8192 /* TNodeFlags.isInteropControl */) {
22042
+ control.ɵinteropControlCreate();
21951
22043
  }
21952
22044
  else {
21953
- // For example, user wrote <div [control]="f">.
21954
- // TODO: https://github.com/orgs/angular/projects/60/views/1?pane=issue&itemId=131860276
21955
- const tagName = tNode.value;
21956
- throw new RuntimeError(318 /* RuntimeErrorCode.INVALID_CONTROL_HOST */, `'<${tagName}>' is an invalid control host. The host must be a native form control (such ` +
21957
- `as <input>', '<select>', or '<textarea>') or a custom form control component with a ` +
21958
- `'value' or 'checked' model.`);
22045
+ listenToNativeControl(lView, tNode, control);
21959
22046
  }
21960
- control.register();
22047
+ controlregister();
21961
22048
  }
21962
22049
  /**
21963
- * Updates a `control` property, and possibly other form control properties, on the current element.
22050
+ * Updates a `field` property, and possibly other form control properties, on the current element.
21964
22051
  *
21965
22052
  * This is a specialized version of the `ɵɵproperty` instruction that handles updating additional
21966
22053
  * form control properties, if set up to do so by {@link ɵɵcontrolCreate} during creation.
@@ -21972,88 +22059,104 @@ function ɵɵcontrolCreate() {
21972
22059
  */
21973
22060
  function ɵɵcontrol(value, sanitizer) {
21974
22061
  const lView = getLView();
21975
- const bindingIndex = nextBindingIndex();
21976
22062
  const tNode = getSelectedTNode();
22063
+ const bindingIndex = nextBindingIndex();
21977
22064
  if (bindingUpdated(lView, bindingIndex, value)) {
21978
22065
  const tView = getTView();
21979
- setPropertyAndInputs(tNode, lView, 'control', value, lView[RENDERER], sanitizer);
21980
- ngDevMode && storePropertyBindingMetadata(tView.data, tNode, 'control', bindingIndex);
22066
+ setPropertyAndInputs(tNode, lView, 'field', value, lView[RENDERER], sanitizer);
22067
+ ngDevMode && storePropertyBindingMetadata(tView.data, tNode, 'field', bindingIndex);
21981
22068
  }
21982
- // TODO: https://github.com/orgs/angular/projects/60/views/1?pane=issue&itemId=131711472
21983
- // * only run if this is really a control binding determine in the create pass.
21984
22069
  const control = getControlDirective(tNode, lView);
21985
- if (!control) {
21986
- return;
21987
- }
21988
- const customControl = getCustomControlComponent(tNode);
21989
- if (customControl) {
21990
- const [componentIndex, modelName] = customControl;
21991
- updateCustomControl(lView, componentIndex, modelName, control);
21992
- }
21993
- else {
21994
- updateNativeControl(tNode, lView, control);
22070
+ if (control) {
22071
+ if (tNode.flags & 2048 /* TNodeFlags.isFormValueControl */) {
22072
+ updateCustomControl(tNode, lView, control, 'value');
22073
+ }
22074
+ else if (tNode.flags & 4096 /* TNodeFlags.isFormCheckboxControl */) {
22075
+ updateCustomControl(tNode, lView, control, 'checked');
22076
+ }
22077
+ else if (tNode.flags & 8192 /* TNodeFlags.isInteropControl */) {
22078
+ control.ɵinteropControlUpdate();
22079
+ }
22080
+ else {
22081
+ updateNativeControl(tNode, lView, control);
22082
+ }
21995
22083
  }
21996
22084
  }
21997
- /**
21998
- * Returns the {@link ɵControl} directive on the specified node, if one is present and a `control`
21999
- * input is bound to it, but not to a component. If a `control` input is bound to a component, we
22000
- * assume the component will manage the control in its own template and return nothing to indicate
22001
- * that the directive should not be set up.
22002
- *
22003
- * @param tNode The `TNode` of the element to check.
22004
- * @param lView The `LView` that contains the element.
22005
- */
22006
- function getControlDirective(tNode, lView) {
22007
- const directiveIndices = tNode.inputs?.['control'];
22085
+ function getControlDirectiveFirstCreatePass(tView, tNode, lView) {
22086
+ const directiveIndices = tNode.inputs?.['field'];
22008
22087
  if (!directiveIndices) {
22009
- // There are no matching inputs for the `[control]` property binding.
22088
+ // There are no matching inputs for the `[field]` property binding.
22010
22089
  return;
22011
22090
  }
22091
+ let componentIndex;
22012
22092
  if (isComponentHost(tNode)) {
22013
- const componentIndex = tNode.directiveStart + tNode.componentOffset;
22093
+ componentIndex = tNode.directiveStart + tNode.componentOffset;
22014
22094
  if (directiveIndices.includes(componentIndex)) {
22015
- // If component has a `control` input, we assume that it will handle binding the field to the
22095
+ // If component has a `field` input, we assume that it will handle binding the field to the
22016
22096
  // appropriate native/custom control in its template, so we do not attempt to bind any inputs
22017
22097
  // on this component.
22018
22098
  return;
22019
22099
  }
22020
22100
  }
22021
- // Search for the `Control` directive.
22022
- for (let index of directiveIndices) {
22023
- const directive = lView[index];
22024
- if (ɵCONTROL in directive) {
22025
- return directive;
22101
+ // Search for the Control` directive.
22102
+ const control = findControlDirective(lView, directiveIndices);
22103
+ if (!control) {
22104
+ // The `ɵControl` directive was not imported by this component.
22105
+ return;
22106
+ }
22107
+ tNode.flags |= 1024 /* TNodeFlags.isFormControl */;
22108
+ if (isComponentHost(tNode)) {
22109
+ const componentDef = tView.data[componentIndex];
22110
+ // TODO: should we check that any additional field state inputs are signal based?
22111
+ if (hasModelInput(componentDef, 'value')) {
22112
+ tNode.flags |= 2048 /* TNodeFlags.isFormValueControl */;
22113
+ return control;
22114
+ }
22115
+ else if (hasModelInput(componentDef, 'checked')) {
22116
+ tNode.flags |= 4096 /* TNodeFlags.isFormCheckboxControl */;
22117
+ return control;
22026
22118
  }
22027
22119
  }
22028
- // The `Control` directive was not imported by this component.
22029
- return;
22120
+ if (control.ɵhasInteropControl) {
22121
+ tNode.flags |= 8192 /* TNodeFlags.isInteropControl */;
22122
+ return control;
22123
+ }
22124
+ if (isNativeControl(tNode)) {
22125
+ if (isNumericInput(tNode)) {
22126
+ tNode.flags |= 16384 /* TNodeFlags.isNativeNumericControl */;
22127
+ }
22128
+ if (isTextControl(tNode)) {
22129
+ tNode.flags |= 32768 /* TNodeFlags.isNativeTextControl */;
22130
+ }
22131
+ return control;
22132
+ }
22133
+ const tagName = tNode.value;
22134
+ throw new RuntimeError(318 /* RuntimeErrorCode.INVALID_FIELD_DIRECTIVE_HOST */, `'<${tagName}>' is an invalid [field] directive host. The host must be a native form control ` +
22135
+ `(such as <input>', '<select>', or '<textarea>') or a custom form control component with a ` +
22136
+ `'value' or 'checked' model.`);
22030
22137
  }
22031
22138
  /**
22032
- * Returns information about the component on the specified node, if it appears to be a custom form
22033
- * control.
22034
- *
22035
- * A component is considered a custom form control if it has a model input named `value` or
22036
- * `checked`.
22139
+ * Returns the {@link ɵControl} directive on the specified node, if one is present and a `field`
22140
+ * input is bound to it, but not to a component. If a `field` input is bound to a component, we
22141
+ * assume the component will manage the control in its own template and return nothing to indicate
22142
+ * that the directive should not be set up.
22037
22143
  *
22038
22144
  * @param tNode The `TNode` of the element to check.
22039
- * @returns an array containing the component index and model input name if it's a custom form
22040
- * control, or undefined.
22145
+ * @param lView The `LView` that contains the element.
22041
22146
  */
22042
- function getCustomControlComponent(tNode) {
22043
- if (!isComponentHost(tNode)) {
22044
- return;
22045
- }
22046
- const tView = getTView();
22047
- const componentIndex = tNode.directiveStart + tNode.componentOffset;
22048
- const componentDef = tView.data[componentIndex];
22049
- if (hasModelInput(componentDef, 'value')) {
22050
- return [componentIndex, 'value'];
22051
- }
22052
- if (hasModelInput(componentDef, 'checked')) {
22053
- return [componentIndex, 'checked'];
22147
+ function getControlDirective(tNode, lView) {
22148
+ return tNode.flags & 1024 /* TNodeFlags.isFormControl */
22149
+ ? findControlDirective(lView, tNode.inputs['field'])
22150
+ : undefined;
22151
+ }
22152
+ function findControlDirective(lView, directiveIndices) {
22153
+ for (let index of directiveIndices) {
22154
+ const directive = lView[index];
22155
+ if (ɵCONTROL in directive) {
22156
+ return directive;
22157
+ }
22054
22158
  }
22055
- // TODO: https://github.com/orgs/angular/projects/60/views/1?pane=issue&itemId=131861022
22056
- // * should we check that any additional field state inputs are signal based?
22159
+ // The `Field` directive was not imported by this component.
22057
22160
  return;
22058
22161
  }
22059
22162
  /** Returns whether the specified `componentDef` has a model input named `name`. */
@@ -22070,7 +22173,7 @@ function hasOutput(componentDef, name) {
22070
22173
  return name in componentDef.outputs;
22071
22174
  }
22072
22175
  /**
22073
- * Adds event listeners to a custom form control component to notify the `control` of changes.
22176
+ * Adds event listeners to a custom form control component to notify the `field` of changes.
22074
22177
  *
22075
22178
  * @param lView The `LView` that contains the custom form control.
22076
22179
  * @param tNode The `TNode` of the custom form control.
@@ -22078,10 +22181,13 @@ function hasOutput(componentDef, name) {
22078
22181
  * @param componentIndex The index of the custom form control component in the `LView`.
22079
22182
  * @param modelName The name of the model property on the custom form control.
22080
22183
  */
22081
- function listenToCustomControl(lView, tNode, control, componentIndex, modelName) {
22184
+ function listenToCustomControl(lView, tNode, control, modelName) {
22185
+ const componentIndex = tNode.directiveStart + tNode.componentOffset;
22082
22186
  const outputName = modelName + 'Change';
22083
22187
  listenToOutput(tNode, lView, componentIndex, outputName, outputName, wrapListener(tNode, lView, (newValue) => {
22084
- control.state().value.set(newValue);
22188
+ const state = control.state();
22189
+ state.value.set(newValue);
22190
+ state.markAsDirty();
22085
22191
  }));
22086
22192
  const tView = getTView();
22087
22193
  const componentDef = tView.data[componentIndex];
@@ -22092,14 +22198,15 @@ function listenToCustomControl(lView, tNode, control, componentIndex, modelName)
22092
22198
  }));
22093
22199
  }
22094
22200
  }
22095
- function isNativeControl(lView, tNode) {
22096
- const element = lView[tNode.index];
22097
- return (element instanceof HTMLInputElement ||
22098
- element instanceof HTMLSelectElement ||
22099
- element instanceof HTMLTextAreaElement);
22201
+ function isNativeControl(tNode) {
22202
+ if (tNode.type !== 2 /* TNodeType.Element */) {
22203
+ return false;
22204
+ }
22205
+ const tagName = tNode.value;
22206
+ return tagName === 'input' || tagName === 'textarea' || tagName === 'select';
22100
22207
  }
22101
22208
  /**
22102
- * Adds event listeners to a native form control element to notify the `control` of changes.
22209
+ * Adds event listeners to a native form control element to notify the `field` of changes.
22103
22210
  *
22104
22211
  * @param lView The `LView` that contains the native form control.
22105
22212
  * @param tNode The `TNode` of the native form control.
@@ -22110,26 +22217,27 @@ function listenToNativeControl(lView, tNode, control) {
22110
22217
  const renderer = lView[RENDERER];
22111
22218
  const inputListener = () => {
22112
22219
  const element = getNativeByTNode(tNode, lView);
22113
- const value = control.state().value;
22114
- value.set(getNativeControlValue(element, value));
22220
+ const state = control.state();
22221
+ state.value.set(getNativeControlValue(element, state.value));
22222
+ state.markAsDirty();
22115
22223
  };
22116
22224
  listenToDomEvent(tNode, tView, lView, undefined, renderer, 'input', inputListener, wrapListener(tNode, lView, inputListener));
22117
22225
  const blurListener = () => {
22118
- // TODO: https://github.com/orgs/angular/projects/60/views/1?pane=issue&itemId=131860538
22119
22226
  control.state().markAsTouched();
22120
22227
  };
22121
22228
  listenToDomEvent(tNode, tView, lView, undefined, renderer, 'blur', blurListener, wrapListener(tNode, lView, blurListener));
22122
22229
  }
22123
22230
  /**
22124
- * Updates the inputs of a custom form control component with the latest state from the `control`.
22231
+ * Updates the inputs of a custom form control component with the latest state from the `field`.
22125
22232
  *
22126
22233
  * @param lView The `LView` that contains the custom form control.
22127
22234
  * @param componentIndex The index of the custom form control component in the `LView`.
22128
22235
  * @param modelName The name of the model property on the custom form control.
22129
22236
  * @param control The `ɵControl` directive instance.
22130
22237
  */
22131
- function updateCustomControl(lView, componentIndex, modelName, control) {
22238
+ function updateCustomControl(tNode, lView, control, modelName) {
22132
22239
  const tView = getTView();
22240
+ const componentIndex = tNode.directiveStart + tNode.componentOffset;
22133
22241
  const component = lView[componentIndex];
22134
22242
  const componentDef = tView.data[componentIndex];
22135
22243
  const state = control.state();
@@ -22138,17 +22246,18 @@ function updateCustomControl(lView, componentIndex, modelName, control) {
22138
22246
  // * cache which inputs exist.
22139
22247
  writeToDirectiveInput(componentDef, component, modelName, state.value());
22140
22248
  maybeWriteToDirectiveInput(componentDef, component, 'errors', state.errors);
22249
+ maybeWriteToDirectiveInput(componentDef, component, 'invalid', state.invalid);
22141
22250
  maybeWriteToDirectiveInput(componentDef, component, 'disabled', state.disabled);
22142
22251
  maybeWriteToDirectiveInput(componentDef, component, 'disabledReasons', state.disabledReasons);
22252
+ maybeWriteToDirectiveInput(componentDef, component, 'name', state.name);
22253
+ maybeWriteToDirectiveInput(componentDef, component, 'readonly', state.readonly);
22254
+ maybeWriteToDirectiveInput(componentDef, component, 'touched', state.touched);
22143
22255
  maybeWriteToDirectiveInput(componentDef, component, 'max', state.max);
22144
22256
  maybeWriteToDirectiveInput(componentDef, component, 'maxLength', state.maxLength);
22145
- maybeWriteToDirectiveInput(componentDef, component, 'min', state.max);
22257
+ maybeWriteToDirectiveInput(componentDef, component, 'min', state.min);
22146
22258
  maybeWriteToDirectiveInput(componentDef, component, 'minLength', state.minLength);
22147
- maybeWriteToDirectiveInput(componentDef, component, 'name', state.name);
22148
22259
  maybeWriteToDirectiveInput(componentDef, component, 'pattern', state.pattern);
22149
- maybeWriteToDirectiveInput(componentDef, component, 'readOnly', state.readonly);
22150
22260
  maybeWriteToDirectiveInput(componentDef, component, 'required', state.required);
22151
- maybeWriteToDirectiveInput(componentDef, component, 'touched', state.touched);
22152
22261
  }
22153
22262
  /**
22154
22263
  * Writes the specified value to a directive input if the input exists.
@@ -22159,12 +22268,12 @@ function updateCustomControl(lView, componentIndex, modelName, control) {
22159
22268
  * @param source A function that returns the value to write.
22160
22269
  */
22161
22270
  function maybeWriteToDirectiveInput(componentDef, component, inputName, source) {
22162
- if (inputName in componentDef.inputs) {
22271
+ if (source && inputName in componentDef.inputs) {
22163
22272
  writeToDirectiveInput(componentDef, component, inputName, source());
22164
22273
  }
22165
22274
  }
22166
22275
  /**
22167
- * Updates the properties of a native form control element with the latest state from the `control`.
22276
+ * Updates the properties of a native form control element with the latest state from the `field`.
22168
22277
  *
22169
22278
  * @param tNode The `TNode` of the native form control.
22170
22279
  * @param lView The `LView` that contains the native form control.
@@ -22178,20 +22287,64 @@ function updateNativeControl(tNode, lView, control) {
22178
22287
  // * check if bindings changed before writing.
22179
22288
  setNativeControlValue(input, state.value());
22180
22289
  renderer.setAttribute(input, 'name', state.name());
22181
- setBooleanAttribute(renderer, input, 'disable', state.disabled());
22290
+ setBooleanAttribute(renderer, input, 'disabled', state.disabled());
22182
22291
  setBooleanAttribute(renderer, input, 'readonly', state.readonly());
22183
- setBooleanAttribute(renderer, input, 'required', state.required());
22184
- // TODO: https://github.com/orgs/angular/projects/60/views/1?pane=issue&itemId=131711472
22185
- // * use tag and type attribute to determine which of these properties to bind.
22186
- setOptionalAttribute(renderer, input, 'max', state.max());
22187
- setOptionalAttribute(renderer, input, 'maxLength', state.maxLength());
22188
- setOptionalAttribute(renderer, input, 'min', state.min());
22189
- setOptionalAttribute(renderer, input, 'minLength', state.minLength());
22292
+ if (state.required) {
22293
+ setBooleanAttribute(renderer, input, 'required', state.required());
22294
+ }
22295
+ if (tNode.flags & 16384 /* TNodeFlags.isNativeNumericControl */) {
22296
+ if (state.max) {
22297
+ setOptionalAttribute(renderer, input, 'max', state.max());
22298
+ }
22299
+ if (state.min) {
22300
+ setOptionalAttribute(renderer, input, 'min', state.min());
22301
+ }
22302
+ }
22303
+ if (tNode.flags & 32768 /* TNodeFlags.isNativeTextControl */) {
22304
+ if (state.maxLength) {
22305
+ setOptionalAttribute(renderer, input, 'maxLength', state.maxLength());
22306
+ }
22307
+ if (state.minLength) {
22308
+ setOptionalAttribute(renderer, input, 'minLength', state.minLength());
22309
+ }
22310
+ }
22190
22311
  }
22191
22312
  /** Checks if a given value is a Date or null */
22192
22313
  function isDateOrNull(value) {
22193
22314
  return value === null || value instanceof Date;
22194
22315
  }
22316
+ /** Returns whether `control` has a numeric input type. */
22317
+ function isNumericInput(tNode) {
22318
+ if (!tNode.attrs || tNode.value !== 'input') {
22319
+ return false;
22320
+ }
22321
+ for (let i = 0; i < tNode.attrs.length; i += 2) {
22322
+ const name = tNode.attrs[i];
22323
+ if (isNameOnlyAttributeMarker(name)) {
22324
+ break;
22325
+ }
22326
+ if (name === 'type') {
22327
+ const value = tNode.attrs[i + 1];
22328
+ return (value === 'date' ||
22329
+ value === 'datetime-local' ||
22330
+ value === 'month' ||
22331
+ value === 'number' ||
22332
+ value === 'range' ||
22333
+ value === 'time' ||
22334
+ value === 'week');
22335
+ }
22336
+ }
22337
+ return false;
22338
+ }
22339
+ /**
22340
+ * Returns whether `control` is a text-based input.
22341
+ *
22342
+ * This is not the same as an input with `type="text"`, but rather any input that accepts
22343
+ * text-based input which includes numeric types.
22344
+ */
22345
+ function isTextControl(tNode) {
22346
+ return tNode.value !== 'select';
22347
+ }
22195
22348
  /**
22196
22349
  * Returns the value from a native control element.
22197
22350
  *
@@ -23523,7 +23676,7 @@ function plural(val) {
23523
23676
  return 1;
23524
23677
  return 5;
23525
23678
  }
23526
- var localeEn = ["en", [["a", "p"], ["AM", "PM"]], [["AM", "PM"]], [["S", "M", "T", "W", "T", "F", "S"], ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]], u, [["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"], ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]], u, [["B", "A"], ["BC", "AD"], ["Before Christ", "Anno Domini"]], 0, [6, 0], ["M/d/yy", "MMM d, y", "MMMM d, y", "EEEE, MMMM d, y"], ["h:mm a", "h:mm:ss a", "h:mm:ss a z", "h:mm:ss a zzzz"], ["{1}, {0}", u, "{1} 'at' {0}", u], [".", ",", ";", "%", "+", "-", "E", "×", "‰", "∞", "NaN", ":"], ["#,##0.###", "#,##0%", "¤#,##0.00", "#E0"], "USD", "$", "US Dollar", {}, "ltr", plural];
23679
+ var localeEn = ["en", [["a", "p"], ["AM", "PM"]], [["AM", "PM"]], [["S", "M", "T", "W", "T", "F", "S"], ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]], u, [["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"], ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]], u, [["B", "A"], ["BC", "AD"], ["Before Christ", "Anno Domini"]], 0, [6, 0], ["M/d/yy", "MMM d, y", "MMMM d, y", "EEEE, MMMM d, y"], ["h:mma", "h:mm:ssa", "h:mm:ssa z", "h:mm:ssa zzzz"], ["{1}, {0}", u, u, u], [".", ",", ";", "%", "+", "-", "E", "×", "‰", "∞", "NaN", ":"], ["#,##0.###", "#,##0%", "¤#,##0.00", "#E0"], "USD", "$", "US Dollar", {}, "ltr", plural];
23527
23680
 
23528
23681
  /**
23529
23682
  * This const is used to store the locale data registered with `registerLocaleData`
@@ -31516,5 +31669,5 @@ function getDebugNode(nativeNode) {
31516
31669
  return null;
31517
31670
  }
31518
31671
 
31519
- export { AFTER_RENDER_PHASES, ANIMATIONS_DISABLED, ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, AcxChangeDetectionStrategy, AcxViewEncapsulation, AfterRenderImpl, AfterRenderManager, AfterRenderSequence, ApplicationInitStatus, ApplicationRef, Attribute, COMPILER_OPTIONS, CONTAINERS, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionSchedulerImpl, ChangeDetectionStrategy, Compiler, CompilerFactory, Component, ComponentFactory, ComponentFactory$1, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ComponentRef as ComponentRef$1, Console, DEFAULT_CURRENCY_CODE, DEFAULT_LOCALE_ID, DEFER_BLOCK_CONFIG, DEFER_BLOCK_DEPENDENCY_INTERCEPTOR, DEFER_BLOCK_ID, DEFER_BLOCK_SSR_ID_ATTRIBUTE, DEFER_BLOCK_STATE$1 as DEFER_BLOCK_STATE, DEFER_BLOCK_STATE as DEFER_BLOCK_STATE$1, DEFER_HYDRATE_TRIGGERS, DEFER_PARENT_BLOCK_ID, DEHYDRATED_BLOCK_REGISTRY, DISCONNECTED_NODES, DebugElement, DebugEventListener, DebugNode, DeferBlockBehavior, DeferBlockState, DehydratedBlockRegistry, Directive, ELEMENT_CONTAINERS, EVENT_REPLAY_ENABLED_DEFAULT, ElementRef, EnvironmentNgModuleRefAdapter, Framework, Host, HostBinding, HostListener, HydrationStatus, I18N_DATA, IMAGE_CONFIG, IMAGE_CONFIG_DEFAULTS, IS_ENABLED_BLOCKING_INITIAL_NAVIGATION, IS_EVENT_REPLAY_ENABLED, IS_HYDRATION_DOM_REUSE_ENABLED, IS_I18N_HYDRATION_ENABLED, IS_INCREMENTAL_HYDRATION_ENABLED, Inject, Injectable, Input, JSACTION_BLOCK_ELEMENT_MAP, JSACTION_EVENT_CONTRACT, LContext, LOCALE_ID, LocaleDataIndex, MAX_ANIMATION_TIMEOUT, MULTIPLIER, MissingTranslationStrategy, ModuleWithComponentFactories, NGH_ATTR_NAME, NGH_DATA_KEY, NGH_DEFER_BLOCKS_KEY, NODES, NOOP_AFTER_RENDER_REF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE, NO_ERRORS_SCHEMA, NUM_ROOT_NODES, NgModule, NgModuleFactory, NgModuleFactory$1, NgModuleRef, NgModuleRef$1, Optional, Output, PLATFORM_ID, PLATFORM_INITIALIZER, PRESERVE_HOST_CONTENT, Pipe, QueryList, ReflectionCapabilities, Renderer2, RendererFactory2, RendererStyleFlags2, SKIP_HYDRATION_ATTR_NAME, SSR_CONTENT_INTEGRITY_MARKER, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TEMPLATES, TEMPLATE_ID, TESTABILITY, TESTABILITY_GETTER, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, TimerScheduler, TracingAction, TracingService, TransferState, Type, UseExhaustiveCheckNoChanges, ViewContainerRef, ViewEncapsulation, ViewRef, _sanitizeHtml, _sanitizeUrl, afterEveryRender, afterNextRender, allLeavingAnimations, allowSanitizationBypassAndThrow, angularCoreEnv, appendDeferBlocksToJSActionMap, asNativeElements, assertComponentDef, assertStandaloneComponentType, bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl, calcPathForNode, checkNoChangesInternal, cleanupDehydratedViews, clearResolutionOfComponentResourcesQueue, collectNativeNodes, collectNativeNodesInLContainer, compileComponent, compileDirective, compileNgModule, compileNgModuleDefs, compilePipe, convertHydrateTriggersToJsAction, countBlocksSkippedByHydration, createEnvironmentInjector, createMultiResultQuerySignalFn, createNgModule, createNgModuleRef, createNgModuleRefWithProviders, createSingleResultOptionalQuerySignalFn, createSingleResultRequiredQuerySignalFn, depsTracker, devModeEqual, enableApplyRootElementTransformImpl, enableClaimDehydratedIcuCaseImpl, enableFindMatchingDehydratedViewImpl, enableLocateOrCreateContainerAnchorImpl, enableLocateOrCreateContainerRefImpl, enableLocateOrCreateElementContainerNodeImpl, enableLocateOrCreateElementNodeImpl, enableLocateOrCreateI18nNodeImpl, enableLocateOrCreateTextNodeImpl, enablePrepareI18nBlockForHydrationImpl, enableProfiling, enableRetrieveDeferBlockDataImpl, enableRetrieveHydrationInfoImpl, enableStashEventListenerImpl, findLocaleData, flushModuleScopingQueueAsMuchAsPossible, gatherDeferBlocksCommentNodes, generateStandaloneInDeclarationsError, getAsyncClassMetadataFn, getCompilerFacade, getDebugNode, getDeferBlocks$1 as getDeferBlocks, getDirectives, getDocument, getHostElement, getLContext, getLDeferBlockDetails, getLNodeForHydration, getLocaleCurrencyCode, getLocalePluralCase, getOrComputeI18nChildren, getRegisteredNgModuleType, getSanitizationBypassType, getTDeferBlockDetails, getTransferState, inferTagNameFromDefinition, inputBinding, invokeListeners, isBoundToModule, isComponentDefPendingResolution, isComponentResourceResolutionQueueEmpty, isDeferBlock, isDetachedByI18n, isDisconnectedNode, isI18nHydrationEnabled, isI18nHydrationSupportEnabled, isInSkipHydrationBlock, isIncrementalHydrationEnabled, isJsObject, isLetDeclaration, isListLikeIterable, isNgModule, isPromise, isSubscribable, isTNodeShape, isViewDirty, iterateListLike, makePropDecorator, makeStateKey, markForRefresh, noSideEffects, optionsReducer, outputBinding, patchComponentDefWithScope, performanceMarkFeature, processAndInitTriggers, processBlockData, processTextNodeBeforeSerialization, profiler, provideAppInitializer, provideNgReflectAttributes, provideZonelessChangeDetection, provideZonelessChangeDetectionInternal, publishDefaultGlobalUtils, publishExternalGlobalUtil, publishSignalConfiguration, readHydrationInfo, readPatchedLView, registerLocaleData, registerNgModuleType, remove, removeListeners, renderDeferBlockState, resetCompiledComponents, resetJitOptions, resolveComponentResources, restoreComponentResolutionQueue, setAllowDuplicateNgModuleIdsForTest, setClassMetadata, setClassMetadataAsync, setDocument, setIsI18nHydrationSupportEnabled, setJSActionAttributes, setJitOptions, setLocaleId, setStashFn, setTestabilityGetter, sharedMapFunction, sharedStashFunction, transitiveScopesFor, triggerHydrationFromBlockName, triggerResourceLoading, trySerializeI18nBlock, twoWayBinding, unregisterAllLocaleData, unsupportedProjectionOfDomNodes, unwrapSafeValue, validAppIdInitializer, validateMatchingNode, validateNodeExists, verifySsrContentsIntegrity, ɵCONTROL, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, ɵsetClassDebugInfo, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, ɵɵCopyDefinitionFeature, ɵɵExternalStylesFeature, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵadvance, ɵɵanimateEnter, ɵɵanimateEnterListener, ɵɵanimateLeave, ɵɵanimateLeaveListener, ɵɵariaProperty, ɵɵattachSourceLocations, ɵɵattribute, ɵɵclassMap, ɵɵclassProp, ɵɵcomponentInstance, ɵɵconditional, ɵɵconditionalBranchCreate, ɵɵconditionalCreate, ɵɵcontentQuery, ɵɵcontentQuerySignal, ɵɵcontrol, ɵɵcontrolCreate, ɵɵdeclareLet, ɵɵdefer, ɵɵdeferEnableTimerScheduling, ɵɵdeferHydrateNever, ɵɵdeferHydrateOnHover, ɵɵdeferHydrateOnIdle, ɵɵdeferHydrateOnImmediate, ɵɵdeferHydrateOnInteraction, ɵɵdeferHydrateOnTimer, ɵɵdeferHydrateOnViewport, ɵɵdeferHydrateWhen, ɵɵdeferOnHover, ɵɵdeferOnIdle, ɵɵdeferOnImmediate, ɵɵdeferOnInteraction, ɵɵdeferOnTimer, ɵɵdeferOnViewport, ɵɵdeferPrefetchOnHover, ɵɵdeferPrefetchOnIdle, ɵɵdeferPrefetchOnImmediate, ɵɵdeferPrefetchOnInteraction, ɵɵdeferPrefetchOnTimer, ɵɵdeferPrefetchOnViewport, ɵɵdeferPrefetchWhen, ɵɵdeferWhen, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdomElement, ɵɵdomElementContainer, ɵɵdomElementContainerEnd, ɵɵdomElementContainerStart, ɵɵdomElementEnd, ɵɵdomElementStart, ɵɵdomListener, ɵɵdomProperty, ɵɵdomTemplate, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵgetComponentDepsFactory, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵgetReplaceMetadataURL, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinjectAttribute, ɵɵinterpolate, ɵɵinterpolate1, ɵɵinterpolate2, ɵɵinterpolate3, ɵɵinterpolate4, ɵɵinterpolate5, ɵɵinterpolate6, ɵɵinterpolate7, ɵɵinterpolate8, ɵɵinterpolateV, ɵɵinvalidFactory, ɵɵlistener, ɵɵloadQuery, ɵɵnextContext, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryAdvance, ɵɵqueryRefresh, ɵɵreadContextLet, ɵɵreference, ɵɵrepeater, ɵɵrepeaterCreate, ɵɵrepeaterTrackByIdentity, ɵɵrepeaterTrackByIndex, ɵɵreplaceMetadata, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstoreLet, ɵɵstyleMap, ɵɵstyleProp, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵtwoWayBindingSet, ɵɵtwoWayListener, ɵɵtwoWayProperty, ɵɵvalidateIframeAttribute, ɵɵviewQuery, ɵɵviewQuerySignal };
31672
+ export { AFTER_RENDER_PHASES, ANIMATIONS_DISABLED, ANIMATION_MODULE_TYPE, APP_BOOTSTRAP_LISTENER, APP_ID, APP_INITIALIZER, AcxChangeDetectionStrategy, AcxViewEncapsulation, AfterRenderImpl, AfterRenderManager, AfterRenderSequence, ApplicationInitStatus, ApplicationRef, Attribute, COMPILER_OPTIONS, CONTAINERS, CSP_NONCE, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionSchedulerImpl, ChangeDetectionStrategy, Compiler, CompilerFactory, Component, ComponentFactory, ComponentFactory$1, ComponentFactoryResolver$1 as ComponentFactoryResolver, ComponentRef$1 as ComponentRef, ComponentRef as ComponentRef$1, Console, DEFAULT_CURRENCY_CODE, DEFAULT_LOCALE_ID, DEFER_BLOCK_CONFIG, DEFER_BLOCK_DEPENDENCY_INTERCEPTOR, DEFER_BLOCK_ID, DEFER_BLOCK_SSR_ID_ATTRIBUTE, DEFER_BLOCK_STATE$1 as DEFER_BLOCK_STATE, DEFER_BLOCK_STATE as DEFER_BLOCK_STATE$1, DEFER_HYDRATE_TRIGGERS, DEFER_PARENT_BLOCK_ID, DEHYDRATED_BLOCK_REGISTRY, DISCONNECTED_NODES, DebugElement, DebugEventListener, DebugNode, DeferBlockBehavior, DeferBlockState, DehydratedBlockRegistry, Directive, ELEMENT_CONTAINERS, EVENT_REPLAY_ENABLED_DEFAULT, ElementRef, EnvironmentNgModuleRefAdapter, Framework, Host, HostBinding, HostListener, HydrationStatus, I18N_DATA, IMAGE_CONFIG, IMAGE_CONFIG_DEFAULTS, IS_ENABLED_BLOCKING_INITIAL_NAVIGATION, IS_EVENT_REPLAY_ENABLED, IS_HYDRATION_DOM_REUSE_ENABLED, IS_I18N_HYDRATION_ENABLED, IS_INCREMENTAL_HYDRATION_ENABLED, Inject, Injectable, Input, JSACTION_BLOCK_ELEMENT_MAP, JSACTION_EVENT_CONTRACT, LContext, LOCALE_ID, LocaleDataIndex, MAX_ANIMATION_TIMEOUT, MULTIPLIER, MissingTranslationStrategy, ModuleWithComponentFactories, NGH_ATTR_NAME, NGH_DATA_KEY, NGH_DEFER_BLOCKS_KEY, NODES, NOOP_AFTER_RENDER_REF, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, NO_CHANGE, NO_ERRORS_SCHEMA, NUM_ROOT_NODES, NgModule, NgModuleFactory, NgModuleFactory$1, NgModuleRef, NgModuleRef$1, Optional, Output, PLATFORM_ID, PLATFORM_INITIALIZER, PRESERVE_HOST_CONTENT, Pipe, QueryList, ReflectionCapabilities, Renderer2, RendererFactory2, RendererStyleFlags2, SKIP_HYDRATION_ATTR_NAME, SSR_CONTENT_INTEGRITY_MARKER, Sanitizer, SecurityContext, Self, SimpleChange, SkipSelf, TEMPLATES, TEMPLATE_ID, TESTABILITY, TESTABILITY_GETTER, TRANSLATIONS, TRANSLATIONS_FORMAT, TemplateRef, Testability, TestabilityRegistry, TimerScheduler, TracingAction, TracingService, TransferState, Type, UseExhaustiveCheckNoChanges, ViewContainerRef, ViewEncapsulation, ViewRef, _sanitizeHtml, _sanitizeUrl, afterEveryRender, afterNextRender, allLeavingAnimations, allowSanitizationBypassAndThrow, angularCoreEnv, appendDeferBlocksToJSActionMap, asNativeElements, assertComponentDef, assertStandaloneComponentType, bypassSanitizationTrustHtml, bypassSanitizationTrustResourceUrl, bypassSanitizationTrustScript, bypassSanitizationTrustStyle, bypassSanitizationTrustUrl, calcPathForNode, checkNoChangesInternal, cleanupDehydratedViews, clearResolutionOfComponentResourcesQueue, collectNativeNodes, collectNativeNodesInLContainer, compileComponent, compileDirective, compileNgModule, compileNgModuleDefs, compilePipe, convertHydrateTriggersToJsAction, countBlocksSkippedByHydration, createEnvironmentInjector, createMultiResultQuerySignalFn, createNgModule, createNgModuleRef, createNgModuleRefWithProviders, createSingleResultOptionalQuerySignalFn, createSingleResultRequiredQuerySignalFn, depsTracker, devModeEqual, enableApplyRootElementTransformImpl, enableClaimDehydratedIcuCaseImpl, enableFindMatchingDehydratedViewImpl, enableLocateOrCreateContainerAnchorImpl, enableLocateOrCreateContainerRefImpl, enableLocateOrCreateElementContainerNodeImpl, enableLocateOrCreateElementNodeImpl, enableLocateOrCreateI18nNodeImpl, enableLocateOrCreateTextNodeImpl, enablePrepareI18nBlockForHydrationImpl, enableProfiling, enableRetrieveDeferBlockDataImpl, enableRetrieveHydrationInfoImpl, enableStashEventListenerImpl, findLocaleData, flushModuleScopingQueueAsMuchAsPossible, gatherDeferBlocksCommentNodes, generateStandaloneInDeclarationsError, getAsyncClassMetadataFn, getCompilerFacade, getDebugNode, getDeferBlocks$1 as getDeferBlocks, getDirectives, getDocument, getHostElement, getLContext, getLDeferBlockDetails, getLNodeForHydration, getLocaleCurrencyCode, getLocalePluralCase, getOrComputeI18nChildren, getRegisteredNgModuleType, getSanitizationBypassType, getTDeferBlockDetails, getTransferState, inferTagNameFromDefinition, inputBinding, invokeListeners, isBoundToModule, isComponentDefPendingResolution, isComponentResourceResolutionQueueEmpty, isDeferBlock, isDetachedByI18n, isDisconnectedNode, isI18nHydrationEnabled, isI18nHydrationSupportEnabled, isInSkipHydrationBlock, isIncrementalHydrationEnabled, isJsObject, isLetDeclaration, isListLikeIterable, isNgModule, isPromise, isSubscribable, isTNodeShape, isViewDirty, iterateListLike, makePropDecorator, makeStateKey, markForRefresh, noSideEffects, optionsReducer, outputBinding, patchComponentDefWithScope, performanceMarkFeature, processAndInitTriggers, processBlockData, processTextNodeBeforeSerialization, profiler, provideAppInitializer, provideNgReflectAttributes, provideZonelessChangeDetection, provideZonelessChangeDetectionInternal, publishDefaultGlobalUtils, publishExternalGlobalUtil, publishSignalConfiguration, readHydrationInfo, readPatchedLView, registerLocaleData, registerNgModuleType, remove, removeListeners, renderDeferBlockState, resetCompiledComponents, resetIncrementalHydrationEnabledWarnedForTests, resetJitOptions, resolveComponentResources, restoreComponentResolutionQueue, setAllowDuplicateNgModuleIdsForTest, setClassMetadata, setClassMetadataAsync, setDocument, setIsI18nHydrationSupportEnabled, setJSActionAttributes, setJitOptions, setLocaleId, setStashFn, setTestabilityGetter, sharedMapFunction, sharedStashFunction, transitiveScopesFor, triggerHydrationFromBlockName, triggerResourceLoading, trySerializeI18nBlock, twoWayBinding, unregisterAllLocaleData, unsupportedProjectionOfDomNodes, unwrapSafeValue, validAppIdInitializer, validateMatchingNode, validateNodeExists, verifySsrContentsIntegrity, ɵCONTROL, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, ɵsetClassDebugInfo, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, ɵɵCopyDefinitionFeature, ɵɵExternalStylesFeature, ɵɵHostDirectivesFeature, ɵɵInheritDefinitionFeature, ɵɵNgOnChangesFeature, ɵɵProvidersFeature, ɵɵadvance, ɵɵanimateEnter, ɵɵanimateEnterListener, ɵɵanimateLeave, ɵɵanimateLeaveListener, ɵɵariaProperty, ɵɵattachSourceLocations, ɵɵattribute, ɵɵclassMap, ɵɵclassProp, ɵɵcomponentInstance, ɵɵconditional, ɵɵconditionalBranchCreate, ɵɵconditionalCreate, ɵɵcontentQuery, ɵɵcontentQuerySignal, ɵɵcontrol, ɵɵcontrolCreate, ɵɵdeclareLet, ɵɵdefer, ɵɵdeferEnableTimerScheduling, ɵɵdeferHydrateNever, ɵɵdeferHydrateOnHover, ɵɵdeferHydrateOnIdle, ɵɵdeferHydrateOnImmediate, ɵɵdeferHydrateOnInteraction, ɵɵdeferHydrateOnTimer, ɵɵdeferHydrateOnViewport, ɵɵdeferHydrateWhen, ɵɵdeferOnHover, ɵɵdeferOnIdle, ɵɵdeferOnImmediate, ɵɵdeferOnInteraction, ɵɵdeferOnTimer, ɵɵdeferOnViewport, ɵɵdeferPrefetchOnHover, ɵɵdeferPrefetchOnIdle, ɵɵdeferPrefetchOnImmediate, ɵɵdeferPrefetchOnInteraction, ɵɵdeferPrefetchOnTimer, ɵɵdeferPrefetchOnViewport, ɵɵdeferPrefetchWhen, ɵɵdeferWhen, ɵɵdefineComponent, ɵɵdefineDirective, ɵɵdefineNgModule, ɵɵdefinePipe, ɵɵdirectiveInject, ɵɵdomElement, ɵɵdomElementContainer, ɵɵdomElementContainerEnd, ɵɵdomElementContainerStart, ɵɵdomElementEnd, ɵɵdomElementStart, ɵɵdomListener, ɵɵdomProperty, ɵɵdomTemplate, ɵɵelement, ɵɵelementContainer, ɵɵelementContainerEnd, ɵɵelementContainerStart, ɵɵelementEnd, ɵɵelementStart, ɵɵgetComponentDepsFactory, ɵɵgetCurrentView, ɵɵgetInheritedFactory, ɵɵgetReplaceMetadataURL, ɵɵi18n, ɵɵi18nApply, ɵɵi18nAttributes, ɵɵi18nEnd, ɵɵi18nExp, ɵɵi18nPostprocess, ɵɵi18nStart, ɵɵinjectAttribute, ɵɵinterpolate, ɵɵinterpolate1, ɵɵinterpolate2, ɵɵinterpolate3, ɵɵinterpolate4, ɵɵinterpolate5, ɵɵinterpolate6, ɵɵinterpolate7, ɵɵinterpolate8, ɵɵinterpolateV, ɵɵinvalidFactory, ɵɵlistener, ɵɵloadQuery, ɵɵnextContext, ɵɵpipe, ɵɵpipeBind1, ɵɵpipeBind2, ɵɵpipeBind3, ɵɵpipeBind4, ɵɵpipeBindV, ɵɵprojection, ɵɵprojectionDef, ɵɵproperty, ɵɵpureFunction0, ɵɵpureFunction1, ɵɵpureFunction2, ɵɵpureFunction3, ɵɵpureFunction4, ɵɵpureFunction5, ɵɵpureFunction6, ɵɵpureFunction7, ɵɵpureFunction8, ɵɵpureFunctionV, ɵɵqueryAdvance, ɵɵqueryRefresh, ɵɵreadContextLet, ɵɵreference, ɵɵrepeater, ɵɵrepeaterCreate, ɵɵrepeaterTrackByIdentity, ɵɵrepeaterTrackByIndex, ɵɵreplaceMetadata, ɵɵresolveBody, ɵɵresolveDocument, ɵɵresolveWindow, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, ɵɵsanitizeStyle, ɵɵsanitizeUrl, ɵɵsanitizeUrlOrResourceUrl, ɵɵsetComponentScope, ɵɵsetNgModuleScope, ɵɵstoreLet, ɵɵstyleMap, ɵɵstyleProp, ɵɵsyntheticHostListener, ɵɵsyntheticHostProperty, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, ɵɵtextInterpolate, ɵɵtextInterpolate1, ɵɵtextInterpolate2, ɵɵtextInterpolate3, ɵɵtextInterpolate4, ɵɵtextInterpolate5, ɵɵtextInterpolate6, ɵɵtextInterpolate7, ɵɵtextInterpolate8, ɵɵtextInterpolateV, ɵɵtrustConstantHtml, ɵɵtrustConstantResourceUrl, ɵɵtwoWayBindingSet, ɵɵtwoWayListener, ɵɵtwoWayProperty, ɵɵvalidateIframeAttribute, ɵɵviewQuery, ɵɵviewQuerySignal };
31520
31673
  //# sourceMappingURL=_debug_node-chunk.mjs.map