diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..058be380
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+lib/dist/
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/angular-webpack/4f31aa1b4f8d93d98bb745abb4ecb43cf8ef1f28/0.pack b/SampleApp/.angular/cache/14.2.3/angular-webpack/4f31aa1b4f8d93d98bb745abb4ecb43cf8ef1f28/0.pack
deleted file mode 100644
index 90e12f4c..00000000
Binary files a/SampleApp/.angular/cache/14.2.3/angular-webpack/4f31aa1b4f8d93d98bb745abb4ecb43cf8ef1f28/0.pack and /dev/null differ
diff --git a/SampleApp/.angular/cache/14.2.3/angular-webpack/4f31aa1b4f8d93d98bb745abb4ecb43cf8ef1f28/1.pack b/SampleApp/.angular/cache/14.2.3/angular-webpack/4f31aa1b4f8d93d98bb745abb4ecb43cf8ef1f28/1.pack
deleted file mode 100644
index 5d43d37d..00000000
Binary files a/SampleApp/.angular/cache/14.2.3/angular-webpack/4f31aa1b4f8d93d98bb745abb4ecb43cf8ef1f28/1.pack and /dev/null differ
diff --git a/SampleApp/.angular/cache/14.2.3/angular-webpack/4f31aa1b4f8d93d98bb745abb4ecb43cf8ef1f28/2.pack b/SampleApp/.angular/cache/14.2.3/angular-webpack/4f31aa1b4f8d93d98bb745abb4ecb43cf8ef1f28/2.pack
deleted file mode 100644
index 8b12324d..00000000
Binary files a/SampleApp/.angular/cache/14.2.3/angular-webpack/4f31aa1b4f8d93d98bb745abb4ecb43cf8ef1f28/2.pack and /dev/null differ
diff --git a/SampleApp/.angular/cache/14.2.3/angular-webpack/4f31aa1b4f8d93d98bb745abb4ecb43cf8ef1f28/index.pack b/SampleApp/.angular/cache/14.2.3/angular-webpack/4f31aa1b4f8d93d98bb745abb4ecb43cf8ef1f28/index.pack
deleted file mode 100644
index ecd99a26..00000000
Binary files a/SampleApp/.angular/cache/14.2.3/angular-webpack/4f31aa1b4f8d93d98bb745abb4ecb43cf8ef1f28/index.pack and /dev/null differ
diff --git a/SampleApp/.angular/cache/14.2.3/angular-webpack/4f31aa1b4f8d93d98bb745abb4ecb43cf8ef1f28/index.pack.old b/SampleApp/.angular/cache/14.2.3/angular-webpack/4f31aa1b4f8d93d98bb745abb4ecb43cf8ef1f28/index.pack.old
deleted file mode 100644
index 54621eb3..00000000
Binary files a/SampleApp/.angular/cache/14.2.3/angular-webpack/4f31aa1b4f8d93d98bb745abb4ecb43cf8ef1f28/index.pack.old and /dev/null differ
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/005a1d68d5a512c9ee40072bc9b09bc1.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/005a1d68d5a512c9ee40072bc9b09bc1.json
deleted file mode 100644
index d71bb7f6..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/005a1d68d5a512c9ee40072bc9b09bc1.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { Observable } from './Observable';\nimport { Subscription, EMPTY_SUBSCRIPTION } from './Subscription';\nimport { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';\nimport { arrRemove } from './util/arrRemove';\nimport { errorContext } from './util/errorContext';\nexport let Subject = /*#__PURE__*/(() => {\n class Subject extends Observable {\n constructor() {\n super();\n this.closed = false;\n this.currentObservers = null;\n this.observers = [];\n this.isStopped = false;\n this.hasError = false;\n this.thrownError = null;\n }\n\n lift(operator) {\n const subject = new AnonymousSubject(this, this);\n subject.operator = operator;\n return subject;\n }\n\n _throwIfClosed() {\n if (this.closed) {\n throw new ObjectUnsubscribedError();\n }\n }\n\n next(value) {\n errorContext(() => {\n this._throwIfClosed();\n\n if (!this.isStopped) {\n if (!this.currentObservers) {\n this.currentObservers = Array.from(this.observers);\n }\n\n for (const observer of this.currentObservers) {\n observer.next(value);\n }\n }\n });\n }\n\n error(err) {\n errorContext(() => {\n this._throwIfClosed();\n\n if (!this.isStopped) {\n this.hasError = this.isStopped = true;\n this.thrownError = err;\n const {\n observers\n } = this;\n\n while (observers.length) {\n observers.shift().error(err);\n }\n }\n });\n }\n\n complete() {\n errorContext(() => {\n this._throwIfClosed();\n\n if (!this.isStopped) {\n this.isStopped = true;\n const {\n observers\n } = this;\n\n while (observers.length) {\n observers.shift().complete();\n }\n }\n });\n }\n\n unsubscribe() {\n this.isStopped = this.closed = true;\n this.observers = this.currentObservers = null;\n }\n\n get observed() {\n var _a;\n\n return ((_a = this.observers) === null || _a === void 0 ? void 0 : _a.length) > 0;\n }\n\n _trySubscribe(subscriber) {\n this._throwIfClosed();\n\n return super._trySubscribe(subscriber);\n }\n\n _subscribe(subscriber) {\n this._throwIfClosed();\n\n this._checkFinalizedStatuses(subscriber);\n\n return this._innerSubscribe(subscriber);\n }\n\n _innerSubscribe(subscriber) {\n const {\n hasError,\n isStopped,\n observers\n } = this;\n\n if (hasError || isStopped) {\n return EMPTY_SUBSCRIPTION;\n }\n\n this.currentObservers = null;\n observers.push(subscriber);\n return new Subscription(() => {\n this.currentObservers = null;\n arrRemove(observers, subscriber);\n });\n }\n\n _checkFinalizedStatuses(subscriber) {\n const {\n hasError,\n thrownError,\n isStopped\n } = this;\n\n if (hasError) {\n subscriber.error(thrownError);\n } else if (isStopped) {\n subscriber.complete();\n }\n }\n\n asObservable() {\n const observable = new Observable();\n observable.source = this;\n return observable;\n }\n\n }\n\n Subject.create = (destination, source) => {\n return new AnonymousSubject(destination, source);\n };\n\n return Subject;\n})();\nexport class AnonymousSubject extends Subject {\n constructor(destination, source) {\n super();\n this.destination = destination;\n this.source = source;\n }\n\n next(value) {\n var _a, _b;\n\n (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.next) === null || _b === void 0 ? void 0 : _b.call(_a, value);\n }\n\n error(err) {\n var _a, _b;\n\n (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.call(_a, err);\n }\n\n complete() {\n var _a, _b;\n\n (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.complete) === null || _b === void 0 ? void 0 : _b.call(_a);\n }\n\n _subscribe(subscriber) {\n var _a, _b;\n\n return (_b = (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber)) !== null && _b !== void 0 ? _b : EMPTY_SUBSCRIPTION;\n }\n\n} //# sourceMappingURL=Subject.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/00febe9fff747c45580af01aee6a7261.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/00febe9fff747c45580af01aee6a7261.json
deleted file mode 100644
index 75b38e08..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/00febe9fff747c45580af01aee6a7261.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import * as i0 from '@angular/core';\nimport { PLATFORM_ID, Injectable, Inject, NgModule } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n// Whether the current platform supports the V8 Break Iterator. The V8 check\n// is necessary to detect all Blink based browsers.\n\nlet hasV8BreakIterator; // We need a try/catch around the reference to `Intl`, because accessing it in some cases can\n// cause IE to throw. These cases are tied to particular versions of Windows and can happen if\n// the consumer is providing a polyfilled `Map`. See:\n// https://github.com/Microsoft/ChakraCore/issues/3189\n// https://github.com/angular/components/issues/15687\n\ntry {\n hasV8BreakIterator = typeof Intl !== 'undefined' && Intl.v8BreakIterator;\n} catch {\n hasV8BreakIterator = false;\n}\n/**\n * Service to detect the current platform by comparing the userAgent strings and\n * checking browser-specific global properties.\n */\n\n\nlet Platform = /*#__PURE__*/(() => {\n class Platform {\n constructor(_platformId) {\n this._platformId = _platformId; // We want to use the Angular platform check because if the Document is shimmed\n // without the navigator, the following checks will fail. This is preferred because\n // sometimes the Document may be shimmed without the user's knowledge or intention\n\n /** Whether the Angular application is being rendered in the browser. */\n\n this.isBrowser = this._platformId ? isPlatformBrowser(this._platformId) : typeof document === 'object' && !!document;\n /** Whether the current browser is Microsoft Edge. */\n\n this.EDGE = this.isBrowser && /(edge)/i.test(navigator.userAgent);\n /** Whether the current rendering engine is Microsoft Trident. */\n\n this.TRIDENT = this.isBrowser && /(msie|trident)/i.test(navigator.userAgent); // EdgeHTML and Trident mock Blink specific things and need to be excluded from this check.\n\n /** Whether the current rendering engine is Blink. */\n\n this.BLINK = this.isBrowser && !!(window.chrome || hasV8BreakIterator) && typeof CSS !== 'undefined' && !this.EDGE && !this.TRIDENT; // Webkit is part of the userAgent in EdgeHTML, Blink and Trident. Therefore we need to\n // ensure that Webkit runs standalone and is not used as another engine's base.\n\n /** Whether the current rendering engine is WebKit. */\n\n this.WEBKIT = this.isBrowser && /AppleWebKit/i.test(navigator.userAgent) && !this.BLINK && !this.EDGE && !this.TRIDENT;\n /** Whether the current platform is Apple iOS. */\n\n this.IOS = this.isBrowser && /iPad|iPhone|iPod/.test(navigator.userAgent) && !('MSStream' in window); // It's difficult to detect the plain Gecko engine, because most of the browsers identify\n // them self as Gecko-like browsers and modify the userAgent's according to that.\n // Since we only cover one explicit Firefox case, we can simply check for Firefox\n // instead of having an unstable check for Gecko.\n\n /** Whether the current browser is Firefox. */\n\n this.FIREFOX = this.isBrowser && /(firefox|minefield)/i.test(navigator.userAgent);\n /** Whether the current platform is Android. */\n // Trident on mobile adds the android platform to the userAgent to trick detections.\n\n this.ANDROID = this.isBrowser && /android/i.test(navigator.userAgent) && !this.TRIDENT; // Safari browsers will include the Safari keyword in their userAgent. Some browsers may fake\n // this and just place the Safari keyword in the userAgent. To be more safe about Safari every\n // Safari browser should also use Webkit as its layout engine.\n\n /** Whether the current browser is Safari. */\n\n this.SAFARI = this.isBrowser && /safari/i.test(navigator.userAgent) && this.WEBKIT;\n }\n\n }\n\n Platform.ɵfac = function Platform_Factory(t) {\n return new (t || Platform)(i0.ɵɵinject(PLATFORM_ID));\n };\n\n Platform.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: Platform,\n factory: Platform.ɵfac,\n providedIn: 'root'\n });\n return Platform;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nlet PlatformModule = /*#__PURE__*/(() => {\n class PlatformModule {}\n\n PlatformModule.ɵfac = function PlatformModule_Factory(t) {\n return new (t || PlatformModule)();\n };\n\n PlatformModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: PlatformModule\n });\n PlatformModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({});\n return PlatformModule;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/** Cached result Set of input types support by the current browser. */\n\n\nlet supportedInputTypes;\n/** Types of ` ` that *might* be supported. */\n\nconst candidateInputTypes = [// `color` must come first. Chrome 56 shows a warning if we change the type to `color` after\n// first changing it to something else:\n// The specified value \"\" does not conform to the required format.\n// The format is \"#rrggbb\" where rr, gg, bb are two-digit hexadecimal numbers.\n'color', 'button', 'checkbox', 'date', 'datetime-local', 'email', 'file', 'hidden', 'image', 'month', 'number', 'password', 'radio', 'range', 'reset', 'search', 'submit', 'tel', 'text', 'time', 'url', 'week'];\n/** @returns The input types supported by this browser. */\n\nfunction getSupportedInputTypes() {\n // Result is cached.\n if (supportedInputTypes) {\n return supportedInputTypes;\n } // We can't check if an input type is not supported until we're on the browser, so say that\n // everything is supported when not on the browser. We don't use `Platform` here since it's\n // just a helper function and can't inject it.\n\n\n if (typeof document !== 'object' || !document) {\n supportedInputTypes = new Set(candidateInputTypes);\n return supportedInputTypes;\n }\n\n let featureTestInput = document.createElement('input');\n supportedInputTypes = new Set(candidateInputTypes.filter(value => {\n featureTestInput.setAttribute('type', value);\n return featureTestInput.type === value;\n }));\n return supportedInputTypes;\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/** Cached result of whether the user's browser supports passive event listeners. */\n\n\nlet supportsPassiveEvents;\n/**\n * Checks whether the user's browser supports passive event listeners.\n * See: https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md\n */\n\nfunction supportsPassiveEventListeners() {\n if (supportsPassiveEvents == null && typeof window !== 'undefined') {\n try {\n window.addEventListener('test', null, Object.defineProperty({}, 'passive', {\n get: () => supportsPassiveEvents = true\n }));\n } finally {\n supportsPassiveEvents = supportsPassiveEvents || false;\n }\n }\n\n return supportsPassiveEvents;\n}\n/**\n * Normalizes an `AddEventListener` object to something that can be passed\n * to `addEventListener` on any browser, no matter whether it supports the\n * `options` parameter.\n * @param options Object to be normalized.\n */\n\n\nfunction normalizePassiveListenerOptions(options) {\n return supportsPassiveEventListeners() ? options : !!options.capture;\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/** Cached result of the way the browser handles the horizontal scroll axis in RTL mode. */\n\n\nlet rtlScrollAxisType;\n/** Cached result of the check that indicates whether the browser supports scroll behaviors. */\n\nlet scrollBehaviorSupported;\n/** Check whether the browser supports scroll behaviors. */\n\nfunction supportsScrollBehavior() {\n if (scrollBehaviorSupported == null) {\n // If we're not in the browser, it can't be supported. Also check for `Element`, because\n // some projects stub out the global `document` during SSR which can throw us off.\n if (typeof document !== 'object' || !document || typeof Element !== 'function' || !Element) {\n scrollBehaviorSupported = false;\n return scrollBehaviorSupported;\n } // If the element can have a `scrollBehavior` style, we can be sure that it's supported.\n\n\n if ('scrollBehavior' in document.documentElement.style) {\n scrollBehaviorSupported = true;\n } else {\n // At this point we have 3 possibilities: `scrollTo` isn't supported at all, it's\n // supported but it doesn't handle scroll behavior, or it has been polyfilled.\n const scrollToFunction = Element.prototype.scrollTo;\n\n if (scrollToFunction) {\n // We can detect if the function has been polyfilled by calling `toString` on it. Native\n // functions are obfuscated using `[native code]`, whereas if it was overwritten we'd get\n // the actual function source. Via https://davidwalsh.name/detect-native-function. Consider\n // polyfilled functions as supporting scroll behavior.\n scrollBehaviorSupported = !/\\{\\s*\\[native code\\]\\s*\\}/.test(scrollToFunction.toString());\n } else {\n scrollBehaviorSupported = false;\n }\n }\n }\n\n return scrollBehaviorSupported;\n}\n/**\n * Checks the type of RTL scroll axis used by this browser. As of time of writing, Chrome is NORMAL,\n * Firefox & Safari are NEGATED, and IE & Edge are INVERTED.\n */\n\n\nfunction getRtlScrollAxisType() {\n // We can't check unless we're on the browser. Just assume 'normal' if we're not.\n if (typeof document !== 'object' || !document) {\n return 0\n /* NORMAL */\n ;\n }\n\n if (rtlScrollAxisType == null) {\n // Create a 1px wide scrolling container and a 2px wide content element.\n const scrollContainer = document.createElement('div');\n const containerStyle = scrollContainer.style;\n scrollContainer.dir = 'rtl';\n containerStyle.width = '1px';\n containerStyle.overflow = 'auto';\n containerStyle.visibility = 'hidden';\n containerStyle.pointerEvents = 'none';\n containerStyle.position = 'absolute';\n const content = document.createElement('div');\n const contentStyle = content.style;\n contentStyle.width = '2px';\n contentStyle.height = '1px';\n scrollContainer.appendChild(content);\n document.body.appendChild(scrollContainer);\n rtlScrollAxisType = 0\n /* NORMAL */\n ; // The viewport starts scrolled all the way to the right in RTL mode. If we are in a NORMAL\n // browser this would mean that the scrollLeft should be 1. If it's zero instead we know we're\n // dealing with one of the other two types of browsers.\n\n if (scrollContainer.scrollLeft === 0) {\n // In a NEGATED browser the scrollLeft is always somewhere in [-maxScrollAmount, 0]. For an\n // INVERTED browser it is always somewhere in [0, maxScrollAmount]. We can determine which by\n // setting to the scrollLeft to 1. This is past the max for a NEGATED browser, so it will\n // return 0 when we read it again.\n scrollContainer.scrollLeft = 1;\n rtlScrollAxisType = scrollContainer.scrollLeft === 0 ? 1\n /* NEGATED */\n : 2\n /* INVERTED */\n ;\n }\n\n scrollContainer.remove();\n }\n\n return rtlScrollAxisType;\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nlet shadowDomIsSupported;\n/** Checks whether the user's browser support Shadow DOM. */\n\nfunction _supportsShadowDom() {\n if (shadowDomIsSupported == null) {\n const head = typeof document !== 'undefined' ? document.head : null;\n shadowDomIsSupported = !!(head && (head.createShadowRoot || head.attachShadow));\n }\n\n return shadowDomIsSupported;\n}\n/** Gets the shadow root of an element, if supported and the element is inside the Shadow DOM. */\n\n\nfunction _getShadowRoot(element) {\n if (_supportsShadowDom()) {\n const rootNode = element.getRootNode ? element.getRootNode() : null; // Note that this should be caught by `_supportsShadowDom`, but some\n // teams have been able to hit this code path on unsupported browsers.\n\n if (typeof ShadowRoot !== 'undefined' && ShadowRoot && rootNode instanceof ShadowRoot) {\n return rootNode;\n }\n }\n\n return null;\n}\n/**\n * Gets the currently-focused element on the page while\n * also piercing through Shadow DOM boundaries.\n */\n\n\nfunction _getFocusedElementPierceShadowDom() {\n let activeElement = typeof document !== 'undefined' && document ? document.activeElement : null;\n\n while (activeElement && activeElement.shadowRoot) {\n const newActiveElement = activeElement.shadowRoot.activeElement;\n\n if (newActiveElement === activeElement) {\n break;\n } else {\n activeElement = newActiveElement;\n }\n }\n\n return activeElement;\n}\n/** Gets the target of an event while accounting for Shadow DOM. */\n\n\nfunction _getEventTarget(event) {\n // If an event is bound outside the Shadow DOM, the `event.target` will\n // point to the shadow root so we have to use `composedPath` instead.\n return event.composedPath ? event.composedPath()[0] : event.target;\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/** Gets whether the code is currently running in a test environment. */\n\n\nfunction _isTestEnvironment() {\n // We can't use `declare const` because it causes conflicts inside Google with the real typings\n // for these symbols and we can't read them off the global object, because they don't appear to\n // be attached there for some runners like Jest.\n // (see: https://github.com/angular/components/issues/23365#issuecomment-938146643)\n return (// @ts-ignore\n typeof __karma__ !== 'undefined' && !!__karma__ || // @ts-ignore\n typeof jasmine !== 'undefined' && !!jasmine || // @ts-ignore\n typeof jest !== 'undefined' && !!jest || // @ts-ignore\n typeof Mocha !== 'undefined' && !!Mocha\n );\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Generated bundle index. Do not edit.\n */\n\n\nexport { Platform, PlatformModule, _getEventTarget, _getFocusedElementPierceShadowDom, _getShadowRoot, _isTestEnvironment, _supportsShadowDom, getRtlScrollAxisType, getSupportedInputTypes, normalizePassiveListenerOptions, supportsPassiveEventListeners, supportsScrollBehavior }; //# sourceMappingURL=platform.mjs.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/01a16e332cc06fbbbcf49ac400089691.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/01a16e332cc06fbbbcf49ac400089691.json
deleted file mode 100644
index 919c188f..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/01a16e332cc06fbbbcf49ac400089691.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { Observable } from '../Observable';\nimport { argsArgArrayOrObject } from '../util/argsArgArrayOrObject';\nimport { from } from './from';\nimport { identity } from '../util/identity';\nimport { mapOneOrManyArgs } from '../util/mapOneOrManyArgs';\nimport { popResultSelector, popScheduler } from '../util/args';\nimport { createObject } from '../util/createObject';\nimport { createOperatorSubscriber } from '../operators/OperatorSubscriber';\nimport { executeSchedule } from '../util/executeSchedule';\nexport function combineLatest(...args) {\n const scheduler = popScheduler(args);\n const resultSelector = popResultSelector(args);\n const {\n args: observables,\n keys\n } = argsArgArrayOrObject(args);\n\n if (observables.length === 0) {\n return from([], scheduler);\n }\n\n const result = new Observable(combineLatestInit(observables, scheduler, keys ? values => createObject(keys, values) : identity));\n return resultSelector ? result.pipe(mapOneOrManyArgs(resultSelector)) : result;\n}\nexport function combineLatestInit(observables, scheduler, valueTransform = identity) {\n return subscriber => {\n maybeSchedule(scheduler, () => {\n const {\n length\n } = observables;\n const values = new Array(length);\n let active = length;\n let remainingFirstValues = length;\n\n for (let i = 0; i < length; i++) {\n maybeSchedule(scheduler, () => {\n const source = from(observables[i], scheduler);\n let hasFirstValue = false;\n source.subscribe(createOperatorSubscriber(subscriber, value => {\n values[i] = value;\n\n if (!hasFirstValue) {\n hasFirstValue = true;\n remainingFirstValues--;\n }\n\n if (!remainingFirstValues) {\n subscriber.next(valueTransform(values.slice()));\n }\n }, () => {\n if (! --active) {\n subscriber.complete();\n }\n }));\n }, subscriber);\n }\n }, subscriber);\n };\n}\n\nfunction maybeSchedule(scheduler, execute, subscription) {\n if (scheduler) {\n executeSchedule(subscription, scheduler, execute);\n } else {\n execute();\n }\n} //# sourceMappingURL=combineLatest.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/01b4d24d3482aa710a9671edd4f63e5d.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/01b4d24d3482aa710a9671edd4f63e5d.json
deleted file mode 100644
index ce634e92..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/01b4d24d3482aa710a9671edd4f63e5d.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { mergeAll } from './mergeAll';\nexport function concatAll() {\n return mergeAll(1);\n} //# sourceMappingURL=concatAll.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/035665f291846f818a98c7bfc3285fba.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/035665f291846f818a98c7bfc3285fba.json
deleted file mode 100644
index 55c7ef82..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/035665f291846f818a98c7bfc3285fba.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { Observable } from '../Observable';\nexport function fromSubscribable(subscribable) {\n return new Observable(subscriber => subscribable.subscribe(subscriber));\n} //# sourceMappingURL=fromSubscribable.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/072c62cb11a3f2cd5879e22509eaa5d6.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/072c62cb11a3f2cd5879e22509eaa5d6.json
deleted file mode 100644
index f9ffec06..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/072c62cb11a3f2cd5879e22509eaa5d6.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { RouterModule } from '@angular/router';\nimport { InlineComponent } from './inline/inline.component';\nimport { BigComponent } from './big/big.component';\nimport { DynamicComponent } from './dynamic/dynamic.component';\nimport * as i0 from \"@angular/core\";\nimport * as i1 from \"@angular/router\";\nconst routes = [{\n path: '',\n component: BigComponent\n}, {\n path: 'inline',\n component: InlineComponent\n}, {\n path: 'dynamic',\n component: DynamicComponent\n}];\nexport let AppRoutingModule = /*#__PURE__*/(() => {\n class AppRoutingModule {}\n\n AppRoutingModule.ɵfac = function AppRoutingModule_Factory(t) {\n return new (t || AppRoutingModule)();\n };\n\n AppRoutingModule.ɵmod = /*@__PURE__*/i0.ɵɵdefineNgModule({\n type: AppRoutingModule\n });\n AppRoutingModule.ɵinj = /*@__PURE__*/i0.ɵɵdefineInjector({\n imports: [RouterModule.forRoot(routes), RouterModule]\n });\n return AppRoutingModule;\n})();","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/074d81b3ab5a1c40144b66764b437e11.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/074d81b3ab5a1c40144b66764b437e11.json
deleted file mode 100644
index 97192d60..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/074d81b3ab5a1c40144b66764b437e11.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"var logLevel = \"info\";\n\nfunction dummy() {}\n\nfunction shouldLog(level) {\n var shouldLog = logLevel === \"info\" && level === \"info\" || [\"info\", \"warning\"].indexOf(logLevel) >= 0 && level === \"warning\" || [\"info\", \"warning\", \"error\"].indexOf(logLevel) >= 0 && level === \"error\";\n return shouldLog;\n}\n\nfunction logGroup(logFn) {\n return function (level, msg) {\n if (shouldLog(level)) {\n logFn(msg);\n }\n };\n}\n\nmodule.exports = function (level, msg) {\n if (shouldLog(level)) {\n if (level === \"info\") {\n console.log(msg);\n } else if (level === \"warning\") {\n console.warn(msg);\n } else if (level === \"error\") {\n console.error(msg);\n }\n }\n};\n/* eslint-disable node/no-unsupported-features/node-builtins */\n\n\nvar group = console.group || dummy;\nvar groupCollapsed = console.groupCollapsed || dummy;\nvar groupEnd = console.groupEnd || dummy;\n/* eslint-enable node/no-unsupported-features/node-builtins */\n\nmodule.exports.group = logGroup(group);\nmodule.exports.groupCollapsed = logGroup(groupCollapsed);\nmodule.exports.groupEnd = logGroup(groupEnd);\n\nmodule.exports.setLogLevel = function (level) {\n logLevel = level;\n};\n\nmodule.exports.formatError = function (err) {\n var message = err.message;\n var stack = err.stack;\n\n if (!stack) {\n return message;\n } else if (stack.indexOf(message) < 0) {\n return message + \"\\n\" + stack;\n } else {\n return stack;\n }\n};","map":null,"metadata":{},"sourceType":"script"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/07e1d4c286e5a93c173c71a416ba9dbe.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/07e1d4c286e5a93c173c71a416ba9dbe.json
deleted file mode 100644
index 2d3b131b..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/07e1d4c286e5a93c173c71a416ba9dbe.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { Observable } from '../Observable';\nimport { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from '../util/isFunction';\nimport { executeSchedule } from '../util/executeSchedule';\nexport function scheduleIterable(input, scheduler) {\n return new Observable(subscriber => {\n let iterator;\n executeSchedule(subscriber, scheduler, () => {\n iterator = input[Symbol_iterator]();\n executeSchedule(subscriber, scheduler, () => {\n let value;\n let done;\n\n try {\n ({\n value,\n done\n } = iterator.next());\n } catch (err) {\n subscriber.error(err);\n return;\n }\n\n if (done) {\n subscriber.complete();\n } else {\n subscriber.next(value);\n }\n }, 0, true);\n });\n return () => isFunction(iterator === null || iterator === void 0 ? void 0 : iterator.return) && iterator.return();\n });\n} //# sourceMappingURL=scheduleIterable.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/0c89599563de83559e64c9168f889bd9.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/0c89599563de83559e64c9168f889bd9.json
deleted file mode 100644
index 3c570f1f..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/0c89599563de83559e64c9168f889bd9.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"export function not(pred, thisArg) {\n return (value, index) => !pred.call(thisArg, value, index);\n} //# sourceMappingURL=not.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/0d29d1082a8b7c44ee608893f02ae573.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/0d29d1082a8b7c44ee608893f02ae573.json
deleted file mode 100644
index 8b2b7a8a..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/0d29d1082a8b7c44ee608893f02ae573.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { map } from './map';\nexport function pluck(...properties) {\n const length = properties.length;\n\n if (length === 0) {\n throw new Error('list of properties cannot be empty.');\n }\n\n return map(x => {\n let currentProp = x;\n\n for (let i = 0; i < length; i++) {\n const p = currentProp === null || currentProp === void 0 ? void 0 : currentProp[properties[i]];\n\n if (typeof p !== 'undefined') {\n currentProp = p;\n } else {\n return undefined;\n }\n }\n\n return currentProp;\n });\n} //# sourceMappingURL=pluck.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/0dd15b66565c716e0ecc5b8a13f62977.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/0dd15b66565c716e0ecc5b8a13f62977.json
deleted file mode 100644
index 9dcf1419..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/0dd15b66565c716e0ecc5b8a13f62977.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { Subject } from '../Subject';\nimport { innerFrom } from '../observable/innerFrom';\nimport { operate } from '../util/lift';\nimport { fromSubscribable } from '../observable/fromSubscribable';\nconst DEFAULT_CONFIG = {\n connector: () => new Subject()\n};\nexport function connect(selector, config = DEFAULT_CONFIG) {\n const {\n connector\n } = config;\n return operate((source, subscriber) => {\n const subject = connector();\n innerFrom(selector(fromSubscribable(subject))).subscribe(subscriber);\n subscriber.add(source.subscribe(subject));\n });\n} //# sourceMappingURL=connect.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/0df3917f2875114b81c171cc86664608.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/0df3917f2875114b81c171cc86664608.json
deleted file mode 100644
index 80c51106..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/0df3917f2875114b81c171cc86664608.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.fromCodePoint = String.fromCodePoint || function (astralCodePoint) {\n return String.fromCharCode(Math.floor((astralCodePoint - 65536) / 1024) + 55296, (astralCodePoint - 65536) % 1024 + 56320);\n};\n\nexports.getCodePoint = String.prototype.codePointAt ? function (input, position) {\n return input.codePointAt(position);\n} : function (input, position) {\n return (input.charCodeAt(position) - 55296) * 1024 + input.charCodeAt(position + 1) - 56320 + 65536;\n};\nexports.highSurrogateFrom = 55296;\nexports.highSurrogateTo = 56319;","map":null,"metadata":{},"sourceType":"script"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/0e88d7a135d1b351611bc745e3ad82a2.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/0e88d7a135d1b351611bc745e3ad82a2.json
deleted file mode 100644
index 8125f528..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/0e88d7a135d1b351611bc745e3ad82a2.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nexport function defaultIfEmpty(defaultValue) {\n return operate((source, subscriber) => {\n let hasValue = false;\n source.subscribe(createOperatorSubscriber(subscriber, value => {\n hasValue = true;\n subscriber.next(value);\n }, () => {\n if (!hasValue) {\n subscriber.next(defaultValue);\n }\n\n subscriber.complete();\n }));\n });\n} //# sourceMappingURL=defaultIfEmpty.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/10bc67cd111a66f372373be3e82c8315.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/10bc67cd111a66f372373be3e82c8315.json
deleted file mode 100644
index 0eaf2962..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/10bc67cd111a66f372373be3e82c8315.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import * as i0 from '@angular/core';\nimport { Directive, Component, ViewEncapsulation, ChangeDetectionStrategy, Input, NgModule } from '@angular/core';\nimport * as i1 from '@angular/cdk/table';\nimport { CdkTable, CDK_TABLE, _COALESCED_STYLE_SCHEDULER, _CoalescedStyleScheduler, STICKY_POSITIONING_LISTENER, CDK_TABLE_TEMPLATE, CdkCellDef, CdkHeaderCellDef, CdkFooterCellDef, CdkColumnDef, CdkHeaderCell, CdkFooterCell, CdkCell, CdkHeaderRowDef, CdkFooterRowDef, CdkRowDef, CdkHeaderRow, CDK_ROW_TEMPLATE, CdkFooterRow, CdkRow, CdkNoDataRow, CdkTextColumn, CdkTableModule, DataSource } from '@angular/cdk/table';\nimport { _VIEW_REPEATER_STRATEGY, _RecycleViewRepeaterStrategy, _DisposeViewRepeaterStrategy } from '@angular/cdk/collections';\nimport { MatCommonModule } from '@angular/material/core';\nimport { _isNumberValue } from '@angular/cdk/coercion';\nimport { BehaviorSubject, Subject, merge, of, combineLatest } from 'rxjs';\nimport { map } from 'rxjs/operators';\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Enables the recycle view repeater strategy, which reduces rendering latency. Not compatible with\n * tables that animate rows.\n */\n\nconst _c0 = [[[\"caption\"]], [[\"colgroup\"], [\"col\"]]];\nconst _c1 = [\"caption\", \"colgroup, col\"];\n\nfunction MatTextColumn_th_1_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementStart(0, \"th\", 3);\n i0.ɵɵtext(1);\n i0.ɵɵelementEnd();\n }\n\n if (rf & 2) {\n const ctx_r0 = i0.ɵɵnextContext();\n i0.ɵɵstyleProp(\"text-align\", ctx_r0.justify);\n i0.ɵɵadvance(1);\n i0.ɵɵtextInterpolate1(\" \", ctx_r0.headerText, \" \");\n }\n}\n\nfunction MatTextColumn_td_2_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementStart(0, \"td\", 4);\n i0.ɵɵtext(1);\n i0.ɵɵelementEnd();\n }\n\n if (rf & 2) {\n const data_r2 = ctx.$implicit;\n const ctx_r1 = i0.ɵɵnextContext();\n i0.ɵɵstyleProp(\"text-align\", ctx_r1.justify);\n i0.ɵɵadvance(1);\n i0.ɵɵtextInterpolate1(\" \", ctx_r1.dataAccessor(data_r2, ctx_r1.name), \" \");\n }\n}\n\nlet MatRecycleRows = /*#__PURE__*/(() => {\n class MatRecycleRows {}\n\n MatRecycleRows.ɵfac = function MatRecycleRows_Factory(t) {\n return new (t || MatRecycleRows)();\n };\n\n MatRecycleRows.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatRecycleRows,\n selectors: [[\"mat-table\", \"recycleRows\", \"\"], [\"table\", \"mat-table\", \"\", \"recycleRows\", \"\"]],\n features: [i0.ɵɵProvidersFeature([{\n provide: _VIEW_REPEATER_STRATEGY,\n useClass: _RecycleViewRepeaterStrategy\n }])]\n });\n return MatRecycleRows;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Wrapper for the CdkTable with Material design styles.\n */\n\n\nlet MatTable = /*#__PURE__*/(() => {\n class MatTable extends CdkTable {\n constructor() {\n super(...arguments);\n /** Overrides the sticky CSS class set by the `CdkTable`. */\n\n this.stickyCssClass = 'mat-table-sticky';\n /** Overrides the need to add position: sticky on every sticky cell element in `CdkTable`. */\n\n this.needsPositionStickyOnElement = false;\n }\n\n }\n\n MatTable.ɵfac = /* @__PURE__ */function () {\n let ɵMatTable_BaseFactory;\n return function MatTable_Factory(t) {\n return (ɵMatTable_BaseFactory || (ɵMatTable_BaseFactory = i0.ɵɵgetInheritedFactory(MatTable)))(t || MatTable);\n };\n }();\n\n MatTable.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatTable,\n selectors: [[\"mat-table\"], [\"table\", \"mat-table\", \"\"]],\n hostAttrs: [1, \"mat-table\"],\n hostVars: 2,\n hostBindings: function MatTable_HostBindings(rf, ctx) {\n if (rf & 2) {\n i0.ɵɵclassProp(\"mat-table-fixed-layout\", ctx.fixedLayout);\n }\n },\n exportAs: [\"matTable\"],\n features: [i0.ɵɵProvidersFeature([// TODO(michaeljamesparsons) Abstract the view repeater strategy to a directive API so this code\n // is only included in the build if used.\n {\n provide: _VIEW_REPEATER_STRATEGY,\n useClass: _DisposeViewRepeaterStrategy\n }, {\n provide: CdkTable,\n useExisting: MatTable\n }, {\n provide: CDK_TABLE,\n useExisting: MatTable\n }, {\n provide: _COALESCED_STYLE_SCHEDULER,\n useClass: _CoalescedStyleScheduler\n }, // Prevent nested tables from seeing this table's StickyPositioningListener.\n {\n provide: STICKY_POSITIONING_LISTENER,\n useValue: null\n }]), i0.ɵɵInheritDefinitionFeature],\n ngContentSelectors: _c1,\n decls: 6,\n vars: 0,\n consts: [[\"headerRowOutlet\", \"\"], [\"rowOutlet\", \"\"], [\"noDataRowOutlet\", \"\"], [\"footerRowOutlet\", \"\"]],\n template: function MatTable_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵprojectionDef(_c0);\n i0.ɵɵprojection(0);\n i0.ɵɵprojection(1, 1);\n i0.ɵɵelementContainer(2, 0)(3, 1)(4, 2)(5, 3);\n }\n },\n dependencies: [i1.HeaderRowOutlet, i1.DataRowOutlet, i1.NoDataRowOutlet, i1.FooterRowOutlet],\n styles: [\"mat-table{display:block}mat-header-row{min-height:56px}mat-row,mat-footer-row{min-height:48px}mat-row,mat-header-row,mat-footer-row{display:flex;border-width:0;border-bottom-width:1px;border-style:solid;align-items:center;box-sizing:border-box}mat-cell:first-of-type,mat-header-cell:first-of-type,mat-footer-cell:first-of-type{padding-left:24px}[dir=rtl] mat-cell:first-of-type:not(:only-of-type),[dir=rtl] mat-header-cell:first-of-type:not(:only-of-type),[dir=rtl] mat-footer-cell:first-of-type:not(:only-of-type){padding-left:0;padding-right:24px}mat-cell:last-of-type,mat-header-cell:last-of-type,mat-footer-cell:last-of-type{padding-right:24px}[dir=rtl] mat-cell:last-of-type:not(:only-of-type),[dir=rtl] mat-header-cell:last-of-type:not(:only-of-type),[dir=rtl] mat-footer-cell:last-of-type:not(:only-of-type){padding-right:0;padding-left:24px}mat-cell,mat-header-cell,mat-footer-cell{flex:1;display:flex;align-items:center;overflow:hidden;word-wrap:break-word;min-height:inherit}table.mat-table{border-spacing:0}tr.mat-header-row{height:56px}tr.mat-row,tr.mat-footer-row{height:48px}th.mat-header-cell{text-align:left}[dir=rtl] th.mat-header-cell{text-align:right}th.mat-header-cell,td.mat-cell,td.mat-footer-cell{padding:0;border-bottom-width:1px;border-bottom-style:solid}th.mat-header-cell:first-of-type,td.mat-cell:first-of-type,td.mat-footer-cell:first-of-type{padding-left:24px}[dir=rtl] th.mat-header-cell:first-of-type:not(:only-of-type),[dir=rtl] td.mat-cell:first-of-type:not(:only-of-type),[dir=rtl] td.mat-footer-cell:first-of-type:not(:only-of-type){padding-left:0;padding-right:24px}th.mat-header-cell:last-of-type,td.mat-cell:last-of-type,td.mat-footer-cell:last-of-type{padding-right:24px}[dir=rtl] th.mat-header-cell:last-of-type:not(:only-of-type),[dir=rtl] td.mat-cell:last-of-type:not(:only-of-type),[dir=rtl] td.mat-footer-cell:last-of-type:not(:only-of-type){padding-right:0;padding-left:24px}.mat-table-sticky{position:-webkit-sticky !important;position:sticky !important}.mat-table-fixed-layout{table-layout:fixed}\\n\"],\n encapsulation: 2\n });\n return MatTable;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Cell definition for the mat-table.\n * Captures the template of a column's data row cell as well as cell-specific properties.\n */\n\n\nlet MatCellDef = /*#__PURE__*/(() => {\n class MatCellDef extends CdkCellDef {}\n\n MatCellDef.ɵfac = /* @__PURE__ */function () {\n let ɵMatCellDef_BaseFactory;\n return function MatCellDef_Factory(t) {\n return (ɵMatCellDef_BaseFactory || (ɵMatCellDef_BaseFactory = i0.ɵɵgetInheritedFactory(MatCellDef)))(t || MatCellDef);\n };\n }();\n\n MatCellDef.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatCellDef,\n selectors: [[\"\", \"matCellDef\", \"\"]],\n features: [i0.ɵɵProvidersFeature([{\n provide: CdkCellDef,\n useExisting: MatCellDef\n }]), i0.ɵɵInheritDefinitionFeature]\n });\n return MatCellDef;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Header cell definition for the mat-table.\n * Captures the template of a column's header cell and as well as cell-specific properties.\n */\n\n\nlet MatHeaderCellDef = /*#__PURE__*/(() => {\n class MatHeaderCellDef extends CdkHeaderCellDef {}\n\n MatHeaderCellDef.ɵfac = /* @__PURE__ */function () {\n let ɵMatHeaderCellDef_BaseFactory;\n return function MatHeaderCellDef_Factory(t) {\n return (ɵMatHeaderCellDef_BaseFactory || (ɵMatHeaderCellDef_BaseFactory = i0.ɵɵgetInheritedFactory(MatHeaderCellDef)))(t || MatHeaderCellDef);\n };\n }();\n\n MatHeaderCellDef.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatHeaderCellDef,\n selectors: [[\"\", \"matHeaderCellDef\", \"\"]],\n features: [i0.ɵɵProvidersFeature([{\n provide: CdkHeaderCellDef,\n useExisting: MatHeaderCellDef\n }]), i0.ɵɵInheritDefinitionFeature]\n });\n return MatHeaderCellDef;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Footer cell definition for the mat-table.\n * Captures the template of a column's footer cell and as well as cell-specific properties.\n */\n\n\nlet MatFooterCellDef = /*#__PURE__*/(() => {\n class MatFooterCellDef extends CdkFooterCellDef {}\n\n MatFooterCellDef.ɵfac = /* @__PURE__ */function () {\n let ɵMatFooterCellDef_BaseFactory;\n return function MatFooterCellDef_Factory(t) {\n return (ɵMatFooterCellDef_BaseFactory || (ɵMatFooterCellDef_BaseFactory = i0.ɵɵgetInheritedFactory(MatFooterCellDef)))(t || MatFooterCellDef);\n };\n }();\n\n MatFooterCellDef.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatFooterCellDef,\n selectors: [[\"\", \"matFooterCellDef\", \"\"]],\n features: [i0.ɵɵProvidersFeature([{\n provide: CdkFooterCellDef,\n useExisting: MatFooterCellDef\n }]), i0.ɵɵInheritDefinitionFeature]\n });\n return MatFooterCellDef;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Column definition for the mat-table.\n * Defines a set of cells available for a table column.\n */\n\n\nlet MatColumnDef = /*#__PURE__*/(() => {\n class MatColumnDef extends CdkColumnDef {\n /** Unique name for this column. */\n get name() {\n return this._name;\n }\n\n set name(name) {\n this._setNameInput(name);\n }\n /**\n * Add \"mat-column-\" prefix in addition to \"cdk-column-\" prefix.\n * In the future, this will only add \"mat-column-\" and columnCssClassName\n * will change from type string[] to string.\n * @docs-private\n */\n\n\n _updateColumnCssClassName() {\n super._updateColumnCssClassName();\n\n this._columnCssClassName.push(`mat-column-${this.cssClassFriendlyName}`);\n }\n\n }\n\n MatColumnDef.ɵfac = /* @__PURE__ */function () {\n let ɵMatColumnDef_BaseFactory;\n return function MatColumnDef_Factory(t) {\n return (ɵMatColumnDef_BaseFactory || (ɵMatColumnDef_BaseFactory = i0.ɵɵgetInheritedFactory(MatColumnDef)))(t || MatColumnDef);\n };\n }();\n\n MatColumnDef.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatColumnDef,\n selectors: [[\"\", \"matColumnDef\", \"\"]],\n inputs: {\n sticky: \"sticky\",\n name: [\"matColumnDef\", \"name\"]\n },\n features: [i0.ɵɵProvidersFeature([{\n provide: CdkColumnDef,\n useExisting: MatColumnDef\n }, {\n provide: 'MAT_SORT_HEADER_COLUMN_DEF',\n useExisting: MatColumnDef\n }]), i0.ɵɵInheritDefinitionFeature]\n });\n return MatColumnDef;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/** Header cell template container that adds the right classes and role. */\n\n\nlet MatHeaderCell = /*#__PURE__*/(() => {\n class MatHeaderCell extends CdkHeaderCell {}\n\n MatHeaderCell.ɵfac = /* @__PURE__ */function () {\n let ɵMatHeaderCell_BaseFactory;\n return function MatHeaderCell_Factory(t) {\n return (ɵMatHeaderCell_BaseFactory || (ɵMatHeaderCell_BaseFactory = i0.ɵɵgetInheritedFactory(MatHeaderCell)))(t || MatHeaderCell);\n };\n }();\n\n MatHeaderCell.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatHeaderCell,\n selectors: [[\"mat-header-cell\"], [\"th\", \"mat-header-cell\", \"\"]],\n hostAttrs: [\"role\", \"columnheader\", 1, \"mat-header-cell\"],\n features: [i0.ɵɵInheritDefinitionFeature]\n });\n return MatHeaderCell;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/** Footer cell template container that adds the right classes and role. */\n\n\nlet MatFooterCell = /*#__PURE__*/(() => {\n class MatFooterCell extends CdkFooterCell {}\n\n MatFooterCell.ɵfac = /* @__PURE__ */function () {\n let ɵMatFooterCell_BaseFactory;\n return function MatFooterCell_Factory(t) {\n return (ɵMatFooterCell_BaseFactory || (ɵMatFooterCell_BaseFactory = i0.ɵɵgetInheritedFactory(MatFooterCell)))(t || MatFooterCell);\n };\n }();\n\n MatFooterCell.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatFooterCell,\n selectors: [[\"mat-footer-cell\"], [\"td\", \"mat-footer-cell\", \"\"]],\n hostAttrs: [\"role\", \"gridcell\", 1, \"mat-footer-cell\"],\n features: [i0.ɵɵInheritDefinitionFeature]\n });\n return MatFooterCell;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/** Cell template container that adds the right classes and role. */\n\n\nlet MatCell = /*#__PURE__*/(() => {\n class MatCell extends CdkCell {}\n\n MatCell.ɵfac = /* @__PURE__ */function () {\n let ɵMatCell_BaseFactory;\n return function MatCell_Factory(t) {\n return (ɵMatCell_BaseFactory || (ɵMatCell_BaseFactory = i0.ɵɵgetInheritedFactory(MatCell)))(t || MatCell);\n };\n }();\n\n MatCell.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatCell,\n selectors: [[\"mat-cell\"], [\"td\", \"mat-cell\", \"\"]],\n hostAttrs: [\"role\", \"gridcell\", 1, \"mat-cell\"],\n features: [i0.ɵɵInheritDefinitionFeature]\n });\n return MatCell;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Header row definition for the mat-table.\n * Captures the header row's template and other header properties such as the columns to display.\n */\n\n\nlet MatHeaderRowDef = /*#__PURE__*/(() => {\n class MatHeaderRowDef extends CdkHeaderRowDef {}\n\n MatHeaderRowDef.ɵfac = /* @__PURE__ */function () {\n let ɵMatHeaderRowDef_BaseFactory;\n return function MatHeaderRowDef_Factory(t) {\n return (ɵMatHeaderRowDef_BaseFactory || (ɵMatHeaderRowDef_BaseFactory = i0.ɵɵgetInheritedFactory(MatHeaderRowDef)))(t || MatHeaderRowDef);\n };\n }();\n\n MatHeaderRowDef.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatHeaderRowDef,\n selectors: [[\"\", \"matHeaderRowDef\", \"\"]],\n inputs: {\n columns: [\"matHeaderRowDef\", \"columns\"],\n sticky: [\"matHeaderRowDefSticky\", \"sticky\"]\n },\n features: [i0.ɵɵProvidersFeature([{\n provide: CdkHeaderRowDef,\n useExisting: MatHeaderRowDef\n }]), i0.ɵɵInheritDefinitionFeature]\n });\n return MatHeaderRowDef;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Footer row definition for the mat-table.\n * Captures the footer row's template and other footer properties such as the columns to display.\n */\n\n\nlet MatFooterRowDef = /*#__PURE__*/(() => {\n class MatFooterRowDef extends CdkFooterRowDef {}\n\n MatFooterRowDef.ɵfac = /* @__PURE__ */function () {\n let ɵMatFooterRowDef_BaseFactory;\n return function MatFooterRowDef_Factory(t) {\n return (ɵMatFooterRowDef_BaseFactory || (ɵMatFooterRowDef_BaseFactory = i0.ɵɵgetInheritedFactory(MatFooterRowDef)))(t || MatFooterRowDef);\n };\n }();\n\n MatFooterRowDef.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatFooterRowDef,\n selectors: [[\"\", \"matFooterRowDef\", \"\"]],\n inputs: {\n columns: [\"matFooterRowDef\", \"columns\"],\n sticky: [\"matFooterRowDefSticky\", \"sticky\"]\n },\n features: [i0.ɵɵProvidersFeature([{\n provide: CdkFooterRowDef,\n useExisting: MatFooterRowDef\n }]), i0.ɵɵInheritDefinitionFeature]\n });\n return MatFooterRowDef;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Data row definition for the mat-table.\n * Captures the data row's template and other properties such as the columns to display and\n * a when predicate that describes when this row should be used.\n */\n\n\nlet MatRowDef = /*#__PURE__*/(() => {\n class MatRowDef extends CdkRowDef {}\n\n MatRowDef.ɵfac = /* @__PURE__ */function () {\n let ɵMatRowDef_BaseFactory;\n return function MatRowDef_Factory(t) {\n return (ɵMatRowDef_BaseFactory || (ɵMatRowDef_BaseFactory = i0.ɵɵgetInheritedFactory(MatRowDef)))(t || MatRowDef);\n };\n }();\n\n MatRowDef.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatRowDef,\n selectors: [[\"\", \"matRowDef\", \"\"]],\n inputs: {\n columns: [\"matRowDefColumns\", \"columns\"],\n when: [\"matRowDefWhen\", \"when\"]\n },\n features: [i0.ɵɵProvidersFeature([{\n provide: CdkRowDef,\n useExisting: MatRowDef\n }]), i0.ɵɵInheritDefinitionFeature]\n });\n return MatRowDef;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/** Header template container that contains the cell outlet. Adds the right class and role. */\n\n\nlet MatHeaderRow = /*#__PURE__*/(() => {\n class MatHeaderRow extends CdkHeaderRow {}\n\n MatHeaderRow.ɵfac = /* @__PURE__ */function () {\n let ɵMatHeaderRow_BaseFactory;\n return function MatHeaderRow_Factory(t) {\n return (ɵMatHeaderRow_BaseFactory || (ɵMatHeaderRow_BaseFactory = i0.ɵɵgetInheritedFactory(MatHeaderRow)))(t || MatHeaderRow);\n };\n }();\n\n MatHeaderRow.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatHeaderRow,\n selectors: [[\"mat-header-row\"], [\"tr\", \"mat-header-row\", \"\"]],\n hostAttrs: [\"role\", \"row\", 1, \"mat-header-row\"],\n exportAs: [\"matHeaderRow\"],\n features: [i0.ɵɵProvidersFeature([{\n provide: CdkHeaderRow,\n useExisting: MatHeaderRow\n }]), i0.ɵɵInheritDefinitionFeature],\n decls: 1,\n vars: 0,\n consts: [[\"cdkCellOutlet\", \"\"]],\n template: function MatHeaderRow_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementContainer(0, 0);\n }\n },\n dependencies: [i1.CdkCellOutlet],\n encapsulation: 2\n });\n return MatHeaderRow;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/** Footer template container that contains the cell outlet. Adds the right class and role. */\n\n\nlet MatFooterRow = /*#__PURE__*/(() => {\n class MatFooterRow extends CdkFooterRow {}\n\n MatFooterRow.ɵfac = /* @__PURE__ */function () {\n let ɵMatFooterRow_BaseFactory;\n return function MatFooterRow_Factory(t) {\n return (ɵMatFooterRow_BaseFactory || (ɵMatFooterRow_BaseFactory = i0.ɵɵgetInheritedFactory(MatFooterRow)))(t || MatFooterRow);\n };\n }();\n\n MatFooterRow.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatFooterRow,\n selectors: [[\"mat-footer-row\"], [\"tr\", \"mat-footer-row\", \"\"]],\n hostAttrs: [\"role\", \"row\", 1, \"mat-footer-row\"],\n exportAs: [\"matFooterRow\"],\n features: [i0.ɵɵProvidersFeature([{\n provide: CdkFooterRow,\n useExisting: MatFooterRow\n }]), i0.ɵɵInheritDefinitionFeature],\n decls: 1,\n vars: 0,\n consts: [[\"cdkCellOutlet\", \"\"]],\n template: function MatFooterRow_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementContainer(0, 0);\n }\n },\n dependencies: [i1.CdkCellOutlet],\n encapsulation: 2\n });\n return MatFooterRow;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/** Data row template container that contains the cell outlet. Adds the right class and role. */\n\n\nlet MatRow = /*#__PURE__*/(() => {\n class MatRow extends CdkRow {}\n\n MatRow.ɵfac = /* @__PURE__ */function () {\n let ɵMatRow_BaseFactory;\n return function MatRow_Factory(t) {\n return (ɵMatRow_BaseFactory || (ɵMatRow_BaseFactory = i0.ɵɵgetInheritedFactory(MatRow)))(t || MatRow);\n };\n }();\n\n MatRow.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatRow,\n selectors: [[\"mat-row\"], [\"tr\", \"mat-row\", \"\"]],\n hostAttrs: [\"role\", \"row\", 1, \"mat-row\"],\n exportAs: [\"matRow\"],\n features: [i0.ɵɵProvidersFeature([{\n provide: CdkRow,\n useExisting: MatRow\n }]), i0.ɵɵInheritDefinitionFeature],\n decls: 1,\n vars: 0,\n consts: [[\"cdkCellOutlet\", \"\"]],\n template: function MatRow_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementContainer(0, 0);\n }\n },\n dependencies: [i1.CdkCellOutlet],\n encapsulation: 2\n });\n return MatRow;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/** Row that can be used to display a message when no data is shown in the table. */\n\n\nlet MatNoDataRow = /*#__PURE__*/(() => {\n class MatNoDataRow extends CdkNoDataRow {\n constructor() {\n super(...arguments);\n this._contentClassName = 'mat-no-data-row';\n }\n\n }\n\n MatNoDataRow.ɵfac = /* @__PURE__ */function () {\n let ɵMatNoDataRow_BaseFactory;\n return function MatNoDataRow_Factory(t) {\n return (ɵMatNoDataRow_BaseFactory || (ɵMatNoDataRow_BaseFactory = i0.ɵɵgetInheritedFactory(MatNoDataRow)))(t || MatNoDataRow);\n };\n }();\n\n MatNoDataRow.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatNoDataRow,\n selectors: [[\"ng-template\", \"matNoDataRow\", \"\"]],\n features: [i0.ɵɵProvidersFeature([{\n provide: CdkNoDataRow,\n useExisting: MatNoDataRow\n }]), i0.ɵɵInheritDefinitionFeature]\n });\n return MatNoDataRow;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Column that simply shows text content for the header and row cells. Assumes that the table\n * is using the native table implementation (`
`).\n *\n * By default, the name of this column will be the header text and data property accessor.\n * The header text can be overridden with the `headerText` input. Cell values can be overridden with\n * the `dataAccessor` input. Change the text justification to the start or end using the `justify`\n * input.\n */\n\n\nlet MatTextColumn = /*#__PURE__*/(() => {\n class MatTextColumn extends CdkTextColumn {}\n\n MatTextColumn.ɵfac = /* @__PURE__ */function () {\n let ɵMatTextColumn_BaseFactory;\n return function MatTextColumn_Factory(t) {\n return (ɵMatTextColumn_BaseFactory || (ɵMatTextColumn_BaseFactory = i0.ɵɵgetInheritedFactory(MatTextColumn)))(t || MatTextColumn);\n };\n }();\n\n MatTextColumn.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatTextColumn,\n selectors: [[\"mat-text-column\"]],\n features: [i0.ɵɵInheritDefinitionFeature],\n decls: 3,\n vars: 0,\n consts: [[\"matColumnDef\", \"\"], [\"mat-header-cell\", \"\", 3, \"text-align\", 4, \"matHeaderCellDef\"], [\"mat-cell\", \"\", 3, \"text-align\", 4, \"matCellDef\"], [\"mat-header-cell\", \"\"], [\"mat-cell\", \"\"]],\n template: function MatTextColumn_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementContainerStart(0, 0);\n i0.ɵɵtemplate(1, MatTextColumn_th_1_Template, 2, 3, \"th\", 1);\n i0.ɵɵtemplate(2, MatTextColumn_td_2_Template, 2, 3, \"td\", 2);\n i0.ɵɵelementContainerEnd();\n }\n },\n dependencies: [MatColumnDef, MatHeaderCellDef, MatHeaderCell, MatCellDef, MatCell],\n encapsulation: 2\n });\n return MatTextColumn;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nconst EXPORTED_DECLARATIONS = [// Table\nMatTable, MatRecycleRows, // Template defs\nMatHeaderCellDef, MatHeaderRowDef, MatColumnDef, MatCellDef, MatRowDef, MatFooterCellDef, MatFooterRowDef, // Cell directives\nMatHeaderCell, MatCell, MatFooterCell, // Row directives\nMatHeaderRow, MatRow, MatFooterRow, MatNoDataRow, MatTextColumn];\nlet MatTableModule = /*#__PURE__*/(() => {\n class MatTableModule {}\n\n MatTableModule.ɵfac = function MatTableModule_Factory(t) {\n return new (t || MatTableModule)();\n };\n\n MatTableModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: MatTableModule\n });\n MatTableModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n imports: [[CdkTableModule, MatCommonModule], MatCommonModule]\n });\n return MatTableModule;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Corresponds to `Number.MAX_SAFE_INTEGER`. Moved out into a variable here due to\n * flaky browser support and the value not being defined in Closure's typings.\n */\n\n\nconst MAX_SAFE_INTEGER = 9007199254740991;\n/** Shared base class with MDC-based implementation. */\n\nclass _MatTableDataSource extends DataSource {\n constructor(initialData = []) {\n super();\n /** Stream emitting render data to the table (depends on ordered data changes). */\n\n this._renderData = new BehaviorSubject([]);\n /** Stream that emits when a new filter string is set on the data source. */\n\n this._filter = new BehaviorSubject('');\n /** Used to react to internal changes of the paginator that are made by the data source itself. */\n\n this._internalPageChanges = new Subject();\n /**\n * Subscription to the changes that should trigger an update to the table's rendered rows, such\n * as filtering, sorting, pagination, or base data changes.\n */\n\n this._renderChangesSubscription = null;\n /**\n * Data accessor function that is used for accessing data properties for sorting through\n * the default sortData function.\n * This default function assumes that the sort header IDs (which defaults to the column name)\n * matches the data's properties (e.g. column Xyz represents data['Xyz']).\n * May be set to a custom function for different behavior.\n * @param data Data object that is being accessed.\n * @param sortHeaderId The name of the column that represents the data.\n */\n\n this.sortingDataAccessor = (data, sortHeaderId) => {\n const value = data[sortHeaderId];\n\n if (_isNumberValue(value)) {\n const numberValue = Number(value); // Numbers beyond `MAX_SAFE_INTEGER` can't be compared reliably so we\n // leave them as strings. For more info: https://goo.gl/y5vbSg\n\n return numberValue < MAX_SAFE_INTEGER ? numberValue : value;\n }\n\n return value;\n };\n /**\n * Gets a sorted copy of the data array based on the state of the MatSort. Called\n * after changes are made to the filtered data or when sort changes are emitted from MatSort.\n * By default, the function retrieves the active sort and its direction and compares data\n * by retrieving data using the sortingDataAccessor. May be overridden for a custom implementation\n * of data ordering.\n * @param data The array of data that should be sorted.\n * @param sort The connected MatSort that holds the current sort state.\n */\n\n\n this.sortData = (data, sort) => {\n const active = sort.active;\n const direction = sort.direction;\n\n if (!active || direction == '') {\n return data;\n }\n\n return data.sort((a, b) => {\n let valueA = this.sortingDataAccessor(a, active);\n let valueB = this.sortingDataAccessor(b, active); // If there are data in the column that can be converted to a number,\n // it must be ensured that the rest of the data\n // is of the same type so as not to order incorrectly.\n\n const valueAType = typeof valueA;\n const valueBType = typeof valueB;\n\n if (valueAType !== valueBType) {\n if (valueAType === 'number') {\n valueA += '';\n }\n\n if (valueBType === 'number') {\n valueB += '';\n }\n } // If both valueA and valueB exist (truthy), then compare the two. Otherwise, check if\n // one value exists while the other doesn't. In this case, existing value should come last.\n // This avoids inconsistent results when comparing values to undefined/null.\n // If neither value exists, return 0 (equal).\n\n\n let comparatorResult = 0;\n\n if (valueA != null && valueB != null) {\n // Check if one value is greater than the other; if equal, comparatorResult should remain 0.\n if (valueA > valueB) {\n comparatorResult = 1;\n } else if (valueA < valueB) {\n comparatorResult = -1;\n }\n } else if (valueA != null) {\n comparatorResult = 1;\n } else if (valueB != null) {\n comparatorResult = -1;\n }\n\n return comparatorResult * (direction == 'asc' ? 1 : -1);\n });\n };\n /**\n * Checks if a data object matches the data source's filter string. By default, each data object\n * is converted to a string of its properties and returns true if the filter has\n * at least one occurrence in that string. By default, the filter string has its whitespace\n * trimmed and the match is case-insensitive. May be overridden for a custom implementation of\n * filter matching.\n * @param data Data object used to check against the filter.\n * @param filter Filter string that has been set on the data source.\n * @returns Whether the filter matches against the data\n */\n\n\n this.filterPredicate = (data, filter) => {\n // Transform the data into a lowercase string of all property values.\n const dataStr = Object.keys(data).reduce((currentTerm, key) => {\n // Use an obscure Unicode character to delimit the words in the concatenated string.\n // This avoids matches where the values of two columns combined will match the user's query\n // (e.g. `Flute` and `Stop` will match `Test`). The character is intended to be something\n // that has a very low chance of being typed in by somebody in a text field. This one in\n // particular is \"White up-pointing triangle with dot\" from\n // https://en.wikipedia.org/wiki/List_of_Unicode_characters\n return currentTerm + data[key] + '◬';\n }, '').toLowerCase(); // Transform the filter by converting it to lowercase and removing whitespace.\n\n const transformedFilter = filter.trim().toLowerCase();\n return dataStr.indexOf(transformedFilter) != -1;\n };\n\n this._data = new BehaviorSubject(initialData);\n\n this._updateChangeSubscription();\n }\n /** Array of data that should be rendered by the table, where each object represents one row. */\n\n\n get data() {\n return this._data.value;\n }\n\n set data(data) {\n data = Array.isArray(data) ? data : [];\n\n this._data.next(data); // Normally the `filteredData` is updated by the re-render\n // subscription, but that won't happen if it's inactive.\n\n\n if (!this._renderChangesSubscription) {\n this._filterData(data);\n }\n }\n /**\n * Filter term that should be used to filter out objects from the data array. To override how\n * data objects match to this filter string, provide a custom function for filterPredicate.\n */\n\n\n get filter() {\n return this._filter.value;\n }\n\n set filter(filter) {\n this._filter.next(filter); // Normally the `filteredData` is updated by the re-render\n // subscription, but that won't happen if it's inactive.\n\n\n if (!this._renderChangesSubscription) {\n this._filterData(this.data);\n }\n }\n /**\n * Instance of the MatSort directive used by the table to control its sorting. Sort changes\n * emitted by the MatSort will trigger an update to the table's rendered data.\n */\n\n\n get sort() {\n return this._sort;\n }\n\n set sort(sort) {\n this._sort = sort;\n\n this._updateChangeSubscription();\n }\n /**\n * Instance of the MatPaginator component used by the table to control what page of the data is\n * displayed. Page changes emitted by the MatPaginator will trigger an update to the\n * table's rendered data.\n *\n * Note that the data source uses the paginator's properties to calculate which page of data\n * should be displayed. If the paginator receives its properties as template inputs,\n * e.g. `[pageLength]=100` or `[pageIndex]=1`, then be sure that the paginator's view has been\n * initialized before assigning it to this data source.\n */\n\n\n get paginator() {\n return this._paginator;\n }\n\n set paginator(paginator) {\n this._paginator = paginator;\n\n this._updateChangeSubscription();\n }\n /**\n * Subscribe to changes that should trigger an update to the table's rendered rows. When the\n * changes occur, process the current state of the filter, sort, and pagination along with\n * the provided base data and send it to the table for rendering.\n */\n\n\n _updateChangeSubscription() {\n var _this$_renderChangesS;\n\n // Sorting and/or pagination should be watched if MatSort and/or MatPaginator are provided.\n // The events should emit whenever the component emits a change or initializes, or if no\n // component is provided, a stream with just a null event should be provided.\n // The `sortChange` and `pageChange` acts as a signal to the combineLatests below so that the\n // pipeline can progress to the next step. Note that the value from these streams are not used,\n // they purely act as a signal to progress in the pipeline.\n const sortChange = this._sort ? merge(this._sort.sortChange, this._sort.initialized) : of(null);\n const pageChange = this._paginator ? merge(this._paginator.page, this._internalPageChanges, this._paginator.initialized) : of(null);\n const dataStream = this._data; // Watch for base data or filter changes to provide a filtered set of data.\n\n const filteredData = combineLatest([dataStream, this._filter]).pipe(map(([data]) => this._filterData(data))); // Watch for filtered data or sort changes to provide an ordered set of data.\n\n const orderedData = combineLatest([filteredData, sortChange]).pipe(map(([data]) => this._orderData(data))); // Watch for ordered data or page changes to provide a paged set of data.\n\n const paginatedData = combineLatest([orderedData, pageChange]).pipe(map(([data]) => this._pageData(data))); // Watched for paged data changes and send the result to the table to render.\n\n (_this$_renderChangesS = this._renderChangesSubscription) === null || _this$_renderChangesS === void 0 ? void 0 : _this$_renderChangesS.unsubscribe();\n this._renderChangesSubscription = paginatedData.subscribe(data => this._renderData.next(data));\n }\n /**\n * Returns a filtered data array where each filter object contains the filter string within\n * the result of the filterTermAccessor function. If no filter is set, returns the data array\n * as provided.\n */\n\n\n _filterData(data) {\n // If there is a filter string, filter out data that does not contain it.\n // Each data object is converted to a string using the function defined by filterTermAccessor.\n // May be overridden for customization.\n this.filteredData = this.filter == null || this.filter === '' ? data : data.filter(obj => this.filterPredicate(obj, this.filter));\n\n if (this.paginator) {\n this._updatePaginator(this.filteredData.length);\n }\n\n return this.filteredData;\n }\n /**\n * Returns a sorted copy of the data if MatSort has a sort applied, otherwise just returns the\n * data array as provided. Uses the default data accessor for data lookup, unless a\n * sortDataAccessor function is defined.\n */\n\n\n _orderData(data) {\n // If there is no active sort or direction, return the data without trying to sort.\n if (!this.sort) {\n return data;\n }\n\n return this.sortData(data.slice(), this.sort);\n }\n /**\n * Returns a paged slice of the provided data array according to the provided MatPaginator's page\n * index and length. If there is no paginator provided, returns the data array as provided.\n */\n\n\n _pageData(data) {\n if (!this.paginator) {\n return data;\n }\n\n const startIndex = this.paginator.pageIndex * this.paginator.pageSize;\n return data.slice(startIndex, startIndex + this.paginator.pageSize);\n }\n /**\n * Updates the paginator to reflect the length of the filtered data, and makes sure that the page\n * index does not exceed the paginator's last page. Values are changed in a resolved promise to\n * guard against making property changes within a round of change detection.\n */\n\n\n _updatePaginator(filteredDataLength) {\n Promise.resolve().then(() => {\n const paginator = this.paginator;\n\n if (!paginator) {\n return;\n }\n\n paginator.length = filteredDataLength; // If the page index is set beyond the page, reduce it to the last page.\n\n if (paginator.pageIndex > 0) {\n const lastPageIndex = Math.ceil(paginator.length / paginator.pageSize) - 1 || 0;\n const newPageIndex = Math.min(paginator.pageIndex, lastPageIndex);\n\n if (newPageIndex !== paginator.pageIndex) {\n paginator.pageIndex = newPageIndex; // Since the paginator only emits after user-generated changes,\n // we need our own stream so we know to should re-render the data.\n\n this._internalPageChanges.next();\n }\n }\n });\n }\n /**\n * Used by the MatTable. Called when it connects to the data source.\n * @docs-private\n */\n\n\n connect() {\n if (!this._renderChangesSubscription) {\n this._updateChangeSubscription();\n }\n\n return this._renderData;\n }\n /**\n * Used by the MatTable. Called when it disconnects from the data source.\n * @docs-private\n */\n\n\n disconnect() {\n var _this$_renderChangesS2;\n\n (_this$_renderChangesS2 = this._renderChangesSubscription) === null || _this$_renderChangesS2 === void 0 ? void 0 : _this$_renderChangesS2.unsubscribe();\n this._renderChangesSubscription = null;\n }\n\n}\n/**\n * Data source that accepts a client-side data array and includes native support of filtering,\n * sorting (using MatSort), and pagination (using MatPaginator).\n *\n * Allows for sort customization by overriding sortingDataAccessor, which defines how data\n * properties are accessed. Also allows for filter customization by overriding filterTermAccessor,\n * which defines how row data is converted to a string for filter matching.\n *\n * **Note:** This class is meant to be a simple data source to help you get started. As such\n * it isn't equipped to handle some more advanced cases like robust i18n support or server-side\n * interactions. If your app needs to support more advanced use cases, consider implementing your\n * own `DataSource`.\n */\n\n\nclass MatTableDataSource extends _MatTableDataSource {}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Generated bundle index. Do not edit.\n */\n\n\nexport { MatCell, MatCellDef, MatColumnDef, MatFooterCell, MatFooterCellDef, MatFooterRow, MatFooterRowDef, MatHeaderCell, MatHeaderCellDef, MatHeaderRow, MatHeaderRowDef, MatNoDataRow, MatRecycleRows, MatRow, MatRowDef, MatTable, MatTableDataSource, MatTableModule, MatTextColumn, _MatTableDataSource }; //# sourceMappingURL=table.mjs.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/113276357a14d9c521f4f9045bebc02e.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/113276357a14d9c521f4f9045bebc02e.json
deleted file mode 100644
index cce73367..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/113276357a14d9c521f4f9045bebc02e.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { coerceElement, coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';\nimport * as i0 from '@angular/core';\nimport { Injectable, EventEmitter, Directive, Output, Input, NgModule } from '@angular/core';\nimport { Observable, Subject } from 'rxjs';\nimport { debounceTime } from 'rxjs/operators';\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Factory that creates a new MutationObserver and allows us to stub it out in unit tests.\n * @docs-private\n */\n\nlet MutationObserverFactory = /*#__PURE__*/(() => {\n class MutationObserverFactory {\n create(callback) {\n return typeof MutationObserver === 'undefined' ? null : new MutationObserver(callback);\n }\n\n }\n\n MutationObserverFactory.ɵfac = function MutationObserverFactory_Factory(t) {\n return new (t || MutationObserverFactory)();\n };\n\n MutationObserverFactory.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: MutationObserverFactory,\n factory: MutationObserverFactory.ɵfac,\n providedIn: 'root'\n });\n return MutationObserverFactory;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/** An injectable service that allows watching elements for changes to their content. */\n\n\nlet ContentObserver = /*#__PURE__*/(() => {\n class ContentObserver {\n constructor(_mutationObserverFactory) {\n this._mutationObserverFactory = _mutationObserverFactory;\n /** Keeps track of the existing MutationObservers so they can be reused. */\n\n this._observedElements = new Map();\n }\n\n ngOnDestroy() {\n this._observedElements.forEach((_, element) => this._cleanupObserver(element));\n }\n\n observe(elementOrRef) {\n const element = coerceElement(elementOrRef);\n return new Observable(observer => {\n const stream = this._observeElement(element);\n\n const subscription = stream.subscribe(observer);\n return () => {\n subscription.unsubscribe();\n\n this._unobserveElement(element);\n };\n });\n }\n /**\n * Observes the given element by using the existing MutationObserver if available, or creating a\n * new one if not.\n */\n\n\n _observeElement(element) {\n if (!this._observedElements.has(element)) {\n const stream = new Subject();\n\n const observer = this._mutationObserverFactory.create(mutations => stream.next(mutations));\n\n if (observer) {\n observer.observe(element, {\n characterData: true,\n childList: true,\n subtree: true\n });\n }\n\n this._observedElements.set(element, {\n observer,\n stream,\n count: 1\n });\n } else {\n this._observedElements.get(element).count++;\n }\n\n return this._observedElements.get(element).stream;\n }\n /**\n * Un-observes the given element and cleans up the underlying MutationObserver if nobody else is\n * observing this element.\n */\n\n\n _unobserveElement(element) {\n if (this._observedElements.has(element)) {\n this._observedElements.get(element).count--;\n\n if (!this._observedElements.get(element).count) {\n this._cleanupObserver(element);\n }\n }\n }\n /** Clean up the underlying MutationObserver for the specified element. */\n\n\n _cleanupObserver(element) {\n if (this._observedElements.has(element)) {\n const {\n observer,\n stream\n } = this._observedElements.get(element);\n\n if (observer) {\n observer.disconnect();\n }\n\n stream.complete();\n\n this._observedElements.delete(element);\n }\n }\n\n }\n\n ContentObserver.ɵfac = function ContentObserver_Factory(t) {\n return new (t || ContentObserver)(i0.ɵɵinject(MutationObserverFactory));\n };\n\n ContentObserver.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: ContentObserver,\n factory: ContentObserver.ɵfac,\n providedIn: 'root'\n });\n return ContentObserver;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Directive that triggers a callback whenever the content of\n * its associated element has changed.\n */\n\n\nlet CdkObserveContent = /*#__PURE__*/(() => {\n class CdkObserveContent {\n constructor(_contentObserver, _elementRef, _ngZone) {\n this._contentObserver = _contentObserver;\n this._elementRef = _elementRef;\n this._ngZone = _ngZone;\n /** Event emitted for each change in the element's content. */\n\n this.event = new EventEmitter();\n this._disabled = false;\n this._currentSubscription = null;\n }\n /**\n * Whether observing content is disabled. This option can be used\n * to disconnect the underlying MutationObserver until it is needed.\n */\n\n\n get disabled() {\n return this._disabled;\n }\n\n set disabled(value) {\n this._disabled = coerceBooleanProperty(value);\n this._disabled ? this._unsubscribe() : this._subscribe();\n }\n /** Debounce interval for emitting the changes. */\n\n\n get debounce() {\n return this._debounce;\n }\n\n set debounce(value) {\n this._debounce = coerceNumberProperty(value);\n\n this._subscribe();\n }\n\n ngAfterContentInit() {\n if (!this._currentSubscription && !this.disabled) {\n this._subscribe();\n }\n }\n\n ngOnDestroy() {\n this._unsubscribe();\n }\n\n _subscribe() {\n this._unsubscribe();\n\n const stream = this._contentObserver.observe(this._elementRef); // TODO(mmalerba): We shouldn't be emitting on this @Output() outside the zone.\n // Consider brining it back inside the zone next time we're making breaking changes.\n // Bringing it back inside can cause things like infinite change detection loops and changed\n // after checked errors if people's code isn't handling it properly.\n\n\n this._ngZone.runOutsideAngular(() => {\n this._currentSubscription = (this.debounce ? stream.pipe(debounceTime(this.debounce)) : stream).subscribe(this.event);\n });\n }\n\n _unsubscribe() {\n var _this$_currentSubscri;\n\n (_this$_currentSubscri = this._currentSubscription) === null || _this$_currentSubscri === void 0 ? void 0 : _this$_currentSubscri.unsubscribe();\n }\n\n }\n\n CdkObserveContent.ɵfac = function CdkObserveContent_Factory(t) {\n return new (t || CdkObserveContent)(i0.ɵɵdirectiveInject(ContentObserver), i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.NgZone));\n };\n\n CdkObserveContent.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: CdkObserveContent,\n selectors: [[\"\", \"cdkObserveContent\", \"\"]],\n inputs: {\n disabled: [\"cdkObserveContentDisabled\", \"disabled\"],\n debounce: \"debounce\"\n },\n outputs: {\n event: \"cdkObserveContent\"\n },\n exportAs: [\"cdkObserveContent\"]\n });\n return CdkObserveContent;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\nlet ObserversModule = /*#__PURE__*/(() => {\n class ObserversModule {}\n\n ObserversModule.ɵfac = function ObserversModule_Factory(t) {\n return new (t || ObserversModule)();\n };\n\n ObserversModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: ObserversModule\n });\n ObserversModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n providers: [MutationObserverFactory]\n });\n return ObserversModule;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Generated bundle index. Do not edit.\n */\n\n\nexport { CdkObserveContent, ContentObserver, MutationObserverFactory, ObserversModule }; //# sourceMappingURL=observers.mjs.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/11b33c477c5369b7fe76ad0a973576dc.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/11b33c477c5369b7fe76ad0a973576dc.json
deleted file mode 100644
index b83130b9..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/11b33c477c5369b7fe76ad0a973576dc.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { dateTimestampProvider } from './scheduler/dateTimestampProvider';\nexport class Scheduler {\n constructor(schedulerActionCtor, now = Scheduler.now) {\n this.schedulerActionCtor = schedulerActionCtor;\n this.now = now;\n }\n\n schedule(work, delay = 0, state) {\n return new this.schedulerActionCtor(this, work).schedule(state, delay);\n }\n\n}\nScheduler.now = dateTimestampProvider.now; //# sourceMappingURL=Scheduler.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/1201d1139b4465f210b40ccdcdec5f2b.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/1201d1139b4465f210b40ccdcdec5f2b.json
deleted file mode 100644
index 79f04b62..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/1201d1139b4465f210b40ccdcdec5f2b.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import * as i0 from '@angular/core';\nimport { Version, InjectionToken, NgModule, Optional, Inject, inject, LOCALE_ID, Injectable, Directive, Input, Component, ViewEncapsulation, ChangeDetectionStrategy, EventEmitter, Output } from '@angular/core';\nimport * as i1 from '@angular/cdk/a11y';\nimport { isFakeMousedownFromScreenReader, isFakeTouchstartFromScreenReader } from '@angular/cdk/a11y';\nimport { BidiModule } from '@angular/cdk/bidi';\nimport { VERSION as VERSION$1 } from '@angular/cdk';\nimport * as i3 from '@angular/common';\nimport { DOCUMENT, CommonModule } from '@angular/common';\nimport * as i1$1 from '@angular/cdk/platform';\nimport { _isTestEnvironment, PlatformModule, normalizePassiveListenerOptions } from '@angular/cdk/platform';\nimport { coerceBooleanProperty, coerceNumberProperty, coerceElement } from '@angular/cdk/coercion';\nimport { Subject, Observable } from 'rxjs';\nimport { startWith } from 'rxjs/operators';\nimport { ANIMATION_MODULE_TYPE } from '@angular/platform-browser/animations';\nimport { ENTER, SPACE, hasModifierKey } from '@angular/cdk/keycodes';\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/** Current version of Angular Material. */\n\nconst _c0 = [\"*\", [[\"mat-option\"], [\"ng-container\"]]];\nconst _c1 = [\"*\", \"mat-option, ng-container\"];\n\nfunction MatOption_mat_pseudo_checkbox_0_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelement(0, \"mat-pseudo-checkbox\", 4);\n }\n\n if (rf & 2) {\n const ctx_r0 = i0.ɵɵnextContext();\n i0.ɵɵproperty(\"state\", ctx_r0.selected ? \"checked\" : \"unchecked\")(\"disabled\", ctx_r0.disabled);\n }\n}\n\nfunction MatOption_span_3_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementStart(0, \"span\", 5);\n i0.ɵɵtext(1);\n i0.ɵɵelementEnd();\n }\n\n if (rf & 2) {\n const ctx_r1 = i0.ɵɵnextContext();\n i0.ɵɵadvance(1);\n i0.ɵɵtextInterpolate1(\"(\", ctx_r1.group.label, \")\");\n }\n}\n\nconst _c2 = [\"*\"];\nconst VERSION = /*#__PURE__*/new Version('13.2.2');\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/** @docs-private */\n\nlet AnimationCurves = /*#__PURE__*/(() => {\n class AnimationCurves {}\n\n AnimationCurves.STANDARD_CURVE = 'cubic-bezier(0.4,0.0,0.2,1)';\n AnimationCurves.DECELERATION_CURVE = 'cubic-bezier(0.0,0.0,0.2,1)';\n AnimationCurves.ACCELERATION_CURVE = 'cubic-bezier(0.4,0.0,1,1)';\n AnimationCurves.SHARP_CURVE = 'cubic-bezier(0.4,0.0,0.6,1)';\n /** @docs-private */\n\n return AnimationCurves;\n})();\nlet AnimationDurations = /*#__PURE__*/(() => {\n class AnimationDurations {}\n\n AnimationDurations.COMPLEX = '375ms';\n AnimationDurations.ENTERING = '225ms';\n AnimationDurations.EXITING = '195ms';\n /**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n /** @docs-private */\n\n return AnimationDurations;\n})();\n\nfunction MATERIAL_SANITY_CHECKS_FACTORY() {\n return true;\n}\n/** Injection token that configures whether the Material sanity checks are enabled. */\n\n\nconst MATERIAL_SANITY_CHECKS = /*#__PURE__*/new InjectionToken('mat-sanity-checks', {\n providedIn: 'root',\n factory: MATERIAL_SANITY_CHECKS_FACTORY\n});\n/**\n * Module that captures anything that should be loaded and/or run for *all* Angular Material\n * components. This includes Bidi, etc.\n *\n * This module should be imported to each top-level component module (e.g., MatTabsModule).\n */\n\nlet MatCommonModule = /*#__PURE__*/(() => {\n class MatCommonModule {\n constructor(highContrastModeDetector, _sanityChecks, _document) {\n this._sanityChecks = _sanityChecks;\n this._document = _document;\n /** Whether we've done the global sanity checks (e.g. a theme is loaded, there is a doctype). */\n\n this._hasDoneGlobalChecks = false; // While A11yModule also does this, we repeat it here to avoid importing A11yModule\n // in MatCommonModule.\n\n highContrastModeDetector._applyBodyHighContrastModeCssClasses();\n\n if (!this._hasDoneGlobalChecks) {\n this._hasDoneGlobalChecks = true;\n\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n if (this._checkIsEnabled('doctype')) {\n _checkDoctypeIsDefined(this._document);\n }\n\n if (this._checkIsEnabled('theme')) {\n _checkThemeIsPresent(this._document);\n }\n\n if (this._checkIsEnabled('version')) {\n _checkCdkVersionMatch();\n }\n }\n }\n }\n /** Gets whether a specific sanity check is enabled. */\n\n\n _checkIsEnabled(name) {\n if (_isTestEnvironment()) {\n return false;\n }\n\n if (typeof this._sanityChecks === 'boolean') {\n return this._sanityChecks;\n }\n\n return !!this._sanityChecks[name];\n }\n\n }\n\n MatCommonModule.ɵfac = function MatCommonModule_Factory(t) {\n return new (t || MatCommonModule)(i0.ɵɵinject(i1.HighContrastModeDetector), i0.ɵɵinject(MATERIAL_SANITY_CHECKS, 8), i0.ɵɵinject(DOCUMENT));\n };\n\n MatCommonModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: MatCommonModule\n });\n MatCommonModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n imports: [[BidiModule], BidiModule]\n });\n return MatCommonModule;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/** Checks that the page has a doctype. */\n\n\nfunction _checkDoctypeIsDefined(doc) {\n if (!doc.doctype) {\n console.warn('Current document does not have a doctype. This may cause ' + 'some Angular Material components not to behave as expected.');\n }\n}\n/** Checks that a theme has been included. */\n\n\nfunction _checkThemeIsPresent(doc) {\n // We need to assert that the `body` is defined, because these checks run very early\n // and the `body` won't be defined if the consumer put their scripts in the `head`.\n if (!doc.body || typeof getComputedStyle !== 'function') {\n return;\n }\n\n const testElement = doc.createElement('div');\n testElement.classList.add('mat-theme-loaded-marker');\n doc.body.appendChild(testElement);\n const computedStyle = getComputedStyle(testElement); // In some situations the computed style of the test element can be null. For example in\n // Firefox, the computed style is null if an application is running inside of a hidden iframe.\n // See: https://bugzilla.mozilla.org/show_bug.cgi?id=548397\n\n if (computedStyle && computedStyle.display !== 'none') {\n console.warn('Could not find Angular Material core theme. Most Material ' + 'components may not work as expected. For more info refer ' + 'to the theming guide: https://material.angular.io/guide/theming');\n }\n\n testElement.remove();\n}\n/** Checks whether the Material version matches the CDK version. */\n\n\nfunction _checkCdkVersionMatch() {\n if (VERSION.full !== VERSION$1.full) {\n console.warn('The Angular Material version (' + VERSION.full + ') does not match ' + 'the Angular CDK version (' + VERSION$1.full + ').\\n' + 'Please ensure the versions of these two packages exactly match.');\n }\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nfunction mixinDisabled(base) {\n return class extends base {\n constructor(...args) {\n super(...args);\n this._disabled = false;\n }\n\n get disabled() {\n return this._disabled;\n }\n\n set disabled(value) {\n this._disabled = coerceBooleanProperty(value);\n }\n\n };\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nfunction mixinColor(base, defaultColor) {\n return class extends base {\n constructor(...args) {\n super(...args);\n this.defaultColor = defaultColor; // Set the default color that can be specified from the mixin.\n\n this.color = defaultColor;\n }\n\n get color() {\n return this._color;\n }\n\n set color(value) {\n const colorPalette = value || this.defaultColor;\n\n if (colorPalette !== this._color) {\n if (this._color) {\n this._elementRef.nativeElement.classList.remove(`mat-${this._color}`);\n }\n\n if (colorPalette) {\n this._elementRef.nativeElement.classList.add(`mat-${colorPalette}`);\n }\n\n this._color = colorPalette;\n }\n }\n\n };\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nfunction mixinDisableRipple(base) {\n return class extends base {\n constructor(...args) {\n super(...args);\n this._disableRipple = false;\n }\n /** Whether the ripple effect is disabled or not. */\n\n\n get disableRipple() {\n return this._disableRipple;\n }\n\n set disableRipple(value) {\n this._disableRipple = coerceBooleanProperty(value);\n }\n\n };\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nfunction mixinTabIndex(base, defaultTabIndex = 0) {\n return class extends base {\n constructor(...args) {\n super(...args);\n this._tabIndex = defaultTabIndex;\n this.defaultTabIndex = defaultTabIndex;\n }\n\n get tabIndex() {\n return this.disabled ? -1 : this._tabIndex;\n }\n\n set tabIndex(value) {\n // If the specified tabIndex value is null or undefined, fall back to the default value.\n this._tabIndex = value != null ? coerceNumberProperty(value) : this.defaultTabIndex;\n }\n\n };\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nfunction mixinErrorState(base) {\n return class extends base {\n constructor(...args) {\n super(...args); // This class member exists as an interop with `MatFormFieldControl` which expects\n // a public `stateChanges` observable to emit whenever the form field should be updated.\n // The description is not specifically mentioning the error state, as classes using this\n // mixin can/should emit an event in other cases too.\n\n /** Emits whenever the component state changes. */\n\n this.stateChanges = new Subject();\n /** Whether the component is in an error state. */\n\n this.errorState = false;\n }\n /** Updates the error state based on the provided error state matcher. */\n\n\n updateErrorState() {\n const oldState = this.errorState;\n const parent = this._parentFormGroup || this._parentForm;\n const matcher = this.errorStateMatcher || this._defaultErrorStateMatcher;\n const control = this.ngControl ? this.ngControl.control : null;\n const newState = matcher.isErrorState(control, parent);\n\n if (newState !== oldState) {\n this.errorState = newState;\n this.stateChanges.next();\n }\n }\n\n };\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/** Mixin to augment a directive with an initialized property that will emits when ngOnInit ends. */\n\n\nfunction mixinInitialized(base) {\n return class extends base {\n constructor(...args) {\n super(...args);\n /** Whether this directive has been marked as initialized. */\n\n this._isInitialized = false;\n /**\n * List of subscribers that subscribed before the directive was initialized. Should be notified\n * during _markInitialized. Set to null after pending subscribers are notified, and should\n * not expect to be populated after.\n */\n\n this._pendingSubscribers = [];\n /**\n * Observable stream that emits when the directive initializes. If already initialized, the\n * subscriber is stored to be notified once _markInitialized is called.\n */\n\n this.initialized = new Observable(subscriber => {\n // If initialized, immediately notify the subscriber. Otherwise store the subscriber to notify\n // when _markInitialized is called.\n if (this._isInitialized) {\n this._notifySubscriber(subscriber);\n } else {\n this._pendingSubscribers.push(subscriber);\n }\n });\n }\n /**\n * Marks the state as initialized and notifies pending subscribers. Should be called at the end\n * of ngOnInit.\n * @docs-private\n */\n\n\n _markInitialized() {\n if (this._isInitialized && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n throw Error('This directive has already been marked as initialized and ' + 'should not be called twice.');\n }\n\n this._isInitialized = true;\n\n this._pendingSubscribers.forEach(this._notifySubscriber);\n\n this._pendingSubscribers = null;\n }\n /** Emits and completes the subscriber stream (should only emit once). */\n\n\n _notifySubscriber(subscriber) {\n subscriber.next();\n subscriber.complete();\n }\n\n };\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/** InjectionToken for datepicker that can be used to override default locale code. */\n\n\nconst MAT_DATE_LOCALE = /*#__PURE__*/new InjectionToken('MAT_DATE_LOCALE', {\n providedIn: 'root',\n factory: MAT_DATE_LOCALE_FACTORY\n});\n/** @docs-private */\n\nfunction MAT_DATE_LOCALE_FACTORY() {\n return inject(LOCALE_ID);\n}\n/** Adapts type `D` to be usable as a date by cdk-based components that work with dates. */\n\n\nclass DateAdapter {\n constructor() {\n this._localeChanges = new Subject();\n /** A stream that emits when the locale changes. */\n\n this.localeChanges = this._localeChanges;\n }\n /**\n * Given a potential date object, returns that same date object if it is\n * a valid date, or `null` if it's not a valid date.\n * @param obj The object to check.\n * @returns A date or `null`.\n */\n\n\n getValidDateOrNull(obj) {\n return this.isDateInstance(obj) && this.isValid(obj) ? obj : null;\n }\n /**\n * Attempts to deserialize a value to a valid date object. This is different from parsing in that\n * deserialize should only accept non-ambiguous, locale-independent formats (e.g. a ISO 8601\n * string). The default implementation does not allow any deserialization, it simply checks that\n * the given value is already a valid date object or null. The `` will call this\n * method on all of its `@Input()` properties that accept dates. It is therefore possible to\n * support passing values from your backend directly to these properties by overriding this method\n * to also deserialize the format used by your backend.\n * @param value The value to be deserialized into a date object.\n * @returns The deserialized date object, either a valid date, null if the value can be\n * deserialized into a null date (e.g. the empty string), or an invalid date.\n */\n\n\n deserialize(value) {\n if (value == null || this.isDateInstance(value) && this.isValid(value)) {\n return value;\n }\n\n return this.invalid();\n }\n /**\n * Sets the locale used for all dates.\n * @param locale The new locale.\n */\n\n\n setLocale(locale) {\n this.locale = locale;\n\n this._localeChanges.next();\n }\n /**\n * Compares two dates.\n * @param first The first date to compare.\n * @param second The second date to compare.\n * @returns 0 if the dates are equal, a number less than 0 if the first date is earlier,\n * a number greater than 0 if the first date is later.\n */\n\n\n compareDate(first, second) {\n return this.getYear(first) - this.getYear(second) || this.getMonth(first) - this.getMonth(second) || this.getDate(first) - this.getDate(second);\n }\n /**\n * Checks if two dates are equal.\n * @param first The first date to check.\n * @param second The second date to check.\n * @returns Whether the two dates are equal.\n * Null dates are considered equal to other null dates.\n */\n\n\n sameDate(first, second) {\n if (first && second) {\n let firstValid = this.isValid(first);\n let secondValid = this.isValid(second);\n\n if (firstValid && secondValid) {\n return !this.compareDate(first, second);\n }\n\n return firstValid == secondValid;\n }\n\n return first == second;\n }\n /**\n * Clamp the given date between min and max dates.\n * @param date The date to clamp.\n * @param min The minimum value to allow. If null or omitted no min is enforced.\n * @param max The maximum value to allow. If null or omitted no max is enforced.\n * @returns `min` if `date` is less than `min`, `max` if date is greater than `max`,\n * otherwise `date`.\n */\n\n\n clampDate(date, min, max) {\n if (min && this.compareDate(date, min) < 0) {\n return min;\n }\n\n if (max && this.compareDate(date, max) > 0) {\n return max;\n }\n\n return date;\n }\n\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nconst MAT_DATE_FORMATS = /*#__PURE__*/new InjectionToken('mat-date-formats');\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Matches strings that have the form of a valid RFC 3339 string\n * (https://tools.ietf.org/html/rfc3339). Note that the string may not actually be a valid date\n * because the regex will match strings an with out of bounds month, date, etc.\n */\n\nconst ISO_8601_REGEX = /^\\d{4}-\\d{2}-\\d{2}(?:T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|(?:(?:\\+|-)\\d{2}:\\d{2}))?)?$/;\n/** Creates an array and fills it with values. */\n\nfunction range(length, valueFunction) {\n const valuesArray = Array(length);\n\n for (let i = 0; i < length; i++) {\n valuesArray[i] = valueFunction(i);\n }\n\n return valuesArray;\n}\n/** Adapts the native JS Date for use with cdk-based components that work with dates. */\n\n\nlet NativeDateAdapter = /*#__PURE__*/(() => {\n class NativeDateAdapter extends DateAdapter {\n constructor(matDateLocale,\n /**\n * @deprecated No longer being used. To be removed.\n * @breaking-change 14.0.0\n */\n _platform) {\n super();\n /**\n * @deprecated No longer being used. To be removed.\n * @breaking-change 14.0.0\n */\n\n this.useUtcForDisplay = false;\n super.setLocale(matDateLocale);\n }\n\n getYear(date) {\n return date.getFullYear();\n }\n\n getMonth(date) {\n return date.getMonth();\n }\n\n getDate(date) {\n return date.getDate();\n }\n\n getDayOfWeek(date) {\n return date.getDay();\n }\n\n getMonthNames(style) {\n const dtf = new Intl.DateTimeFormat(this.locale, {\n month: style,\n timeZone: 'utc'\n });\n return range(12, i => this._format(dtf, new Date(2017, i, 1)));\n }\n\n getDateNames() {\n const dtf = new Intl.DateTimeFormat(this.locale, {\n day: 'numeric',\n timeZone: 'utc'\n });\n return range(31, i => this._format(dtf, new Date(2017, 0, i + 1)));\n }\n\n getDayOfWeekNames(style) {\n const dtf = new Intl.DateTimeFormat(this.locale, {\n weekday: style,\n timeZone: 'utc'\n });\n return range(7, i => this._format(dtf, new Date(2017, 0, i + 1)));\n }\n\n getYearName(date) {\n const dtf = new Intl.DateTimeFormat(this.locale, {\n year: 'numeric',\n timeZone: 'utc'\n });\n return this._format(dtf, date);\n }\n\n getFirstDayOfWeek() {\n // We can't tell using native JS Date what the first day of the week is, we default to Sunday.\n return 0;\n }\n\n getNumDaysInMonth(date) {\n return this.getDate(this._createDateWithOverflow(this.getYear(date), this.getMonth(date) + 1, 0));\n }\n\n clone(date) {\n return new Date(date.getTime());\n }\n\n createDate(year, month, date) {\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n // Check for invalid month and date (except upper bound on date which we have to check after\n // creating the Date).\n if (month < 0 || month > 11) {\n throw Error(`Invalid month index \"${month}\". Month index has to be between 0 and 11.`);\n }\n\n if (date < 1) {\n throw Error(`Invalid date \"${date}\". Date has to be greater than 0.`);\n }\n }\n\n let result = this._createDateWithOverflow(year, month, date); // Check that the date wasn't above the upper bound for the month, causing the month to overflow\n\n\n if (result.getMonth() != month && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n throw Error(`Invalid date \"${date}\" for month with index \"${month}\".`);\n }\n\n return result;\n }\n\n today() {\n return new Date();\n }\n\n parse(value) {\n // We have no way using the native JS Date to set the parse format or locale, so we ignore these\n // parameters.\n if (typeof value == 'number') {\n return new Date(value);\n }\n\n return value ? new Date(Date.parse(value)) : null;\n }\n\n format(date, displayFormat) {\n if (!this.isValid(date)) {\n throw Error('NativeDateAdapter: Cannot format invalid date.');\n }\n\n const dtf = new Intl.DateTimeFormat(this.locale, { ...displayFormat,\n timeZone: 'utc'\n });\n return this._format(dtf, date);\n }\n\n addCalendarYears(date, years) {\n return this.addCalendarMonths(date, years * 12);\n }\n\n addCalendarMonths(date, months) {\n let newDate = this._createDateWithOverflow(this.getYear(date), this.getMonth(date) + months, this.getDate(date)); // It's possible to wind up in the wrong month if the original month has more days than the new\n // month. In this case we want to go to the last day of the desired month.\n // Note: the additional + 12 % 12 ensures we end up with a positive number, since JS % doesn't\n // guarantee this.\n\n\n if (this.getMonth(newDate) != ((this.getMonth(date) + months) % 12 + 12) % 12) {\n newDate = this._createDateWithOverflow(this.getYear(newDate), this.getMonth(newDate), 0);\n }\n\n return newDate;\n }\n\n addCalendarDays(date, days) {\n return this._createDateWithOverflow(this.getYear(date), this.getMonth(date), this.getDate(date) + days);\n }\n\n toIso8601(date) {\n return [date.getUTCFullYear(), this._2digit(date.getUTCMonth() + 1), this._2digit(date.getUTCDate())].join('-');\n }\n /**\n * Returns the given value if given a valid Date or null. Deserializes valid ISO 8601 strings\n * (https://www.ietf.org/rfc/rfc3339.txt) into valid Dates and empty string into null. Returns an\n * invalid date for all other values.\n */\n\n\n deserialize(value) {\n if (typeof value === 'string') {\n if (!value) {\n return null;\n } // The `Date` constructor accepts formats other than ISO 8601, so we need to make sure the\n // string is the right format first.\n\n\n if (ISO_8601_REGEX.test(value)) {\n let date = new Date(value);\n\n if (this.isValid(date)) {\n return date;\n }\n }\n }\n\n return super.deserialize(value);\n }\n\n isDateInstance(obj) {\n return obj instanceof Date;\n }\n\n isValid(date) {\n return !isNaN(date.getTime());\n }\n\n invalid() {\n return new Date(NaN);\n }\n /** Creates a date but allows the month and date to overflow. */\n\n\n _createDateWithOverflow(year, month, date) {\n // Passing the year to the constructor causes year numbers <100 to be converted to 19xx.\n // To work around this we use `setFullYear` and `setHours` instead.\n const d = new Date();\n d.setFullYear(year, month, date);\n d.setHours(0, 0, 0, 0);\n return d;\n }\n /**\n * Pads a number to make it two digits.\n * @param n The number to pad.\n * @returns The padded number.\n */\n\n\n _2digit(n) {\n return ('00' + n).slice(-2);\n }\n /**\n * When converting Date object to string, javascript built-in functions may return wrong\n * results because it applies its internal DST rules. The DST rules around the world change\n * very frequently, and the current valid rule is not always valid in previous years though.\n * We work around this problem building a new Date object which has its internal UTC\n * representation with the local date and time.\n * @param dtf Intl.DateTimeFormat object, containg the desired string format. It must have\n * timeZone set to 'utc' to work fine.\n * @param date Date from which we want to get the string representation according to dtf\n * @returns A Date object with its UTC representation based on the passed in date info\n */\n\n\n _format(dtf, date) {\n // Passing the year to the constructor causes year numbers <100 to be converted to 19xx.\n // To work around this we use `setUTCFullYear` and `setUTCHours` instead.\n const d = new Date();\n d.setUTCFullYear(date.getFullYear(), date.getMonth(), date.getDate());\n d.setUTCHours(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());\n return dtf.format(d);\n }\n\n }\n\n NativeDateAdapter.ɵfac = function NativeDateAdapter_Factory(t) {\n return new (t || NativeDateAdapter)(i0.ɵɵinject(MAT_DATE_LOCALE, 8), i0.ɵɵinject(i1$1.Platform));\n };\n\n NativeDateAdapter.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: NativeDateAdapter,\n factory: NativeDateAdapter.ɵfac\n });\n return NativeDateAdapter;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nconst MAT_NATIVE_DATE_FORMATS = {\n parse: {\n dateInput: null\n },\n display: {\n dateInput: {\n year: 'numeric',\n month: 'numeric',\n day: 'numeric'\n },\n monthYearLabel: {\n year: 'numeric',\n month: 'short'\n },\n dateA11yLabel: {\n year: 'numeric',\n month: 'long',\n day: 'numeric'\n },\n monthYearA11yLabel: {\n year: 'numeric',\n month: 'long'\n }\n }\n};\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nlet NativeDateModule = /*#__PURE__*/(() => {\n class NativeDateModule {}\n\n NativeDateModule.ɵfac = function NativeDateModule_Factory(t) {\n return new (t || NativeDateModule)();\n };\n\n NativeDateModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: NativeDateModule\n });\n NativeDateModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n providers: [{\n provide: DateAdapter,\n useClass: NativeDateAdapter\n }],\n imports: [[PlatformModule]]\n });\n return NativeDateModule;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\nlet MatNativeDateModule = /*#__PURE__*/(() => {\n class MatNativeDateModule {}\n\n MatNativeDateModule.ɵfac = function MatNativeDateModule_Factory(t) {\n return new (t || MatNativeDateModule)();\n };\n\n MatNativeDateModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: MatNativeDateModule\n });\n MatNativeDateModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n providers: [{\n provide: MAT_DATE_FORMATS,\n useValue: MAT_NATIVE_DATE_FORMATS\n }],\n imports: [[NativeDateModule]]\n });\n return MatNativeDateModule;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/** Error state matcher that matches when a control is invalid and dirty. */\n\n\nlet ShowOnDirtyErrorStateMatcher = /*#__PURE__*/(() => {\n class ShowOnDirtyErrorStateMatcher {\n isErrorState(control, form) {\n return !!(control && control.invalid && (control.dirty || form && form.submitted));\n }\n\n }\n\n ShowOnDirtyErrorStateMatcher.ɵfac = function ShowOnDirtyErrorStateMatcher_Factory(t) {\n return new (t || ShowOnDirtyErrorStateMatcher)();\n };\n\n ShowOnDirtyErrorStateMatcher.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: ShowOnDirtyErrorStateMatcher,\n factory: ShowOnDirtyErrorStateMatcher.ɵfac\n });\n return ShowOnDirtyErrorStateMatcher;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/** Provider that defines how form controls behave with regards to displaying error messages. */\n\n\nlet ErrorStateMatcher = /*#__PURE__*/(() => {\n class ErrorStateMatcher {\n isErrorState(control, form) {\n return !!(control && control.invalid && (control.touched || form && form.submitted));\n }\n\n }\n\n ErrorStateMatcher.ɵfac = function ErrorStateMatcher_Factory(t) {\n return new (t || ErrorStateMatcher)();\n };\n\n ErrorStateMatcher.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: ErrorStateMatcher,\n factory: ErrorStateMatcher.ɵfac,\n providedIn: 'root'\n });\n return ErrorStateMatcher;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Shared directive to count lines inside a text area, such as a list item.\n * Line elements can be extracted with a @ContentChildren(MatLine) query, then\n * counted by checking the query list's length.\n */\n\n\nlet MatLine = /*#__PURE__*/(() => {\n class MatLine {}\n\n MatLine.ɵfac = function MatLine_Factory(t) {\n return new (t || MatLine)();\n };\n\n MatLine.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatLine,\n selectors: [[\"\", \"mat-line\", \"\"], [\"\", \"matLine\", \"\"]],\n hostAttrs: [1, \"mat-line\"]\n });\n return MatLine;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Helper that takes a query list of lines and sets the correct class on the host.\n * @docs-private\n */\n\n\nfunction setLines(lines, element, prefix = 'mat') {\n // Note: doesn't need to unsubscribe, because `changes`\n // gets completed by Angular when the view is destroyed.\n lines.changes.pipe(startWith(lines)).subscribe(({\n length\n }) => {\n setClass(element, `${prefix}-2-line`, false);\n setClass(element, `${prefix}-3-line`, false);\n setClass(element, `${prefix}-multi-line`, false);\n\n if (length === 2 || length === 3) {\n setClass(element, `${prefix}-${length}-line`, true);\n } else if (length > 3) {\n setClass(element, `${prefix}-multi-line`, true);\n }\n });\n}\n/** Adds or removes a class from an element. */\n\n\nfunction setClass(element, className, isAdd) {\n element.nativeElement.classList.toggle(className, isAdd);\n}\n\nlet MatLineModule = /*#__PURE__*/(() => {\n class MatLineModule {}\n\n MatLineModule.ɵfac = function MatLineModule_Factory(t) {\n return new (t || MatLineModule)();\n };\n\n MatLineModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: MatLineModule\n });\n MatLineModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n imports: [[MatCommonModule], MatCommonModule]\n });\n return MatLineModule;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Reference to a previously launched ripple element.\n */\n\n\nclass RippleRef {\n constructor(_renderer,\n /** Reference to the ripple HTML element. */\n element,\n /** Ripple configuration used for the ripple. */\n config) {\n this._renderer = _renderer;\n this.element = element;\n this.config = config;\n /** Current state of the ripple. */\n\n this.state = 3\n /* HIDDEN */\n ;\n }\n /** Fades out the ripple element. */\n\n\n fadeOut() {\n this._renderer.fadeOutRipple(this);\n }\n\n} // TODO: import these values from `@material/ripple` eventually.\n\n/**\n * Default ripple animation configuration for ripples without an explicit\n * animation config specified.\n */\n\n\nconst defaultRippleAnimationConfig = {\n enterDuration: 225,\n exitDuration: 150\n};\n/**\n * Timeout for ignoring mouse events. Mouse events will be temporary ignored after touch\n * events to avoid synthetic mouse events.\n */\n\nconst ignoreMouseEventsTimeout = 800;\n/** Options that apply to all the event listeners that are bound by the ripple renderer. */\n\nconst passiveEventOptions = /*#__PURE__*/normalizePassiveListenerOptions({\n passive: true\n});\n/** Events that signal that the pointer is down. */\n\nconst pointerDownEvents = ['mousedown', 'touchstart'];\n/** Events that signal that the pointer is up. */\n\nconst pointerUpEvents = ['mouseup', 'mouseleave', 'touchend', 'touchcancel'];\n/**\n * Helper service that performs DOM manipulations. Not intended to be used outside this module.\n * The constructor takes a reference to the ripple directive's host element and a map of DOM\n * event handlers to be installed on the element that triggers ripple animations.\n * This will eventually become a custom renderer once Angular support exists.\n * @docs-private\n */\n\nclass RippleRenderer {\n constructor(_target, _ngZone, elementOrElementRef, platform) {\n this._target = _target;\n this._ngZone = _ngZone;\n /** Whether the pointer is currently down or not. */\n\n this._isPointerDown = false;\n /** Set of currently active ripple references. */\n\n this._activeRipples = new Set();\n /** Whether pointer-up event listeners have been registered. */\n\n this._pointerUpEventsRegistered = false; // Only do anything if we're on the browser.\n\n if (platform.isBrowser) {\n this._containerElement = coerceElement(elementOrElementRef);\n }\n }\n /**\n * Fades in a ripple at the given coordinates.\n * @param x Coordinate within the element, along the X axis at which to start the ripple.\n * @param y Coordinate within the element, along the Y axis at which to start the ripple.\n * @param config Extra ripple options.\n */\n\n\n fadeInRipple(x, y, config = {}) {\n const containerRect = this._containerRect = this._containerRect || this._containerElement.getBoundingClientRect();\n\n const animationConfig = { ...defaultRippleAnimationConfig,\n ...config.animation\n };\n\n if (config.centered) {\n x = containerRect.left + containerRect.width / 2;\n y = containerRect.top + containerRect.height / 2;\n }\n\n const radius = config.radius || distanceToFurthestCorner(x, y, containerRect);\n const offsetX = x - containerRect.left;\n const offsetY = y - containerRect.top;\n const duration = animationConfig.enterDuration;\n const ripple = document.createElement('div');\n ripple.classList.add('mat-ripple-element');\n ripple.style.left = `${offsetX - radius}px`;\n ripple.style.top = `${offsetY - radius}px`;\n ripple.style.height = `${radius * 2}px`;\n ripple.style.width = `${radius * 2}px`; // If a custom color has been specified, set it as inline style. If no color is\n // set, the default color will be applied through the ripple theme styles.\n\n if (config.color != null) {\n ripple.style.backgroundColor = config.color;\n }\n\n ripple.style.transitionDuration = `${duration}ms`;\n\n this._containerElement.appendChild(ripple); // By default the browser does not recalculate the styles of dynamically created\n // ripple elements. This is critical because then the `scale` would not animate properly.\n\n\n enforceStyleRecalculation(ripple);\n ripple.style.transform = 'scale(1)'; // Exposed reference to the ripple that will be returned.\n\n const rippleRef = new RippleRef(this, ripple, config);\n rippleRef.state = 0\n /* FADING_IN */\n ; // Add the ripple reference to the list of all active ripples.\n\n this._activeRipples.add(rippleRef);\n\n if (!config.persistent) {\n this._mostRecentTransientRipple = rippleRef;\n } // Wait for the ripple element to be completely faded in.\n // Once it's faded in, the ripple can be hidden immediately if the mouse is released.\n\n\n this._runTimeoutOutsideZone(() => {\n const isMostRecentTransientRipple = rippleRef === this._mostRecentTransientRipple;\n rippleRef.state = 1\n /* VISIBLE */\n ; // When the timer runs out while the user has kept their pointer down, we want to\n // keep only the persistent ripples and the latest transient ripple. We do this,\n // because we don't want stacked transient ripples to appear after their enter\n // animation has finished.\n\n if (!config.persistent && (!isMostRecentTransientRipple || !this._isPointerDown)) {\n rippleRef.fadeOut();\n }\n }, duration);\n\n return rippleRef;\n }\n /** Fades out a ripple reference. */\n\n\n fadeOutRipple(rippleRef) {\n const wasActive = this._activeRipples.delete(rippleRef);\n\n if (rippleRef === this._mostRecentTransientRipple) {\n this._mostRecentTransientRipple = null;\n } // Clear out the cached bounding rect if we have no more ripples.\n\n\n if (!this._activeRipples.size) {\n this._containerRect = null;\n } // For ripples that are not active anymore, don't re-run the fade-out animation.\n\n\n if (!wasActive) {\n return;\n }\n\n const rippleEl = rippleRef.element;\n const animationConfig = { ...defaultRippleAnimationConfig,\n ...rippleRef.config.animation\n };\n rippleEl.style.transitionDuration = `${animationConfig.exitDuration}ms`;\n rippleEl.style.opacity = '0';\n rippleRef.state = 2\n /* FADING_OUT */\n ; // Once the ripple faded out, the ripple can be safely removed from the DOM.\n\n this._runTimeoutOutsideZone(() => {\n rippleRef.state = 3\n /* HIDDEN */\n ;\n rippleEl.remove();\n }, animationConfig.exitDuration);\n }\n /** Fades out all currently active ripples. */\n\n\n fadeOutAll() {\n this._activeRipples.forEach(ripple => ripple.fadeOut());\n }\n /** Fades out all currently active non-persistent ripples. */\n\n\n fadeOutAllNonPersistent() {\n this._activeRipples.forEach(ripple => {\n if (!ripple.config.persistent) {\n ripple.fadeOut();\n }\n });\n }\n /** Sets up the trigger event listeners */\n\n\n setupTriggerEvents(elementOrElementRef) {\n const element = coerceElement(elementOrElementRef);\n\n if (!element || element === this._triggerElement) {\n return;\n } // Remove all previously registered event listeners from the trigger element.\n\n\n this._removeTriggerEvents();\n\n this._triggerElement = element;\n\n this._registerEvents(pointerDownEvents);\n }\n /**\n * Handles all registered events.\n * @docs-private\n */\n\n\n handleEvent(event) {\n if (event.type === 'mousedown') {\n this._onMousedown(event);\n } else if (event.type === 'touchstart') {\n this._onTouchStart(event);\n } else {\n this._onPointerUp();\n } // If pointer-up events haven't been registered yet, do so now.\n // We do this on-demand in order to reduce the total number of event listeners\n // registered by the ripples, which speeds up the rendering time for large UIs.\n\n\n if (!this._pointerUpEventsRegistered) {\n this._registerEvents(pointerUpEvents);\n\n this._pointerUpEventsRegistered = true;\n }\n }\n /** Function being called whenever the trigger is being pressed using mouse. */\n\n\n _onMousedown(event) {\n // Screen readers will fire fake mouse events for space/enter. Skip launching a\n // ripple in this case for consistency with the non-screen-reader experience.\n const isFakeMousedown = isFakeMousedownFromScreenReader(event);\n const isSyntheticEvent = this._lastTouchStartEvent && Date.now() < this._lastTouchStartEvent + ignoreMouseEventsTimeout;\n\n if (!this._target.rippleDisabled && !isFakeMousedown && !isSyntheticEvent) {\n this._isPointerDown = true;\n this.fadeInRipple(event.clientX, event.clientY, this._target.rippleConfig);\n }\n }\n /** Function being called whenever the trigger is being pressed using touch. */\n\n\n _onTouchStart(event) {\n if (!this._target.rippleDisabled && !isFakeTouchstartFromScreenReader(event)) {\n // Some browsers fire mouse events after a `touchstart` event. Those synthetic mouse\n // events will launch a second ripple if we don't ignore mouse events for a specific\n // time after a touchstart event.\n this._lastTouchStartEvent = Date.now();\n this._isPointerDown = true; // Use `changedTouches` so we skip any touches where the user put\n // their finger down, but used another finger to tap the element again.\n\n const touches = event.changedTouches;\n\n for (let i = 0; i < touches.length; i++) {\n this.fadeInRipple(touches[i].clientX, touches[i].clientY, this._target.rippleConfig);\n }\n }\n }\n /** Function being called whenever the trigger is being released. */\n\n\n _onPointerUp() {\n if (!this._isPointerDown) {\n return;\n }\n\n this._isPointerDown = false; // Fade-out all ripples that are visible and not persistent.\n\n this._activeRipples.forEach(ripple => {\n // By default, only ripples that are completely visible will fade out on pointer release.\n // If the `terminateOnPointerUp` option is set, ripples that still fade in will also fade out.\n const isVisible = ripple.state === 1\n /* VISIBLE */\n || ripple.config.terminateOnPointerUp && ripple.state === 0\n /* FADING_IN */\n ;\n\n if (!ripple.config.persistent && isVisible) {\n ripple.fadeOut();\n }\n });\n }\n /** Runs a timeout outside of the Angular zone to avoid triggering the change detection. */\n\n\n _runTimeoutOutsideZone(fn, delay = 0) {\n this._ngZone.runOutsideAngular(() => setTimeout(fn, delay));\n }\n /** Registers event listeners for a given list of events. */\n\n\n _registerEvents(eventTypes) {\n this._ngZone.runOutsideAngular(() => {\n eventTypes.forEach(type => {\n this._triggerElement.addEventListener(type, this, passiveEventOptions);\n });\n });\n }\n /** Removes previously registered event listeners from the trigger element. */\n\n\n _removeTriggerEvents() {\n if (this._triggerElement) {\n pointerDownEvents.forEach(type => {\n this._triggerElement.removeEventListener(type, this, passiveEventOptions);\n });\n\n if (this._pointerUpEventsRegistered) {\n pointerUpEvents.forEach(type => {\n this._triggerElement.removeEventListener(type, this, passiveEventOptions);\n });\n }\n }\n }\n\n}\n/** Enforces a style recalculation of a DOM element by computing its styles. */\n\n\nfunction enforceStyleRecalculation(element) {\n // Enforce a style recalculation by calling `getComputedStyle` and accessing any property.\n // Calling `getPropertyValue` is important to let optimizers know that this is not a noop.\n // See: https://gist.github.com/paulirish/5d52fb081b3570c81e3a\n window.getComputedStyle(element).getPropertyValue('opacity');\n}\n/**\n * Returns the distance from the point (x, y) to the furthest corner of a rectangle.\n */\n\n\nfunction distanceToFurthestCorner(x, y, rect) {\n const distX = Math.max(Math.abs(x - rect.left), Math.abs(x - rect.right));\n const distY = Math.max(Math.abs(y - rect.top), Math.abs(y - rect.bottom));\n return Math.sqrt(distX * distX + distY * distY);\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/** Injection token that can be used to specify the global ripple options. */\n\n\nconst MAT_RIPPLE_GLOBAL_OPTIONS = /*#__PURE__*/new InjectionToken('mat-ripple-global-options');\nlet MatRipple = /*#__PURE__*/(() => {\n class MatRipple {\n constructor(_elementRef, ngZone, platform, globalOptions, _animationMode) {\n this._elementRef = _elementRef;\n this._animationMode = _animationMode;\n /**\n * If set, the radius in pixels of foreground ripples when fully expanded. If unset, the radius\n * will be the distance from the center of the ripple to the furthest corner of the host element's\n * bounding rectangle.\n */\n\n this.radius = 0;\n this._disabled = false;\n /** Whether ripple directive is initialized and the input bindings are set. */\n\n this._isInitialized = false;\n this._globalOptions = globalOptions || {};\n this._rippleRenderer = new RippleRenderer(this, ngZone, _elementRef, platform);\n }\n /**\n * Whether click events will not trigger the ripple. Ripples can be still launched manually\n * by using the `launch()` method.\n */\n\n\n get disabled() {\n return this._disabled;\n }\n\n set disabled(value) {\n if (value) {\n this.fadeOutAllNonPersistent();\n }\n\n this._disabled = value;\n\n this._setupTriggerEventsIfEnabled();\n }\n /**\n * The element that triggers the ripple when click events are received.\n * Defaults to the directive's host element.\n */\n\n\n get trigger() {\n return this._trigger || this._elementRef.nativeElement;\n }\n\n set trigger(trigger) {\n this._trigger = trigger;\n\n this._setupTriggerEventsIfEnabled();\n }\n\n ngOnInit() {\n this._isInitialized = true;\n\n this._setupTriggerEventsIfEnabled();\n }\n\n ngOnDestroy() {\n this._rippleRenderer._removeTriggerEvents();\n }\n /** Fades out all currently showing ripple elements. */\n\n\n fadeOutAll() {\n this._rippleRenderer.fadeOutAll();\n }\n /** Fades out all currently showing non-persistent ripple elements. */\n\n\n fadeOutAllNonPersistent() {\n this._rippleRenderer.fadeOutAllNonPersistent();\n }\n /**\n * Ripple configuration from the directive's input values.\n * @docs-private Implemented as part of RippleTarget\n */\n\n\n get rippleConfig() {\n return {\n centered: this.centered,\n radius: this.radius,\n color: this.color,\n animation: { ...this._globalOptions.animation,\n ...(this._animationMode === 'NoopAnimations' ? {\n enterDuration: 0,\n exitDuration: 0\n } : {}),\n ...this.animation\n },\n terminateOnPointerUp: this._globalOptions.terminateOnPointerUp\n };\n }\n /**\n * Whether ripples on pointer-down are disabled or not.\n * @docs-private Implemented as part of RippleTarget\n */\n\n\n get rippleDisabled() {\n return this.disabled || !!this._globalOptions.disabled;\n }\n /** Sets up the trigger event listeners if ripples are enabled. */\n\n\n _setupTriggerEventsIfEnabled() {\n if (!this.disabled && this._isInitialized) {\n this._rippleRenderer.setupTriggerEvents(this.trigger);\n }\n }\n /** Launches a manual ripple at the specified coordinated or just by the ripple config. */\n\n\n launch(configOrX, y = 0, config) {\n if (typeof configOrX === 'number') {\n return this._rippleRenderer.fadeInRipple(configOrX, y, { ...this.rippleConfig,\n ...config\n });\n } else {\n return this._rippleRenderer.fadeInRipple(0, 0, { ...this.rippleConfig,\n ...configOrX\n });\n }\n }\n\n }\n\n MatRipple.ɵfac = function MatRipple_Factory(t) {\n return new (t || MatRipple)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.NgZone), i0.ɵɵdirectiveInject(i1$1.Platform), i0.ɵɵdirectiveInject(MAT_RIPPLE_GLOBAL_OPTIONS, 8), i0.ɵɵdirectiveInject(ANIMATION_MODULE_TYPE, 8));\n };\n\n MatRipple.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatRipple,\n selectors: [[\"\", \"mat-ripple\", \"\"], [\"\", \"matRipple\", \"\"]],\n hostAttrs: [1, \"mat-ripple\"],\n hostVars: 2,\n hostBindings: function MatRipple_HostBindings(rf, ctx) {\n if (rf & 2) {\n i0.ɵɵclassProp(\"mat-ripple-unbounded\", ctx.unbounded);\n }\n },\n inputs: {\n color: [\"matRippleColor\", \"color\"],\n unbounded: [\"matRippleUnbounded\", \"unbounded\"],\n centered: [\"matRippleCentered\", \"centered\"],\n radius: [\"matRippleRadius\", \"radius\"],\n animation: [\"matRippleAnimation\", \"animation\"],\n disabled: [\"matRippleDisabled\", \"disabled\"],\n trigger: [\"matRippleTrigger\", \"trigger\"]\n },\n exportAs: [\"matRipple\"]\n });\n return MatRipple;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nlet MatRippleModule = /*#__PURE__*/(() => {\n class MatRippleModule {}\n\n MatRippleModule.ɵfac = function MatRippleModule_Factory(t) {\n return new (t || MatRippleModule)();\n };\n\n MatRippleModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: MatRippleModule\n });\n MatRippleModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n imports: [[MatCommonModule, PlatformModule], MatCommonModule]\n });\n return MatRippleModule;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Component that shows a simplified checkbox without including any kind of \"real\" checkbox.\n * Meant to be used when the checkbox is purely decorative and a large number of them will be\n * included, such as for the options in a multi-select. Uses no SVGs or complex animations.\n * Note that theming is meant to be handled by the parent element, e.g.\n * `mat-primary .mat-pseudo-checkbox`.\n *\n * Note that this component will be completely invisible to screen-reader users. This is *not*\n * interchangeable with `` and should *not* be used if the user would directly\n * interact with the checkbox. The pseudo-checkbox should only be used as an implementation detail\n * of more complex components that appropriately handle selected / checked state.\n * @docs-private\n */\n\n\nlet MatPseudoCheckbox = /*#__PURE__*/(() => {\n class MatPseudoCheckbox {\n constructor(_animationMode) {\n this._animationMode = _animationMode;\n /** Display state of the checkbox. */\n\n this.state = 'unchecked';\n /** Whether the checkbox is disabled. */\n\n this.disabled = false;\n }\n\n }\n\n MatPseudoCheckbox.ɵfac = function MatPseudoCheckbox_Factory(t) {\n return new (t || MatPseudoCheckbox)(i0.ɵɵdirectiveInject(ANIMATION_MODULE_TYPE, 8));\n };\n\n MatPseudoCheckbox.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatPseudoCheckbox,\n selectors: [[\"mat-pseudo-checkbox\"]],\n hostAttrs: [1, \"mat-pseudo-checkbox\"],\n hostVars: 8,\n hostBindings: function MatPseudoCheckbox_HostBindings(rf, ctx) {\n if (rf & 2) {\n i0.ɵɵclassProp(\"mat-pseudo-checkbox-indeterminate\", ctx.state === \"indeterminate\")(\"mat-pseudo-checkbox-checked\", ctx.state === \"checked\")(\"mat-pseudo-checkbox-disabled\", ctx.disabled)(\"_mat-animation-noopable\", ctx._animationMode === \"NoopAnimations\");\n }\n },\n inputs: {\n state: \"state\",\n disabled: \"disabled\"\n },\n decls: 0,\n vars: 0,\n template: function MatPseudoCheckbox_Template(rf, ctx) {},\n styles: [\".mat-pseudo-checkbox{width:16px;height:16px;border:2px solid;border-radius:2px;cursor:pointer;display:inline-block;vertical-align:middle;box-sizing:border-box;position:relative;flex-shrink:0;transition:border-color 90ms cubic-bezier(0, 0, 0.2, 0.1),background-color 90ms cubic-bezier(0, 0, 0.2, 0.1)}.mat-pseudo-checkbox::after{position:absolute;opacity:0;content:\\\"\\\";border-bottom:2px solid currentColor;transition:opacity 90ms cubic-bezier(0, 0, 0.2, 0.1)}.mat-pseudo-checkbox.mat-pseudo-checkbox-checked,.mat-pseudo-checkbox.mat-pseudo-checkbox-indeterminate{border-color:transparent}._mat-animation-noopable.mat-pseudo-checkbox{transition:none;animation:none}._mat-animation-noopable.mat-pseudo-checkbox::after{transition:none}.mat-pseudo-checkbox-disabled{cursor:default}.mat-pseudo-checkbox-indeterminate::after{top:5px;left:1px;width:10px;opacity:1;border-radius:2px}.mat-pseudo-checkbox-checked::after{top:2.4px;left:1px;width:8px;height:3px;border-left:2px solid currentColor;transform:rotate(-45deg);opacity:1;box-sizing:content-box}\\n\"],\n encapsulation: 2,\n changeDetection: 0\n });\n return MatPseudoCheckbox;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nlet MatPseudoCheckboxModule = /*#__PURE__*/(() => {\n class MatPseudoCheckboxModule {}\n\n MatPseudoCheckboxModule.ɵfac = function MatPseudoCheckboxModule_Factory(t) {\n return new (t || MatPseudoCheckboxModule)();\n };\n\n MatPseudoCheckboxModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: MatPseudoCheckboxModule\n });\n MatPseudoCheckboxModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n imports: [[MatCommonModule]]\n });\n return MatPseudoCheckboxModule;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Injection token used to provide the parent component to options.\n */\n\n\nconst MAT_OPTION_PARENT_COMPONENT = /*#__PURE__*/new InjectionToken('MAT_OPTION_PARENT_COMPONENT');\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n// Notes on the accessibility pattern used for `mat-optgroup`.\n// The option group has two different \"modes\": regular and inert. The regular mode uses the\n// recommended a11y pattern which has `role=\"group\"` on the group element with `aria-labelledby`\n// pointing to the label. This works for `mat-select`, but it seems to hit a bug for autocomplete\n// under VoiceOver where the group doesn't get read out at all. The bug appears to be that if\n// there's __any__ a11y-related attribute on the group (e.g. `role` or `aria-labelledby`),\n// VoiceOver on Safari won't read it out.\n// We've introduced the `inert` mode as a workaround. Under this mode, all a11y attributes are\n// removed from the group, and we get the screen reader to read out the group label by mirroring it\n// inside an invisible element in the option. This is sub-optimal, because the screen reader will\n// repeat the group label on each navigation, whereas the default pattern only reads the group when\n// the user enters a new group. The following alternate approaches were considered:\n// 1. Reading out the group label using the `LiveAnnouncer` solves the problem, but we can't control\n// when the text will be read out so sometimes it comes in too late or never if the user\n// navigates quickly.\n// 2. ` {\n class _MatOptgroupBase extends _MatOptgroupMixinBase {\n constructor(parent) {\n var _parent$inertGroups;\n\n super();\n /** Unique id for the underlying label. */\n\n this._labelId = `mat-optgroup-label-${_uniqueOptgroupIdCounter++}`;\n this._inert = (_parent$inertGroups = parent === null || parent === void 0 ? void 0 : parent.inertGroups) !== null && _parent$inertGroups !== void 0 ? _parent$inertGroups : false;\n }\n\n }\n\n _MatOptgroupBase.ɵfac = function _MatOptgroupBase_Factory(t) {\n return new (t || _MatOptgroupBase)(i0.ɵɵdirectiveInject(MAT_OPTION_PARENT_COMPONENT, 8));\n };\n\n _MatOptgroupBase.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: _MatOptgroupBase,\n inputs: {\n label: \"label\"\n },\n features: [i0.ɵɵInheritDefinitionFeature]\n });\n return _MatOptgroupBase;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Injection token that can be used to reference instances of `MatOptgroup`. It serves as\n * alternative token to the actual `MatOptgroup` class which could cause unnecessary\n * retention of the class and its component metadata.\n */\n\n\nconst MAT_OPTGROUP = /*#__PURE__*/new InjectionToken('MatOptgroup');\n/**\n * Component that is used to group instances of `mat-option`.\n */\n\nlet MatOptgroup = /*#__PURE__*/(() => {\n class MatOptgroup extends _MatOptgroupBase {}\n\n MatOptgroup.ɵfac = /* @__PURE__ */function () {\n let ɵMatOptgroup_BaseFactory;\n return function MatOptgroup_Factory(t) {\n return (ɵMatOptgroup_BaseFactory || (ɵMatOptgroup_BaseFactory = i0.ɵɵgetInheritedFactory(MatOptgroup)))(t || MatOptgroup);\n };\n }();\n\n MatOptgroup.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatOptgroup,\n selectors: [[\"mat-optgroup\"]],\n hostAttrs: [1, \"mat-optgroup\"],\n hostVars: 5,\n hostBindings: function MatOptgroup_HostBindings(rf, ctx) {\n if (rf & 2) {\n i0.ɵɵattribute(\"role\", ctx._inert ? null : \"group\")(\"aria-disabled\", ctx._inert ? null : ctx.disabled.toString())(\"aria-labelledby\", ctx._inert ? null : ctx._labelId);\n i0.ɵɵclassProp(\"mat-optgroup-disabled\", ctx.disabled);\n }\n },\n inputs: {\n disabled: \"disabled\"\n },\n exportAs: [\"matOptgroup\"],\n features: [i0.ɵɵProvidersFeature([{\n provide: MAT_OPTGROUP,\n useExisting: MatOptgroup\n }]), i0.ɵɵInheritDefinitionFeature],\n ngContentSelectors: _c1,\n decls: 4,\n vars: 2,\n consts: [[\"aria-hidden\", \"true\", 1, \"mat-optgroup-label\", 3, \"id\"]],\n template: function MatOptgroup_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵprojectionDef(_c0);\n i0.ɵɵelementStart(0, \"span\", 0);\n i0.ɵɵtext(1);\n i0.ɵɵprojection(2);\n i0.ɵɵelementEnd();\n i0.ɵɵprojection(3, 1);\n }\n\n if (rf & 2) {\n i0.ɵɵproperty(\"id\", ctx._labelId);\n i0.ɵɵadvance(1);\n i0.ɵɵtextInterpolate1(\"\", ctx.label, \" \");\n }\n },\n styles: [\".mat-optgroup-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;line-height:48px;height:48px;padding:0 16px;text-align:left;text-decoration:none;max-width:100%;-webkit-user-select:none;-moz-user-select:none;user-select:none;cursor:default}.mat-optgroup-label[disabled]{cursor:default}[dir=rtl] .mat-optgroup-label{text-align:right}.mat-optgroup-label .mat-icon{margin-right:16px;vertical-align:middle}.mat-optgroup-label .mat-icon svg{vertical-align:top}[dir=rtl] .mat-optgroup-label .mat-icon{margin-left:16px;margin-right:0}\\n\"],\n encapsulation: 2,\n changeDetection: 0\n });\n return MatOptgroup;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Option IDs need to be unique across components, so this counter exists outside of\n * the component definition.\n */\n\n\nlet _uniqueIdCounter = 0;\n/** Event object emitted by MatOption when selected or deselected. */\n\nclass MatOptionSelectionChange {\n constructor(\n /** Reference to the option that emitted the event. */\n source,\n /** Whether the change in the option's value was a result of a user action. */\n isUserInput = false) {\n this.source = source;\n this.isUserInput = isUserInput;\n }\n\n}\n\nlet _MatOptionBase = /*#__PURE__*/(() => {\n class _MatOptionBase {\n constructor(_element, _changeDetectorRef, _parent, group) {\n this._element = _element;\n this._changeDetectorRef = _changeDetectorRef;\n this._parent = _parent;\n this.group = group;\n this._selected = false;\n this._active = false;\n this._disabled = false;\n this._mostRecentViewValue = '';\n /** The unique ID of the option. */\n\n this.id = `mat-option-${_uniqueIdCounter++}`;\n /** Event emitted when the option is selected or deselected. */\n // tslint:disable-next-line:no-output-on-prefix\n\n this.onSelectionChange = new EventEmitter();\n /** Emits when the state of the option changes and any parents have to be notified. */\n\n this._stateChanges = new Subject();\n }\n /** Whether the wrapping component is in multiple selection mode. */\n\n\n get multiple() {\n return this._parent && this._parent.multiple;\n }\n /** Whether or not the option is currently selected. */\n\n\n get selected() {\n return this._selected;\n }\n /** Whether the option is disabled. */\n\n\n get disabled() {\n return this.group && this.group.disabled || this._disabled;\n }\n\n set disabled(value) {\n this._disabled = coerceBooleanProperty(value);\n }\n /** Whether ripples for the option are disabled. */\n\n\n get disableRipple() {\n return !!(this._parent && this._parent.disableRipple);\n }\n /**\n * Whether or not the option is currently active and ready to be selected.\n * An active option displays styles as if it is focused, but the\n * focus is actually retained somewhere else. This comes in handy\n * for components like autocomplete where focus must remain on the input.\n */\n\n\n get active() {\n return this._active;\n }\n /**\n * The displayed value of the option. It is necessary to show the selected option in the\n * select's trigger.\n */\n\n\n get viewValue() {\n // TODO(kara): Add input property alternative for node envs.\n return (this._getHostElement().textContent || '').trim();\n }\n /** Selects the option. */\n\n\n select() {\n if (!this._selected) {\n this._selected = true;\n\n this._changeDetectorRef.markForCheck();\n\n this._emitSelectionChangeEvent();\n }\n }\n /** Deselects the option. */\n\n\n deselect() {\n if (this._selected) {\n this._selected = false;\n\n this._changeDetectorRef.markForCheck();\n\n this._emitSelectionChangeEvent();\n }\n }\n /** Sets focus onto this option. */\n\n\n focus(_origin, options) {\n // Note that we aren't using `_origin`, but we need to keep it because some internal consumers\n // use `MatOption` in a `FocusKeyManager` and we need it to match `FocusableOption`.\n const element = this._getHostElement();\n\n if (typeof element.focus === 'function') {\n element.focus(options);\n }\n }\n /**\n * This method sets display styles on the option to make it appear\n * active. This is used by the ActiveDescendantKeyManager so key\n * events will display the proper options as active on arrow key events.\n */\n\n\n setActiveStyles() {\n if (!this._active) {\n this._active = true;\n\n this._changeDetectorRef.markForCheck();\n }\n }\n /**\n * This method removes display styles on the option that made it appear\n * active. This is used by the ActiveDescendantKeyManager so key\n * events will display the proper options as active on arrow key events.\n */\n\n\n setInactiveStyles() {\n if (this._active) {\n this._active = false;\n\n this._changeDetectorRef.markForCheck();\n }\n }\n /** Gets the label to be used when determining whether the option should be focused. */\n\n\n getLabel() {\n return this.viewValue;\n }\n /** Ensures the option is selected when activated from the keyboard. */\n\n\n _handleKeydown(event) {\n if ((event.keyCode === ENTER || event.keyCode === SPACE) && !hasModifierKey(event)) {\n this._selectViaInteraction(); // Prevent the page from scrolling down and form submits.\n\n\n event.preventDefault();\n }\n }\n /**\n * `Selects the option while indicating the selection came from the user. Used to\n * determine if the select's view -> model callback should be invoked.`\n */\n\n\n _selectViaInteraction() {\n if (!this.disabled) {\n this._selected = this.multiple ? !this._selected : true;\n\n this._changeDetectorRef.markForCheck();\n\n this._emitSelectionChangeEvent(true);\n }\n }\n /**\n * Gets the `aria-selected` value for the option. We explicitly omit the `aria-selected`\n * attribute from single-selection, unselected options. Including the `aria-selected=\"false\"`\n * attributes adds a significant amount of noise to screen-reader users without providing useful\n * information.\n */\n\n\n _getAriaSelected() {\n return this.selected || (this.multiple ? false : null);\n }\n /** Returns the correct tabindex for the option depending on disabled state. */\n\n\n _getTabIndex() {\n return this.disabled ? '-1' : '0';\n }\n /** Gets the host DOM element. */\n\n\n _getHostElement() {\n return this._element.nativeElement;\n }\n\n ngAfterViewChecked() {\n // Since parent components could be using the option's label to display the selected values\n // (e.g. `mat-select`) and they don't have a way of knowing if the option's label has changed\n // we have to check for changes in the DOM ourselves and dispatch an event. These checks are\n // relatively cheap, however we still limit them only to selected options in order to avoid\n // hitting the DOM too often.\n if (this._selected) {\n const viewValue = this.viewValue;\n\n if (viewValue !== this._mostRecentViewValue) {\n this._mostRecentViewValue = viewValue;\n\n this._stateChanges.next();\n }\n }\n }\n\n ngOnDestroy() {\n this._stateChanges.complete();\n }\n /** Emits the selection change event. */\n\n\n _emitSelectionChangeEvent(isUserInput = false) {\n this.onSelectionChange.emit(new MatOptionSelectionChange(this, isUserInput));\n }\n\n }\n\n _MatOptionBase.ɵfac = function _MatOptionBase_Factory(t) {\n i0.ɵɵinvalidFactory();\n };\n\n _MatOptionBase.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: _MatOptionBase,\n inputs: {\n value: \"value\",\n id: \"id\",\n disabled: \"disabled\"\n },\n outputs: {\n onSelectionChange: \"onSelectionChange\"\n }\n });\n return _MatOptionBase;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Single option inside of a `` element.\n */\n\n\nlet MatOption = /*#__PURE__*/(() => {\n class MatOption extends _MatOptionBase {\n constructor(element, changeDetectorRef, parent, group) {\n super(element, changeDetectorRef, parent, group);\n }\n\n }\n\n MatOption.ɵfac = function MatOption_Factory(t) {\n return new (t || MatOption)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(MAT_OPTION_PARENT_COMPONENT, 8), i0.ɵɵdirectiveInject(MAT_OPTGROUP, 8));\n };\n\n MatOption.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatOption,\n selectors: [[\"mat-option\"]],\n hostAttrs: [\"role\", \"option\", 1, \"mat-option\", \"mat-focus-indicator\"],\n hostVars: 12,\n hostBindings: function MatOption_HostBindings(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵlistener(\"click\", function MatOption_click_HostBindingHandler() {\n return ctx._selectViaInteraction();\n })(\"keydown\", function MatOption_keydown_HostBindingHandler($event) {\n return ctx._handleKeydown($event);\n });\n }\n\n if (rf & 2) {\n i0.ɵɵhostProperty(\"id\", ctx.id);\n i0.ɵɵattribute(\"tabindex\", ctx._getTabIndex())(\"aria-selected\", ctx._getAriaSelected())(\"aria-disabled\", ctx.disabled.toString());\n i0.ɵɵclassProp(\"mat-selected\", ctx.selected)(\"mat-option-multiple\", ctx.multiple)(\"mat-active\", ctx.active)(\"mat-option-disabled\", ctx.disabled);\n }\n },\n exportAs: [\"matOption\"],\n features: [i0.ɵɵInheritDefinitionFeature],\n ngContentSelectors: _c2,\n decls: 5,\n vars: 4,\n consts: [[\"class\", \"mat-option-pseudo-checkbox\", 3, \"state\", \"disabled\", 4, \"ngIf\"], [1, \"mat-option-text\"], [\"class\", \"cdk-visually-hidden\", 4, \"ngIf\"], [\"mat-ripple\", \"\", 1, \"mat-option-ripple\", 3, \"matRippleTrigger\", \"matRippleDisabled\"], [1, \"mat-option-pseudo-checkbox\", 3, \"state\", \"disabled\"], [1, \"cdk-visually-hidden\"]],\n template: function MatOption_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵprojectionDef();\n i0.ɵɵtemplate(0, MatOption_mat_pseudo_checkbox_0_Template, 1, 2, \"mat-pseudo-checkbox\", 0);\n i0.ɵɵelementStart(1, \"span\", 1);\n i0.ɵɵprojection(2);\n i0.ɵɵelementEnd();\n i0.ɵɵtemplate(3, MatOption_span_3_Template, 2, 1, \"span\", 2);\n i0.ɵɵelement(4, \"div\", 3);\n }\n\n if (rf & 2) {\n i0.ɵɵproperty(\"ngIf\", ctx.multiple);\n i0.ɵɵadvance(3);\n i0.ɵɵproperty(\"ngIf\", ctx.group && ctx.group._inert);\n i0.ɵɵadvance(1);\n i0.ɵɵproperty(\"matRippleTrigger\", ctx._getHostElement())(\"matRippleDisabled\", ctx.disabled || ctx.disableRipple);\n }\n },\n dependencies: [MatPseudoCheckbox, i3.NgIf, MatRipple],\n styles: [\".mat-option{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;line-height:48px;height:48px;padding:0 16px;text-align:left;text-decoration:none;max-width:100%;position:relative;cursor:pointer;outline:none;display:flex;flex-direction:row;max-width:100%;box-sizing:border-box;align-items:center;-webkit-tap-highlight-color:transparent}.mat-option[disabled]{cursor:default}[dir=rtl] .mat-option{text-align:right}.mat-option .mat-icon{margin-right:16px;vertical-align:middle}.mat-option .mat-icon svg{vertical-align:top}[dir=rtl] .mat-option .mat-icon{margin-left:16px;margin-right:0}.mat-option[aria-disabled=true]{-webkit-user-select:none;-moz-user-select:none;user-select:none;cursor:default}.mat-optgroup .mat-option:not(.mat-option-multiple){padding-left:32px}[dir=rtl] .mat-optgroup .mat-option:not(.mat-option-multiple){padding-left:16px;padding-right:32px}.cdk-high-contrast-active .mat-option{margin:0 1px}.cdk-high-contrast-active .mat-option.mat-active{border:solid 1px currentColor;margin:0}.cdk-high-contrast-active .mat-option[aria-disabled=true]{opacity:.5}.mat-option-text{display:inline-block;flex-grow:1;overflow:hidden;text-overflow:ellipsis}.mat-option .mat-option-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}.mat-option-pseudo-checkbox{margin-right:8px}[dir=rtl] .mat-option-pseudo-checkbox{margin-left:8px;margin-right:0}\\n\"],\n encapsulation: 2,\n changeDetection: 0\n });\n return MatOption;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Counts the amount of option group labels that precede the specified option.\n * @param optionIndex Index of the option at which to start counting.\n * @param options Flat list of all of the options.\n * @param optionGroups Flat list of all of the option groups.\n * @docs-private\n */\n\n\nfunction _countGroupLabelsBeforeOption(optionIndex, options, optionGroups) {\n if (optionGroups.length) {\n let optionsArray = options.toArray();\n let groups = optionGroups.toArray();\n let groupCounter = 0;\n\n for (let i = 0; i < optionIndex + 1; i++) {\n if (optionsArray[i].group && optionsArray[i].group === groups[groupCounter]) {\n groupCounter++;\n }\n }\n\n return groupCounter;\n }\n\n return 0;\n}\n/**\n * Determines the position to which to scroll a panel in order for an option to be into view.\n * @param optionOffset Offset of the option from the top of the panel.\n * @param optionHeight Height of the options.\n * @param currentScrollPosition Current scroll position of the panel.\n * @param panelHeight Height of the panel.\n * @docs-private\n */\n\n\nfunction _getOptionScrollPosition(optionOffset, optionHeight, currentScrollPosition, panelHeight) {\n if (optionOffset < currentScrollPosition) {\n return optionOffset;\n }\n\n if (optionOffset + optionHeight > currentScrollPosition + panelHeight) {\n return Math.max(0, optionOffset - panelHeight + optionHeight);\n }\n\n return currentScrollPosition;\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nlet MatOptionModule = /*#__PURE__*/(() => {\n class MatOptionModule {}\n\n MatOptionModule.ɵfac = function MatOptionModule_Factory(t) {\n return new (t || MatOptionModule)();\n };\n\n MatOptionModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: MatOptionModule\n });\n MatOptionModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n imports: [[MatRippleModule, CommonModule, MatCommonModule, MatPseudoCheckboxModule]]\n });\n return MatOptionModule;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Generated bundle index. Do not edit.\n */\n\n\nexport { AnimationCurves, AnimationDurations, DateAdapter, ErrorStateMatcher, MATERIAL_SANITY_CHECKS, MAT_DATE_FORMATS, MAT_DATE_LOCALE, MAT_DATE_LOCALE_FACTORY, MAT_NATIVE_DATE_FORMATS, MAT_OPTGROUP, MAT_OPTION_PARENT_COMPONENT, MAT_RIPPLE_GLOBAL_OPTIONS, MatCommonModule, MatLine, MatLineModule, MatNativeDateModule, MatOptgroup, MatOption, MatOptionModule, MatOptionSelectionChange, MatPseudoCheckbox, MatPseudoCheckboxModule, MatRipple, MatRippleModule, NativeDateAdapter, NativeDateModule, RippleRef, RippleRenderer, ShowOnDirtyErrorStateMatcher, VERSION, _MatOptgroupBase, _MatOptionBase, _countGroupLabelsBeforeOption, _getOptionScrollPosition, defaultRippleAnimationConfig, mixinColor, mixinDisableRipple, mixinDisabled, mixinErrorState, mixinInitialized, mixinTabIndex, setLines }; //# sourceMappingURL=core.mjs.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/12412f6174200e3dc4bb2e5d122242dc.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/12412f6174200e3dc4bb2e5d122242dc.json
deleted file mode 100644
index 9ea2a19a..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/12412f6174200e3dc4bb2e5d122242dc.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { reduce } from './reduce';\nexport function count(predicate) {\n return reduce((total, value, i) => !predicate || predicate(value, i) ? total + 1 : total, 0);\n} //# sourceMappingURL=count.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/1307db4157df5ee21608136eb86eb42a.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/1307db4157df5ee21608136eb86eb42a.json
deleted file mode 100644
index 11e76f0a..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/1307db4157df5ee21608136eb86eb42a.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { Observable } from '../Observable';\nimport { Subscription } from '../Subscription';\nimport { refCount as higherOrderRefCount } from '../operators/refCount';\nimport { createOperatorSubscriber } from '../operators/OperatorSubscriber';\nimport { hasLift } from '../util/lift';\nexport class ConnectableObservable extends Observable {\n constructor(source, subjectFactory) {\n super();\n this.source = source;\n this.subjectFactory = subjectFactory;\n this._subject = null;\n this._refCount = 0;\n this._connection = null;\n\n if (hasLift(source)) {\n this.lift = source.lift;\n }\n }\n\n _subscribe(subscriber) {\n return this.getSubject().subscribe(subscriber);\n }\n\n getSubject() {\n const subject = this._subject;\n\n if (!subject || subject.isStopped) {\n this._subject = this.subjectFactory();\n }\n\n return this._subject;\n }\n\n _teardown() {\n this._refCount = 0;\n const {\n _connection\n } = this;\n this._subject = this._connection = null;\n _connection === null || _connection === void 0 ? void 0 : _connection.unsubscribe();\n }\n\n connect() {\n let connection = this._connection;\n\n if (!connection) {\n connection = this._connection = new Subscription();\n const subject = this.getSubject();\n connection.add(this.source.subscribe(createOperatorSubscriber(subject, undefined, () => {\n this._teardown();\n\n subject.complete();\n }, err => {\n this._teardown();\n\n subject.error(err);\n }, () => this._teardown())));\n\n if (connection.closed) {\n this._connection = null;\n connection = Subscription.EMPTY;\n }\n }\n\n return connection;\n }\n\n refCount() {\n return higherOrderRefCount()(this);\n }\n\n} //# sourceMappingURL=ConnectableObservable.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/1379c236fea753d50c7d181409fefae5.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/1379c236fea753d50c7d181409fefae5.json
deleted file mode 100644
index f20ef51d..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/1379c236fea753d50c7d181409fefae5.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { Subscription } from '../Subscription';\nimport { operate } from '../util/lift';\nimport { innerFrom } from '../observable/innerFrom';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { noop } from '../util/noop';\nimport { arrRemove } from '../util/arrRemove';\nexport function bufferToggle(openings, closingSelector) {\n return operate((source, subscriber) => {\n const buffers = [];\n innerFrom(openings).subscribe(createOperatorSubscriber(subscriber, openValue => {\n const buffer = [];\n buffers.push(buffer);\n const closingSubscription = new Subscription();\n\n const emitBuffer = () => {\n arrRemove(buffers, buffer);\n subscriber.next(buffer);\n closingSubscription.unsubscribe();\n };\n\n closingSubscription.add(innerFrom(closingSelector(openValue)).subscribe(createOperatorSubscriber(subscriber, emitBuffer, noop)));\n }, noop));\n source.subscribe(createOperatorSubscriber(subscriber, value => {\n for (const buffer of buffers) {\n buffer.push(value);\n }\n }, () => {\n while (buffers.length > 0) {\n subscriber.next(buffers.shift());\n }\n\n subscriber.complete();\n }));\n });\n} //# sourceMappingURL=bufferToggle.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/13dc4826bb203cc33d6cc91877672be9.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/13dc4826bb203cc33d6cc91877672be9.json
deleted file mode 100644
index 0eca2abf..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/13dc4826bb203cc33d6cc91877672be9.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { concatMap } from './concatMap';\nimport { isFunction } from '../util/isFunction';\nexport function concatMapTo(innerObservable, resultSelector) {\n return isFunction(resultSelector) ? concatMap(() => innerObservable, resultSelector) : concatMap(() => innerObservable);\n} //# sourceMappingURL=concatMapTo.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/163503093a06efb4a401b4fca8e39b03.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/163503093a06efb4a401b4fca8e39b03.json
deleted file mode 100644
index 6dbb6abf..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/163503093a06efb4a401b4fca8e39b03.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { operate } from '../util/lift';\nimport { innerFrom } from '../observable/innerFrom';\nimport { argsOrArgArray } from '../util/argsOrArgArray';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { noop } from '../util/noop';\nexport function onErrorResumeNext(...sources) {\n const nextSources = argsOrArgArray(sources);\n return operate((source, subscriber) => {\n const remaining = [source, ...nextSources];\n\n const subscribeNext = () => {\n if (!subscriber.closed) {\n if (remaining.length > 0) {\n let nextSource;\n\n try {\n nextSource = innerFrom(remaining.shift());\n } catch (err) {\n subscribeNext();\n return;\n }\n\n const innerSub = createOperatorSubscriber(subscriber, undefined, noop, noop);\n nextSource.subscribe(innerSub);\n innerSub.add(subscribeNext);\n } else {\n subscriber.complete();\n }\n }\n };\n\n subscribeNext();\n });\n} //# sourceMappingURL=onErrorResumeNext.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/16457eb10185da875f5606ec04099742.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/16457eb10185da875f5606ec04099742.json
deleted file mode 100644
index 8537fec0..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/16457eb10185da875f5606ec04099742.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { not } from '../util/not';\nimport { filter } from './filter';\nexport function partition(predicate, thisArg) {\n return source => [filter(predicate, thisArg)(source), filter(not(predicate, thisArg))(source)];\n} //# sourceMappingURL=partition.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/16af03fa8879c58c1dc75a7987ac88c0.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/16af03fa8879c58c1dc75a7987ac88c0.json
deleted file mode 100644
index 6524d9ce..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/16af03fa8879c58c1dc75a7987ac88c0.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { operate } from '../util/lift';\nimport { mergeInternals } from './mergeInternals';\nexport function mergeScan(accumulator, seed, concurrent = Infinity) {\n return operate((source, subscriber) => {\n let state = seed;\n return mergeInternals(source, subscriber, (value, index) => accumulator(state, value, index), concurrent, value => {\n state = value;\n }, false, undefined, () => state = null);\n });\n} //# sourceMappingURL=mergeScan.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/1722db6a200cef57c5293768c369a964.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/1722db6a200cef57c5293768c369a964.json
deleted file mode 100644
index acc499cd..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/1722db6a200cef57c5293768c369a964.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { asyncScheduler } from '../scheduler/async';\nimport { sample } from './sample';\nimport { interval } from '../observable/interval';\nexport function sampleTime(period, scheduler = asyncScheduler) {\n return sample(interval(period, scheduler));\n} //# sourceMappingURL=sampleTime.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/18df18633db52a398bd325b6c1186a87.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/18df18633db52a398bd325b6c1186a87.json
deleted file mode 100644
index 81e21db9..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/18df18633db52a398bd325b6c1186a87.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nexport function skipWhile(predicate) {\n return operate((source, subscriber) => {\n let taking = false;\n let index = 0;\n source.subscribe(createOperatorSubscriber(subscriber, value => (taking || (taking = !predicate(value, index++))) && subscriber.next(value)));\n });\n} //# sourceMappingURL=skipWhile.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/18f16954b27e80f1c6af8dfdb887f5ea.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/18f16954b27e80f1c6af8dfdb887f5ea.json
deleted file mode 100644
index ac06da98..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/18f16954b27e80f1c6af8dfdb887f5ea.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nimport { arrRemove } from './util/arrRemove';\nexport class Subscription {\n constructor(initialTeardown) {\n this.initialTeardown = initialTeardown;\n this.closed = false;\n this._parentage = null;\n this._finalizers = null;\n }\n\n unsubscribe() {\n let errors;\n\n if (!this.closed) {\n this.closed = true;\n const {\n _parentage\n } = this;\n\n if (_parentage) {\n this._parentage = null;\n\n if (Array.isArray(_parentage)) {\n for (const parent of _parentage) {\n parent.remove(this);\n }\n } else {\n _parentage.remove(this);\n }\n }\n\n const {\n initialTeardown: initialFinalizer\n } = this;\n\n if (isFunction(initialFinalizer)) {\n try {\n initialFinalizer();\n } catch (e) {\n errors = e instanceof UnsubscriptionError ? e.errors : [e];\n }\n }\n\n const {\n _finalizers\n } = this;\n\n if (_finalizers) {\n this._finalizers = null;\n\n for (const finalizer of _finalizers) {\n try {\n execFinalizer(finalizer);\n } catch (err) {\n errors = errors !== null && errors !== void 0 ? errors : [];\n\n if (err instanceof UnsubscriptionError) {\n errors = [...errors, ...err.errors];\n } else {\n errors.push(err);\n }\n }\n }\n }\n\n if (errors) {\n throw new UnsubscriptionError(errors);\n }\n }\n }\n\n add(teardown) {\n var _a;\n\n if (teardown && teardown !== this) {\n if (this.closed) {\n execFinalizer(teardown);\n } else {\n if (teardown instanceof Subscription) {\n if (teardown.closed || teardown._hasParent(this)) {\n return;\n }\n\n teardown._addParent(this);\n }\n\n (this._finalizers = (_a = this._finalizers) !== null && _a !== void 0 ? _a : []).push(teardown);\n }\n }\n }\n\n _hasParent(parent) {\n const {\n _parentage\n } = this;\n return _parentage === parent || Array.isArray(_parentage) && _parentage.includes(parent);\n }\n\n _addParent(parent) {\n const {\n _parentage\n } = this;\n this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;\n }\n\n _removeParent(parent) {\n const {\n _parentage\n } = this;\n\n if (_parentage === parent) {\n this._parentage = null;\n } else if (Array.isArray(_parentage)) {\n arrRemove(_parentage, parent);\n }\n }\n\n remove(teardown) {\n const {\n _finalizers\n } = this;\n _finalizers && arrRemove(_finalizers, teardown);\n\n if (teardown instanceof Subscription) {\n teardown._removeParent(this);\n }\n }\n\n}\n\nSubscription.EMPTY = (() => {\n const empty = new Subscription();\n empty.closed = true;\n return empty;\n})();\n\nexport const EMPTY_SUBSCRIPTION = Subscription.EMPTY;\nexport function isSubscription(value) {\n return value instanceof Subscription || value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe);\n}\n\nfunction execFinalizer(finalizer) {\n if (isFunction(finalizer)) {\n finalizer();\n } else {\n finalizer.unsubscribe();\n }\n} //# sourceMappingURL=Subscription.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/19e8d5eefc26cf7b0532bdf5a68eca0b.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/19e8d5eefc26cf7b0532bdf5a68eca0b.json
deleted file mode 100644
index 961b6eab..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/19e8d5eefc26cf7b0532bdf5a68eca0b.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import * as i0 from \"@angular/core\";\nimport * as i1 from \"ng2-pdfjs-viewer\";\nconst _c0 = [\"inlinePdfViewer\"];\nexport let InlineComponent = /*#__PURE__*/(() => {\n class InlineComponent {\n constructor() {\n this.isPdfLoaded = false;\n }\n\n ngAfterViewInit() {}\n\n }\n\n InlineComponent.ɵfac = function InlineComponent_Factory(t) {\n return new (t || InlineComponent)();\n };\n\n InlineComponent.ɵcmp = /*@__PURE__*/i0.ɵɵdefineComponent({\n type: InlineComponent,\n selectors: [[\"app-inline\"]],\n viewQuery: function InlineComponent_Query(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵviewQuery(_c0, 7);\n }\n\n if (rf & 2) {\n let _t;\n\n i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.inlinePdfViewer = _t.first);\n }\n },\n decls: 7,\n vars: 3,\n consts: [[2, \"height\", \"40vh\"], [\"pdfSrc\", \"gre_research_validity_data.pdf\", \"viewerId\", \"inline\", 3, \"print\", \"fullScreen\", \"find\"], [\"inlinePdfViewer\", \"\"]],\n template: function InlineComponent_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementStart(0, \"p\");\n i0.ɵɵtext(1, \" Lorem ipsum, or lipsum as it is sometimes known, is dummy text used in laying out print, graphic or web designs. The passage is attributed to an unknown typesetter in the 15th century who is thought to have scrambled parts of Cicero's De Finibus Bonorum et Malorum for use in a type specimen book. It usually begins with: \\u201CLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\\u201D The purpose of lorem ipsum is to create a natural looking block of text (sentence, paragraph, page, etc.) that doesn't distract from the layout. A practice not without controversy, laying out pages with meaningless filler text can be very useful when the focus is meant to be on design, not content.\\n\");\n i0.ɵɵelementEnd();\n i0.ɵɵelementStart(2, \"div\", 0);\n i0.ɵɵelement(3, \"ng2-pdfjs-viewer\", 1, 2);\n i0.ɵɵelementEnd();\n i0.ɵɵelementStart(5, \"p\");\n i0.ɵɵtext(6, \" Lorem ipsum, or lipsum as it is sometimes known, is dummy text used in laying out print, graphic or web designs. The passage is attributed to an unknown typesetter in the 15th century who is thought to have scrambled parts of Cicero's De Finibus Bonorum et Malorum for use in a type specimen book. It usually begins with: \\u201CLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\\u201D The purpose of lorem ipsum is to create a natural looking block of text (sentence, paragraph, page, etc.) that doesn't distract from the layout. A practice not without controversy, laying out pages with meaningless filler text can be very useful when the focus is meant to be on design, not content.\\n\");\n i0.ɵɵelementEnd();\n }\n\n if (rf & 2) {\n i0.ɵɵadvance(3);\n i0.ɵɵproperty(\"print\", false)(\"fullScreen\", false)(\"find\", false);\n }\n },\n dependencies: [i1.PdfJsViewerComponent]\n });\n return InlineComponent;\n})();","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/1aa3b2afe500aa4e210b976ced3d0cf5.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/1aa3b2afe500aa4e210b976ced3d0cf5.json
deleted file mode 100644
index 88e22c68..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/1aa3b2afe500aa4e210b976ced3d0cf5.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"export function noop() {} //# sourceMappingURL=noop.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/1b3bfc66954563fac9dbec462792c5a6.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/1b3bfc66954563fac9dbec462792c5a6.json
deleted file mode 100644
index ca3ae0c4..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/1b3bfc66954563fac9dbec462792c5a6.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { isFunction } from './isFunction';\nimport { isScheduler } from './isScheduler';\n\nfunction last(arr) {\n return arr[arr.length - 1];\n}\n\nexport function popResultSelector(args) {\n return isFunction(last(args)) ? args.pop() : undefined;\n}\nexport function popScheduler(args) {\n return isScheduler(last(args)) ? args.pop() : undefined;\n}\nexport function popNumber(args, defaultValue) {\n return typeof last(args) === 'number' ? args.pop() : defaultValue;\n} //# sourceMappingURL=args.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/1d40a10473a183713494ea857e52c83d.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/1d40a10473a183713494ea857e52c83d.json
deleted file mode 100644
index a284a776..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/1d40a10473a183713494ea857e52c83d.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"/**\n * @license Angular v14.2.3\n * (c) 2010-2022 Google LLC. https://angular.io/\n * License: MIT\n */\nimport { ɵDomAdapter, ɵsetRootDomAdapter, ɵparseCookieValue, ɵgetDOM, DOCUMENT, ɵPLATFORM_BROWSER_ID, XhrFactory, CommonModule } from '@angular/common';\nexport { ɵgetDOM } from '@angular/common';\nimport * as i0 from '@angular/core';\nimport { InjectionToken, ApplicationInitStatus, APP_INITIALIZER, Injector, ɵglobal, Injectable, Inject, ViewEncapsulation, APP_ID, RendererStyleFlags2, ɵinternalCreateApplication, ErrorHandler, ɵsetDocument, PLATFORM_ID, PLATFORM_INITIALIZER, createPlatformFactory, platformCore, ɵTESTABILITY_GETTER, ɵTESTABILITY, Testability, NgZone, TestabilityRegistry, ɵINJECTOR_SCOPE, RendererFactory2, ApplicationModule, NgModule, Optional, SkipSelf, ɵɵinject, ApplicationRef, inject, ɵConsole, forwardRef, SecurityContext, ɵallowSanitizationBypassAndThrow, ɵunwrapSafeValue, ɵ_sanitizeUrl, ɵ_sanitizeHtml, ɵbypassSanitizationTrustHtml, ɵbypassSanitizationTrustStyle, ɵbypassSanitizationTrustScript, ɵbypassSanitizationTrustUrl, ɵbypassSanitizationTrustResourceUrl, Version } from '@angular/core';\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Provides DOM operations in any browser environment.\n *\n * @security Tread carefully! Interacting with the DOM directly is dangerous and\n * can introduce XSS risks.\n */\n\nclass GenericBrowserDomAdapter extends ɵDomAdapter {\n constructor() {\n super(...arguments);\n this.supportsDOMEvents = true;\n }\n\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * A `DomAdapter` powered by full browser DOM APIs.\n *\n * @security Tread carefully! Interacting with the DOM directly is dangerous and\n * can introduce XSS risks.\n */\n\n/* tslint:disable:requireParameterType no-console */\n\n\nclass BrowserDomAdapter extends GenericBrowserDomAdapter {\n static makeCurrent() {\n ɵsetRootDomAdapter(new BrowserDomAdapter());\n }\n\n onAndCancel(el, evt, listener) {\n el.addEventListener(evt, listener, false); // Needed to follow Dart's subscription semantic, until fix of\n // https://code.google.com/p/dart/issues/detail?id=17406\n\n return () => {\n el.removeEventListener(evt, listener, false);\n };\n }\n\n dispatchEvent(el, evt) {\n el.dispatchEvent(evt);\n }\n\n remove(node) {\n if (node.parentNode) {\n node.parentNode.removeChild(node);\n }\n }\n\n createElement(tagName, doc) {\n doc = doc || this.getDefaultDocument();\n return doc.createElement(tagName);\n }\n\n createHtmlDocument() {\n return document.implementation.createHTMLDocument('fakeTitle');\n }\n\n getDefaultDocument() {\n return document;\n }\n\n isElementNode(node) {\n return node.nodeType === Node.ELEMENT_NODE;\n }\n\n isShadowRoot(node) {\n return node instanceof DocumentFragment;\n }\n /** @deprecated No longer being used in Ivy code. To be removed in version 14. */\n\n\n getGlobalEventTarget(doc, target) {\n if (target === 'window') {\n return window;\n }\n\n if (target === 'document') {\n return doc;\n }\n\n if (target === 'body') {\n return doc.body;\n }\n\n return null;\n }\n\n getBaseHref(doc) {\n const href = getBaseElementHref();\n return href == null ? null : relativePath(href);\n }\n\n resetBaseElement() {\n baseElement = null;\n }\n\n getUserAgent() {\n return window.navigator.userAgent;\n }\n\n getCookie(name) {\n return ɵparseCookieValue(document.cookie, name);\n }\n\n}\n\nlet baseElement = null;\n\nfunction getBaseElementHref() {\n baseElement = baseElement || document.querySelector('base');\n return baseElement ? baseElement.getAttribute('href') : null;\n} // based on urlUtils.js in AngularJS 1\n\n\nlet urlParsingNode;\n\nfunction relativePath(url) {\n urlParsingNode = urlParsingNode || document.createElement('a');\n urlParsingNode.setAttribute('href', url);\n const pathName = urlParsingNode.pathname;\n return pathName.charAt(0) === '/' ? pathName : `/${pathName}`;\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * An id that identifies a particular application being bootstrapped, that should\n * match across the client/server boundary.\n */\n\n\nconst TRANSITION_ID = /*#__PURE__*/new InjectionToken('TRANSITION_ID');\n\nfunction appInitializerFactory(transitionId, document, injector) {\n return () => {\n // Wait for all application initializers to be completed before removing the styles set by\n // the server.\n injector.get(ApplicationInitStatus).donePromise.then(() => {\n const dom = ɵgetDOM();\n const styles = document.querySelectorAll(`style[ng-transition=\"${transitionId}\"]`);\n\n for (let i = 0; i < styles.length; i++) {\n dom.remove(styles[i]);\n }\n });\n };\n}\n\nconst SERVER_TRANSITION_PROVIDERS = [{\n provide: APP_INITIALIZER,\n useFactory: appInitializerFactory,\n deps: [TRANSITION_ID, DOCUMENT, Injector],\n multi: true\n}];\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nclass BrowserGetTestability {\n addToWindow(registry) {\n ɵglobal['getAngularTestability'] = (elem, findInAncestors = true) => {\n const testability = registry.findTestabilityInTree(elem, findInAncestors);\n\n if (testability == null) {\n throw new Error('Could not find testability for element.');\n }\n\n return testability;\n };\n\n ɵglobal['getAllAngularTestabilities'] = () => registry.getAllTestabilities();\n\n ɵglobal['getAllAngularRootElements'] = () => registry.getAllRootElements();\n\n const whenAllStable = (callback\n /** TODO #9100 */\n ) => {\n const testabilities = ɵglobal['getAllAngularTestabilities']();\n let count = testabilities.length;\n let didWork = false;\n\n const decrement = function (didWork_\n /** TODO #9100 */\n ) {\n didWork = didWork || didWork_;\n count--;\n\n if (count == 0) {\n callback(didWork);\n }\n };\n\n testabilities.forEach(function (testability\n /** TODO #9100 */\n ) {\n testability.whenStable(decrement);\n });\n };\n\n if (!ɵglobal['frameworkStabilizers']) {\n ɵglobal['frameworkStabilizers'] = [];\n }\n\n ɵglobal['frameworkStabilizers'].push(whenAllStable);\n }\n\n findTestabilityInTree(registry, elem, findInAncestors) {\n if (elem == null) {\n return null;\n }\n\n const t = registry.getTestability(elem);\n\n if (t != null) {\n return t;\n } else if (!findInAncestors) {\n return null;\n }\n\n if (ɵgetDOM().isShadowRoot(elem)) {\n return this.findTestabilityInTree(registry, elem.host, true);\n }\n\n return this.findTestabilityInTree(registry, elem.parentElement, true);\n }\n\n}\n/**\n * A factory for `HttpXhrBackend` that uses the `XMLHttpRequest` browser API.\n */\n\n\nlet BrowserXhr = /*#__PURE__*/(() => {\n class BrowserXhr {\n build() {\n return new XMLHttpRequest();\n }\n\n }\n\n BrowserXhr.ɵfac = function BrowserXhr_Factory(t) {\n return new (t || BrowserXhr)();\n };\n\n BrowserXhr.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: BrowserXhr,\n factory: BrowserXhr.ɵfac\n });\n return BrowserXhr;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * The injection token for the event-manager plug-in service.\n *\n * @publicApi\n */\n\n\nconst EVENT_MANAGER_PLUGINS = /*#__PURE__*/new InjectionToken('EventManagerPlugins');\n/**\n * An injectable service that provides event management for Angular\n * through a browser plug-in.\n *\n * @publicApi\n */\n\nlet EventManager = /*#__PURE__*/(() => {\n class EventManager {\n /**\n * Initializes an instance of the event-manager service.\n */\n constructor(plugins, _zone) {\n this._zone = _zone;\n this._eventNameToPlugin = new Map();\n plugins.forEach(p => p.manager = this);\n this._plugins = plugins.slice().reverse();\n }\n /**\n * Registers a handler for a specific element and event.\n *\n * @param element The HTML element to receive event notifications.\n * @param eventName The name of the event to listen for.\n * @param handler A function to call when the notification occurs. Receives the\n * event object as an argument.\n * @returns A callback function that can be used to remove the handler.\n */\n\n\n addEventListener(element, eventName, handler) {\n const plugin = this._findPluginFor(eventName);\n\n return plugin.addEventListener(element, eventName, handler);\n }\n /**\n * Registers a global handler for an event in a target view.\n *\n * @param target A target for global event notifications. One of \"window\", \"document\", or \"body\".\n * @param eventName The name of the event to listen for.\n * @param handler A function to call when the notification occurs. Receives the\n * event object as an argument.\n * @returns A callback function that can be used to remove the handler.\n * @deprecated No longer being used in Ivy code. To be removed in version 14.\n */\n\n\n addGlobalEventListener(target, eventName, handler) {\n const plugin = this._findPluginFor(eventName);\n\n return plugin.addGlobalEventListener(target, eventName, handler);\n }\n /**\n * Retrieves the compilation zone in which event listeners are registered.\n */\n\n\n getZone() {\n return this._zone;\n }\n /** @internal */\n\n\n _findPluginFor(eventName) {\n const plugin = this._eventNameToPlugin.get(eventName);\n\n if (plugin) {\n return plugin;\n }\n\n const plugins = this._plugins;\n\n for (let i = 0; i < plugins.length; i++) {\n const plugin = plugins[i];\n\n if (plugin.supports(eventName)) {\n this._eventNameToPlugin.set(eventName, plugin);\n\n return plugin;\n }\n }\n\n throw new Error(`No event manager plugin found for event ${eventName}`);\n }\n\n }\n\n EventManager.ɵfac = function EventManager_Factory(t) {\n return new (t || EventManager)(i0.ɵɵinject(EVENT_MANAGER_PLUGINS), i0.ɵɵinject(i0.NgZone));\n };\n\n EventManager.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: EventManager,\n factory: EventManager.ɵfac\n });\n return EventManager;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\nclass EventManagerPlugin {\n constructor(_doc) {\n this._doc = _doc;\n }\n\n addGlobalEventListener(element, eventName, handler) {\n const target = ɵgetDOM().getGlobalEventTarget(this._doc, element);\n\n if (!target) {\n throw new Error(`Unsupported event target ${target} for event ${eventName}`);\n }\n\n return this.addEventListener(target, eventName, handler);\n }\n\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nlet SharedStylesHost = /*#__PURE__*/(() => {\n class SharedStylesHost {\n constructor() {\n /** @internal */\n this._stylesSet = new Set();\n }\n\n addStyles(styles) {\n const additions = new Set();\n styles.forEach(style => {\n if (!this._stylesSet.has(style)) {\n this._stylesSet.add(style);\n\n additions.add(style);\n }\n });\n this.onStylesAdded(additions);\n }\n\n onStylesAdded(additions) {}\n\n getAllStyles() {\n return Array.from(this._stylesSet);\n }\n\n }\n\n SharedStylesHost.ɵfac = function SharedStylesHost_Factory(t) {\n return new (t || SharedStylesHost)();\n };\n\n SharedStylesHost.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: SharedStylesHost,\n factory: SharedStylesHost.ɵfac\n });\n return SharedStylesHost;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\nlet DomSharedStylesHost = /*#__PURE__*/(() => {\n class DomSharedStylesHost extends SharedStylesHost {\n constructor(_doc) {\n super();\n this._doc = _doc; // Maps all registered host nodes to a list of style nodes that have been added to the host node.\n\n this._hostNodes = new Map();\n\n this._hostNodes.set(_doc.head, []);\n }\n\n _addStylesToHost(styles, host, styleNodes) {\n styles.forEach(style => {\n const styleEl = this._doc.createElement('style');\n\n styleEl.textContent = style;\n styleNodes.push(host.appendChild(styleEl));\n });\n }\n\n addHost(hostNode) {\n const styleNodes = [];\n\n this._addStylesToHost(this._stylesSet, hostNode, styleNodes);\n\n this._hostNodes.set(hostNode, styleNodes);\n }\n\n removeHost(hostNode) {\n const styleNodes = this._hostNodes.get(hostNode);\n\n if (styleNodes) {\n styleNodes.forEach(removeStyle);\n }\n\n this._hostNodes.delete(hostNode);\n }\n\n onStylesAdded(additions) {\n this._hostNodes.forEach((styleNodes, hostNode) => {\n this._addStylesToHost(additions, hostNode, styleNodes);\n });\n }\n\n ngOnDestroy() {\n this._hostNodes.forEach(styleNodes => styleNodes.forEach(removeStyle));\n }\n\n }\n\n DomSharedStylesHost.ɵfac = function DomSharedStylesHost_Factory(t) {\n return new (t || DomSharedStylesHost)(i0.ɵɵinject(DOCUMENT));\n };\n\n DomSharedStylesHost.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: DomSharedStylesHost,\n factory: DomSharedStylesHost.ɵfac\n });\n return DomSharedStylesHost;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\nfunction removeStyle(styleNode) {\n ɵgetDOM().remove(styleNode);\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nconst NAMESPACE_URIS = {\n 'svg': 'http://www.w3.org/2000/svg',\n 'xhtml': 'http://www.w3.org/1999/xhtml',\n 'xlink': 'http://www.w3.org/1999/xlink',\n 'xml': 'http://www.w3.org/XML/1998/namespace',\n 'xmlns': 'http://www.w3.org/2000/xmlns/',\n 'math': 'http://www.w3.org/1998/MathML/'\n};\nconst COMPONENT_REGEX = /%COMP%/g;\nconst NG_DEV_MODE$1 = typeof ngDevMode === 'undefined' || !!ngDevMode;\nconst COMPONENT_VARIABLE = '%COMP%';\nconst HOST_ATTR = `_nghost-${COMPONENT_VARIABLE}`;\nconst CONTENT_ATTR = `_ngcontent-${COMPONENT_VARIABLE}`;\n\nfunction shimContentAttribute(componentShortId) {\n return CONTENT_ATTR.replace(COMPONENT_REGEX, componentShortId);\n}\n\nfunction shimHostAttribute(componentShortId) {\n return HOST_ATTR.replace(COMPONENT_REGEX, componentShortId);\n}\n\nfunction flattenStyles(compId, styles, target) {\n for (let i = 0; i < styles.length; i++) {\n let style = styles[i];\n\n if (Array.isArray(style)) {\n flattenStyles(compId, style, target);\n } else {\n style = style.replace(COMPONENT_REGEX, compId);\n target.push(style);\n }\n }\n\n return target;\n}\n\nfunction decoratePreventDefault(eventHandler) {\n // `DebugNode.triggerEventHandler` needs to know if the listener was created with\n // decoratePreventDefault or is a listener added outside the Angular context so it can handle the\n // two differently. In the first case, the special '__ngUnwrap__' token is passed to the unwrap\n // the listener (see below).\n return event => {\n // Ivy uses '__ngUnwrap__' as a special token that allows us to unwrap the function\n // so that it can be invoked programmatically by `DebugNode.triggerEventHandler`. The debug_node\n // can inspect the listener toString contents for the existence of this special token. Because\n // the token is a string literal, it is ensured to not be modified by compiled code.\n if (event === '__ngUnwrap__') {\n return eventHandler;\n }\n\n const allowDefaultBehavior = eventHandler(event);\n\n if (allowDefaultBehavior === false) {\n // TODO(tbosch): move preventDefault into event plugins...\n event.preventDefault();\n event.returnValue = false;\n }\n\n return undefined;\n };\n}\n\nlet hasLoggedNativeEncapsulationWarning = false;\nlet DomRendererFactory2 = /*#__PURE__*/(() => {\n class DomRendererFactory2 {\n constructor(eventManager, sharedStylesHost, appId) {\n this.eventManager = eventManager;\n this.sharedStylesHost = sharedStylesHost;\n this.appId = appId;\n this.rendererByCompId = new Map();\n this.defaultRenderer = new DefaultDomRenderer2(eventManager);\n }\n\n createRenderer(element, type) {\n if (!element || !type) {\n return this.defaultRenderer;\n }\n\n switch (type.encapsulation) {\n case ViewEncapsulation.Emulated:\n {\n let renderer = this.rendererByCompId.get(type.id);\n\n if (!renderer) {\n renderer = new EmulatedEncapsulationDomRenderer2(this.eventManager, this.sharedStylesHost, type, this.appId);\n this.rendererByCompId.set(type.id, renderer);\n }\n\n renderer.applyToHost(element);\n return renderer;\n }\n // @ts-ignore TODO: Remove as part of FW-2290. TS complains about us dealing with an enum\n // value that is not known (but previously was the value for ViewEncapsulation.Native)\n\n case 1:\n case ViewEncapsulation.ShadowDom:\n // TODO(FW-2290): remove the `case 1:` fallback logic and the warning in v12.\n if ((typeof ngDevMode === 'undefined' || ngDevMode) && // @ts-ignore TODO: Remove as part of FW-2290. TS complains about us dealing with an\n // enum value that is not known (but previously was the value for\n // ViewEncapsulation.Native)\n !hasLoggedNativeEncapsulationWarning && type.encapsulation === 1) {\n hasLoggedNativeEncapsulationWarning = true;\n console.warn('ViewEncapsulation.Native is no longer supported. Falling back to ViewEncapsulation.ShadowDom. The fallback will be removed in v12.');\n }\n\n return new ShadowDomRenderer(this.eventManager, this.sharedStylesHost, element, type);\n\n default:\n {\n if (!this.rendererByCompId.has(type.id)) {\n const styles = flattenStyles(type.id, type.styles, []);\n this.sharedStylesHost.addStyles(styles);\n this.rendererByCompId.set(type.id, this.defaultRenderer);\n }\n\n return this.defaultRenderer;\n }\n }\n }\n\n begin() {}\n\n end() {}\n\n }\n\n DomRendererFactory2.ɵfac = function DomRendererFactory2_Factory(t) {\n return new (t || DomRendererFactory2)(i0.ɵɵinject(EventManager), i0.ɵɵinject(DomSharedStylesHost), i0.ɵɵinject(APP_ID));\n };\n\n DomRendererFactory2.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: DomRendererFactory2,\n factory: DomRendererFactory2.ɵfac\n });\n return DomRendererFactory2;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\nclass DefaultDomRenderer2 {\n constructor(eventManager) {\n this.eventManager = eventManager;\n this.data = Object.create(null);\n this.destroyNode = null;\n }\n\n destroy() {}\n\n createElement(name, namespace) {\n if (namespace) {\n // TODO: `|| namespace` was added in\n // https://github.com/angular/angular/commit/2b9cc8503d48173492c29f5a271b61126104fbdb to\n // support how Ivy passed around the namespace URI rather than short name at the time. It did\n // not, however extend the support to other parts of the system (setAttribute, setAttribute,\n // and the ServerRenderer). We should decide what exactly the semantics for dealing with\n // namespaces should be and make it consistent.\n // Related issues:\n // https://github.com/angular/angular/issues/44028\n // https://github.com/angular/angular/issues/44883\n return document.createElementNS(NAMESPACE_URIS[namespace] || namespace, name);\n }\n\n return document.createElement(name);\n }\n\n createComment(value) {\n return document.createComment(value);\n }\n\n createText(value) {\n return document.createTextNode(value);\n }\n\n appendChild(parent, newChild) {\n const targetParent = isTemplateNode(parent) ? parent.content : parent;\n targetParent.appendChild(newChild);\n }\n\n insertBefore(parent, newChild, refChild) {\n if (parent) {\n const targetParent = isTemplateNode(parent) ? parent.content : parent;\n targetParent.insertBefore(newChild, refChild);\n }\n }\n\n removeChild(parent, oldChild) {\n if (parent) {\n parent.removeChild(oldChild);\n }\n }\n\n selectRootElement(selectorOrNode, preserveContent) {\n let el = typeof selectorOrNode === 'string' ? document.querySelector(selectorOrNode) : selectorOrNode;\n\n if (!el) {\n throw new Error(`The selector \"${selectorOrNode}\" did not match any elements`);\n }\n\n if (!preserveContent) {\n el.textContent = '';\n }\n\n return el;\n }\n\n parentNode(node) {\n return node.parentNode;\n }\n\n nextSibling(node) {\n return node.nextSibling;\n }\n\n setAttribute(el, name, value, namespace) {\n if (namespace) {\n name = namespace + ':' + name;\n const namespaceUri = NAMESPACE_URIS[namespace];\n\n if (namespaceUri) {\n el.setAttributeNS(namespaceUri, name, value);\n } else {\n el.setAttribute(name, value);\n }\n } else {\n el.setAttribute(name, value);\n }\n }\n\n removeAttribute(el, name, namespace) {\n if (namespace) {\n const namespaceUri = NAMESPACE_URIS[namespace];\n\n if (namespaceUri) {\n el.removeAttributeNS(namespaceUri, name);\n } else {\n el.removeAttribute(`${namespace}:${name}`);\n }\n } else {\n el.removeAttribute(name);\n }\n }\n\n addClass(el, name) {\n el.classList.add(name);\n }\n\n removeClass(el, name) {\n el.classList.remove(name);\n }\n\n setStyle(el, style, value, flags) {\n if (flags & (RendererStyleFlags2.DashCase | RendererStyleFlags2.Important)) {\n el.style.setProperty(style, value, flags & RendererStyleFlags2.Important ? 'important' : '');\n } else {\n el.style[style] = value;\n }\n }\n\n removeStyle(el, style, flags) {\n if (flags & RendererStyleFlags2.DashCase) {\n el.style.removeProperty(style);\n } else {\n // IE requires '' instead of null\n // see https://github.com/angular/angular/issues/7916\n el.style[style] = '';\n }\n }\n\n setProperty(el, name, value) {\n NG_DEV_MODE$1 && checkNoSyntheticProp(name, 'property');\n el[name] = value;\n }\n\n setValue(node, value) {\n node.nodeValue = value;\n }\n\n listen(target, event, callback) {\n NG_DEV_MODE$1 && checkNoSyntheticProp(event, 'listener');\n\n if (typeof target === 'string') {\n return this.eventManager.addGlobalEventListener(target, event, decoratePreventDefault(callback));\n }\n\n return this.eventManager.addEventListener(target, event, decoratePreventDefault(callback));\n }\n\n}\n\nconst AT_CHARCODE = /*#__PURE__*/(() => '@'.charCodeAt(0))();\n\nfunction checkNoSyntheticProp(name, nameKind) {\n if (name.charCodeAt(0) === AT_CHARCODE) {\n throw new Error(`Unexpected synthetic ${nameKind} ${name} found. Please make sure that:\n - Either \\`BrowserAnimationsModule\\` or \\`NoopAnimationsModule\\` are imported in your application.\n - There is corresponding configuration for the animation named \\`${name}\\` defined in the \\`animations\\` field of the \\`@Component\\` decorator (see https://angular.io/api/core/Component#animations).`);\n }\n}\n\nfunction isTemplateNode(node) {\n return node.tagName === 'TEMPLATE' && node.content !== undefined;\n}\n\nclass EmulatedEncapsulationDomRenderer2 extends DefaultDomRenderer2 {\n constructor(eventManager, sharedStylesHost, component, appId) {\n super(eventManager);\n this.component = component;\n const styles = flattenStyles(appId + '-' + component.id, component.styles, []);\n sharedStylesHost.addStyles(styles);\n this.contentAttr = shimContentAttribute(appId + '-' + component.id);\n this.hostAttr = shimHostAttribute(appId + '-' + component.id);\n }\n\n applyToHost(element) {\n super.setAttribute(element, this.hostAttr, '');\n }\n\n createElement(parent, name) {\n const el = super.createElement(parent, name);\n super.setAttribute(el, this.contentAttr, '');\n return el;\n }\n\n}\n\nclass ShadowDomRenderer extends DefaultDomRenderer2 {\n constructor(eventManager, sharedStylesHost, hostEl, component) {\n super(eventManager);\n this.sharedStylesHost = sharedStylesHost;\n this.hostEl = hostEl;\n this.shadowRoot = hostEl.attachShadow({\n mode: 'open'\n });\n this.sharedStylesHost.addHost(this.shadowRoot);\n const styles = flattenStyles(component.id, component.styles, []);\n\n for (let i = 0; i < styles.length; i++) {\n const styleEl = document.createElement('style');\n styleEl.textContent = styles[i];\n this.shadowRoot.appendChild(styleEl);\n }\n }\n\n nodeOrShadowRoot(node) {\n return node === this.hostEl ? this.shadowRoot : node;\n }\n\n destroy() {\n this.sharedStylesHost.removeHost(this.shadowRoot);\n }\n\n appendChild(parent, newChild) {\n return super.appendChild(this.nodeOrShadowRoot(parent), newChild);\n }\n\n insertBefore(parent, newChild, refChild) {\n return super.insertBefore(this.nodeOrShadowRoot(parent), newChild, refChild);\n }\n\n removeChild(parent, oldChild) {\n return super.removeChild(this.nodeOrShadowRoot(parent), oldChild);\n }\n\n parentNode(node) {\n return this.nodeOrShadowRoot(super.parentNode(this.nodeOrShadowRoot(node)));\n }\n\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nlet DomEventsPlugin = /*#__PURE__*/(() => {\n class DomEventsPlugin extends EventManagerPlugin {\n constructor(doc) {\n super(doc);\n } // This plugin should come last in the list of plugins, because it accepts all\n // events.\n\n\n supports(eventName) {\n return true;\n }\n\n addEventListener(element, eventName, handler) {\n element.addEventListener(eventName, handler, false);\n return () => this.removeEventListener(element, eventName, handler);\n }\n\n removeEventListener(target, eventName, callback) {\n return target.removeEventListener(eventName, callback);\n }\n\n }\n\n DomEventsPlugin.ɵfac = function DomEventsPlugin_Factory(t) {\n return new (t || DomEventsPlugin)(i0.ɵɵinject(DOCUMENT));\n };\n\n DomEventsPlugin.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: DomEventsPlugin,\n factory: DomEventsPlugin.ɵfac\n });\n return DomEventsPlugin;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Defines supported modifiers for key events.\n */\n\n\nconst MODIFIER_KEYS = ['alt', 'control', 'meta', 'shift']; // The following values are here for cross-browser compatibility and to match the W3C standard\n// cf https://www.w3.org/TR/DOM-Level-3-Events-key/\n\nconst _keyMap = {\n '\\b': 'Backspace',\n '\\t': 'Tab',\n '\\x7F': 'Delete',\n '\\x1B': 'Escape',\n 'Del': 'Delete',\n 'Esc': 'Escape',\n 'Left': 'ArrowLeft',\n 'Right': 'ArrowRight',\n 'Up': 'ArrowUp',\n 'Down': 'ArrowDown',\n 'Menu': 'ContextMenu',\n 'Scroll': 'ScrollLock',\n 'Win': 'OS'\n};\n/**\n * Retrieves modifiers from key-event objects.\n */\n\nconst MODIFIER_KEY_GETTERS = {\n 'alt': event => event.altKey,\n 'control': event => event.ctrlKey,\n 'meta': event => event.metaKey,\n 'shift': event => event.shiftKey\n};\n/**\n * @publicApi\n * A browser plug-in that provides support for handling of key events in Angular.\n */\n\nlet KeyEventsPlugin = /*#__PURE__*/(() => {\n class KeyEventsPlugin extends EventManagerPlugin {\n /**\n * Initializes an instance of the browser plug-in.\n * @param doc The document in which key events will be detected.\n */\n constructor(doc) {\n super(doc);\n }\n /**\n * Reports whether a named key event is supported.\n * @param eventName The event name to query.\n * @return True if the named key event is supported.\n */\n\n\n supports(eventName) {\n return KeyEventsPlugin.parseEventName(eventName) != null;\n }\n /**\n * Registers a handler for a specific element and key event.\n * @param element The HTML element to receive event notifications.\n * @param eventName The name of the key event to listen for.\n * @param handler A function to call when the notification occurs. Receives the\n * event object as an argument.\n * @returns The key event that was registered.\n */\n\n\n addEventListener(element, eventName, handler) {\n const parsedEvent = KeyEventsPlugin.parseEventName(eventName);\n const outsideHandler = KeyEventsPlugin.eventCallback(parsedEvent['fullKey'], handler, this.manager.getZone());\n return this.manager.getZone().runOutsideAngular(() => {\n return ɵgetDOM().onAndCancel(element, parsedEvent['domEventName'], outsideHandler);\n });\n }\n /**\n * Parses the user provided full keyboard event definition and normalizes it for\n * later internal use. It ensures the string is all lowercase, converts special\n * characters to a standard spelling, and orders all the values consistently.\n *\n * @param eventName The name of the key event to listen for.\n * @returns an object with the full, normalized string, and the dom event name\n * or null in the case when the event doesn't match a keyboard event.\n */\n\n\n static parseEventName(eventName) {\n const parts = eventName.toLowerCase().split('.');\n const domEventName = parts.shift();\n\n if (parts.length === 0 || !(domEventName === 'keydown' || domEventName === 'keyup')) {\n return null;\n }\n\n const key = KeyEventsPlugin._normalizeKey(parts.pop());\n\n let fullKey = '';\n let codeIX = parts.indexOf('code');\n\n if (codeIX > -1) {\n parts.splice(codeIX, 1);\n fullKey = 'code.';\n }\n\n MODIFIER_KEYS.forEach(modifierName => {\n const index = parts.indexOf(modifierName);\n\n if (index > -1) {\n parts.splice(index, 1);\n fullKey += modifierName + '.';\n }\n });\n fullKey += key;\n\n if (parts.length != 0 || key.length === 0) {\n // returning null instead of throwing to let another plugin process the event\n return null;\n } // NOTE: Please don't rewrite this as so, as it will break JSCompiler property renaming.\n // The code must remain in the `result['domEventName']` form.\n // return {domEventName, fullKey};\n\n\n const result = {};\n result['domEventName'] = domEventName;\n result['fullKey'] = fullKey;\n return result;\n }\n /**\n * Determines whether the actual keys pressed match the configured key code string.\n * The `fullKeyCode` event is normalized in the `parseEventName` method when the\n * event is attached to the DOM during the `addEventListener` call. This is unseen\n * by the end user and is normalized for internal consistency and parsing.\n *\n * @param event The keyboard event.\n * @param fullKeyCode The normalized user defined expected key event string\n * @returns boolean.\n */\n\n\n static matchEventFullKeyCode(event, fullKeyCode) {\n let keycode = _keyMap[event.key] || event.key;\n let key = '';\n\n if (fullKeyCode.indexOf('code.') > -1) {\n keycode = event.code;\n key = 'code.';\n } // the keycode could be unidentified so we have to check here\n\n\n if (keycode == null || !keycode) return false;\n keycode = keycode.toLowerCase();\n\n if (keycode === ' ') {\n keycode = 'space'; // for readability\n } else if (keycode === '.') {\n keycode = 'dot'; // because '.' is used as a separator in event names\n }\n\n MODIFIER_KEYS.forEach(modifierName => {\n if (modifierName !== keycode) {\n const modifierGetter = MODIFIER_KEY_GETTERS[modifierName];\n\n if (modifierGetter(event)) {\n key += modifierName + '.';\n }\n }\n });\n key += keycode;\n return key === fullKeyCode;\n }\n /**\n * Configures a handler callback for a key event.\n * @param fullKey The event name that combines all simultaneous keystrokes.\n * @param handler The function that responds to the key event.\n * @param zone The zone in which the event occurred.\n * @returns A callback function.\n */\n\n\n static eventCallback(fullKey, handler, zone) {\n return event => {\n if (KeyEventsPlugin.matchEventFullKeyCode(event, fullKey)) {\n zone.runGuarded(() => handler(event));\n }\n };\n }\n /** @internal */\n\n\n static _normalizeKey(keyName) {\n // TODO: switch to a Map if the mapping grows too much\n switch (keyName) {\n case 'esc':\n return 'escape';\n\n default:\n return keyName;\n }\n }\n\n }\n\n KeyEventsPlugin.ɵfac = function KeyEventsPlugin_Factory(t) {\n return new (t || KeyEventsPlugin)(i0.ɵɵinject(DOCUMENT));\n };\n\n KeyEventsPlugin.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: KeyEventsPlugin,\n factory: KeyEventsPlugin.ɵfac\n });\n return KeyEventsPlugin;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nconst NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;\n/**\n * Bootstraps an instance of an Angular application and renders a standalone component as the\n * application's root component. More information about standalone components can be found in [this\n * guide](guide/standalone-components).\n *\n * @usageNotes\n * The root component passed into this function *must* be a standalone one (should have the\n * `standalone: true` flag in the `@Component` decorator config).\n *\n * ```typescript\n * @Component({\n * standalone: true,\n * template: 'Hello world!'\n * })\n * class RootComponent {}\n *\n * const appRef: ApplicationRef = await bootstrapApplication(RootComponent);\n * ```\n *\n * You can add the list of providers that should be available in the application injector by\n * specifying the `providers` field in an object passed as the second argument:\n *\n * ```typescript\n * await bootstrapApplication(RootComponent, {\n * providers: [\n * {provide: BACKEND_URL, useValue: 'https://yourdomain.com/api'}\n * ]\n * });\n * ```\n *\n * The `importProvidersFrom` helper method can be used to collect all providers from any\n * existing NgModule (and transitively from all NgModules that it imports):\n *\n * ```typescript\n * await bootstrapApplication(RootComponent, {\n * providers: [\n * importProvidersFrom(SomeNgModule)\n * ]\n * });\n * ```\n *\n * Note: the `bootstrapApplication` method doesn't include [Testability](api/core/Testability) by\n * default. You can add [Testability](api/core/Testability) by getting the list of necessary\n * providers using `provideProtractorTestingSupport()` function and adding them into the `providers`\n * array, for example:\n *\n * ```typescript\n * import {provideProtractorTestingSupport} from '@angular/platform-browser';\n *\n * await bootstrapApplication(RootComponent, {providers: [provideProtractorTestingSupport()]});\n * ```\n *\n * @param rootComponent A reference to a standalone component that should be rendered.\n * @param options Extra configuration for the bootstrap operation, see `ApplicationConfig` for\n * additional info.\n * @returns A promise that returns an `ApplicationRef` instance once resolved.\n *\n * @publicApi\n * @developerPreview\n */\n\nfunction bootstrapApplication(rootComponent, options) {\n return ɵinternalCreateApplication({\n rootComponent,\n ...createProvidersConfig(options)\n });\n}\n/**\n * Create an instance of an Angular application without bootstrapping any components. This is useful\n * for the situation where one wants to decouple application environment creation (a platform and\n * associated injectors) from rendering components on a screen. Components can be subsequently\n * bootstrapped on the returned `ApplicationRef`.\n *\n * @param options Extra configuration for the application environment, see `ApplicationConfig` for\n * additional info.\n * @returns A promise that returns an `ApplicationRef` instance once resolved.\n *\n * @publicApi\n * @developerPreview\n */\n\n\nfunction createApplication(options) {\n return ɵinternalCreateApplication(createProvidersConfig(options));\n}\n\nfunction createProvidersConfig(options) {\n var _options$providers;\n\n return {\n appProviders: [...BROWSER_MODULE_PROVIDERS, ...((_options$providers = options === null || options === void 0 ? void 0 : options.providers) !== null && _options$providers !== void 0 ? _options$providers : [])],\n platformProviders: INTERNAL_BROWSER_PLATFORM_PROVIDERS\n };\n}\n/**\n * Returns a set of providers required to setup [Testability](api/core/Testability) for an\n * application bootstrapped using the `bootstrapApplication` function. The set of providers is\n * needed to support testing an application with Protractor (which relies on the Testability APIs\n * to be present).\n *\n * @returns An array of providers required to setup Testability for an application and make it\n * available for testing using Protractor.\n *\n * @developerPreview\n * @publicApi\n */\n\n\nfunction provideProtractorTestingSupport() {\n // Return a copy to prevent changes to the original array in case any in-place\n // alterations are performed to the `provideProtractorTestingSupport` call results in app code.\n return [...TESTABILITY_PROVIDERS];\n}\n\nfunction initDomAdapter() {\n BrowserDomAdapter.makeCurrent();\n}\n\nfunction errorHandler() {\n return new ErrorHandler();\n}\n\nfunction _document() {\n // Tell ivy about the global document\n ɵsetDocument(document);\n return document;\n}\n\nconst INTERNAL_BROWSER_PLATFORM_PROVIDERS = [{\n provide: PLATFORM_ID,\n useValue: ɵPLATFORM_BROWSER_ID\n}, {\n provide: PLATFORM_INITIALIZER,\n useValue: initDomAdapter,\n multi: true\n}, {\n provide: DOCUMENT,\n useFactory: _document,\n deps: []\n}];\n/**\n * A factory function that returns a `PlatformRef` instance associated with browser service\n * providers.\n *\n * @publicApi\n */\n\nconst platformBrowser = /*#__PURE__*/createPlatformFactory(platformCore, 'browser', INTERNAL_BROWSER_PLATFORM_PROVIDERS);\n/**\n * Internal marker to signal whether providers from the `BrowserModule` are already present in DI.\n * This is needed to avoid loading `BrowserModule` providers twice. We can't rely on the\n * `BrowserModule` presence itself, since the standalone-based bootstrap just imports\n * `BrowserModule` providers without referencing the module itself.\n */\n\nconst BROWSER_MODULE_PROVIDERS_MARKER = /*#__PURE__*/new InjectionToken(NG_DEV_MODE ? 'BrowserModule Providers Marker' : '');\nconst TESTABILITY_PROVIDERS = [{\n provide: ɵTESTABILITY_GETTER,\n useClass: BrowserGetTestability,\n deps: []\n}, {\n provide: ɵTESTABILITY,\n useClass: Testability,\n deps: [NgZone, TestabilityRegistry, ɵTESTABILITY_GETTER]\n}, {\n provide: Testability,\n useClass: Testability,\n deps: [NgZone, TestabilityRegistry, ɵTESTABILITY_GETTER]\n}];\nconst BROWSER_MODULE_PROVIDERS = [{\n provide: ɵINJECTOR_SCOPE,\n useValue: 'root'\n}, {\n provide: ErrorHandler,\n useFactory: errorHandler,\n deps: []\n}, {\n provide: EVENT_MANAGER_PLUGINS,\n useClass: DomEventsPlugin,\n multi: true,\n deps: [DOCUMENT, NgZone, PLATFORM_ID]\n}, {\n provide: EVENT_MANAGER_PLUGINS,\n useClass: KeyEventsPlugin,\n multi: true,\n deps: [DOCUMENT]\n}, {\n provide: DomRendererFactory2,\n useClass: DomRendererFactory2,\n deps: [EventManager, DomSharedStylesHost, APP_ID]\n}, {\n provide: RendererFactory2,\n useExisting: DomRendererFactory2\n}, {\n provide: SharedStylesHost,\n useExisting: DomSharedStylesHost\n}, {\n provide: DomSharedStylesHost,\n useClass: DomSharedStylesHost,\n deps: [DOCUMENT]\n}, {\n provide: EventManager,\n useClass: EventManager,\n deps: [EVENT_MANAGER_PLUGINS, NgZone]\n}, {\n provide: XhrFactory,\n useClass: BrowserXhr,\n deps: []\n}, NG_DEV_MODE ? {\n provide: BROWSER_MODULE_PROVIDERS_MARKER,\n useValue: true\n} : []];\n/**\n * Exports required infrastructure for all Angular apps.\n * Included by default in all Angular apps created with the CLI\n * `new` command.\n * Re-exports `CommonModule` and `ApplicationModule`, making their\n * exports and providers available to all apps.\n *\n * @publicApi\n */\n\nlet BrowserModule = /*#__PURE__*/(() => {\n class BrowserModule {\n constructor(providersAlreadyPresent) {\n if (NG_DEV_MODE && providersAlreadyPresent) {\n throw new Error(`Providers from the \\`BrowserModule\\` have already been loaded. If you need access ` + `to common directives such as NgIf and NgFor, import the \\`CommonModule\\` instead.`);\n }\n }\n /**\n * Configures a browser-based app to transition from a server-rendered app, if\n * one is present on the page.\n *\n * @param params An object containing an identifier for the app to transition.\n * The ID must match between the client and server versions of the app.\n * @returns The reconfigured `BrowserModule` to import into the app's root `AppModule`.\n */\n\n\n static withServerTransition(params) {\n return {\n ngModule: BrowserModule,\n providers: [{\n provide: APP_ID,\n useValue: params.appId\n }, {\n provide: TRANSITION_ID,\n useExisting: APP_ID\n }, SERVER_TRANSITION_PROVIDERS]\n };\n }\n\n }\n\n BrowserModule.ɵfac = function BrowserModule_Factory(t) {\n return new (t || BrowserModule)(i0.ɵɵinject(BROWSER_MODULE_PROVIDERS_MARKER, 12));\n };\n\n BrowserModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: BrowserModule\n });\n BrowserModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n providers: [...BROWSER_MODULE_PROVIDERS, ...TESTABILITY_PROVIDERS],\n imports: [CommonModule, ApplicationModule]\n });\n return BrowserModule;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Factory to create a `Meta` service instance for the current DOM document.\n */\n\n\nfunction createMeta() {\n return new Meta(ɵɵinject(DOCUMENT));\n}\n/**\n * A service for managing HTML ` ` tags.\n *\n * Properties of the `MetaDefinition` object match the attributes of the\n * HTML ` ` tag. These tags define document metadata that is important for\n * things like configuring a Content Security Policy, defining browser compatibility\n * and security settings, setting HTTP Headers, defining rich content for social sharing,\n * and Search Engine Optimization (SEO).\n *\n * To identify specific ` ` tags in a document, use an attribute selection\n * string in the format `\"tag_attribute='value string'\"`.\n * For example, an `attrSelector` value of `\"name='description'\"` matches a tag\n * whose `name` attribute has the value `\"description\"`.\n * Selectors are used with the `querySelector()` Document method,\n * in the format `meta[{attrSelector}]`.\n *\n * @see [HTML meta tag](https://developer.mozilla.org/docs/Web/HTML/Element/meta)\n * @see [Document.querySelector()](https://developer.mozilla.org/docs/Web/API/Document/querySelector)\n *\n *\n * @publicApi\n */\n\n\nlet Meta = /*#__PURE__*/(() => {\n class Meta {\n constructor(_doc) {\n this._doc = _doc;\n this._dom = ɵgetDOM();\n }\n /**\n * Retrieves or creates a specific ` ` tag element in the current HTML document.\n * In searching for an existing tag, Angular attempts to match the `name` or `property` attribute\n * values in the provided tag definition, and verifies that all other attribute values are equal.\n * If an existing element is found, it is returned and is not modified in any way.\n * @param tag The definition of a ` ` element to match or create.\n * @param forceCreation True to create a new element without checking whether one already exists.\n * @returns The existing element with the same attributes and values if found,\n * the new element if no match is found, or `null` if the tag parameter is not defined.\n */\n\n\n addTag(tag, forceCreation = false) {\n if (!tag) return null;\n return this._getOrCreateElement(tag, forceCreation);\n }\n /**\n * Retrieves or creates a set of ` ` tag elements in the current HTML document.\n * In searching for an existing tag, Angular attempts to match the `name` or `property` attribute\n * values in the provided tag definition, and verifies that all other attribute values are equal.\n * @param tags An array of tag definitions to match or create.\n * @param forceCreation True to create new elements without checking whether they already exist.\n * @returns The matching elements if found, or the new elements.\n */\n\n\n addTags(tags, forceCreation = false) {\n if (!tags) return [];\n return tags.reduce((result, tag) => {\n if (tag) {\n result.push(this._getOrCreateElement(tag, forceCreation));\n }\n\n return result;\n }, []);\n }\n /**\n * Retrieves a ` ` tag element in the current HTML document.\n * @param attrSelector The tag attribute and value to match against, in the format\n * `\"tag_attribute='value string'\"`.\n * @returns The matching element, if any.\n */\n\n\n getTag(attrSelector) {\n if (!attrSelector) return null;\n return this._doc.querySelector(`meta[${attrSelector}]`) || null;\n }\n /**\n * Retrieves a set of ` ` tag elements in the current HTML document.\n * @param attrSelector The tag attribute and value to match against, in the format\n * `\"tag_attribute='value string'\"`.\n * @returns The matching elements, if any.\n */\n\n\n getTags(attrSelector) {\n if (!attrSelector) return [];\n\n const list\n /*NodeList*/\n = this._doc.querySelectorAll(`meta[${attrSelector}]`);\n\n return list ? [].slice.call(list) : [];\n }\n /**\n * Modifies an existing ` ` tag element in the current HTML document.\n * @param tag The tag description with which to replace the existing tag content.\n * @param selector A tag attribute and value to match against, to identify\n * an existing tag. A string in the format `\"tag_attribute=`value string`\"`.\n * If not supplied, matches a tag with the same `name` or `property` attribute value as the\n * replacement tag.\n * @return The modified element.\n */\n\n\n updateTag(tag, selector) {\n if (!tag) return null;\n selector = selector || this._parseSelector(tag);\n const meta = this.getTag(selector);\n\n if (meta) {\n return this._setMetaElementAttributes(tag, meta);\n }\n\n return this._getOrCreateElement(tag, true);\n }\n /**\n * Removes an existing ` ` tag element from the current HTML document.\n * @param attrSelector A tag attribute and value to match against, to identify\n * an existing tag. A string in the format `\"tag_attribute=`value string`\"`.\n */\n\n\n removeTag(attrSelector) {\n this.removeTagElement(this.getTag(attrSelector));\n }\n /**\n * Removes an existing ` ` tag element from the current HTML document.\n * @param meta The tag definition to match against to identify an existing tag.\n */\n\n\n removeTagElement(meta) {\n if (meta) {\n this._dom.remove(meta);\n }\n }\n\n _getOrCreateElement(meta, forceCreation = false) {\n if (!forceCreation) {\n const selector = this._parseSelector(meta); // It's allowed to have multiple elements with the same name so it's not enough to\n // just check that element with the same name already present on the page. We also need to\n // check if element has tag attributes\n\n\n const elem = this.getTags(selector).filter(elem => this._containsAttributes(meta, elem))[0];\n if (elem !== undefined) return elem;\n }\n\n const element = this._dom.createElement('meta');\n\n this._setMetaElementAttributes(meta, element);\n\n const head = this._doc.getElementsByTagName('head')[0];\n\n head.appendChild(element);\n return element;\n }\n\n _setMetaElementAttributes(tag, el) {\n Object.keys(tag).forEach(prop => el.setAttribute(this._getMetaKeyMap(prop), tag[prop]));\n return el;\n }\n\n _parseSelector(tag) {\n const attr = tag.name ? 'name' : 'property';\n return `${attr}=\"${tag[attr]}\"`;\n }\n\n _containsAttributes(tag, elem) {\n return Object.keys(tag).every(key => elem.getAttribute(this._getMetaKeyMap(key)) === tag[key]);\n }\n\n _getMetaKeyMap(prop) {\n return META_KEYS_MAP[prop] || prop;\n }\n\n }\n\n Meta.ɵfac = function Meta_Factory(t) {\n return new (t || Meta)(i0.ɵɵinject(DOCUMENT));\n };\n\n Meta.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: Meta,\n factory: function Meta_Factory(t) {\n let r = null;\n\n if (t) {\n r = new t();\n } else {\n r = createMeta();\n }\n\n return r;\n },\n providedIn: 'root'\n });\n return Meta;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Mapping for MetaDefinition properties with their correct meta attribute names\n */\n\n\nconst META_KEYS_MAP = {\n httpEquiv: 'http-equiv'\n};\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Factory to create Title service.\n */\n\nfunction createTitle() {\n return new Title(ɵɵinject(DOCUMENT));\n}\n/**\n * A service that can be used to get and set the title of a current HTML document.\n *\n * Since an Angular application can't be bootstrapped on the entire HTML document (`` tag)\n * it is not possible to bind to the `text` property of the `HTMLTitleElement` elements\n * (representing the `` tag). Instead, this service can be used to set and get the current\n * title value.\n *\n * @publicApi\n */\n\n\nlet Title = /*#__PURE__*/(() => {\n class Title {\n constructor(_doc) {\n this._doc = _doc;\n }\n /**\n * Get the title of the current HTML document.\n */\n\n\n getTitle() {\n return this._doc.title;\n }\n /**\n * Set the title of the current HTML document.\n * @param newTitle\n */\n\n\n setTitle(newTitle) {\n this._doc.title = newTitle || '';\n }\n\n }\n\n Title.ɵfac = function Title_Factory(t) {\n return new (t || Title)(i0.ɵɵinject(DOCUMENT));\n };\n\n Title.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: Title,\n factory: function Title_Factory(t) {\n let r = null;\n\n if (t) {\n r = new t();\n } else {\n r = createTitle();\n }\n\n return r;\n },\n providedIn: 'root'\n });\n return Title;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nconst CAMEL_CASE_REGEXP = /([A-Z])/g;\nconst DASH_CASE_REGEXP = /-([a-z])/g;\n\nfunction camelCaseToDashCase(input) {\n return input.replace(CAMEL_CASE_REGEXP, (...m) => '-' + m[1].toLowerCase());\n}\n\nfunction dashCaseToCamelCase(input) {\n return input.replace(DASH_CASE_REGEXP, (...m) => m[1].toUpperCase());\n}\n/**\n * Exports the value under a given `name` in the global property `ng`. For example `ng.probe` if\n * `name` is `'probe'`.\n * @param name Name under which it will be exported. Keep in mind this will be a property of the\n * global `ng` object.\n * @param value The value to export.\n */\n\n\nfunction exportNgVar(name, value) {\n if (typeof COMPILED === 'undefined' || !COMPILED) {\n // Note: we can't export `ng` when using closure enhanced optimization as:\n // - closure declares globals itself for minified names, which sometimes clobber our `ng` global\n // - we can't declare a closure extern as the namespace `ng` is already used within Google\n // for typings for angularJS (via `goog.provide('ng....')`).\n const ng = ɵglobal['ng'] = ɵglobal['ng'] || {};\n ng[name] = value;\n }\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nconst win = typeof window !== 'undefined' && window || {};\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nclass ChangeDetectionPerfRecord {\n constructor(msPerTick, numTicks) {\n this.msPerTick = msPerTick;\n this.numTicks = numTicks;\n }\n\n}\n/**\n * Entry point for all Angular profiling-related debug tools. This object\n * corresponds to the `ng.profiler` in the dev console.\n */\n\n\nclass AngularProfiler {\n constructor(ref) {\n this.appRef = ref.injector.get(ApplicationRef);\n } // tslint:disable:no-console\n\n /**\n * Exercises change detection in a loop and then prints the average amount of\n * time in milliseconds how long a single round of change detection takes for\n * the current state of the UI. It runs a minimum of 5 rounds for a minimum\n * of 500 milliseconds.\n *\n * Optionally, a user may pass a `config` parameter containing a map of\n * options. Supported options are:\n *\n * `record` (boolean) - causes the profiler to record a CPU profile while\n * it exercises the change detector. Example:\n *\n * ```\n * ng.profiler.timeChangeDetection({record: true})\n * ```\n */\n\n\n timeChangeDetection(config) {\n const record = config && config['record'];\n const profileName = 'Change Detection'; // Profiler is not available in Android browsers without dev tools opened\n\n const isProfilerAvailable = win.console.profile != null;\n\n if (record && isProfilerAvailable) {\n win.console.profile(profileName);\n }\n\n const start = performanceNow();\n let numTicks = 0;\n\n while (numTicks < 5 || performanceNow() - start < 500) {\n this.appRef.tick();\n numTicks++;\n }\n\n const end = performanceNow();\n\n if (record && isProfilerAvailable) {\n win.console.profileEnd(profileName);\n }\n\n const msPerTick = (end - start) / numTicks;\n win.console.log(`ran ${numTicks} change detection cycles`);\n win.console.log(`${msPerTick.toFixed(2)} ms per check`);\n return new ChangeDetectionPerfRecord(msPerTick, numTicks);\n }\n\n}\n\nfunction performanceNow() {\n return win.performance && win.performance.now ? win.performance.now() : new Date().getTime();\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nconst PROFILER_GLOBAL_NAME = 'profiler';\n/**\n * Enabled Angular debug tools that are accessible via your browser's\n * developer console.\n *\n * Usage:\n *\n * 1. Open developer console (e.g. in Chrome Ctrl + Shift + j)\n * 1. Type `ng.` (usually the console will show auto-complete suggestion)\n * 1. Try the change detection profiler `ng.profiler.timeChangeDetection()`\n * then hit Enter.\n *\n * @publicApi\n */\n\nfunction enableDebugTools(ref) {\n exportNgVar(PROFILER_GLOBAL_NAME, new AngularProfiler(ref));\n return ref;\n}\n/**\n * Disables Angular tools.\n *\n * @publicApi\n */\n\n\nfunction disableDebugTools() {\n exportNgVar(PROFILER_GLOBAL_NAME, null);\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nfunction escapeHtml(text) {\n const escapedText = {\n '&': '&a;',\n '\"': '&q;',\n '\\'': '&s;',\n '<': '&l;',\n '>': '&g;'\n };\n return text.replace(/[&\"'<>]/g, s => escapedText[s]);\n}\n\nfunction unescapeHtml(text) {\n const unescapedText = {\n '&a;': '&',\n '&q;': '\"',\n '&s;': '\\'',\n '&l;': '<',\n '&g;': '>'\n };\n return text.replace(/&[^;]+;/g, s => unescapedText[s]);\n}\n/**\n * Create a `StateKey` that can be used to store value of type T with `TransferState`.\n *\n * Example:\n *\n * ```\n * const COUNTER_KEY = makeStateKey('counter');\n * let value = 10;\n *\n * transferState.set(COUNTER_KEY, value);\n * ```\n *\n * @publicApi\n */\n\n\nfunction makeStateKey(key) {\n return key;\n}\n/**\n * A key value store that is transferred from the application on the server side to the application\n * on the client side.\n *\n * The `TransferState` is available as an injectable token.\n * On the client, just inject this token using DI and use it, it will be lazily initialized.\n * On the server it's already included if `renderApplication` function is used. Otherwise, import\n * the `ServerTransferStateModule` module to make the `TransferState` available.\n *\n * The values in the store are serialized/deserialized using JSON.stringify/JSON.parse. So only\n * boolean, number, string, null and non-class objects will be serialized and deserialized in a\n * non-lossy manner.\n *\n * @publicApi\n */\n\n\nlet TransferState = /*#__PURE__*/(() => {\n class TransferState {\n constructor() {\n this.store = {};\n this.onSerializeCallbacks = {};\n }\n /**\n * Get the value corresponding to a key. Return `defaultValue` if key is not found.\n */\n\n\n get(key, defaultValue) {\n return this.store[key] !== undefined ? this.store[key] : defaultValue;\n }\n /**\n * Set the value corresponding to a key.\n */\n\n\n set(key, value) {\n this.store[key] = value;\n }\n /**\n * Remove a key from the store.\n */\n\n\n remove(key) {\n delete this.store[key];\n }\n /**\n * Test whether a key exists in the store.\n */\n\n\n hasKey(key) {\n return this.store.hasOwnProperty(key);\n }\n /**\n * Indicates whether the state is empty.\n */\n\n\n get isEmpty() {\n return Object.keys(this.store).length === 0;\n }\n /**\n * Register a callback to provide the value for a key when `toJson` is called.\n */\n\n\n onSerialize(key, callback) {\n this.onSerializeCallbacks[key] = callback;\n }\n /**\n * Serialize the current state of the store to JSON.\n */\n\n\n toJson() {\n // Call the onSerialize callbacks and put those values into the store.\n for (const key in this.onSerializeCallbacks) {\n if (this.onSerializeCallbacks.hasOwnProperty(key)) {\n try {\n this.store[key] = this.onSerializeCallbacks[key]();\n } catch (e) {\n console.warn('Exception in onSerialize callback: ', e);\n }\n }\n }\n\n return JSON.stringify(this.store);\n }\n\n }\n\n TransferState.ɵfac = function TransferState_Factory(t) {\n return new (t || TransferState)();\n };\n\n TransferState.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: TransferState,\n factory: function () {\n return (() => {\n const doc = inject(DOCUMENT);\n const appId = inject(APP_ID);\n const state = new TransferState();\n state.store = retrieveTransferredState(doc, appId);\n return state;\n })();\n },\n providedIn: 'root'\n });\n return TransferState;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\nfunction retrieveTransferredState(doc, appId) {\n // Locate the script tag with the JSON data transferred from the server.\n // The id of the script tag is set to the Angular appId + 'state'.\n const script = doc.getElementById(appId + '-state');\n let initialState = {};\n\n if (script && script.textContent) {\n try {\n // Avoid using any here as it triggers lint errors in google3 (any is not allowed).\n initialState = JSON.parse(unescapeHtml(script.textContent));\n } catch (e) {\n console.warn('Exception while restoring TransferState for app ' + appId, e);\n }\n }\n\n return initialState;\n}\n/**\n * NgModule to install on the client side while using the `TransferState` to transfer state from\n * server to client.\n *\n * @publicApi\n * @deprecated no longer needed, you can inject the `TransferState` in an app without providing\n * this module.\n */\n\n\nlet BrowserTransferStateModule = /*#__PURE__*/(() => {\n class BrowserTransferStateModule {}\n\n BrowserTransferStateModule.ɵfac = function BrowserTransferStateModule_Factory(t) {\n return new (t || BrowserTransferStateModule)();\n };\n\n BrowserTransferStateModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: BrowserTransferStateModule\n });\n BrowserTransferStateModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({});\n return BrowserTransferStateModule;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Predicates for use with {@link DebugElement}'s query functions.\n *\n * @publicApi\n */\n\n\nclass By {\n /**\n * Match all nodes.\n *\n * @usageNotes\n * ### Example\n *\n * {@example platform-browser/dom/debug/ts/by/by.ts region='by_all'}\n */\n static all() {\n return () => true;\n }\n /**\n * Match elements by the given CSS selector.\n *\n * @usageNotes\n * ### Example\n *\n * {@example platform-browser/dom/debug/ts/by/by.ts region='by_css'}\n */\n\n\n static css(selector) {\n return debugElement => {\n return debugElement.nativeElement != null ? elementMatches(debugElement.nativeElement, selector) : false;\n };\n }\n /**\n * Match nodes that have the given directive present.\n *\n * @usageNotes\n * ### Example\n *\n * {@example platform-browser/dom/debug/ts/by/by.ts region='by_directive'}\n */\n\n\n static directive(type) {\n return debugNode => debugNode.providerTokens.indexOf(type) !== -1;\n }\n\n}\n\nfunction elementMatches(n, selector) {\n if (ɵgetDOM().isElementNode(n)) {\n return n.matches && n.matches(selector) || n.msMatchesSelector && n.msMatchesSelector(selector) || n.webkitMatchesSelector && n.webkitMatchesSelector(selector);\n }\n\n return false;\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Supported HammerJS recognizer event names.\n */\n\n\nconst EVENT_NAMES = {\n // pan\n 'pan': true,\n 'panstart': true,\n 'panmove': true,\n 'panend': true,\n 'pancancel': true,\n 'panleft': true,\n 'panright': true,\n 'panup': true,\n 'pandown': true,\n // pinch\n 'pinch': true,\n 'pinchstart': true,\n 'pinchmove': true,\n 'pinchend': true,\n 'pinchcancel': true,\n 'pinchin': true,\n 'pinchout': true,\n // press\n 'press': true,\n 'pressup': true,\n // rotate\n 'rotate': true,\n 'rotatestart': true,\n 'rotatemove': true,\n 'rotateend': true,\n 'rotatecancel': true,\n // swipe\n 'swipe': true,\n 'swipeleft': true,\n 'swiperight': true,\n 'swipeup': true,\n 'swipedown': true,\n // tap\n 'tap': true,\n 'doubletap': true\n};\n/**\n * DI token for providing [HammerJS](https://hammerjs.github.io/) support to Angular.\n * @see `HammerGestureConfig`\n *\n * @ngModule HammerModule\n * @publicApi\n */\n\nconst HAMMER_GESTURE_CONFIG = /*#__PURE__*/new InjectionToken('HammerGestureConfig');\n/**\n * Injection token used to provide a {@link HammerLoader} to Angular.\n *\n * @publicApi\n */\n\nconst HAMMER_LOADER = /*#__PURE__*/new InjectionToken('HammerLoader');\n/**\n * An injectable [HammerJS Manager](https://hammerjs.github.io/api/#hammermanager)\n * for gesture recognition. Configures specific event recognition.\n * @publicApi\n */\n\nlet HammerGestureConfig = /*#__PURE__*/(() => {\n class HammerGestureConfig {\n constructor() {\n /**\n * A set of supported event names for gestures to be used in Angular.\n * Angular supports all built-in recognizers, as listed in\n * [HammerJS documentation](https://hammerjs.github.io/).\n */\n this.events = [];\n /**\n * Maps gesture event names to a set of configuration options\n * that specify overrides to the default values for specific properties.\n *\n * The key is a supported event name to be configured,\n * and the options object contains a set of properties, with override values\n * to be applied to the named recognizer event.\n * For example, to disable recognition of the rotate event, specify\n * `{\"rotate\": {\"enable\": false}}`.\n *\n * Properties that are not present take the HammerJS default values.\n * For information about which properties are supported for which events,\n * and their allowed and default values, see\n * [HammerJS documentation](https://hammerjs.github.io/).\n *\n */\n\n this.overrides = {};\n }\n /**\n * Creates a [HammerJS Manager](https://hammerjs.github.io/api/#hammermanager)\n * and attaches it to a given HTML element.\n * @param element The element that will recognize gestures.\n * @returns A HammerJS event-manager object.\n */\n\n\n buildHammer(element) {\n const mc = new Hammer(element, this.options);\n mc.get('pinch').set({\n enable: true\n });\n mc.get('rotate').set({\n enable: true\n });\n\n for (const eventName in this.overrides) {\n mc.get(eventName).set(this.overrides[eventName]);\n }\n\n return mc;\n }\n\n }\n\n HammerGestureConfig.ɵfac = function HammerGestureConfig_Factory(t) {\n return new (t || HammerGestureConfig)();\n };\n\n HammerGestureConfig.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: HammerGestureConfig,\n factory: HammerGestureConfig.ɵfac\n });\n return HammerGestureConfig;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Event plugin that adds Hammer support to an application.\n *\n * @ngModule HammerModule\n */\n\n\nlet HammerGesturesPlugin = /*#__PURE__*/(() => {\n class HammerGesturesPlugin extends EventManagerPlugin {\n constructor(doc, _config, console, loader) {\n super(doc);\n this._config = _config;\n this.console = console;\n this.loader = loader;\n this._loaderPromise = null;\n }\n\n supports(eventName) {\n if (!EVENT_NAMES.hasOwnProperty(eventName.toLowerCase()) && !this.isCustomEvent(eventName)) {\n return false;\n }\n\n if (!window.Hammer && !this.loader) {\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n this.console.warn(`The \"${eventName}\" event cannot be bound because Hammer.JS is not ` + `loaded and no custom loader has been specified.`);\n }\n\n return false;\n }\n\n return true;\n }\n\n addEventListener(element, eventName, handler) {\n const zone = this.manager.getZone();\n eventName = eventName.toLowerCase(); // If Hammer is not present but a loader is specified, we defer adding the event listener\n // until Hammer is loaded.\n\n if (!window.Hammer && this.loader) {\n this._loaderPromise = this._loaderPromise || zone.runOutsideAngular(() => this.loader()); // This `addEventListener` method returns a function to remove the added listener.\n // Until Hammer is loaded, the returned function needs to *cancel* the registration rather\n // than remove anything.\n\n let cancelRegistration = false;\n\n let deregister = () => {\n cancelRegistration = true;\n };\n\n zone.runOutsideAngular(() => this._loaderPromise.then(() => {\n // If Hammer isn't actually loaded when the custom loader resolves, give up.\n if (!window.Hammer) {\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n this.console.warn(`The custom HAMMER_LOADER completed, but Hammer.JS is not present.`);\n }\n\n deregister = () => {};\n\n return;\n }\n\n if (!cancelRegistration) {\n // Now that Hammer is loaded and the listener is being loaded for real,\n // the deregistration function changes from canceling registration to\n // removal.\n deregister = this.addEventListener(element, eventName, handler);\n }\n }).catch(() => {\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n this.console.warn(`The \"${eventName}\" event cannot be bound because the custom ` + `Hammer.JS loader failed.`);\n }\n\n deregister = () => {};\n })); // Return a function that *executes* `deregister` (and not `deregister` itself) so that we\n // can change the behavior of `deregister` once the listener is added. Using a closure in\n // this way allows us to avoid any additional data structures to track listener removal.\n\n return () => {\n deregister();\n };\n }\n\n return zone.runOutsideAngular(() => {\n // Creating the manager bind events, must be done outside of angular\n const mc = this._config.buildHammer(element);\n\n const callback = function (eventObj) {\n zone.runGuarded(function () {\n handler(eventObj);\n });\n };\n\n mc.on(eventName, callback);\n return () => {\n mc.off(eventName, callback); // destroy mc to prevent memory leak\n\n if (typeof mc.destroy === 'function') {\n mc.destroy();\n }\n };\n });\n }\n\n isCustomEvent(eventName) {\n return this._config.events.indexOf(eventName) > -1;\n }\n\n }\n\n HammerGesturesPlugin.ɵfac = function HammerGesturesPlugin_Factory(t) {\n return new (t || HammerGesturesPlugin)(i0.ɵɵinject(DOCUMENT), i0.ɵɵinject(HAMMER_GESTURE_CONFIG), i0.ɵɵinject(i0.ɵConsole), i0.ɵɵinject(HAMMER_LOADER, 8));\n };\n\n HammerGesturesPlugin.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: HammerGesturesPlugin,\n factory: HammerGesturesPlugin.ɵfac\n });\n return HammerGesturesPlugin;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Adds support for HammerJS.\n *\n * Import this module at the root of your application so that Angular can work with\n * HammerJS to detect gesture events.\n *\n * Note that applications still need to include the HammerJS script itself. This module\n * simply sets up the coordination layer between HammerJS and Angular's EventManager.\n *\n * @publicApi\n */\n\n\nlet HammerModule = /*#__PURE__*/(() => {\n class HammerModule {}\n\n HammerModule.ɵfac = function HammerModule_Factory(t) {\n return new (t || HammerModule)();\n };\n\n HammerModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: HammerModule\n });\n HammerModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n providers: [{\n provide: EVENT_MANAGER_PLUGINS,\n useClass: HammerGesturesPlugin,\n multi: true,\n deps: [DOCUMENT, HAMMER_GESTURE_CONFIG, ɵConsole, [new Optional(), HAMMER_LOADER]]\n }, {\n provide: HAMMER_GESTURE_CONFIG,\n useClass: HammerGestureConfig,\n deps: []\n }]\n });\n return HammerModule;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * DomSanitizer helps preventing Cross Site Scripting Security bugs (XSS) by sanitizing\n * values to be safe to use in the different DOM contexts.\n *\n * For example, when binding a URL in an `` hyperlink, `someValue` will be\n * sanitized so that an attacker cannot inject e.g. a `javascript:` URL that would execute code on\n * the website.\n *\n * In specific situations, it might be necessary to disable sanitization, for example if the\n * application genuinely needs to produce a `javascript:` style link with a dynamic value in it.\n * Users can bypass security by constructing a value with one of the `bypassSecurityTrust...`\n * methods, and then binding to that value from the template.\n *\n * These situations should be very rare, and extraordinary care must be taken to avoid creating a\n * Cross Site Scripting (XSS) security bug!\n *\n * When using `bypassSecurityTrust...`, make sure to call the method as early as possible and as\n * close as possible to the source of the value, to make it easy to verify no security bug is\n * created by its use.\n *\n * It is not required (and not recommended) to bypass security if the value is safe, e.g. a URL that\n * does not start with a suspicious protocol, or an HTML snippet that does not contain dangerous\n * code. The sanitizer leaves safe values intact.\n *\n * @security Calling any of the `bypassSecurityTrust...` APIs disables Angular's built-in\n * sanitization for the value passed in. Carefully check and audit all values and code paths going\n * into this call. Make sure any user data is appropriately escaped for this security context.\n * For more detail, see the [Security Guide](https://g.co/ng/security).\n *\n * @publicApi\n */\n\n\nlet DomSanitizer = /*#__PURE__*/(() => {\n class DomSanitizer {}\n\n DomSanitizer.ɵfac = function DomSanitizer_Factory(t) {\n return new (t || DomSanitizer)();\n };\n\n DomSanitizer.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: DomSanitizer,\n factory: function DomSanitizer_Factory(t) {\n let r = null;\n\n if (t) {\n r = new (t || DomSanitizer)();\n } else {\n r = i0.ɵɵinject(DomSanitizerImpl);\n }\n\n return r;\n },\n providedIn: 'root'\n });\n return DomSanitizer;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\nfunction domSanitizerImplFactory(injector) {\n return new DomSanitizerImpl(injector.get(DOCUMENT));\n}\n\nlet DomSanitizerImpl = /*#__PURE__*/(() => {\n class DomSanitizerImpl extends DomSanitizer {\n constructor(_doc) {\n super();\n this._doc = _doc;\n }\n\n sanitize(ctx, value) {\n if (value == null) return null;\n\n switch (ctx) {\n case SecurityContext.NONE:\n return value;\n\n case SecurityContext.HTML:\n if (ɵallowSanitizationBypassAndThrow(value, \"HTML\"\n /* BypassType.Html */\n )) {\n return ɵunwrapSafeValue(value);\n }\n\n return ɵ_sanitizeHtml(this._doc, String(value)).toString();\n\n case SecurityContext.STYLE:\n if (ɵallowSanitizationBypassAndThrow(value, \"Style\"\n /* BypassType.Style */\n )) {\n return ɵunwrapSafeValue(value);\n }\n\n return value;\n\n case SecurityContext.SCRIPT:\n if (ɵallowSanitizationBypassAndThrow(value, \"Script\"\n /* BypassType.Script */\n )) {\n return ɵunwrapSafeValue(value);\n }\n\n throw new Error('unsafe value used in a script context');\n\n case SecurityContext.URL:\n if (ɵallowSanitizationBypassAndThrow(value, \"URL\"\n /* BypassType.Url */\n )) {\n return ɵunwrapSafeValue(value);\n }\n\n return ɵ_sanitizeUrl(String(value));\n\n case SecurityContext.RESOURCE_URL:\n if (ɵallowSanitizationBypassAndThrow(value, \"ResourceURL\"\n /* BypassType.ResourceUrl */\n )) {\n return ɵunwrapSafeValue(value);\n }\n\n throw new Error('unsafe value used in a resource URL context (see https://g.co/ng/security#xss)');\n\n default:\n throw new Error(`Unexpected SecurityContext ${ctx} (see https://g.co/ng/security#xss)`);\n }\n }\n\n bypassSecurityTrustHtml(value) {\n return ɵbypassSanitizationTrustHtml(value);\n }\n\n bypassSecurityTrustStyle(value) {\n return ɵbypassSanitizationTrustStyle(value);\n }\n\n bypassSecurityTrustScript(value) {\n return ɵbypassSanitizationTrustScript(value);\n }\n\n bypassSecurityTrustUrl(value) {\n return ɵbypassSanitizationTrustUrl(value);\n }\n\n bypassSecurityTrustResourceUrl(value) {\n return ɵbypassSanitizationTrustResourceUrl(value);\n }\n\n }\n\n DomSanitizerImpl.ɵfac = function DomSanitizerImpl_Factory(t) {\n return new (t || DomSanitizerImpl)(i0.ɵɵinject(DOCUMENT));\n };\n\n DomSanitizerImpl.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: DomSanitizerImpl,\n factory: function DomSanitizerImpl_Factory(t) {\n let r = null;\n\n if (t) {\n r = new t();\n } else {\n r = domSanitizerImplFactory(i0.ɵɵinject(Injector));\n }\n\n return r;\n },\n providedIn: 'root'\n });\n return DomSanitizerImpl;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @publicApi\n */\n\n\nconst VERSION = /*#__PURE__*/new Version('14.2.3');\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n// This file only reexports content of the `src` folder. Keep it that way.\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Generated bundle index. Do not edit.\n */\n\nexport { BrowserModule, BrowserTransferStateModule, By, DomSanitizer, EVENT_MANAGER_PLUGINS, EventManager, HAMMER_GESTURE_CONFIG, HAMMER_LOADER, HammerGestureConfig, HammerModule, Meta, Title, TransferState, VERSION, bootstrapApplication, createApplication, disableDebugTools, enableDebugTools, makeStateKey, platformBrowser, provideProtractorTestingSupport, BrowserDomAdapter as ɵBrowserDomAdapter, BrowserGetTestability as ɵBrowserGetTestability, DomEventsPlugin as ɵDomEventsPlugin, DomRendererFactory2 as ɵDomRendererFactory2, DomSanitizerImpl as ɵDomSanitizerImpl, DomSharedStylesHost as ɵDomSharedStylesHost, HammerGesturesPlugin as ɵHammerGesturesPlugin, INTERNAL_BROWSER_PLATFORM_PROVIDERS as ɵINTERNAL_BROWSER_PLATFORM_PROVIDERS, KeyEventsPlugin as ɵKeyEventsPlugin, NAMESPACE_URIS as ɵNAMESPACE_URIS, SharedStylesHost as ɵSharedStylesHost, TRANSITION_ID as ɵTRANSITION_ID, escapeHtml as ɵescapeHtml, flattenStyles as ɵflattenStyles, initDomAdapter as ɵinitDomAdapter, shimContentAttribute as ɵshimContentAttribute, shimHostAttribute as ɵshimHostAttribute }; //# sourceMappingURL=platform-browser.mjs.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/214f826e072f44693d90d305d6cc4e25.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/214f826e072f44693d90d305d6cc4e25.json
deleted file mode 100644
index 98e10b81..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/214f826e072f44693d90d305d6cc4e25.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { Subject } from '../Subject';\nimport { asyncScheduler } from '../scheduler/async';\nimport { Subscription } from '../Subscription';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { arrRemove } from '../util/arrRemove';\nimport { popScheduler } from '../util/args';\nimport { executeSchedule } from '../util/executeSchedule';\nexport function windowTime(windowTimeSpan, ...otherArgs) {\n var _a, _b;\n\n const scheduler = (_a = popScheduler(otherArgs)) !== null && _a !== void 0 ? _a : asyncScheduler;\n const windowCreationInterval = (_b = otherArgs[0]) !== null && _b !== void 0 ? _b : null;\n const maxWindowSize = otherArgs[1] || Infinity;\n return operate((source, subscriber) => {\n let windowRecords = [];\n let restartOnClose = false;\n\n const closeWindow = record => {\n const {\n window,\n subs\n } = record;\n window.complete();\n subs.unsubscribe();\n arrRemove(windowRecords, record);\n restartOnClose && startWindow();\n };\n\n const startWindow = () => {\n if (windowRecords) {\n const subs = new Subscription();\n subscriber.add(subs);\n const window = new Subject();\n const record = {\n window,\n subs,\n seen: 0\n };\n windowRecords.push(record);\n subscriber.next(window.asObservable());\n executeSchedule(subs, scheduler, () => closeWindow(record), windowTimeSpan);\n }\n };\n\n if (windowCreationInterval !== null && windowCreationInterval >= 0) {\n executeSchedule(subscriber, scheduler, startWindow, windowCreationInterval, true);\n } else {\n restartOnClose = true;\n }\n\n startWindow();\n\n const loop = cb => windowRecords.slice().forEach(cb);\n\n const terminate = cb => {\n loop(({\n window\n }) => cb(window));\n cb(subscriber);\n subscriber.unsubscribe();\n };\n\n source.subscribe(createOperatorSubscriber(subscriber, value => {\n loop(record => {\n record.window.next(value);\n maxWindowSize <= ++record.seen && closeWindow(record);\n });\n }, () => terminate(consumer => consumer.complete()), err => terminate(consumer => consumer.error(err))));\n return () => {\n windowRecords = null;\n };\n });\n} //# sourceMappingURL=windowTime.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/21ef2ddc0340f19eb55e1849c9a1f65b.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/21ef2ddc0340f19eb55e1849c9a1f65b.json
deleted file mode 100644
index 2c47972a..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/21ef2ddc0340f19eb55e1849c9a1f65b.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { Observable } from '../Observable';\nimport { innerFrom } from '../observable/innerFrom';\nimport { Subject } from '../Subject';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber, OperatorSubscriber } from './OperatorSubscriber';\nexport function groupBy(keySelector, elementOrOptions, duration, connector) {\n return operate((source, subscriber) => {\n let element;\n\n if (!elementOrOptions || typeof elementOrOptions === 'function') {\n element = elementOrOptions;\n } else {\n ({\n duration,\n element,\n connector\n } = elementOrOptions);\n }\n\n const groups = new Map();\n\n const notify = cb => {\n groups.forEach(cb);\n cb(subscriber);\n };\n\n const handleError = err => notify(consumer => consumer.error(err));\n\n let activeGroups = 0;\n let teardownAttempted = false;\n const groupBySourceSubscriber = new OperatorSubscriber(subscriber, value => {\n try {\n const key = keySelector(value);\n let group = groups.get(key);\n\n if (!group) {\n groups.set(key, group = connector ? connector() : new Subject());\n const grouped = createGroupedObservable(key, group);\n subscriber.next(grouped);\n\n if (duration) {\n const durationSubscriber = createOperatorSubscriber(group, () => {\n group.complete();\n durationSubscriber === null || durationSubscriber === void 0 ? void 0 : durationSubscriber.unsubscribe();\n }, undefined, undefined, () => groups.delete(key));\n groupBySourceSubscriber.add(innerFrom(duration(grouped)).subscribe(durationSubscriber));\n }\n }\n\n group.next(element ? element(value) : value);\n } catch (err) {\n handleError(err);\n }\n }, () => notify(consumer => consumer.complete()), handleError, () => groups.clear(), () => {\n teardownAttempted = true;\n return activeGroups === 0;\n });\n source.subscribe(groupBySourceSubscriber);\n\n function createGroupedObservable(key, groupSubject) {\n const result = new Observable(groupSubscriber => {\n activeGroups++;\n const innerSub = groupSubject.subscribe(groupSubscriber);\n return () => {\n innerSub.unsubscribe();\n --activeGroups === 0 && teardownAttempted && groupBySourceSubscriber.unsubscribe();\n };\n });\n result.key = key;\n return result;\n }\n });\n} //# sourceMappingURL=groupBy.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/22a3fbd397174b3155d167193be40c85.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/22a3fbd397174b3155d167193be40c85.json
deleted file mode 100644
index 77813542..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/22a3fbd397174b3155d167193be40c85.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"/**\n * @license Angular v14.2.3\n * (c) 2010-2022 Google LLC. https://angular.io/\n * License: MIT\n */\nimport { ɵAnimationGroupPlayer, NoopAnimationPlayer, AUTO_STYLE, ɵPRE_STYLE, sequence, style } from '@angular/animations';\nimport * as i0 from '@angular/core';\nimport { ɵRuntimeError, Injectable } from '@angular/core';\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nconst LINE_START = '\\n - ';\n\nfunction invalidTimingValue(exp) {\n return new ɵRuntimeError(3000\n /* RuntimeErrorCode.INVALID_TIMING_VALUE */\n , ngDevMode && `The provided timing value \"${exp}\" is invalid.`);\n}\n\nfunction negativeStepValue() {\n return new ɵRuntimeError(3100\n /* RuntimeErrorCode.NEGATIVE_STEP_VALUE */\n , ngDevMode && 'Duration values below 0 are not allowed for this animation step.');\n}\n\nfunction negativeDelayValue() {\n return new ɵRuntimeError(3101\n /* RuntimeErrorCode.NEGATIVE_DELAY_VALUE */\n , ngDevMode && 'Delay values below 0 are not allowed for this animation step.');\n}\n\nfunction invalidStyleParams(varName) {\n return new ɵRuntimeError(3001\n /* RuntimeErrorCode.INVALID_STYLE_PARAMS */\n , ngDevMode && `Unable to resolve the local animation param ${varName} in the given list of values`);\n}\n\nfunction invalidParamValue(varName) {\n return new ɵRuntimeError(3003\n /* RuntimeErrorCode.INVALID_PARAM_VALUE */\n , ngDevMode && `Please provide a value for the animation param ${varName}`);\n}\n\nfunction invalidNodeType(nodeType) {\n return new ɵRuntimeError(3004\n /* RuntimeErrorCode.INVALID_NODE_TYPE */\n , ngDevMode && `Unable to resolve animation metadata node #${nodeType}`);\n}\n\nfunction invalidCssUnitValue(userProvidedProperty, value) {\n return new ɵRuntimeError(3005\n /* RuntimeErrorCode.INVALID_CSS_UNIT_VALUE */\n , ngDevMode && `Please provide a CSS unit value for ${userProvidedProperty}:${value}`);\n}\n\nfunction invalidTrigger() {\n return new ɵRuntimeError(3006\n /* RuntimeErrorCode.INVALID_TRIGGER */\n , ngDevMode && 'animation triggers cannot be prefixed with an `@` sign (e.g. trigger(\\'@foo\\', [...]))');\n}\n\nfunction invalidDefinition() {\n return new ɵRuntimeError(3007\n /* RuntimeErrorCode.INVALID_DEFINITION */\n , ngDevMode && 'only state() and transition() definitions can sit inside of a trigger()');\n}\n\nfunction invalidState(metadataName, missingSubs) {\n return new ɵRuntimeError(3008\n /* RuntimeErrorCode.INVALID_STATE */\n , ngDevMode && `state(\"${metadataName}\", ...) must define default values for all the following style substitutions: ${missingSubs.join(', ')}`);\n}\n\nfunction invalidStyleValue(value) {\n return new ɵRuntimeError(3002\n /* RuntimeErrorCode.INVALID_STYLE_VALUE */\n , ngDevMode && `The provided style string value ${value} is not allowed.`);\n}\n\nfunction invalidProperty(prop) {\n return new ɵRuntimeError(3009\n /* RuntimeErrorCode.INVALID_PROPERTY */\n , ngDevMode && `The provided animation property \"${prop}\" is not a supported CSS property for animations`);\n}\n\nfunction invalidParallelAnimation(prop, firstStart, firstEnd, secondStart, secondEnd) {\n return new ɵRuntimeError(3010\n /* RuntimeErrorCode.INVALID_PARALLEL_ANIMATION */\n , ngDevMode && `The CSS property \"${prop}\" that exists between the times of \"${firstStart}ms\" and \"${firstEnd}ms\" is also being animated in a parallel animation between the times of \"${secondStart}ms\" and \"${secondEnd}ms\"`);\n}\n\nfunction invalidKeyframes() {\n return new ɵRuntimeError(3011\n /* RuntimeErrorCode.INVALID_KEYFRAMES */\n , ngDevMode && `keyframes() must be placed inside of a call to animate()`);\n}\n\nfunction invalidOffset() {\n return new ɵRuntimeError(3012\n /* RuntimeErrorCode.INVALID_OFFSET */\n , ngDevMode && `Please ensure that all keyframe offsets are between 0 and 1`);\n}\n\nfunction keyframeOffsetsOutOfOrder() {\n return new ɵRuntimeError(3200\n /* RuntimeErrorCode.KEYFRAME_OFFSETS_OUT_OF_ORDER */\n , ngDevMode && `Please ensure that all keyframe offsets are in order`);\n}\n\nfunction keyframesMissingOffsets() {\n return new ɵRuntimeError(3202\n /* RuntimeErrorCode.KEYFRAMES_MISSING_OFFSETS */\n , ngDevMode && `Not all style() steps within the declared keyframes() contain offsets`);\n}\n\nfunction invalidStagger() {\n return new ɵRuntimeError(3013\n /* RuntimeErrorCode.INVALID_STAGGER */\n , ngDevMode && `stagger() can only be used inside of query()`);\n}\n\nfunction invalidQuery(selector) {\n return new ɵRuntimeError(3014\n /* RuntimeErrorCode.INVALID_QUERY */\n , ngDevMode && `\\`query(\"${selector}\")\\` returned zero elements. (Use \\`query(\"${selector}\", { optional: true })\\` if you wish to allow this.)`);\n}\n\nfunction invalidExpression(expr) {\n return new ɵRuntimeError(3015\n /* RuntimeErrorCode.INVALID_EXPRESSION */\n , ngDevMode && `The provided transition expression \"${expr}\" is not supported`);\n}\n\nfunction invalidTransitionAlias(alias) {\n return new ɵRuntimeError(3016\n /* RuntimeErrorCode.INVALID_TRANSITION_ALIAS */\n , ngDevMode && `The transition alias value \"${alias}\" is not supported`);\n}\n\nfunction validationFailed(errors) {\n return new ɵRuntimeError(3500\n /* RuntimeErrorCode.VALIDATION_FAILED */\n , ngDevMode && `animation validation failed:\\n${errors.map(err => err.message).join('\\n')}`);\n}\n\nfunction buildingFailed(errors) {\n return new ɵRuntimeError(3501\n /* RuntimeErrorCode.BUILDING_FAILED */\n , ngDevMode && `animation building failed:\\n${errors.map(err => err.message).join('\\n')}`);\n}\n\nfunction triggerBuildFailed(name, errors) {\n return new ɵRuntimeError(3404\n /* RuntimeErrorCode.TRIGGER_BUILD_FAILED */\n , ngDevMode && `The animation trigger \"${name}\" has failed to build due to the following errors:\\n - ${errors.map(err => err.message).join('\\n - ')}`);\n}\n\nfunction animationFailed(errors) {\n return new ɵRuntimeError(3502\n /* RuntimeErrorCode.ANIMATION_FAILED */\n , ngDevMode && `Unable to animate due to the following errors:${LINE_START}${errors.map(err => err.message).join(LINE_START)}`);\n}\n\nfunction registerFailed(errors) {\n return new ɵRuntimeError(3503\n /* RuntimeErrorCode.REGISTRATION_FAILED */\n , ngDevMode && `Unable to build the animation due to the following errors: ${errors.map(err => err.message).join('\\n')}`);\n}\n\nfunction missingOrDestroyedAnimation() {\n return new ɵRuntimeError(3300\n /* RuntimeErrorCode.MISSING_OR_DESTROYED_ANIMATION */\n , ngDevMode && 'The requested animation doesn\\'t exist or has already been destroyed');\n}\n\nfunction createAnimationFailed(errors) {\n return new ɵRuntimeError(3504\n /* RuntimeErrorCode.CREATE_ANIMATION_FAILED */\n , ngDevMode && `Unable to create the animation due to the following errors:${errors.map(err => err.message).join('\\n')}`);\n}\n\nfunction missingPlayer(id) {\n return new ɵRuntimeError(3301\n /* RuntimeErrorCode.MISSING_PLAYER */\n , ngDevMode && `Unable to find the timeline player referenced by ${id}`);\n}\n\nfunction missingTrigger(phase, name) {\n return new ɵRuntimeError(3302\n /* RuntimeErrorCode.MISSING_TRIGGER */\n , ngDevMode && `Unable to listen on the animation trigger event \"${phase}\" because the animation trigger \"${name}\" doesn\\'t exist!`);\n}\n\nfunction missingEvent(name) {\n return new ɵRuntimeError(3303\n /* RuntimeErrorCode.MISSING_EVENT */\n , ngDevMode && `Unable to listen on the animation trigger \"${name}\" because the provided event is undefined!`);\n}\n\nfunction unsupportedTriggerEvent(phase, name) {\n return new ɵRuntimeError(3400\n /* RuntimeErrorCode.UNSUPPORTED_TRIGGER_EVENT */\n , ngDevMode && `The provided animation trigger event \"${phase}\" for the animation trigger \"${name}\" is not supported!`);\n}\n\nfunction unregisteredTrigger(name) {\n return new ɵRuntimeError(3401\n /* RuntimeErrorCode.UNREGISTERED_TRIGGER */\n , ngDevMode && `The provided animation trigger \"${name}\" has not been registered!`);\n}\n\nfunction triggerTransitionsFailed(errors) {\n return new ɵRuntimeError(3402\n /* RuntimeErrorCode.TRIGGER_TRANSITIONS_FAILED */\n , ngDevMode && `Unable to process animations due to the following failed trigger transitions\\n ${errors.map(err => err.message).join('\\n')}`);\n}\n\nfunction triggerParsingFailed(name, errors) {\n return new ɵRuntimeError(3403\n /* RuntimeErrorCode.TRIGGER_PARSING_FAILED */\n , ngDevMode && `Animation parsing for the ${name} trigger have failed:${LINE_START}${errors.map(err => err.message).join(LINE_START)}`);\n}\n\nfunction transitionFailed(name, errors) {\n return new ɵRuntimeError(3505\n /* RuntimeErrorCode.TRANSITION_FAILED */\n , ngDevMode && `@${name} has failed due to:\\n ${errors.map(err => err.message).join('\\n- ')}`);\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Set of all animatable CSS properties\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties\n */\n\n\nconst ANIMATABLE_PROP_SET = /*#__PURE__*/new Set(['-moz-outline-radius', '-moz-outline-radius-bottomleft', '-moz-outline-radius-bottomright', '-moz-outline-radius-topleft', '-moz-outline-radius-topright', '-ms-grid-columns', '-ms-grid-rows', '-webkit-line-clamp', '-webkit-text-fill-color', '-webkit-text-stroke', '-webkit-text-stroke-color', 'accent-color', 'all', 'backdrop-filter', 'background', 'background-color', 'background-position', 'background-size', 'block-size', 'border', 'border-block-end', 'border-block-end-color', 'border-block-end-width', 'border-block-start', 'border-block-start-color', 'border-block-start-width', 'border-bottom', 'border-bottom-color', 'border-bottom-left-radius', 'border-bottom-right-radius', 'border-bottom-width', 'border-color', 'border-end-end-radius', 'border-end-start-radius', 'border-image-outset', 'border-image-slice', 'border-image-width', 'border-inline-end', 'border-inline-end-color', 'border-inline-end-width', 'border-inline-start', 'border-inline-start-color', 'border-inline-start-width', 'border-left', 'border-left-color', 'border-left-width', 'border-radius', 'border-right', 'border-right-color', 'border-right-width', 'border-start-end-radius', 'border-start-start-radius', 'border-top', 'border-top-color', 'border-top-left-radius', 'border-top-right-radius', 'border-top-width', 'border-width', 'bottom', 'box-shadow', 'caret-color', 'clip', 'clip-path', 'color', 'column-count', 'column-gap', 'column-rule', 'column-rule-color', 'column-rule-width', 'column-width', 'columns', 'filter', 'flex', 'flex-basis', 'flex-grow', 'flex-shrink', 'font', 'font-size', 'font-size-adjust', 'font-stretch', 'font-variation-settings', 'font-weight', 'gap', 'grid-column-gap', 'grid-gap', 'grid-row-gap', 'grid-template-columns', 'grid-template-rows', 'height', 'inline-size', 'input-security', 'inset', 'inset-block', 'inset-block-end', 'inset-block-start', 'inset-inline', 'inset-inline-end', 'inset-inline-start', 'left', 'letter-spacing', 'line-clamp', 'line-height', 'margin', 'margin-block-end', 'margin-block-start', 'margin-bottom', 'margin-inline-end', 'margin-inline-start', 'margin-left', 'margin-right', 'margin-top', 'mask', 'mask-border', 'mask-position', 'mask-size', 'max-block-size', 'max-height', 'max-inline-size', 'max-lines', 'max-width', 'min-block-size', 'min-height', 'min-inline-size', 'min-width', 'object-position', 'offset', 'offset-anchor', 'offset-distance', 'offset-path', 'offset-position', 'offset-rotate', 'opacity', 'order', 'outline', 'outline-color', 'outline-offset', 'outline-width', 'padding', 'padding-block-end', 'padding-block-start', 'padding-bottom', 'padding-inline-end', 'padding-inline-start', 'padding-left', 'padding-right', 'padding-top', 'perspective', 'perspective-origin', 'right', 'rotate', 'row-gap', 'scale', 'scroll-margin', 'scroll-margin-block', 'scroll-margin-block-end', 'scroll-margin-block-start', 'scroll-margin-bottom', 'scroll-margin-inline', 'scroll-margin-inline-end', 'scroll-margin-inline-start', 'scroll-margin-left', 'scroll-margin-right', 'scroll-margin-top', 'scroll-padding', 'scroll-padding-block', 'scroll-padding-block-end', 'scroll-padding-block-start', 'scroll-padding-bottom', 'scroll-padding-inline', 'scroll-padding-inline-end', 'scroll-padding-inline-start', 'scroll-padding-left', 'scroll-padding-right', 'scroll-padding-top', 'scroll-snap-coordinate', 'scroll-snap-destination', 'scrollbar-color', 'shape-image-threshold', 'shape-margin', 'shape-outside', 'tab-size', 'text-decoration', 'text-decoration-color', 'text-decoration-thickness', 'text-emphasis', 'text-emphasis-color', 'text-indent', 'text-shadow', 'text-underline-offset', 'top', 'transform', 'transform-origin', 'translate', 'vertical-align', 'visibility', 'width', 'word-spacing', 'z-index', 'zoom']);\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nfunction isBrowser() {\n return typeof window !== 'undefined' && typeof window.document !== 'undefined';\n}\n\nfunction isNode() {\n // Checking only for `process` isn't enough to identify whether or not we're in a Node\n // environment, because Webpack by default will polyfill the `process`. While we can discern\n // that Webpack polyfilled it by looking at `process.browser`, it's very Webpack-specific and\n // might not be future-proof. Instead we look at the stringified version of `process` which\n // is `[object process]` in Node and `[object Object]` when polyfilled.\n return typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';\n}\n\nfunction optimizeGroupPlayer(players) {\n switch (players.length) {\n case 0:\n return new NoopAnimationPlayer();\n\n case 1:\n return players[0];\n\n default:\n return new ɵAnimationGroupPlayer(players);\n }\n}\n\nfunction normalizeKeyframes$1(driver, normalizer, element, keyframes, preStyles = new Map(), postStyles = new Map()) {\n const errors = [];\n const normalizedKeyframes = [];\n let previousOffset = -1;\n let previousKeyframe = null;\n keyframes.forEach(kf => {\n const offset = kf.get('offset');\n const isSameOffset = offset == previousOffset;\n const normalizedKeyframe = isSameOffset && previousKeyframe || new Map();\n kf.forEach((val, prop) => {\n let normalizedProp = prop;\n let normalizedValue = val;\n\n if (prop !== 'offset') {\n normalizedProp = normalizer.normalizePropertyName(normalizedProp, errors);\n\n switch (normalizedValue) {\n case ɵPRE_STYLE:\n normalizedValue = preStyles.get(prop);\n break;\n\n case AUTO_STYLE:\n normalizedValue = postStyles.get(prop);\n break;\n\n default:\n normalizedValue = normalizer.normalizeStyleValue(prop, normalizedProp, normalizedValue, errors);\n break;\n }\n }\n\n normalizedKeyframe.set(normalizedProp, normalizedValue);\n });\n\n if (!isSameOffset) {\n normalizedKeyframes.push(normalizedKeyframe);\n }\n\n previousKeyframe = normalizedKeyframe;\n previousOffset = offset;\n });\n\n if (errors.length) {\n throw animationFailed(errors);\n }\n\n return normalizedKeyframes;\n}\n\nfunction listenOnPlayer(player, eventName, event, callback) {\n switch (eventName) {\n case 'start':\n player.onStart(() => callback(event && copyAnimationEvent(event, 'start', player)));\n break;\n\n case 'done':\n player.onDone(() => callback(event && copyAnimationEvent(event, 'done', player)));\n break;\n\n case 'destroy':\n player.onDestroy(() => callback(event && copyAnimationEvent(event, 'destroy', player)));\n break;\n }\n}\n\nfunction copyAnimationEvent(e, phaseName, player) {\n const totalTime = player.totalTime;\n const disabled = player.disabled ? true : false;\n const event = makeAnimationEvent(e.element, e.triggerName, e.fromState, e.toState, phaseName || e.phaseName, totalTime == undefined ? e.totalTime : totalTime, disabled);\n const data = e['_data'];\n\n if (data != null) {\n event['_data'] = data;\n }\n\n return event;\n}\n\nfunction makeAnimationEvent(element, triggerName, fromState, toState, phaseName = '', totalTime = 0, disabled) {\n return {\n element,\n triggerName,\n fromState,\n toState,\n phaseName,\n totalTime,\n disabled: !!disabled\n };\n}\n\nfunction getOrSetDefaultValue(map, key, defaultValue) {\n let value = map.get(key);\n\n if (!value) {\n map.set(key, value = defaultValue);\n }\n\n return value;\n}\n\nfunction parseTimelineCommand(command) {\n const separatorPos = command.indexOf(':');\n const id = command.substring(1, separatorPos);\n const action = command.slice(separatorPos + 1);\n return [id, action];\n}\n\nlet _contains = (elm1, elm2) => false;\n\nlet _query = (element, selector, multi) => {\n return [];\n};\n\nlet _documentElement = null;\n\nfunction getParentElement(element) {\n const parent = element.parentNode || element.host; // consider host to support shadow DOM\n\n if (parent === _documentElement) {\n return null;\n }\n\n return parent;\n} // Define utility methods for browsers and platform-server(domino) where Element\n// and utility methods exist.\n\n\nconst _isNode = /*#__PURE__*/isNode();\n\nif (_isNode || typeof Element !== 'undefined') {\n if (! /*#__PURE__*/isBrowser()) {\n _contains = (elm1, elm2) => elm1.contains(elm2);\n } else {\n // Read the document element in an IIFE that's been marked pure to avoid a top-level property\n // read that may prevent tree-shaking.\n _documentElement = /* @__PURE__ */(() => document.documentElement)();\n\n _contains = (elm1, elm2) => {\n while (elm2) {\n if (elm2 === elm1) {\n return true;\n }\n\n elm2 = getParentElement(elm2);\n }\n\n return false;\n };\n }\n\n _query = (element, selector, multi) => {\n if (multi) {\n return Array.from(element.querySelectorAll(selector));\n }\n\n const elem = element.querySelector(selector);\n return elem ? [elem] : [];\n };\n}\n\nfunction containsVendorPrefix(prop) {\n // Webkit is the only real popular vendor prefix nowadays\n // cc: http://shouldiprefix.com/\n return prop.substring(1, 6) == 'ebkit'; // webkit or Webkit\n}\n\nlet _CACHED_BODY = null;\nlet _IS_WEBKIT = false;\n\nfunction validateStyleProperty(prop) {\n if (!_CACHED_BODY) {\n _CACHED_BODY = getBodyNode() || {};\n _IS_WEBKIT = _CACHED_BODY.style ? 'WebkitAppearance' in _CACHED_BODY.style : false;\n }\n\n let result = true;\n\n if (_CACHED_BODY.style && !containsVendorPrefix(prop)) {\n result = prop in _CACHED_BODY.style;\n\n if (!result && _IS_WEBKIT) {\n const camelProp = 'Webkit' + prop.charAt(0).toUpperCase() + prop.slice(1);\n result = camelProp in _CACHED_BODY.style;\n }\n }\n\n return result;\n}\n\nfunction validateWebAnimatableStyleProperty(prop) {\n return ANIMATABLE_PROP_SET.has(prop);\n}\n\nfunction getBodyNode() {\n if (typeof document != 'undefined') {\n return document.body;\n }\n\n return null;\n}\n\nconst containsElement = _contains;\nconst invokeQuery = _query;\n\nfunction hypenatePropsKeys(original) {\n const newMap = new Map();\n original.forEach((val, prop) => {\n const newProp = prop.replace(/([a-z])([A-Z])/g, '$1-$2');\n newMap.set(newProp, val);\n });\n return newMap;\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @publicApi\n */\n\n\nlet NoopAnimationDriver = /*#__PURE__*/(() => {\n class NoopAnimationDriver {\n validateStyleProperty(prop) {\n return validateStyleProperty(prop);\n }\n\n matchesElement(_element, _selector) {\n // This method is deprecated and no longer in use so we return false.\n return false;\n }\n\n containsElement(elm1, elm2) {\n return containsElement(elm1, elm2);\n }\n\n getParentElement(element) {\n return getParentElement(element);\n }\n\n query(element, selector, multi) {\n return invokeQuery(element, selector, multi);\n }\n\n computeStyle(element, prop, defaultValue) {\n return defaultValue || '';\n }\n\n animate(element, keyframes, duration, delay, easing, previousPlayers = [], scrubberAccessRequested) {\n return new NoopAnimationPlayer(duration, delay);\n }\n\n }\n\n NoopAnimationDriver.ɵfac = function NoopAnimationDriver_Factory(t) {\n return new (t || NoopAnimationDriver)();\n };\n\n NoopAnimationDriver.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: NoopAnimationDriver,\n factory: NoopAnimationDriver.ɵfac\n });\n return NoopAnimationDriver;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @publicApi\n */\n\n\nlet AnimationDriver = /*#__PURE__*/(() => {\n class AnimationDriver {}\n\n AnimationDriver.NOOP = /* @__PURE__ */new NoopAnimationDriver();\n /**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n return AnimationDriver;\n})();\nconst ONE_SECOND = 1000;\nconst SUBSTITUTION_EXPR_START = '{{';\nconst SUBSTITUTION_EXPR_END = '}}';\nconst ENTER_CLASSNAME = 'ng-enter';\nconst LEAVE_CLASSNAME = 'ng-leave';\nconst NG_TRIGGER_CLASSNAME = 'ng-trigger';\nconst NG_TRIGGER_SELECTOR = '.ng-trigger';\nconst NG_ANIMATING_CLASSNAME = 'ng-animating';\nconst NG_ANIMATING_SELECTOR = '.ng-animating';\n\nfunction resolveTimingValue(value) {\n if (typeof value == 'number') return value;\n const matches = value.match(/^(-?[\\.\\d]+)(m?s)/);\n if (!matches || matches.length < 2) return 0;\n return _convertTimeValueToMS(parseFloat(matches[1]), matches[2]);\n}\n\nfunction _convertTimeValueToMS(value, unit) {\n switch (unit) {\n case 's':\n return value * ONE_SECOND;\n\n default:\n // ms or something else\n return value;\n }\n}\n\nfunction resolveTiming(timings, errors, allowNegativeValues) {\n return timings.hasOwnProperty('duration') ? timings : parseTimeExpression(timings, errors, allowNegativeValues);\n}\n\nfunction parseTimeExpression(exp, errors, allowNegativeValues) {\n const regex = /^(-?[\\.\\d]+)(m?s)(?:\\s+(-?[\\.\\d]+)(m?s))?(?:\\s+([-a-z]+(?:\\(.+?\\))?))?$/i;\n let duration;\n let delay = 0;\n let easing = '';\n\n if (typeof exp === 'string') {\n const matches = exp.match(regex);\n\n if (matches === null) {\n errors.push(invalidTimingValue(exp));\n return {\n duration: 0,\n delay: 0,\n easing: ''\n };\n }\n\n duration = _convertTimeValueToMS(parseFloat(matches[1]), matches[2]);\n const delayMatch = matches[3];\n\n if (delayMatch != null) {\n delay = _convertTimeValueToMS(parseFloat(delayMatch), matches[4]);\n }\n\n const easingVal = matches[5];\n\n if (easingVal) {\n easing = easingVal;\n }\n } else {\n duration = exp;\n }\n\n if (!allowNegativeValues) {\n let containsErrors = false;\n let startIndex = errors.length;\n\n if (duration < 0) {\n errors.push(negativeStepValue());\n containsErrors = true;\n }\n\n if (delay < 0) {\n errors.push(negativeDelayValue());\n containsErrors = true;\n }\n\n if (containsErrors) {\n errors.splice(startIndex, 0, invalidTimingValue(exp));\n }\n }\n\n return {\n duration,\n delay,\n easing\n };\n}\n\nfunction copyObj(obj, destination = {}) {\n Object.keys(obj).forEach(prop => {\n destination[prop] = obj[prop];\n });\n return destination;\n}\n\nfunction convertToMap(obj) {\n const styleMap = new Map();\n Object.keys(obj).forEach(prop => {\n const val = obj[prop];\n styleMap.set(prop, val);\n });\n return styleMap;\n}\n\nfunction normalizeKeyframes(keyframes) {\n if (!keyframes.length) {\n return [];\n }\n\n if (keyframes[0] instanceof Map) {\n return keyframes;\n }\n\n return keyframes.map(kf => convertToMap(kf));\n}\n\nfunction normalizeStyles(styles) {\n const normalizedStyles = new Map();\n\n if (Array.isArray(styles)) {\n styles.forEach(data => copyStyles(data, normalizedStyles));\n } else {\n copyStyles(styles, normalizedStyles);\n }\n\n return normalizedStyles;\n}\n\nfunction copyStyles(styles, destination = new Map(), backfill) {\n if (backfill) {\n for (let [prop, val] of backfill) {\n destination.set(prop, val);\n }\n }\n\n for (let [prop, val] of styles) {\n destination.set(prop, val);\n }\n\n return destination;\n}\n\nfunction getStyleAttributeString(element, key, value) {\n // Return the key-value pair string to be added to the style attribute for the\n // given CSS style key.\n if (value) {\n return key + ':' + value + ';';\n } else {\n return '';\n }\n}\n\nfunction writeStyleAttribute(element) {\n // Read the style property of the element and manually reflect it to the\n // style attribute. This is needed because Domino on platform-server doesn't\n // understand the full set of allowed CSS properties and doesn't reflect some\n // of them automatically.\n let styleAttrValue = '';\n\n for (let i = 0; i < element.style.length; i++) {\n const key = element.style.item(i);\n styleAttrValue += getStyleAttributeString(element, key, element.style.getPropertyValue(key));\n }\n\n for (const key in element.style) {\n // Skip internal Domino properties that don't need to be reflected.\n if (!element.style.hasOwnProperty(key) || key.startsWith('_')) {\n continue;\n }\n\n const dashKey = camelCaseToDashCase(key);\n styleAttrValue += getStyleAttributeString(element, dashKey, element.style[key]);\n }\n\n element.setAttribute('style', styleAttrValue);\n}\n\nfunction setStyles(element, styles, formerStyles) {\n if (element['style']) {\n styles.forEach((val, prop) => {\n const camelProp = dashCaseToCamelCase(prop);\n\n if (formerStyles && !formerStyles.has(prop)) {\n formerStyles.set(prop, element.style[camelProp]);\n }\n\n element.style[camelProp] = val;\n }); // On the server set the 'style' attribute since it's not automatically reflected.\n\n if (isNode()) {\n writeStyleAttribute(element);\n }\n }\n}\n\nfunction eraseStyles(element, styles) {\n if (element['style']) {\n styles.forEach((_, prop) => {\n const camelProp = dashCaseToCamelCase(prop);\n element.style[camelProp] = '';\n }); // On the server set the 'style' attribute since it's not automatically reflected.\n\n if (isNode()) {\n writeStyleAttribute(element);\n }\n }\n}\n\nfunction normalizeAnimationEntry(steps) {\n if (Array.isArray(steps)) {\n if (steps.length == 1) return steps[0];\n return sequence(steps);\n }\n\n return steps;\n}\n\nfunction validateStyleParams(value, options, errors) {\n const params = options.params || {};\n const matches = extractStyleParams(value);\n\n if (matches.length) {\n matches.forEach(varName => {\n if (!params.hasOwnProperty(varName)) {\n errors.push(invalidStyleParams(varName));\n }\n });\n }\n}\n\nconst PARAM_REGEX = /*#__PURE__*/new RegExp(`${SUBSTITUTION_EXPR_START}\\\\s*(.+?)\\\\s*${SUBSTITUTION_EXPR_END}`, 'g');\n\nfunction extractStyleParams(value) {\n let params = [];\n\n if (typeof value === 'string') {\n let match;\n\n while (match = PARAM_REGEX.exec(value)) {\n params.push(match[1]);\n }\n\n PARAM_REGEX.lastIndex = 0;\n }\n\n return params;\n}\n\nfunction interpolateParams(value, params, errors) {\n const original = value.toString();\n const str = original.replace(PARAM_REGEX, (_, varName) => {\n let localVal = params[varName]; // this means that the value was never overridden by the data passed in by the user\n\n if (localVal == null) {\n errors.push(invalidParamValue(varName));\n localVal = '';\n }\n\n return localVal.toString();\n }); // we do this to assert that numeric values stay as they are\n\n return str == original ? value : str;\n}\n\nfunction iteratorToArray(iterator) {\n const arr = [];\n let item = iterator.next();\n\n while (!item.done) {\n arr.push(item.value);\n item = iterator.next();\n }\n\n return arr;\n}\n\nconst DASH_CASE_REGEXP = /-+([a-z0-9])/g;\n\nfunction dashCaseToCamelCase(input) {\n return input.replace(DASH_CASE_REGEXP, (...m) => m[1].toUpperCase());\n}\n\nfunction camelCaseToDashCase(input) {\n return input.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n}\n\nfunction allowPreviousPlayerStylesMerge(duration, delay) {\n return duration === 0 || delay === 0;\n}\n\nfunction balancePreviousStylesIntoKeyframes(element, keyframes, previousStyles) {\n if (previousStyles.size && keyframes.length) {\n let startingKeyframe = keyframes[0];\n let missingStyleProps = [];\n previousStyles.forEach((val, prop) => {\n if (!startingKeyframe.has(prop)) {\n missingStyleProps.push(prop);\n }\n\n startingKeyframe.set(prop, val);\n });\n\n if (missingStyleProps.length) {\n for (let i = 1; i < keyframes.length; i++) {\n let kf = keyframes[i];\n missingStyleProps.forEach(prop => kf.set(prop, computeStyle(element, prop)));\n }\n }\n }\n\n return keyframes;\n}\n\nfunction visitDslNode(visitor, node, context) {\n switch (node.type) {\n case 7\n /* AnimationMetadataType.Trigger */\n :\n return visitor.visitTrigger(node, context);\n\n case 0\n /* AnimationMetadataType.State */\n :\n return visitor.visitState(node, context);\n\n case 1\n /* AnimationMetadataType.Transition */\n :\n return visitor.visitTransition(node, context);\n\n case 2\n /* AnimationMetadataType.Sequence */\n :\n return visitor.visitSequence(node, context);\n\n case 3\n /* AnimationMetadataType.Group */\n :\n return visitor.visitGroup(node, context);\n\n case 4\n /* AnimationMetadataType.Animate */\n :\n return visitor.visitAnimate(node, context);\n\n case 5\n /* AnimationMetadataType.Keyframes */\n :\n return visitor.visitKeyframes(node, context);\n\n case 6\n /* AnimationMetadataType.Style */\n :\n return visitor.visitStyle(node, context);\n\n case 8\n /* AnimationMetadataType.Reference */\n :\n return visitor.visitReference(node, context);\n\n case 9\n /* AnimationMetadataType.AnimateChild */\n :\n return visitor.visitAnimateChild(node, context);\n\n case 10\n /* AnimationMetadataType.AnimateRef */\n :\n return visitor.visitAnimateRef(node, context);\n\n case 11\n /* AnimationMetadataType.Query */\n :\n return visitor.visitQuery(node, context);\n\n case 12\n /* AnimationMetadataType.Stagger */\n :\n return visitor.visitStagger(node, context);\n\n default:\n throw invalidNodeType(node.type);\n }\n}\n\nfunction computeStyle(element, prop) {\n return window.getComputedStyle(element)[prop];\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nconst NG_DEV_MODE = typeof ngDevMode === 'undefined' || !!ngDevMode;\n\nfunction createListOfWarnings(warnings) {\n const LINE_START = '\\n - ';\n return `${LINE_START}${warnings.filter(Boolean).map(warning => warning).join(LINE_START)}`;\n}\n\nfunction warnValidation(warnings) {\n NG_DEV_MODE && console.warn(`animation validation warnings:${createListOfWarnings(warnings)}`);\n}\n\nfunction warnTriggerBuild(name, warnings) {\n NG_DEV_MODE && console.warn(`The animation trigger \"${name}\" has built with the following warnings:${createListOfWarnings(warnings)}`);\n}\n\nfunction warnRegister(warnings) {\n NG_DEV_MODE && console.warn(`Animation built with the following warnings:${createListOfWarnings(warnings)}`);\n}\n\nfunction triggerParsingWarnings(name, warnings) {\n NG_DEV_MODE && console.warn(`Animation parsing for the ${name} trigger presents the following warnings:${createListOfWarnings(warnings)}`);\n}\n\nfunction pushUnrecognizedPropertiesWarning(warnings, props) {\n if (props.length) {\n warnings.push(`The following provided properties are not recognized: ${props.join(', ')}`);\n }\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nconst ANY_STATE = '*';\n\nfunction parseTransitionExpr(transitionValue, errors) {\n const expressions = [];\n\n if (typeof transitionValue == 'string') {\n transitionValue.split(/\\s*,\\s*/).forEach(str => parseInnerTransitionStr(str, expressions, errors));\n } else {\n expressions.push(transitionValue);\n }\n\n return expressions;\n}\n\nfunction parseInnerTransitionStr(eventStr, expressions, errors) {\n if (eventStr[0] == ':') {\n const result = parseAnimationAlias(eventStr, errors);\n\n if (typeof result == 'function') {\n expressions.push(result);\n return;\n }\n\n eventStr = result;\n }\n\n const match = eventStr.match(/^(\\*|[-\\w]+)\\s*([=-]>)\\s*(\\*|[-\\w]+)$/);\n\n if (match == null || match.length < 4) {\n errors.push(invalidExpression(eventStr));\n return expressions;\n }\n\n const fromState = match[1];\n const separator = match[2];\n const toState = match[3];\n expressions.push(makeLambdaFromStates(fromState, toState));\n const isFullAnyStateExpr = fromState == ANY_STATE && toState == ANY_STATE;\n\n if (separator[0] == '<' && !isFullAnyStateExpr) {\n expressions.push(makeLambdaFromStates(toState, fromState));\n }\n}\n\nfunction parseAnimationAlias(alias, errors) {\n switch (alias) {\n case ':enter':\n return 'void => *';\n\n case ':leave':\n return '* => void';\n\n case ':increment':\n return (fromState, toState) => parseFloat(toState) > parseFloat(fromState);\n\n case ':decrement':\n return (fromState, toState) => parseFloat(toState) < parseFloat(fromState);\n\n default:\n errors.push(invalidTransitionAlias(alias));\n return '* => *';\n }\n} // DO NOT REFACTOR ... keep the follow set instantiations\n// with the values intact (closure compiler for some reason\n// removes follow-up lines that add the values outside of\n// the constructor...\n\n\nconst TRUE_BOOLEAN_VALUES = /*#__PURE__*/new Set(['true', '1']);\nconst FALSE_BOOLEAN_VALUES = /*#__PURE__*/new Set(['false', '0']);\n\nfunction makeLambdaFromStates(lhs, rhs) {\n const LHS_MATCH_BOOLEAN = TRUE_BOOLEAN_VALUES.has(lhs) || FALSE_BOOLEAN_VALUES.has(lhs);\n const RHS_MATCH_BOOLEAN = TRUE_BOOLEAN_VALUES.has(rhs) || FALSE_BOOLEAN_VALUES.has(rhs);\n return (fromState, toState) => {\n let lhsMatch = lhs == ANY_STATE || lhs == fromState;\n let rhsMatch = rhs == ANY_STATE || rhs == toState;\n\n if (!lhsMatch && LHS_MATCH_BOOLEAN && typeof fromState === 'boolean') {\n lhsMatch = fromState ? TRUE_BOOLEAN_VALUES.has(lhs) : FALSE_BOOLEAN_VALUES.has(lhs);\n }\n\n if (!rhsMatch && RHS_MATCH_BOOLEAN && typeof toState === 'boolean') {\n rhsMatch = toState ? TRUE_BOOLEAN_VALUES.has(rhs) : FALSE_BOOLEAN_VALUES.has(rhs);\n }\n\n return lhsMatch && rhsMatch;\n };\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nconst SELF_TOKEN = ':self';\nconst SELF_TOKEN_REGEX = /*#__PURE__*/new RegExp(`\\s*${SELF_TOKEN}\\s*,?`, 'g');\n/*\n * [Validation]\n * The visitor code below will traverse the animation AST generated by the animation verb functions\n * (the output is a tree of objects) and attempt to perform a series of validations on the data. The\n * following corner-cases will be validated:\n *\n * 1. Overlap of animations\n * Given that a CSS property cannot be animated in more than one place at the same time, it's\n * important that this behavior is detected and validated. The way in which this occurs is that\n * each time a style property is examined, a string-map containing the property will be updated with\n * the start and end times for when the property is used within an animation step.\n *\n * If there are two or more parallel animations that are currently running (these are invoked by the\n * group()) on the same element then the validator will throw an error. Since the start/end timing\n * values are collected for each property then if the current animation step is animating the same\n * property and its timing values fall anywhere into the window of time that the property is\n * currently being animated within then this is what causes an error.\n *\n * 2. Timing values\n * The validator will validate to see if a timing value of `duration delay easing` or\n * `durationNumber` is valid or not.\n *\n * (note that upon validation the code below will replace the timing data with an object containing\n * {duration,delay,easing}.\n *\n * 3. Offset Validation\n * Each of the style() calls are allowed to have an offset value when placed inside of keyframes().\n * Offsets within keyframes() are considered valid when:\n *\n * - No offsets are used at all\n * - Each style() entry contains an offset value\n * - Each offset is between 0 and 1\n * - Each offset is greater to or equal than the previous one\n *\n * Otherwise an error will be thrown.\n */\n\nfunction buildAnimationAst(driver, metadata, errors, warnings) {\n return new AnimationAstBuilderVisitor(driver).build(metadata, errors, warnings);\n}\n\nconst ROOT_SELECTOR = '';\n\nclass AnimationAstBuilderVisitor {\n constructor(_driver) {\n this._driver = _driver;\n }\n\n build(metadata, errors, warnings) {\n const context = new AnimationAstBuilderContext(errors);\n\n this._resetContextStyleTimingState(context);\n\n const ast = visitDslNode(this, normalizeAnimationEntry(metadata), context);\n\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n if (context.unsupportedCSSPropertiesFound.size) {\n pushUnrecognizedPropertiesWarning(warnings, [...context.unsupportedCSSPropertiesFound.keys()]);\n }\n }\n\n return ast;\n }\n\n _resetContextStyleTimingState(context) {\n context.currentQuerySelector = ROOT_SELECTOR;\n context.collectedStyles = new Map();\n context.collectedStyles.set(ROOT_SELECTOR, new Map());\n context.currentTime = 0;\n }\n\n visitTrigger(metadata, context) {\n let queryCount = context.queryCount = 0;\n let depCount = context.depCount = 0;\n const states = [];\n const transitions = [];\n\n if (metadata.name.charAt(0) == '@') {\n context.errors.push(invalidTrigger());\n }\n\n metadata.definitions.forEach(def => {\n this._resetContextStyleTimingState(context);\n\n if (def.type == 0\n /* AnimationMetadataType.State */\n ) {\n const stateDef = def;\n const name = stateDef.name;\n name.toString().split(/\\s*,\\s*/).forEach(n => {\n stateDef.name = n;\n states.push(this.visitState(stateDef, context));\n });\n stateDef.name = name;\n } else if (def.type == 1\n /* AnimationMetadataType.Transition */\n ) {\n const transition = this.visitTransition(def, context);\n queryCount += transition.queryCount;\n depCount += transition.depCount;\n transitions.push(transition);\n } else {\n context.errors.push(invalidDefinition());\n }\n });\n return {\n type: 7\n /* AnimationMetadataType.Trigger */\n ,\n name: metadata.name,\n states,\n transitions,\n queryCount,\n depCount,\n options: null\n };\n }\n\n visitState(metadata, context) {\n const styleAst = this.visitStyle(metadata.styles, context);\n const astParams = metadata.options && metadata.options.params || null;\n\n if (styleAst.containsDynamicStyles) {\n const missingSubs = new Set();\n const params = astParams || {};\n styleAst.styles.forEach(style => {\n if (style instanceof Map) {\n style.forEach(value => {\n extractStyleParams(value).forEach(sub => {\n if (!params.hasOwnProperty(sub)) {\n missingSubs.add(sub);\n }\n });\n });\n }\n });\n\n if (missingSubs.size) {\n const missingSubsArr = iteratorToArray(missingSubs.values());\n context.errors.push(invalidState(metadata.name, missingSubsArr));\n }\n }\n\n return {\n type: 0\n /* AnimationMetadataType.State */\n ,\n name: metadata.name,\n style: styleAst,\n options: astParams ? {\n params: astParams\n } : null\n };\n }\n\n visitTransition(metadata, context) {\n context.queryCount = 0;\n context.depCount = 0;\n const animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);\n const matchers = parseTransitionExpr(metadata.expr, context.errors);\n return {\n type: 1\n /* AnimationMetadataType.Transition */\n ,\n matchers,\n animation,\n queryCount: context.queryCount,\n depCount: context.depCount,\n options: normalizeAnimationOptions(metadata.options)\n };\n }\n\n visitSequence(metadata, context) {\n return {\n type: 2\n /* AnimationMetadataType.Sequence */\n ,\n steps: metadata.steps.map(s => visitDslNode(this, s, context)),\n options: normalizeAnimationOptions(metadata.options)\n };\n }\n\n visitGroup(metadata, context) {\n const currentTime = context.currentTime;\n let furthestTime = 0;\n const steps = metadata.steps.map(step => {\n context.currentTime = currentTime;\n const innerAst = visitDslNode(this, step, context);\n furthestTime = Math.max(furthestTime, context.currentTime);\n return innerAst;\n });\n context.currentTime = furthestTime;\n return {\n type: 3\n /* AnimationMetadataType.Group */\n ,\n steps,\n options: normalizeAnimationOptions(metadata.options)\n };\n }\n\n visitAnimate(metadata, context) {\n const timingAst = constructTimingAst(metadata.timings, context.errors);\n context.currentAnimateTimings = timingAst;\n let styleAst;\n let styleMetadata = metadata.styles ? metadata.styles : style({});\n\n if (styleMetadata.type == 5\n /* AnimationMetadataType.Keyframes */\n ) {\n styleAst = this.visitKeyframes(styleMetadata, context);\n } else {\n let styleMetadata = metadata.styles;\n let isEmpty = false;\n\n if (!styleMetadata) {\n isEmpty = true;\n const newStyleData = {};\n\n if (timingAst.easing) {\n newStyleData['easing'] = timingAst.easing;\n }\n\n styleMetadata = style(newStyleData);\n }\n\n context.currentTime += timingAst.duration + timingAst.delay;\n\n const _styleAst = this.visitStyle(styleMetadata, context);\n\n _styleAst.isEmptyStep = isEmpty;\n styleAst = _styleAst;\n }\n\n context.currentAnimateTimings = null;\n return {\n type: 4\n /* AnimationMetadataType.Animate */\n ,\n timings: timingAst,\n style: styleAst,\n options: null\n };\n }\n\n visitStyle(metadata, context) {\n const ast = this._makeStyleAst(metadata, context);\n\n this._validateStyleAst(ast, context);\n\n return ast;\n }\n\n _makeStyleAst(metadata, context) {\n const styles = [];\n const metadataStyles = Array.isArray(metadata.styles) ? metadata.styles : [metadata.styles];\n\n for (let styleTuple of metadataStyles) {\n if (typeof styleTuple === 'string') {\n if (styleTuple === AUTO_STYLE) {\n styles.push(styleTuple);\n } else {\n context.errors.push(invalidStyleValue(styleTuple));\n }\n } else {\n styles.push(convertToMap(styleTuple));\n }\n }\n\n let containsDynamicStyles = false;\n let collectedEasing = null;\n styles.forEach(styleData => {\n if (styleData instanceof Map) {\n if (styleData.has('easing')) {\n collectedEasing = styleData.get('easing');\n styleData.delete('easing');\n }\n\n if (!containsDynamicStyles) {\n for (let value of styleData.values()) {\n if (value.toString().indexOf(SUBSTITUTION_EXPR_START) >= 0) {\n containsDynamicStyles = true;\n break;\n }\n }\n }\n }\n });\n return {\n type: 6\n /* AnimationMetadataType.Style */\n ,\n styles,\n easing: collectedEasing,\n offset: metadata.offset,\n containsDynamicStyles,\n options: null\n };\n }\n\n _validateStyleAst(ast, context) {\n const timings = context.currentAnimateTimings;\n let endTime = context.currentTime;\n let startTime = context.currentTime;\n\n if (timings && startTime > 0) {\n startTime -= timings.duration + timings.delay;\n }\n\n ast.styles.forEach(tuple => {\n if (typeof tuple === 'string') return;\n tuple.forEach((value, prop) => {\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n if (!this._driver.validateStyleProperty(prop)) {\n tuple.delete(prop);\n context.unsupportedCSSPropertiesFound.add(prop);\n return;\n }\n } // This is guaranteed to have a defined Map at this querySelector location making it\n // safe to add the assertion here. It is set as a default empty map in prior methods.\n\n\n const collectedStyles = context.collectedStyles.get(context.currentQuerySelector);\n const collectedEntry = collectedStyles.get(prop);\n let updateCollectedStyle = true;\n\n if (collectedEntry) {\n if (startTime != endTime && startTime >= collectedEntry.startTime && endTime <= collectedEntry.endTime) {\n context.errors.push(invalidParallelAnimation(prop, collectedEntry.startTime, collectedEntry.endTime, startTime, endTime));\n updateCollectedStyle = false;\n } // we always choose the smaller start time value since we\n // want to have a record of the entire animation window where\n // the style property is being animated in between\n\n\n startTime = collectedEntry.startTime;\n }\n\n if (updateCollectedStyle) {\n collectedStyles.set(prop, {\n startTime,\n endTime\n });\n }\n\n if (context.options) {\n validateStyleParams(value, context.options, context.errors);\n }\n });\n });\n }\n\n visitKeyframes(metadata, context) {\n const ast = {\n type: 5\n /* AnimationMetadataType.Keyframes */\n ,\n styles: [],\n options: null\n };\n\n if (!context.currentAnimateTimings) {\n context.errors.push(invalidKeyframes());\n return ast;\n }\n\n const MAX_KEYFRAME_OFFSET = 1;\n let totalKeyframesWithOffsets = 0;\n const offsets = [];\n let offsetsOutOfOrder = false;\n let keyframesOutOfRange = false;\n let previousOffset = 0;\n const keyframes = metadata.steps.map(styles => {\n const style = this._makeStyleAst(styles, context);\n\n let offsetVal = style.offset != null ? style.offset : consumeOffset(style.styles);\n let offset = 0;\n\n if (offsetVal != null) {\n totalKeyframesWithOffsets++;\n offset = style.offset = offsetVal;\n }\n\n keyframesOutOfRange = keyframesOutOfRange || offset < 0 || offset > 1;\n offsetsOutOfOrder = offsetsOutOfOrder || offset < previousOffset;\n previousOffset = offset;\n offsets.push(offset);\n return style;\n });\n\n if (keyframesOutOfRange) {\n context.errors.push(invalidOffset());\n }\n\n if (offsetsOutOfOrder) {\n context.errors.push(keyframeOffsetsOutOfOrder());\n }\n\n const length = metadata.steps.length;\n let generatedOffset = 0;\n\n if (totalKeyframesWithOffsets > 0 && totalKeyframesWithOffsets < length) {\n context.errors.push(keyframesMissingOffsets());\n } else if (totalKeyframesWithOffsets == 0) {\n generatedOffset = MAX_KEYFRAME_OFFSET / (length - 1);\n }\n\n const limit = length - 1;\n const currentTime = context.currentTime;\n const currentAnimateTimings = context.currentAnimateTimings;\n const animateDuration = currentAnimateTimings.duration;\n keyframes.forEach((kf, i) => {\n const offset = generatedOffset > 0 ? i == limit ? 1 : generatedOffset * i : offsets[i];\n const durationUpToThisFrame = offset * animateDuration;\n context.currentTime = currentTime + currentAnimateTimings.delay + durationUpToThisFrame;\n currentAnimateTimings.duration = durationUpToThisFrame;\n\n this._validateStyleAst(kf, context);\n\n kf.offset = offset;\n ast.styles.push(kf);\n });\n return ast;\n }\n\n visitReference(metadata, context) {\n return {\n type: 8\n /* AnimationMetadataType.Reference */\n ,\n animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context),\n options: normalizeAnimationOptions(metadata.options)\n };\n }\n\n visitAnimateChild(metadata, context) {\n context.depCount++;\n return {\n type: 9\n /* AnimationMetadataType.AnimateChild */\n ,\n options: normalizeAnimationOptions(metadata.options)\n };\n }\n\n visitAnimateRef(metadata, context) {\n return {\n type: 10\n /* AnimationMetadataType.AnimateRef */\n ,\n animation: this.visitReference(metadata.animation, context),\n options: normalizeAnimationOptions(metadata.options)\n };\n }\n\n visitQuery(metadata, context) {\n const parentSelector = context.currentQuerySelector;\n const options = metadata.options || {};\n context.queryCount++;\n context.currentQuery = metadata;\n const [selector, includeSelf] = normalizeSelector(metadata.selector);\n context.currentQuerySelector = parentSelector.length ? parentSelector + ' ' + selector : selector;\n getOrSetDefaultValue(context.collectedStyles, context.currentQuerySelector, new Map());\n const animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);\n context.currentQuery = null;\n context.currentQuerySelector = parentSelector;\n return {\n type: 11\n /* AnimationMetadataType.Query */\n ,\n selector,\n limit: options.limit || 0,\n optional: !!options.optional,\n includeSelf,\n animation,\n originalSelector: metadata.selector,\n options: normalizeAnimationOptions(metadata.options)\n };\n }\n\n visitStagger(metadata, context) {\n if (!context.currentQuery) {\n context.errors.push(invalidStagger());\n }\n\n const timings = metadata.timings === 'full' ? {\n duration: 0,\n delay: 0,\n easing: 'full'\n } : resolveTiming(metadata.timings, context.errors, true);\n return {\n type: 12\n /* AnimationMetadataType.Stagger */\n ,\n animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context),\n timings,\n options: null\n };\n }\n\n}\n\nfunction normalizeSelector(selector) {\n const hasAmpersand = selector.split(/\\s*,\\s*/).find(token => token == SELF_TOKEN) ? true : false;\n\n if (hasAmpersand) {\n selector = selector.replace(SELF_TOKEN_REGEX, '');\n } // Note: the :enter and :leave aren't normalized here since those\n // selectors are filled in at runtime during timeline building\n\n\n selector = selector.replace(/@\\*/g, NG_TRIGGER_SELECTOR).replace(/@\\w+/g, match => NG_TRIGGER_SELECTOR + '-' + match.slice(1)).replace(/:animating/g, NG_ANIMATING_SELECTOR);\n return [selector, hasAmpersand];\n}\n\nfunction normalizeParams(obj) {\n return obj ? copyObj(obj) : null;\n}\n\nclass AnimationAstBuilderContext {\n constructor(errors) {\n this.errors = errors;\n this.queryCount = 0;\n this.depCount = 0;\n this.currentTransition = null;\n this.currentQuery = null;\n this.currentQuerySelector = null;\n this.currentAnimateTimings = null;\n this.currentTime = 0;\n this.collectedStyles = new Map();\n this.options = null;\n this.unsupportedCSSPropertiesFound = new Set();\n }\n\n}\n\nfunction consumeOffset(styles) {\n if (typeof styles == 'string') return null;\n let offset = null;\n\n if (Array.isArray(styles)) {\n styles.forEach(styleTuple => {\n if (styleTuple instanceof Map && styleTuple.has('offset')) {\n const obj = styleTuple;\n offset = parseFloat(obj.get('offset'));\n obj.delete('offset');\n }\n });\n } else if (styles instanceof Map && styles.has('offset')) {\n const obj = styles;\n offset = parseFloat(obj.get('offset'));\n obj.delete('offset');\n }\n\n return offset;\n}\n\nfunction constructTimingAst(value, errors) {\n if (value.hasOwnProperty('duration')) {\n return value;\n }\n\n if (typeof value == 'number') {\n const duration = resolveTiming(value, errors).duration;\n return makeTimingAst(duration, 0, '');\n }\n\n const strValue = value;\n const isDynamic = strValue.split(/\\s+/).some(v => v.charAt(0) == '{' && v.charAt(1) == '{');\n\n if (isDynamic) {\n const ast = makeTimingAst(0, 0, '');\n ast.dynamic = true;\n ast.strValue = strValue;\n return ast;\n }\n\n const timings = resolveTiming(strValue, errors);\n return makeTimingAst(timings.duration, timings.delay, timings.easing);\n}\n\nfunction normalizeAnimationOptions(options) {\n if (options) {\n options = copyObj(options);\n\n if (options['params']) {\n options['params'] = normalizeParams(options['params']);\n }\n } else {\n options = {};\n }\n\n return options;\n}\n\nfunction makeTimingAst(duration, delay, easing) {\n return {\n duration,\n delay,\n easing\n };\n}\n\nfunction createTimelineInstruction(element, keyframes, preStyleProps, postStyleProps, duration, delay, easing = null, subTimeline = false) {\n return {\n type: 1\n /* AnimationTransitionInstructionType.TimelineAnimation */\n ,\n element,\n keyframes,\n preStyleProps,\n postStyleProps,\n duration,\n delay,\n totalTime: duration + delay,\n easing,\n subTimeline\n };\n}\n\nclass ElementInstructionMap {\n constructor() {\n this._map = new Map();\n }\n\n get(element) {\n return this._map.get(element) || [];\n }\n\n append(element, instructions) {\n let existingInstructions = this._map.get(element);\n\n if (!existingInstructions) {\n this._map.set(element, existingInstructions = []);\n }\n\n existingInstructions.push(...instructions);\n }\n\n has(element) {\n return this._map.has(element);\n }\n\n clear() {\n this._map.clear();\n }\n\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nconst ONE_FRAME_IN_MILLISECONDS = 1;\nconst ENTER_TOKEN = ':enter';\nconst ENTER_TOKEN_REGEX = /*#__PURE__*/new RegExp(ENTER_TOKEN, 'g');\nconst LEAVE_TOKEN = ':leave';\nconst LEAVE_TOKEN_REGEX = /*#__PURE__*/new RegExp(LEAVE_TOKEN, 'g');\n/*\n * The code within this file aims to generate web-animations-compatible keyframes from Angular's\n * animation DSL code.\n *\n * The code below will be converted from:\n *\n * ```\n * sequence([\n * style({ opacity: 0 }),\n * animate(1000, style({ opacity: 0 }))\n * ])\n * ```\n *\n * To:\n * ```\n * keyframes = [{ opacity: 0, offset: 0 }, { opacity: 1, offset: 1 }]\n * duration = 1000\n * delay = 0\n * easing = ''\n * ```\n *\n * For this operation to cover the combination of animation verbs (style, animate, group, etc...) a\n * combination of AST traversal and merge-sort-like algorithms are used.\n *\n * [AST Traversal]\n * Each of the animation verbs, when executed, will return an string-map object representing what\n * type of action it is (style, animate, group, etc...) and the data associated with it. This means\n * that when functional composition mix of these functions is evaluated (like in the example above)\n * then it will end up producing a tree of objects representing the animation itself.\n *\n * When this animation object tree is processed by the visitor code below it will visit each of the\n * verb statements within the visitor. And during each visit it will build the context of the\n * animation keyframes by interacting with the `TimelineBuilder`.\n *\n * [TimelineBuilder]\n * This class is responsible for tracking the styles and building a series of keyframe objects for a\n * timeline between a start and end time. The builder starts off with an initial timeline and each\n * time the AST comes across a `group()`, `keyframes()` or a combination of the two within a\n * `sequence()` then it will generate a sub timeline for each step as well as a new one after\n * they are complete.\n *\n * As the AST is traversed, the timing state on each of the timelines will be incremented. If a sub\n * timeline was created (based on one of the cases above) then the parent timeline will attempt to\n * merge the styles used within the sub timelines into itself (only with group() this will happen).\n * This happens with a merge operation (much like how the merge works in mergeSort) and it will only\n * copy the most recently used styles from the sub timelines into the parent timeline. This ensures\n * that if the styles are used later on in another phase of the animation then they will be the most\n * up-to-date values.\n *\n * [How Missing Styles Are Updated]\n * Each timeline has a `backFill` property which is responsible for filling in new styles into\n * already processed keyframes if a new style shows up later within the animation sequence.\n *\n * ```\n * sequence([\n * style({ width: 0 }),\n * animate(1000, style({ width: 100 })),\n * animate(1000, style({ width: 200 })),\n * animate(1000, style({ width: 300 }))\n * animate(1000, style({ width: 400, height: 400 })) // notice how `height` doesn't exist anywhere\n * else\n * ])\n * ```\n *\n * What is happening here is that the `height` value is added later in the sequence, but is missing\n * from all previous animation steps. Therefore when a keyframe is created it would also be missing\n * from all previous keyframes up until where it is first used. For the timeline keyframe generation\n * to properly fill in the style it will place the previous value (the value from the parent\n * timeline) or a default value of `*` into the backFill map. The `copyStyles` method in util.ts\n * handles propagating that backfill map to the styles object.\n *\n * When a sub-timeline is created it will have its own backFill property. This is done so that\n * styles present within the sub-timeline do not accidentally seep into the previous/future timeline\n * keyframes\n *\n * [Validation]\n * The code in this file is not responsible for validation. That functionality happens with within\n * the `AnimationValidatorVisitor` code.\n */\n\nfunction buildAnimationTimelines(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles = new Map(), finalStyles = new Map(), options, subInstructions, errors = []) {\n return new AnimationTimelineBuilderVisitor().buildKeyframes(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors);\n}\n\nclass AnimationTimelineBuilderVisitor {\n buildKeyframes(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors = []) {\n subInstructions = subInstructions || new ElementInstructionMap();\n const context = new AnimationTimelineContext(driver, rootElement, subInstructions, enterClassName, leaveClassName, errors, []);\n context.options = options;\n const delay = options.delay ? resolveTimingValue(options.delay) : 0;\n context.currentTimeline.delayNextStep(delay);\n context.currentTimeline.setStyles([startingStyles], null, context.errors, options);\n visitDslNode(this, ast, context); // this checks to see if an actual animation happened\n\n const timelines = context.timelines.filter(timeline => timeline.containsAnimation()); // note: we just want to apply the final styles for the rootElement, so we do not\n // just apply the styles to the last timeline but the last timeline which\n // element is the root one (basically `*`-styles are replaced with the actual\n // state style values only for the root element)\n\n if (timelines.length && finalStyles.size) {\n let lastRootTimeline;\n\n for (let i = timelines.length - 1; i >= 0; i--) {\n const timeline = timelines[i];\n\n if (timeline.element === rootElement) {\n lastRootTimeline = timeline;\n break;\n }\n }\n\n if (lastRootTimeline && !lastRootTimeline.allowOnlyTimelineStyles()) {\n lastRootTimeline.setStyles([finalStyles], null, context.errors, options);\n }\n }\n\n return timelines.length ? timelines.map(timeline => timeline.buildKeyframes()) : [createTimelineInstruction(rootElement, [], [], [], 0, delay, '', false)];\n }\n\n visitTrigger(ast, context) {// these values are not visited in this AST\n }\n\n visitState(ast, context) {// these values are not visited in this AST\n }\n\n visitTransition(ast, context) {// these values are not visited in this AST\n }\n\n visitAnimateChild(ast, context) {\n const elementInstructions = context.subInstructions.get(context.element);\n\n if (elementInstructions) {\n const innerContext = context.createSubContext(ast.options);\n const startTime = context.currentTimeline.currentTime;\n\n const endTime = this._visitSubInstructions(elementInstructions, innerContext, innerContext.options);\n\n if (startTime != endTime) {\n // we do this on the upper context because we created a sub context for\n // the sub child animations\n context.transformIntoNewTimeline(endTime);\n }\n }\n\n context.previousNode = ast;\n }\n\n visitAnimateRef(ast, context) {\n const innerContext = context.createSubContext(ast.options);\n innerContext.transformIntoNewTimeline();\n\n this._applyAnimationRefDelays([ast.options, ast.animation.options], context, innerContext);\n\n this.visitReference(ast.animation, innerContext);\n context.transformIntoNewTimeline(innerContext.currentTimeline.currentTime);\n context.previousNode = ast;\n }\n\n _applyAnimationRefDelays(animationsRefsOptions, context, innerContext) {\n for (const animationRefOptions of animationsRefsOptions) {\n const animationDelay = animationRefOptions === null || animationRefOptions === void 0 ? void 0 : animationRefOptions.delay;\n\n if (animationDelay) {\n var _animationRefOptions$;\n\n const animationDelayValue = typeof animationDelay === 'number' ? animationDelay : resolveTimingValue(interpolateParams(animationDelay, (_animationRefOptions$ = animationRefOptions === null || animationRefOptions === void 0 ? void 0 : animationRefOptions.params) !== null && _animationRefOptions$ !== void 0 ? _animationRefOptions$ : {}, context.errors));\n innerContext.delayNextStep(animationDelayValue);\n }\n }\n }\n\n _visitSubInstructions(instructions, context, options) {\n const startTime = context.currentTimeline.currentTime;\n let furthestTime = startTime; // this is a special-case for when a user wants to skip a sub\n // animation from being fired entirely.\n\n const duration = options.duration != null ? resolveTimingValue(options.duration) : null;\n const delay = options.delay != null ? resolveTimingValue(options.delay) : null;\n\n if (duration !== 0) {\n instructions.forEach(instruction => {\n const instructionTimings = context.appendInstructionToTimeline(instruction, duration, delay);\n furthestTime = Math.max(furthestTime, instructionTimings.duration + instructionTimings.delay);\n });\n }\n\n return furthestTime;\n }\n\n visitReference(ast, context) {\n context.updateOptions(ast.options, true);\n visitDslNode(this, ast.animation, context);\n context.previousNode = ast;\n }\n\n visitSequence(ast, context) {\n const subContextCount = context.subContextCount;\n let ctx = context;\n const options = ast.options;\n\n if (options && (options.params || options.delay)) {\n ctx = context.createSubContext(options);\n ctx.transformIntoNewTimeline();\n\n if (options.delay != null) {\n if (ctx.previousNode.type == 6\n /* AnimationMetadataType.Style */\n ) {\n ctx.currentTimeline.snapshotCurrentStyles();\n ctx.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;\n }\n\n const delay = resolveTimingValue(options.delay);\n ctx.delayNextStep(delay);\n }\n }\n\n if (ast.steps.length) {\n ast.steps.forEach(s => visitDslNode(this, s, ctx)); // this is here just in case the inner steps only contain or end with a style() call\n\n ctx.currentTimeline.applyStylesToKeyframe(); // this means that some animation function within the sequence\n // ended up creating a sub timeline (which means the current\n // timeline cannot overlap with the contents of the sequence)\n\n if (ctx.subContextCount > subContextCount) {\n ctx.transformIntoNewTimeline();\n }\n }\n\n context.previousNode = ast;\n }\n\n visitGroup(ast, context) {\n const innerTimelines = [];\n let furthestTime = context.currentTimeline.currentTime;\n const delay = ast.options && ast.options.delay ? resolveTimingValue(ast.options.delay) : 0;\n ast.steps.forEach(s => {\n const innerContext = context.createSubContext(ast.options);\n\n if (delay) {\n innerContext.delayNextStep(delay);\n }\n\n visitDslNode(this, s, innerContext);\n furthestTime = Math.max(furthestTime, innerContext.currentTimeline.currentTime);\n innerTimelines.push(innerContext.currentTimeline);\n }); // this operation is run after the AST loop because otherwise\n // if the parent timeline's collected styles were updated then\n // it would pass in invalid data into the new-to-be forked items\n\n innerTimelines.forEach(timeline => context.currentTimeline.mergeTimelineCollectedStyles(timeline));\n context.transformIntoNewTimeline(furthestTime);\n context.previousNode = ast;\n }\n\n _visitTiming(ast, context) {\n if (ast.dynamic) {\n const strValue = ast.strValue;\n const timingValue = context.params ? interpolateParams(strValue, context.params, context.errors) : strValue;\n return resolveTiming(timingValue, context.errors);\n } else {\n return {\n duration: ast.duration,\n delay: ast.delay,\n easing: ast.easing\n };\n }\n }\n\n visitAnimate(ast, context) {\n const timings = context.currentAnimateTimings = this._visitTiming(ast.timings, context);\n\n const timeline = context.currentTimeline;\n\n if (timings.delay) {\n context.incrementTime(timings.delay);\n timeline.snapshotCurrentStyles();\n }\n\n const style = ast.style;\n\n if (style.type == 5\n /* AnimationMetadataType.Keyframes */\n ) {\n this.visitKeyframes(style, context);\n } else {\n context.incrementTime(timings.duration);\n this.visitStyle(style, context);\n timeline.applyStylesToKeyframe();\n }\n\n context.currentAnimateTimings = null;\n context.previousNode = ast;\n }\n\n visitStyle(ast, context) {\n const timeline = context.currentTimeline;\n const timings = context.currentAnimateTimings; // this is a special case for when a style() call\n // directly follows an animate() call (but not inside of an animate() call)\n\n if (!timings && timeline.hasCurrentStyleProperties()) {\n timeline.forwardFrame();\n }\n\n const easing = timings && timings.easing || ast.easing;\n\n if (ast.isEmptyStep) {\n timeline.applyEmptyStep(easing);\n } else {\n timeline.setStyles(ast.styles, easing, context.errors, context.options);\n }\n\n context.previousNode = ast;\n }\n\n visitKeyframes(ast, context) {\n const currentAnimateTimings = context.currentAnimateTimings;\n const startTime = context.currentTimeline.duration;\n const duration = currentAnimateTimings.duration;\n const innerContext = context.createSubContext();\n const innerTimeline = innerContext.currentTimeline;\n innerTimeline.easing = currentAnimateTimings.easing;\n ast.styles.forEach(step => {\n const offset = step.offset || 0;\n innerTimeline.forwardTime(offset * duration);\n innerTimeline.setStyles(step.styles, step.easing, context.errors, context.options);\n innerTimeline.applyStylesToKeyframe();\n }); // this will ensure that the parent timeline gets all the styles from\n // the child even if the new timeline below is not used\n\n context.currentTimeline.mergeTimelineCollectedStyles(innerTimeline); // we do this because the window between this timeline and the sub timeline\n // should ensure that the styles within are exactly the same as they were before\n\n context.transformIntoNewTimeline(startTime + duration);\n context.previousNode = ast;\n }\n\n visitQuery(ast, context) {\n // in the event that the first step before this is a style step we need\n // to ensure the styles are applied before the children are animated\n const startTime = context.currentTimeline.currentTime;\n const options = ast.options || {};\n const delay = options.delay ? resolveTimingValue(options.delay) : 0;\n\n if (delay && (context.previousNode.type === 6\n /* AnimationMetadataType.Style */\n || startTime == 0 && context.currentTimeline.hasCurrentStyleProperties())) {\n context.currentTimeline.snapshotCurrentStyles();\n context.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;\n }\n\n let furthestTime = startTime;\n const elms = context.invokeQuery(ast.selector, ast.originalSelector, ast.limit, ast.includeSelf, options.optional ? true : false, context.errors);\n context.currentQueryTotal = elms.length;\n let sameElementTimeline = null;\n elms.forEach((element, i) => {\n context.currentQueryIndex = i;\n const innerContext = context.createSubContext(ast.options, element);\n\n if (delay) {\n innerContext.delayNextStep(delay);\n }\n\n if (element === context.element) {\n sameElementTimeline = innerContext.currentTimeline;\n }\n\n visitDslNode(this, ast.animation, innerContext); // this is here just incase the inner steps only contain or end\n // with a style() call (which is here to signal that this is a preparatory\n // call to style an element before it is animated again)\n\n innerContext.currentTimeline.applyStylesToKeyframe();\n const endTime = innerContext.currentTimeline.currentTime;\n furthestTime = Math.max(furthestTime, endTime);\n });\n context.currentQueryIndex = 0;\n context.currentQueryTotal = 0;\n context.transformIntoNewTimeline(furthestTime);\n\n if (sameElementTimeline) {\n context.currentTimeline.mergeTimelineCollectedStyles(sameElementTimeline);\n context.currentTimeline.snapshotCurrentStyles();\n }\n\n context.previousNode = ast;\n }\n\n visitStagger(ast, context) {\n const parentContext = context.parentContext;\n const tl = context.currentTimeline;\n const timings = ast.timings;\n const duration = Math.abs(timings.duration);\n const maxTime = duration * (context.currentQueryTotal - 1);\n let delay = duration * context.currentQueryIndex;\n let staggerTransformer = timings.duration < 0 ? 'reverse' : timings.easing;\n\n switch (staggerTransformer) {\n case 'reverse':\n delay = maxTime - delay;\n break;\n\n case 'full':\n delay = parentContext.currentStaggerTime;\n break;\n }\n\n const timeline = context.currentTimeline;\n\n if (delay) {\n timeline.delayNextStep(delay);\n }\n\n const startingTime = timeline.currentTime;\n visitDslNode(this, ast.animation, context);\n context.previousNode = ast; // time = duration + delay\n // the reason why this computation is so complex is because\n // the inner timeline may either have a delay value or a stretched\n // keyframe depending on if a subtimeline is not used or is used.\n\n parentContext.currentStaggerTime = tl.currentTime - startingTime + (tl.startTime - parentContext.currentTimeline.startTime);\n }\n\n}\n\nconst DEFAULT_NOOP_PREVIOUS_NODE = {};\n\nclass AnimationTimelineContext {\n constructor(_driver, element, subInstructions, _enterClassName, _leaveClassName, errors, timelines, initialTimeline) {\n this._driver = _driver;\n this.element = element;\n this.subInstructions = subInstructions;\n this._enterClassName = _enterClassName;\n this._leaveClassName = _leaveClassName;\n this.errors = errors;\n this.timelines = timelines;\n this.parentContext = null;\n this.currentAnimateTimings = null;\n this.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;\n this.subContextCount = 0;\n this.options = {};\n this.currentQueryIndex = 0;\n this.currentQueryTotal = 0;\n this.currentStaggerTime = 0;\n this.currentTimeline = initialTimeline || new TimelineBuilder(this._driver, element, 0);\n timelines.push(this.currentTimeline);\n }\n\n get params() {\n return this.options.params;\n }\n\n updateOptions(options, skipIfExists) {\n if (!options) return;\n const newOptions = options;\n let optionsToUpdate = this.options; // NOTE: this will get patched up when other animation methods support duration overrides\n\n if (newOptions.duration != null) {\n optionsToUpdate.duration = resolveTimingValue(newOptions.duration);\n }\n\n if (newOptions.delay != null) {\n optionsToUpdate.delay = resolveTimingValue(newOptions.delay);\n }\n\n const newParams = newOptions.params;\n\n if (newParams) {\n let paramsToUpdate = optionsToUpdate.params;\n\n if (!paramsToUpdate) {\n paramsToUpdate = this.options.params = {};\n }\n\n Object.keys(newParams).forEach(name => {\n if (!skipIfExists || !paramsToUpdate.hasOwnProperty(name)) {\n paramsToUpdate[name] = interpolateParams(newParams[name], paramsToUpdate, this.errors);\n }\n });\n }\n }\n\n _copyOptions() {\n const options = {};\n\n if (this.options) {\n const oldParams = this.options.params;\n\n if (oldParams) {\n const params = options['params'] = {};\n Object.keys(oldParams).forEach(name => {\n params[name] = oldParams[name];\n });\n }\n }\n\n return options;\n }\n\n createSubContext(options = null, element, newTime) {\n const target = element || this.element;\n const context = new AnimationTimelineContext(this._driver, target, this.subInstructions, this._enterClassName, this._leaveClassName, this.errors, this.timelines, this.currentTimeline.fork(target, newTime || 0));\n context.previousNode = this.previousNode;\n context.currentAnimateTimings = this.currentAnimateTimings;\n context.options = this._copyOptions();\n context.updateOptions(options);\n context.currentQueryIndex = this.currentQueryIndex;\n context.currentQueryTotal = this.currentQueryTotal;\n context.parentContext = this;\n this.subContextCount++;\n return context;\n }\n\n transformIntoNewTimeline(newTime) {\n this.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;\n this.currentTimeline = this.currentTimeline.fork(this.element, newTime);\n this.timelines.push(this.currentTimeline);\n return this.currentTimeline;\n }\n\n appendInstructionToTimeline(instruction, duration, delay) {\n const updatedTimings = {\n duration: duration != null ? duration : instruction.duration,\n delay: this.currentTimeline.currentTime + (delay != null ? delay : 0) + instruction.delay,\n easing: ''\n };\n const builder = new SubTimelineBuilder(this._driver, instruction.element, instruction.keyframes, instruction.preStyleProps, instruction.postStyleProps, updatedTimings, instruction.stretchStartingKeyframe);\n this.timelines.push(builder);\n return updatedTimings;\n }\n\n incrementTime(time) {\n this.currentTimeline.forwardTime(this.currentTimeline.duration + time);\n }\n\n delayNextStep(delay) {\n // negative delays are not yet supported\n if (delay > 0) {\n this.currentTimeline.delayNextStep(delay);\n }\n }\n\n invokeQuery(selector, originalSelector, limit, includeSelf, optional, errors) {\n let results = [];\n\n if (includeSelf) {\n results.push(this.element);\n }\n\n if (selector.length > 0) {\n // only if :self is used then the selector can be empty\n selector = selector.replace(ENTER_TOKEN_REGEX, '.' + this._enterClassName);\n selector = selector.replace(LEAVE_TOKEN_REGEX, '.' + this._leaveClassName);\n const multi = limit != 1;\n\n let elements = this._driver.query(this.element, selector, multi);\n\n if (limit !== 0) {\n elements = limit < 0 ? elements.slice(elements.length + limit, elements.length) : elements.slice(0, limit);\n }\n\n results.push(...elements);\n }\n\n if (!optional && results.length == 0) {\n errors.push(invalidQuery(originalSelector));\n }\n\n return results;\n }\n\n}\n\nclass TimelineBuilder {\n constructor(_driver, element, startTime, _elementTimelineStylesLookup) {\n this._driver = _driver;\n this.element = element;\n this.startTime = startTime;\n this._elementTimelineStylesLookup = _elementTimelineStylesLookup;\n this.duration = 0;\n this._previousKeyframe = new Map();\n this._currentKeyframe = new Map();\n this._keyframes = new Map();\n this._styleSummary = new Map();\n this._localTimelineStyles = new Map();\n this._pendingStyles = new Map();\n this._backFill = new Map();\n this._currentEmptyStepKeyframe = null;\n\n if (!this._elementTimelineStylesLookup) {\n this._elementTimelineStylesLookup = new Map();\n }\n\n this._globalTimelineStyles = this._elementTimelineStylesLookup.get(element);\n\n if (!this._globalTimelineStyles) {\n this._globalTimelineStyles = this._localTimelineStyles;\n\n this._elementTimelineStylesLookup.set(element, this._localTimelineStyles);\n }\n\n this._loadKeyframe();\n }\n\n containsAnimation() {\n switch (this._keyframes.size) {\n case 0:\n return false;\n\n case 1:\n return this.hasCurrentStyleProperties();\n\n default:\n return true;\n }\n }\n\n hasCurrentStyleProperties() {\n return this._currentKeyframe.size > 0;\n }\n\n get currentTime() {\n return this.startTime + this.duration;\n }\n\n delayNextStep(delay) {\n // in the event that a style() step is placed right before a stagger()\n // and that style() step is the very first style() value in the animation\n // then we need to make a copy of the keyframe [0, copy, 1] so that the delay\n // properly applies the style() values to work with the stagger...\n const hasPreStyleStep = this._keyframes.size === 1 && this._pendingStyles.size;\n\n if (this.duration || hasPreStyleStep) {\n this.forwardTime(this.currentTime + delay);\n\n if (hasPreStyleStep) {\n this.snapshotCurrentStyles();\n }\n } else {\n this.startTime += delay;\n }\n }\n\n fork(element, currentTime) {\n this.applyStylesToKeyframe();\n return new TimelineBuilder(this._driver, element, currentTime || this.currentTime, this._elementTimelineStylesLookup);\n }\n\n _loadKeyframe() {\n if (this._currentKeyframe) {\n this._previousKeyframe = this._currentKeyframe;\n }\n\n this._currentKeyframe = this._keyframes.get(this.duration);\n\n if (!this._currentKeyframe) {\n this._currentKeyframe = new Map();\n\n this._keyframes.set(this.duration, this._currentKeyframe);\n }\n }\n\n forwardFrame() {\n this.duration += ONE_FRAME_IN_MILLISECONDS;\n\n this._loadKeyframe();\n }\n\n forwardTime(time) {\n this.applyStylesToKeyframe();\n this.duration = time;\n\n this._loadKeyframe();\n }\n\n _updateStyle(prop, value) {\n this._localTimelineStyles.set(prop, value);\n\n this._globalTimelineStyles.set(prop, value);\n\n this._styleSummary.set(prop, {\n time: this.currentTime,\n value\n });\n }\n\n allowOnlyTimelineStyles() {\n return this._currentEmptyStepKeyframe !== this._currentKeyframe;\n }\n\n applyEmptyStep(easing) {\n if (easing) {\n this._previousKeyframe.set('easing', easing);\n } // special case for animate(duration):\n // all missing styles are filled with a `*` value then\n // if any destination styles are filled in later on the same\n // keyframe then they will override the overridden styles\n // We use `_globalTimelineStyles` here because there may be\n // styles in previous keyframes that are not present in this timeline\n\n\n for (let [prop, value] of this._globalTimelineStyles) {\n this._backFill.set(prop, value || AUTO_STYLE);\n\n this._currentKeyframe.set(prop, AUTO_STYLE);\n }\n\n this._currentEmptyStepKeyframe = this._currentKeyframe;\n }\n\n setStyles(input, easing, errors, options) {\n if (easing) {\n this._previousKeyframe.set('easing', easing);\n }\n\n const params = options && options.params || {};\n const styles = flattenStyles(input, this._globalTimelineStyles);\n\n for (let [prop, value] of styles) {\n const val = interpolateParams(value, params, errors);\n\n this._pendingStyles.set(prop, val);\n\n if (!this._localTimelineStyles.has(prop)) {\n var _this$_globalTimeline;\n\n this._backFill.set(prop, (_this$_globalTimeline = this._globalTimelineStyles.get(prop)) !== null && _this$_globalTimeline !== void 0 ? _this$_globalTimeline : AUTO_STYLE);\n }\n\n this._updateStyle(prop, val);\n }\n }\n\n applyStylesToKeyframe() {\n if (this._pendingStyles.size == 0) return;\n\n this._pendingStyles.forEach((val, prop) => {\n this._currentKeyframe.set(prop, val);\n });\n\n this._pendingStyles.clear();\n\n this._localTimelineStyles.forEach((val, prop) => {\n if (!this._currentKeyframe.has(prop)) {\n this._currentKeyframe.set(prop, val);\n }\n });\n }\n\n snapshotCurrentStyles() {\n for (let [prop, val] of this._localTimelineStyles) {\n this._pendingStyles.set(prop, val);\n\n this._updateStyle(prop, val);\n }\n }\n\n getFinalKeyframe() {\n return this._keyframes.get(this.duration);\n }\n\n get properties() {\n const properties = [];\n\n for (let prop in this._currentKeyframe) {\n properties.push(prop);\n }\n\n return properties;\n }\n\n mergeTimelineCollectedStyles(timeline) {\n timeline._styleSummary.forEach((details1, prop) => {\n const details0 = this._styleSummary.get(prop);\n\n if (!details0 || details1.time > details0.time) {\n this._updateStyle(prop, details1.value);\n }\n });\n }\n\n buildKeyframes() {\n this.applyStylesToKeyframe();\n const preStyleProps = new Set();\n const postStyleProps = new Set();\n const isEmpty = this._keyframes.size === 1 && this.duration === 0;\n let finalKeyframes = [];\n\n this._keyframes.forEach((keyframe, time) => {\n const finalKeyframe = copyStyles(keyframe, new Map(), this._backFill);\n finalKeyframe.forEach((value, prop) => {\n if (value === ɵPRE_STYLE) {\n preStyleProps.add(prop);\n } else if (value === AUTO_STYLE) {\n postStyleProps.add(prop);\n }\n });\n\n if (!isEmpty) {\n finalKeyframe.set('offset', time / this.duration);\n }\n\n finalKeyframes.push(finalKeyframe);\n });\n\n const preProps = preStyleProps.size ? iteratorToArray(preStyleProps.values()) : [];\n const postProps = postStyleProps.size ? iteratorToArray(postStyleProps.values()) : []; // special case for a 0-second animation (which is designed just to place styles onscreen)\n\n if (isEmpty) {\n const kf0 = finalKeyframes[0];\n const kf1 = new Map(kf0);\n kf0.set('offset', 0);\n kf1.set('offset', 1);\n finalKeyframes = [kf0, kf1];\n }\n\n return createTimelineInstruction(this.element, finalKeyframes, preProps, postProps, this.duration, this.startTime, this.easing, false);\n }\n\n}\n\nclass SubTimelineBuilder extends TimelineBuilder {\n constructor(driver, element, keyframes, preStyleProps, postStyleProps, timings, _stretchStartingKeyframe = false) {\n super(driver, element, timings.delay);\n this.keyframes = keyframes;\n this.preStyleProps = preStyleProps;\n this.postStyleProps = postStyleProps;\n this._stretchStartingKeyframe = _stretchStartingKeyframe;\n this.timings = {\n duration: timings.duration,\n delay: timings.delay,\n easing: timings.easing\n };\n }\n\n containsAnimation() {\n return this.keyframes.length > 1;\n }\n\n buildKeyframes() {\n let keyframes = this.keyframes;\n let {\n delay,\n duration,\n easing\n } = this.timings;\n\n if (this._stretchStartingKeyframe && delay) {\n const newKeyframes = [];\n const totalTime = duration + delay;\n const startingGap = delay / totalTime; // the original starting keyframe now starts once the delay is done\n\n const newFirstKeyframe = copyStyles(keyframes[0]);\n newFirstKeyframe.set('offset', 0);\n newKeyframes.push(newFirstKeyframe);\n const oldFirstKeyframe = copyStyles(keyframes[0]);\n oldFirstKeyframe.set('offset', roundOffset(startingGap));\n newKeyframes.push(oldFirstKeyframe);\n /*\n When the keyframe is stretched then it means that the delay before the animation\n starts is gone. Instead the first keyframe is placed at the start of the animation\n and it is then copied to where it starts when the original delay is over. This basically\n means nothing animates during that delay, but the styles are still rendered. For this\n to work the original offset values that exist in the original keyframes must be \"warped\"\n so that they can take the new keyframe + delay into account.\n delay=1000, duration=1000, keyframes = 0 .5 1\n turns into\n delay=0, duration=2000, keyframes = 0 .33 .66 1\n */\n // offsets between 1 ... n -1 are all warped by the keyframe stretch\n\n const limit = keyframes.length - 1;\n\n for (let i = 1; i <= limit; i++) {\n let kf = copyStyles(keyframes[i]);\n const oldOffset = kf.get('offset');\n const timeAtKeyframe = delay + oldOffset * duration;\n kf.set('offset', roundOffset(timeAtKeyframe / totalTime));\n newKeyframes.push(kf);\n } // the new starting keyframe should be added at the start\n\n\n duration = totalTime;\n delay = 0;\n easing = '';\n keyframes = newKeyframes;\n }\n\n return createTimelineInstruction(this.element, keyframes, this.preStyleProps, this.postStyleProps, duration, delay, easing, true);\n }\n\n}\n\nfunction roundOffset(offset, decimalPoints = 3) {\n const mult = Math.pow(10, decimalPoints - 1);\n return Math.round(offset * mult) / mult;\n}\n\nfunction flattenStyles(input, allStyles) {\n const styles = new Map();\n let allProperties;\n input.forEach(token => {\n if (token === '*') {\n allProperties = allProperties || allStyles.keys();\n\n for (let prop of allProperties) {\n styles.set(prop, AUTO_STYLE);\n }\n } else {\n copyStyles(token, styles);\n }\n });\n return styles;\n}\n\nclass Animation {\n constructor(_driver, input) {\n this._driver = _driver;\n const errors = [];\n const warnings = [];\n const ast = buildAnimationAst(_driver, input, errors, warnings);\n\n if (errors.length) {\n throw validationFailed(errors);\n }\n\n if (warnings.length) {\n warnValidation(warnings);\n }\n\n this._animationAst = ast;\n }\n\n buildTimelines(element, startingStyles, destinationStyles, options, subInstructions) {\n const start = Array.isArray(startingStyles) ? normalizeStyles(startingStyles) : startingStyles;\n const dest = Array.isArray(destinationStyles) ? normalizeStyles(destinationStyles) : destinationStyles;\n const errors = [];\n subInstructions = subInstructions || new ElementInstructionMap();\n const result = buildAnimationTimelines(this._driver, element, this._animationAst, ENTER_CLASSNAME, LEAVE_CLASSNAME, start, dest, options, subInstructions, errors);\n\n if (errors.length) {\n throw buildingFailed(errors);\n }\n\n return result;\n }\n\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @publicApi\n */\n\n\nclass AnimationStyleNormalizer {}\n/**\n * @publicApi\n */\n\n\nclass NoopAnimationStyleNormalizer {\n normalizePropertyName(propertyName, errors) {\n return propertyName;\n }\n\n normalizeStyleValue(userProvidedProperty, normalizedProperty, value, errors) {\n return value;\n }\n\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nconst DIMENSIONAL_PROP_SET = /*#__PURE__*/new Set(['width', 'height', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight', 'left', 'top', 'bottom', 'right', 'fontSize', 'outlineWidth', 'outlineOffset', 'paddingTop', 'paddingLeft', 'paddingBottom', 'paddingRight', 'marginTop', 'marginLeft', 'marginBottom', 'marginRight', 'borderRadius', 'borderWidth', 'borderTopWidth', 'borderLeftWidth', 'borderRightWidth', 'borderBottomWidth', 'textIndent', 'perspective']);\n\nclass WebAnimationsStyleNormalizer extends AnimationStyleNormalizer {\n normalizePropertyName(propertyName, errors) {\n return dashCaseToCamelCase(propertyName);\n }\n\n normalizeStyleValue(userProvidedProperty, normalizedProperty, value, errors) {\n let unit = '';\n const strVal = value.toString().trim();\n\n if (DIMENSIONAL_PROP_SET.has(normalizedProperty) && value !== 0 && value !== '0') {\n if (typeof value === 'number') {\n unit = 'px';\n } else {\n const valAndSuffixMatch = value.match(/^[+-]?[\\d\\.]+([a-z]*)$/);\n\n if (valAndSuffixMatch && valAndSuffixMatch[1].length == 0) {\n errors.push(invalidCssUnitValue(userProvidedProperty, value));\n }\n }\n }\n\n return strVal + unit;\n }\n\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nfunction createTransitionInstruction(element, triggerName, fromState, toState, isRemovalTransition, fromStyles, toStyles, timelines, queriedElements, preStyleProps, postStyleProps, totalTime, errors) {\n return {\n type: 0\n /* AnimationTransitionInstructionType.TransitionAnimation */\n ,\n element,\n triggerName,\n isRemovalTransition,\n fromState,\n fromStyles,\n toState,\n toStyles,\n timelines,\n queriedElements,\n preStyleProps,\n postStyleProps,\n totalTime,\n errors\n };\n}\n\nconst EMPTY_OBJECT = {};\n\nclass AnimationTransitionFactory {\n constructor(_triggerName, ast, _stateStyles) {\n this._triggerName = _triggerName;\n this.ast = ast;\n this._stateStyles = _stateStyles;\n }\n\n match(currentState, nextState, element, params) {\n return oneOrMoreTransitionsMatch(this.ast.matchers, currentState, nextState, element, params);\n }\n\n buildStyles(stateName, params, errors) {\n let styler = this._stateStyles.get('*');\n\n if (stateName !== undefined) {\n styler = this._stateStyles.get(stateName === null || stateName === void 0 ? void 0 : stateName.toString()) || styler;\n }\n\n return styler ? styler.buildStyles(params, errors) : new Map();\n }\n\n build(driver, element, currentState, nextState, enterClassName, leaveClassName, currentOptions, nextOptions, subInstructions, skipAstBuild) {\n var _this$ast$options;\n\n const errors = [];\n const transitionAnimationParams = this.ast.options && this.ast.options.params || EMPTY_OBJECT;\n const currentAnimationParams = currentOptions && currentOptions.params || EMPTY_OBJECT;\n const currentStateStyles = this.buildStyles(currentState, currentAnimationParams, errors);\n const nextAnimationParams = nextOptions && nextOptions.params || EMPTY_OBJECT;\n const nextStateStyles = this.buildStyles(nextState, nextAnimationParams, errors);\n const queriedElements = new Set();\n const preStyleMap = new Map();\n const postStyleMap = new Map();\n const isRemoval = nextState === 'void';\n const animationOptions = {\n params: applyParamDefaults(nextAnimationParams, transitionAnimationParams),\n delay: (_this$ast$options = this.ast.options) === null || _this$ast$options === void 0 ? void 0 : _this$ast$options.delay\n };\n const timelines = skipAstBuild ? [] : buildAnimationTimelines(driver, element, this.ast.animation, enterClassName, leaveClassName, currentStateStyles, nextStateStyles, animationOptions, subInstructions, errors);\n let totalTime = 0;\n timelines.forEach(tl => {\n totalTime = Math.max(tl.duration + tl.delay, totalTime);\n });\n\n if (errors.length) {\n return createTransitionInstruction(element, this._triggerName, currentState, nextState, isRemoval, currentStateStyles, nextStateStyles, [], [], preStyleMap, postStyleMap, totalTime, errors);\n }\n\n timelines.forEach(tl => {\n const elm = tl.element;\n const preProps = getOrSetDefaultValue(preStyleMap, elm, new Set());\n tl.preStyleProps.forEach(prop => preProps.add(prop));\n const postProps = getOrSetDefaultValue(postStyleMap, elm, new Set());\n tl.postStyleProps.forEach(prop => postProps.add(prop));\n\n if (elm !== element) {\n queriedElements.add(elm);\n }\n });\n\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n checkNonAnimatableInTimelines(timelines, this._triggerName, driver);\n }\n\n const queriedElementsList = iteratorToArray(queriedElements.values());\n return createTransitionInstruction(element, this._triggerName, currentState, nextState, isRemoval, currentStateStyles, nextStateStyles, timelines, queriedElementsList, preStyleMap, postStyleMap, totalTime);\n }\n\n}\n/**\n * Checks inside a set of timelines if they try to animate a css property which is not considered\n * animatable, in that case it prints a warning on the console.\n * Besides that the function doesn't have any other effect.\n *\n * Note: this check is done here after the timelines are built instead of doing on a lower level so\n * that we can make sure that the warning appears only once per instruction (we can aggregate here\n * all the issues instead of finding them separately).\n *\n * @param timelines The built timelines for the current instruction.\n * @param triggerName The name of the trigger for the current instruction.\n * @param driver Animation driver used to perform the check.\n *\n */\n\n\nfunction checkNonAnimatableInTimelines(timelines, triggerName, driver) {\n if (!driver.validateAnimatableStyleProperty) {\n return;\n }\n\n const invalidNonAnimatableProps = new Set();\n timelines.forEach(({\n keyframes\n }) => {\n const nonAnimatablePropsInitialValues = new Map();\n keyframes.forEach(keyframe => {\n for (const [prop, value] of keyframe.entries()) {\n if (!driver.validateAnimatableStyleProperty(prop)) {\n if (nonAnimatablePropsInitialValues.has(prop) && !invalidNonAnimatableProps.has(prop)) {\n const propInitialValue = nonAnimatablePropsInitialValues.get(prop);\n\n if (propInitialValue !== value) {\n invalidNonAnimatableProps.add(prop);\n }\n } else {\n nonAnimatablePropsInitialValues.set(prop, value);\n }\n }\n }\n });\n });\n\n if (invalidNonAnimatableProps.size > 0) {\n console.warn(`Warning: The animation trigger \"${triggerName}\" is attempting to animate the following` + ' not animatable properties: ' + Array.from(invalidNonAnimatableProps).join(', ') + '\\n' + '(to check the list of all animatable properties visit https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties)');\n }\n}\n\nfunction oneOrMoreTransitionsMatch(matchFns, currentState, nextState, element, params) {\n return matchFns.some(fn => fn(currentState, nextState, element, params));\n}\n\nfunction applyParamDefaults(userParams, defaults) {\n const result = copyObj(defaults);\n\n for (const key in userParams) {\n if (userParams.hasOwnProperty(key) && userParams[key] != null) {\n result[key] = userParams[key];\n }\n }\n\n return result;\n}\n\nclass AnimationStateStyles {\n constructor(styles, defaultParams, normalizer) {\n this.styles = styles;\n this.defaultParams = defaultParams;\n this.normalizer = normalizer;\n }\n\n buildStyles(params, errors) {\n const finalStyles = new Map();\n const combinedParams = copyObj(this.defaultParams);\n Object.keys(params).forEach(key => {\n const value = params[key];\n\n if (value !== null) {\n combinedParams[key] = value;\n }\n });\n this.styles.styles.forEach(value => {\n if (typeof value !== 'string') {\n value.forEach((val, prop) => {\n if (val) {\n val = interpolateParams(val, combinedParams, errors);\n }\n\n const normalizedProp = this.normalizer.normalizePropertyName(prop, errors);\n val = this.normalizer.normalizeStyleValue(prop, normalizedProp, val, errors);\n finalStyles.set(normalizedProp, val);\n });\n }\n });\n return finalStyles;\n }\n\n}\n\nfunction buildTrigger(name, ast, normalizer) {\n return new AnimationTrigger(name, ast, normalizer);\n}\n\nclass AnimationTrigger {\n constructor(name, ast, _normalizer) {\n this.name = name;\n this.ast = ast;\n this._normalizer = _normalizer;\n this.transitionFactories = [];\n this.states = new Map();\n ast.states.forEach(ast => {\n const defaultParams = ast.options && ast.options.params || {};\n this.states.set(ast.name, new AnimationStateStyles(ast.style, defaultParams, _normalizer));\n });\n balanceProperties(this.states, 'true', '1');\n balanceProperties(this.states, 'false', '0');\n ast.transitions.forEach(ast => {\n this.transitionFactories.push(new AnimationTransitionFactory(name, ast, this.states));\n });\n this.fallbackTransition = createFallbackTransition(name, this.states, this._normalizer);\n }\n\n get containsQueries() {\n return this.ast.queryCount > 0;\n }\n\n matchTransition(currentState, nextState, element, params) {\n const entry = this.transitionFactories.find(f => f.match(currentState, nextState, element, params));\n return entry || null;\n }\n\n matchStyles(currentState, params, errors) {\n return this.fallbackTransition.buildStyles(currentState, params, errors);\n }\n\n}\n\nfunction createFallbackTransition(triggerName, states, normalizer) {\n const matchers = [(fromState, toState) => true];\n const animation = {\n type: 2\n /* AnimationMetadataType.Sequence */\n ,\n steps: [],\n options: null\n };\n const transition = {\n type: 1\n /* AnimationMetadataType.Transition */\n ,\n animation,\n matchers,\n options: null,\n queryCount: 0,\n depCount: 0\n };\n return new AnimationTransitionFactory(triggerName, transition, states);\n}\n\nfunction balanceProperties(stateMap, key1, key2) {\n if (stateMap.has(key1)) {\n if (!stateMap.has(key2)) {\n stateMap.set(key2, stateMap.get(key1));\n }\n } else if (stateMap.has(key2)) {\n stateMap.set(key1, stateMap.get(key2));\n }\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nconst EMPTY_INSTRUCTION_MAP = /*#__PURE__*/new ElementInstructionMap();\n\nclass TimelineAnimationEngine {\n constructor(bodyNode, _driver, _normalizer) {\n this.bodyNode = bodyNode;\n this._driver = _driver;\n this._normalizer = _normalizer;\n this._animations = new Map();\n this._playersById = new Map();\n this.players = [];\n }\n\n register(id, metadata) {\n const errors = [];\n const warnings = [];\n const ast = buildAnimationAst(this._driver, metadata, errors, warnings);\n\n if (errors.length) {\n throw registerFailed(errors);\n } else {\n if (warnings.length) {\n warnRegister(warnings);\n }\n\n this._animations.set(id, ast);\n }\n }\n\n _buildPlayer(i, preStyles, postStyles) {\n const element = i.element;\n const keyframes = normalizeKeyframes$1(this._driver, this._normalizer, element, i.keyframes, preStyles, postStyles);\n return this._driver.animate(element, keyframes, i.duration, i.delay, i.easing, [], true);\n }\n\n create(id, element, options = {}) {\n const errors = [];\n\n const ast = this._animations.get(id);\n\n let instructions;\n const autoStylesMap = new Map();\n\n if (ast) {\n instructions = buildAnimationTimelines(this._driver, element, ast, ENTER_CLASSNAME, LEAVE_CLASSNAME, new Map(), new Map(), options, EMPTY_INSTRUCTION_MAP, errors);\n instructions.forEach(inst => {\n const styles = getOrSetDefaultValue(autoStylesMap, inst.element, new Map());\n inst.postStyleProps.forEach(prop => styles.set(prop, null));\n });\n } else {\n errors.push(missingOrDestroyedAnimation());\n instructions = [];\n }\n\n if (errors.length) {\n throw createAnimationFailed(errors);\n }\n\n autoStylesMap.forEach((styles, element) => {\n styles.forEach((_, prop) => {\n styles.set(prop, this._driver.computeStyle(element, prop, AUTO_STYLE));\n });\n });\n const players = instructions.map(i => {\n const styles = autoStylesMap.get(i.element);\n return this._buildPlayer(i, new Map(), styles);\n });\n const player = optimizeGroupPlayer(players);\n\n this._playersById.set(id, player);\n\n player.onDestroy(() => this.destroy(id));\n this.players.push(player);\n return player;\n }\n\n destroy(id) {\n const player = this._getPlayer(id);\n\n player.destroy();\n\n this._playersById.delete(id);\n\n const index = this.players.indexOf(player);\n\n if (index >= 0) {\n this.players.splice(index, 1);\n }\n }\n\n _getPlayer(id) {\n const player = this._playersById.get(id);\n\n if (!player) {\n throw missingPlayer(id);\n }\n\n return player;\n }\n\n listen(id, element, eventName, callback) {\n // triggerName, fromState, toState are all ignored for timeline animations\n const baseEvent = makeAnimationEvent(element, '', '', '');\n listenOnPlayer(this._getPlayer(id), eventName, baseEvent, callback);\n return () => {};\n }\n\n command(id, element, command, args) {\n if (command == 'register') {\n this.register(id, args[0]);\n return;\n }\n\n if (command == 'create') {\n const options = args[0] || {};\n this.create(id, element, options);\n return;\n }\n\n const player = this._getPlayer(id);\n\n switch (command) {\n case 'play':\n player.play();\n break;\n\n case 'pause':\n player.pause();\n break;\n\n case 'reset':\n player.reset();\n break;\n\n case 'restart':\n player.restart();\n break;\n\n case 'finish':\n player.finish();\n break;\n\n case 'init':\n player.init();\n break;\n\n case 'setPosition':\n player.setPosition(parseFloat(args[0]));\n break;\n\n case 'destroy':\n this.destroy(id);\n break;\n }\n }\n\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nconst QUEUED_CLASSNAME = 'ng-animate-queued';\nconst QUEUED_SELECTOR = '.ng-animate-queued';\nconst DISABLED_CLASSNAME = 'ng-animate-disabled';\nconst DISABLED_SELECTOR = '.ng-animate-disabled';\nconst STAR_CLASSNAME = 'ng-star-inserted';\nconst STAR_SELECTOR = '.ng-star-inserted';\nconst EMPTY_PLAYER_ARRAY = [];\nconst NULL_REMOVAL_STATE = {\n namespaceId: '',\n setForRemoval: false,\n setForMove: false,\n hasAnimation: false,\n removedBeforeQueried: false\n};\nconst NULL_REMOVED_QUERIED_STATE = {\n namespaceId: '',\n setForMove: false,\n setForRemoval: false,\n hasAnimation: false,\n removedBeforeQueried: true\n};\nconst REMOVAL_FLAG = '__ng_removed';\n\nclass StateValue {\n constructor(input, namespaceId = '') {\n this.namespaceId = namespaceId;\n const isObj = input && input.hasOwnProperty('value');\n const value = isObj ? input['value'] : input;\n this.value = normalizeTriggerValue(value);\n\n if (isObj) {\n const options = copyObj(input);\n delete options['value'];\n this.options = options;\n } else {\n this.options = {};\n }\n\n if (!this.options.params) {\n this.options.params = {};\n }\n }\n\n get params() {\n return this.options.params;\n }\n\n absorbOptions(options) {\n const newParams = options.params;\n\n if (newParams) {\n const oldParams = this.options.params;\n Object.keys(newParams).forEach(prop => {\n if (oldParams[prop] == null) {\n oldParams[prop] = newParams[prop];\n }\n });\n }\n }\n\n}\n\nconst VOID_VALUE = 'void';\nconst DEFAULT_STATE_VALUE = /*#__PURE__*/new StateValue(VOID_VALUE);\n\nclass AnimationTransitionNamespace {\n constructor(id, hostElement, _engine) {\n this.id = id;\n this.hostElement = hostElement;\n this._engine = _engine;\n this.players = [];\n this._triggers = new Map();\n this._queue = [];\n this._elementListeners = new Map();\n this._hostClassName = 'ng-tns-' + id;\n addClass(hostElement, this._hostClassName);\n }\n\n listen(element, name, phase, callback) {\n if (!this._triggers.has(name)) {\n throw missingTrigger(phase, name);\n }\n\n if (phase == null || phase.length == 0) {\n throw missingEvent(name);\n }\n\n if (!isTriggerEventValid(phase)) {\n throw unsupportedTriggerEvent(phase, name);\n }\n\n const listeners = getOrSetDefaultValue(this._elementListeners, element, []);\n const data = {\n name,\n phase,\n callback\n };\n listeners.push(data);\n const triggersWithStates = getOrSetDefaultValue(this._engine.statesByElement, element, new Map());\n\n if (!triggersWithStates.has(name)) {\n addClass(element, NG_TRIGGER_CLASSNAME);\n addClass(element, NG_TRIGGER_CLASSNAME + '-' + name);\n triggersWithStates.set(name, DEFAULT_STATE_VALUE);\n }\n\n return () => {\n // the event listener is removed AFTER the flush has occurred such\n // that leave animations callbacks can fire (otherwise if the node\n // is removed in between then the listeners would be deregistered)\n this._engine.afterFlush(() => {\n const index = listeners.indexOf(data);\n\n if (index >= 0) {\n listeners.splice(index, 1);\n }\n\n if (!this._triggers.has(name)) {\n triggersWithStates.delete(name);\n }\n });\n };\n }\n\n register(name, ast) {\n if (this._triggers.has(name)) {\n // throw\n return false;\n } else {\n this._triggers.set(name, ast);\n\n return true;\n }\n }\n\n _getTrigger(name) {\n const trigger = this._triggers.get(name);\n\n if (!trigger) {\n throw unregisteredTrigger(name);\n }\n\n return trigger;\n }\n\n trigger(element, triggerName, value, defaultToFallback = true) {\n const trigger = this._getTrigger(triggerName);\n\n const player = new TransitionAnimationPlayer(this.id, triggerName, element);\n\n let triggersWithStates = this._engine.statesByElement.get(element);\n\n if (!triggersWithStates) {\n addClass(element, NG_TRIGGER_CLASSNAME);\n addClass(element, NG_TRIGGER_CLASSNAME + '-' + triggerName);\n\n this._engine.statesByElement.set(element, triggersWithStates = new Map());\n }\n\n let fromState = triggersWithStates.get(triggerName);\n const toState = new StateValue(value, this.id);\n const isObj = value && value.hasOwnProperty('value');\n\n if (!isObj && fromState) {\n toState.absorbOptions(fromState.options);\n }\n\n triggersWithStates.set(triggerName, toState);\n\n if (!fromState) {\n fromState = DEFAULT_STATE_VALUE;\n }\n\n const isRemoval = toState.value === VOID_VALUE; // normally this isn't reached by here, however, if an object expression\n // is passed in then it may be a new object each time. Comparing the value\n // is important since that will stay the same despite there being a new object.\n // The removal arc here is special cased because the same element is triggered\n // twice in the event that it contains animations on the outer/inner portions\n // of the host container\n\n if (!isRemoval && fromState.value === toState.value) {\n // this means that despite the value not changing, some inner params\n // have changed which means that the animation final styles need to be applied\n if (!objEquals(fromState.params, toState.params)) {\n const errors = [];\n const fromStyles = trigger.matchStyles(fromState.value, fromState.params, errors);\n const toStyles = trigger.matchStyles(toState.value, toState.params, errors);\n\n if (errors.length) {\n this._engine.reportError(errors);\n } else {\n this._engine.afterFlush(() => {\n eraseStyles(element, fromStyles);\n setStyles(element, toStyles);\n });\n }\n }\n\n return;\n }\n\n const playersOnElement = getOrSetDefaultValue(this._engine.playersByElement, element, []);\n playersOnElement.forEach(player => {\n // only remove the player if it is queued on the EXACT same trigger/namespace\n // we only also deal with queued players here because if the animation has\n // started then we want to keep the player alive until the flush happens\n // (which is where the previousPlayers are passed into the new player)\n if (player.namespaceId == this.id && player.triggerName == triggerName && player.queued) {\n player.destroy();\n }\n });\n let transition = trigger.matchTransition(fromState.value, toState.value, element, toState.params);\n let isFallbackTransition = false;\n\n if (!transition) {\n if (!defaultToFallback) return;\n transition = trigger.fallbackTransition;\n isFallbackTransition = true;\n }\n\n this._engine.totalQueuedPlayers++;\n\n this._queue.push({\n element,\n triggerName,\n transition,\n fromState,\n toState,\n player,\n isFallbackTransition\n });\n\n if (!isFallbackTransition) {\n addClass(element, QUEUED_CLASSNAME);\n player.onStart(() => {\n removeClass(element, QUEUED_CLASSNAME);\n });\n }\n\n player.onDone(() => {\n let index = this.players.indexOf(player);\n\n if (index >= 0) {\n this.players.splice(index, 1);\n }\n\n const players = this._engine.playersByElement.get(element);\n\n if (players) {\n let index = players.indexOf(player);\n\n if (index >= 0) {\n players.splice(index, 1);\n }\n }\n });\n this.players.push(player);\n playersOnElement.push(player);\n return player;\n }\n\n deregister(name) {\n this._triggers.delete(name);\n\n this._engine.statesByElement.forEach(stateMap => stateMap.delete(name));\n\n this._elementListeners.forEach((listeners, element) => {\n this._elementListeners.set(element, listeners.filter(entry => {\n return entry.name != name;\n }));\n });\n }\n\n clearElementCache(element) {\n this._engine.statesByElement.delete(element);\n\n this._elementListeners.delete(element);\n\n const elementPlayers = this._engine.playersByElement.get(element);\n\n if (elementPlayers) {\n elementPlayers.forEach(player => player.destroy());\n\n this._engine.playersByElement.delete(element);\n }\n }\n\n _signalRemovalForInnerTriggers(rootElement, context) {\n const elements = this._engine.driver.query(rootElement, NG_TRIGGER_SELECTOR, true); // emulate a leave animation for all inner nodes within this node.\n // If there are no animations found for any of the nodes then clear the cache\n // for the element.\n\n\n elements.forEach(elm => {\n // this means that an inner remove() operation has already kicked off\n // the animation on this element...\n if (elm[REMOVAL_FLAG]) return;\n\n const namespaces = this._engine.fetchNamespacesByElement(elm);\n\n if (namespaces.size) {\n namespaces.forEach(ns => ns.triggerLeaveAnimation(elm, context, false, true));\n } else {\n this.clearElementCache(elm);\n }\n }); // If the child elements were removed along with the parent, their animations might not\n // have completed. Clear all the elements from the cache so we don't end up with a memory leak.\n\n this._engine.afterFlushAnimationsDone(() => elements.forEach(elm => this.clearElementCache(elm)));\n }\n\n triggerLeaveAnimation(element, context, destroyAfterComplete, defaultToFallback) {\n const triggerStates = this._engine.statesByElement.get(element);\n\n const previousTriggersValues = new Map();\n\n if (triggerStates) {\n const players = [];\n triggerStates.forEach((state, triggerName) => {\n previousTriggersValues.set(triggerName, state.value); // this check is here in the event that an element is removed\n // twice (both on the host level and the component level)\n\n if (this._triggers.has(triggerName)) {\n const player = this.trigger(element, triggerName, VOID_VALUE, defaultToFallback);\n\n if (player) {\n players.push(player);\n }\n }\n });\n\n if (players.length) {\n this._engine.markElementAsRemoved(this.id, element, true, context, previousTriggersValues);\n\n if (destroyAfterComplete) {\n optimizeGroupPlayer(players).onDone(() => this._engine.processLeaveNode(element));\n }\n\n return true;\n }\n }\n\n return false;\n }\n\n prepareLeaveAnimationListeners(element) {\n const listeners = this._elementListeners.get(element);\n\n const elementStates = this._engine.statesByElement.get(element); // if this statement fails then it means that the element was picked up\n // by an earlier flush (or there are no listeners at all to track the leave).\n\n\n if (listeners && elementStates) {\n const visitedTriggers = new Set();\n listeners.forEach(listener => {\n const triggerName = listener.name;\n if (visitedTriggers.has(triggerName)) return;\n visitedTriggers.add(triggerName);\n\n const trigger = this._triggers.get(triggerName);\n\n const transition = trigger.fallbackTransition;\n const fromState = elementStates.get(triggerName) || DEFAULT_STATE_VALUE;\n const toState = new StateValue(VOID_VALUE);\n const player = new TransitionAnimationPlayer(this.id, triggerName, element);\n this._engine.totalQueuedPlayers++;\n\n this._queue.push({\n element,\n triggerName,\n transition,\n fromState,\n toState,\n player,\n isFallbackTransition: true\n });\n });\n }\n }\n\n removeNode(element, context) {\n const engine = this._engine;\n\n if (element.childElementCount) {\n this._signalRemovalForInnerTriggers(element, context);\n } // this means that a * => VOID animation was detected and kicked off\n\n\n if (this.triggerLeaveAnimation(element, context, true)) return; // find the player that is animating and make sure that the\n // removal is delayed until that player has completed\n\n let containsPotentialParentTransition = false;\n\n if (engine.totalAnimations) {\n const currentPlayers = engine.players.length ? engine.playersByQueriedElement.get(element) : []; // when this `if statement` does not continue forward it means that\n // a previous animation query has selected the current element and\n // is animating it. In this situation want to continue forwards and\n // allow the element to be queued up for animation later.\n\n if (currentPlayers && currentPlayers.length) {\n containsPotentialParentTransition = true;\n } else {\n let parent = element;\n\n while (parent = parent.parentNode) {\n const triggers = engine.statesByElement.get(parent);\n\n if (triggers) {\n containsPotentialParentTransition = true;\n break;\n }\n }\n }\n } // at this stage we know that the element will either get removed\n // during flush or will be picked up by a parent query. Either way\n // we need to fire the listeners for this element when it DOES get\n // removed (once the query parent animation is done or after flush)\n\n\n this.prepareLeaveAnimationListeners(element); // whether or not a parent has an animation we need to delay the deferral of the leave\n // operation until we have more information (which we do after flush() has been called)\n\n if (containsPotentialParentTransition) {\n engine.markElementAsRemoved(this.id, element, false, context);\n } else {\n const removalFlag = element[REMOVAL_FLAG];\n\n if (!removalFlag || removalFlag === NULL_REMOVAL_STATE) {\n // we do this after the flush has occurred such\n // that the callbacks can be fired\n engine.afterFlush(() => this.clearElementCache(element));\n engine.destroyInnerAnimations(element);\n\n engine._onRemovalComplete(element, context);\n }\n }\n }\n\n insertNode(element, parent) {\n addClass(element, this._hostClassName);\n }\n\n drainQueuedTransitions(microtaskId) {\n const instructions = [];\n\n this._queue.forEach(entry => {\n const player = entry.player;\n if (player.destroyed) return;\n const element = entry.element;\n\n const listeners = this._elementListeners.get(element);\n\n if (listeners) {\n listeners.forEach(listener => {\n if (listener.name == entry.triggerName) {\n const baseEvent = makeAnimationEvent(element, entry.triggerName, entry.fromState.value, entry.toState.value);\n baseEvent['_data'] = microtaskId;\n listenOnPlayer(entry.player, listener.phase, baseEvent, listener.callback);\n }\n });\n }\n\n if (player.markedForDestroy) {\n this._engine.afterFlush(() => {\n // now we can destroy the element properly since the event listeners have\n // been bound to the player\n player.destroy();\n });\n } else {\n instructions.push(entry);\n }\n });\n\n this._queue = [];\n return instructions.sort((a, b) => {\n // if depCount == 0 them move to front\n // otherwise if a contains b then move back\n const d0 = a.transition.ast.depCount;\n const d1 = b.transition.ast.depCount;\n\n if (d0 == 0 || d1 == 0) {\n return d0 - d1;\n }\n\n return this._engine.driver.containsElement(a.element, b.element) ? 1 : -1;\n });\n }\n\n destroy(context) {\n this.players.forEach(p => p.destroy());\n\n this._signalRemovalForInnerTriggers(this.hostElement, context);\n }\n\n elementContainsData(element) {\n let containsData = false;\n if (this._elementListeners.has(element)) containsData = true;\n containsData = (this._queue.find(entry => entry.element === element) ? true : false) || containsData;\n return containsData;\n }\n\n}\n\nclass TransitionAnimationEngine {\n constructor(bodyNode, driver, _normalizer) {\n this.bodyNode = bodyNode;\n this.driver = driver;\n this._normalizer = _normalizer;\n this.players = [];\n this.newHostElements = new Map();\n this.playersByElement = new Map();\n this.playersByQueriedElement = new Map();\n this.statesByElement = new Map();\n this.disabledNodes = new Set();\n this.totalAnimations = 0;\n this.totalQueuedPlayers = 0;\n this._namespaceLookup = {};\n this._namespaceList = [];\n this._flushFns = [];\n this._whenQuietFns = [];\n this.namespacesByHostElement = new Map();\n this.collectedEnterElements = [];\n this.collectedLeaveElements = []; // this method is designed to be overridden by the code that uses this engine\n\n this.onRemovalComplete = (element, context) => {};\n }\n /** @internal */\n\n\n _onRemovalComplete(element, context) {\n this.onRemovalComplete(element, context);\n }\n\n get queuedPlayers() {\n const players = [];\n\n this._namespaceList.forEach(ns => {\n ns.players.forEach(player => {\n if (player.queued) {\n players.push(player);\n }\n });\n });\n\n return players;\n }\n\n createNamespace(namespaceId, hostElement) {\n const ns = new AnimationTransitionNamespace(namespaceId, hostElement, this);\n\n if (this.bodyNode && this.driver.containsElement(this.bodyNode, hostElement)) {\n this._balanceNamespaceList(ns, hostElement);\n } else {\n // defer this later until flush during when the host element has\n // been inserted so that we know exactly where to place it in\n // the namespace list\n this.newHostElements.set(hostElement, ns); // given that this host element is a part of the animation code, it\n // may or may not be inserted by a parent node that is of an\n // animation renderer type. If this happens then we can still have\n // access to this item when we query for :enter nodes. If the parent\n // is a renderer then the set data-structure will normalize the entry\n\n this.collectEnterElement(hostElement);\n }\n\n return this._namespaceLookup[namespaceId] = ns;\n }\n\n _balanceNamespaceList(ns, hostElement) {\n const namespaceList = this._namespaceList;\n const namespacesByHostElement = this.namespacesByHostElement;\n const limit = namespaceList.length - 1;\n\n if (limit >= 0) {\n let found = false; // Find the closest ancestor with an existing namespace so we can then insert `ns` after it,\n // establishing a top-down ordering of namespaces in `this._namespaceList`.\n\n let ancestor = this.driver.getParentElement(hostElement);\n\n while (ancestor) {\n const ancestorNs = namespacesByHostElement.get(ancestor);\n\n if (ancestorNs) {\n // An animation namespace has been registered for this ancestor, so we insert `ns`\n // right after it to establish top-down ordering of animation namespaces.\n const index = namespaceList.indexOf(ancestorNs);\n namespaceList.splice(index + 1, 0, ns);\n found = true;\n break;\n }\n\n ancestor = this.driver.getParentElement(ancestor);\n }\n\n if (!found) {\n // No namespace exists that is an ancestor of `ns`, so `ns` is inserted at the front to\n // ensure that any existing descendants are ordered after `ns`, retaining the desired\n // top-down ordering.\n namespaceList.unshift(ns);\n }\n } else {\n namespaceList.push(ns);\n }\n\n namespacesByHostElement.set(hostElement, ns);\n return ns;\n }\n\n register(namespaceId, hostElement) {\n let ns = this._namespaceLookup[namespaceId];\n\n if (!ns) {\n ns = this.createNamespace(namespaceId, hostElement);\n }\n\n return ns;\n }\n\n registerTrigger(namespaceId, name, trigger) {\n let ns = this._namespaceLookup[namespaceId];\n\n if (ns && ns.register(name, trigger)) {\n this.totalAnimations++;\n }\n }\n\n destroy(namespaceId, context) {\n if (!namespaceId) return;\n\n const ns = this._fetchNamespace(namespaceId);\n\n this.afterFlush(() => {\n this.namespacesByHostElement.delete(ns.hostElement);\n delete this._namespaceLookup[namespaceId];\n\n const index = this._namespaceList.indexOf(ns);\n\n if (index >= 0) {\n this._namespaceList.splice(index, 1);\n }\n });\n this.afterFlushAnimationsDone(() => ns.destroy(context));\n }\n\n _fetchNamespace(id) {\n return this._namespaceLookup[id];\n }\n\n fetchNamespacesByElement(element) {\n // normally there should only be one namespace per element, however\n // if @triggers are placed on both the component element and then\n // its host element (within the component code) then there will be\n // two namespaces returned. We use a set here to simply deduplicate\n // the namespaces in case (for the reason described above) there are multiple triggers\n const namespaces = new Set();\n const elementStates = this.statesByElement.get(element);\n\n if (elementStates) {\n for (let stateValue of elementStates.values()) {\n if (stateValue.namespaceId) {\n const ns = this._fetchNamespace(stateValue.namespaceId);\n\n if (ns) {\n namespaces.add(ns);\n }\n }\n }\n }\n\n return namespaces;\n }\n\n trigger(namespaceId, element, name, value) {\n if (isElementNode(element)) {\n const ns = this._fetchNamespace(namespaceId);\n\n if (ns) {\n ns.trigger(element, name, value);\n return true;\n }\n }\n\n return false;\n }\n\n insertNode(namespaceId, element, parent, insertBefore) {\n if (!isElementNode(element)) return; // special case for when an element is removed and reinserted (move operation)\n // when this occurs we do not want to use the element for deletion later\n\n const details = element[REMOVAL_FLAG];\n\n if (details && details.setForRemoval) {\n details.setForRemoval = false;\n details.setForMove = true;\n const index = this.collectedLeaveElements.indexOf(element);\n\n if (index >= 0) {\n this.collectedLeaveElements.splice(index, 1);\n }\n } // in the event that the namespaceId is blank then the caller\n // code does not contain any animation code in it, but it is\n // just being called so that the node is marked as being inserted\n\n\n if (namespaceId) {\n const ns = this._fetchNamespace(namespaceId); // This if-statement is a workaround for router issue #21947.\n // The router sometimes hits a race condition where while a route\n // is being instantiated a new navigation arrives, triggering leave\n // animation of DOM that has not been fully initialized, until this\n // is resolved, we need to handle the scenario when DOM is not in a\n // consistent state during the animation.\n\n\n if (ns) {\n ns.insertNode(element, parent);\n }\n } // only *directives and host elements are inserted before\n\n\n if (insertBefore) {\n this.collectEnterElement(element);\n }\n }\n\n collectEnterElement(element) {\n this.collectedEnterElements.push(element);\n }\n\n markElementAsDisabled(element, value) {\n if (value) {\n if (!this.disabledNodes.has(element)) {\n this.disabledNodes.add(element);\n addClass(element, DISABLED_CLASSNAME);\n }\n } else if (this.disabledNodes.has(element)) {\n this.disabledNodes.delete(element);\n removeClass(element, DISABLED_CLASSNAME);\n }\n }\n\n removeNode(namespaceId, element, isHostElement, context) {\n if (isElementNode(element)) {\n const ns = namespaceId ? this._fetchNamespace(namespaceId) : null;\n\n if (ns) {\n ns.removeNode(element, context);\n } else {\n this.markElementAsRemoved(namespaceId, element, false, context);\n }\n\n if (isHostElement) {\n const hostNS = this.namespacesByHostElement.get(element);\n\n if (hostNS && hostNS.id !== namespaceId) {\n hostNS.removeNode(element, context);\n }\n }\n } else {\n this._onRemovalComplete(element, context);\n }\n }\n\n markElementAsRemoved(namespaceId, element, hasAnimation, context, previousTriggersValues) {\n this.collectedLeaveElements.push(element);\n element[REMOVAL_FLAG] = {\n namespaceId,\n setForRemoval: context,\n hasAnimation,\n removedBeforeQueried: false,\n previousTriggersValues\n };\n }\n\n listen(namespaceId, element, name, phase, callback) {\n if (isElementNode(element)) {\n return this._fetchNamespace(namespaceId).listen(element, name, phase, callback);\n }\n\n return () => {};\n }\n\n _buildInstruction(entry, subTimelines, enterClassName, leaveClassName, skipBuildAst) {\n return entry.transition.build(this.driver, entry.element, entry.fromState.value, entry.toState.value, enterClassName, leaveClassName, entry.fromState.options, entry.toState.options, subTimelines, skipBuildAst);\n }\n\n destroyInnerAnimations(containerElement) {\n let elements = this.driver.query(containerElement, NG_TRIGGER_SELECTOR, true);\n elements.forEach(element => this.destroyActiveAnimationsForElement(element));\n if (this.playersByQueriedElement.size == 0) return;\n elements = this.driver.query(containerElement, NG_ANIMATING_SELECTOR, true);\n elements.forEach(element => this.finishActiveQueriedAnimationOnElement(element));\n }\n\n destroyActiveAnimationsForElement(element) {\n const players = this.playersByElement.get(element);\n\n if (players) {\n players.forEach(player => {\n // special case for when an element is set for destruction, but hasn't started.\n // in this situation we want to delay the destruction until the flush occurs\n // so that any event listeners attached to the player are triggered.\n if (player.queued) {\n player.markedForDestroy = true;\n } else {\n player.destroy();\n }\n });\n }\n }\n\n finishActiveQueriedAnimationOnElement(element) {\n const players = this.playersByQueriedElement.get(element);\n\n if (players) {\n players.forEach(player => player.finish());\n }\n }\n\n whenRenderingDone() {\n return new Promise(resolve => {\n if (this.players.length) {\n return optimizeGroupPlayer(this.players).onDone(() => resolve());\n } else {\n resolve();\n }\n });\n }\n\n processLeaveNode(element) {\n var _element$classList;\n\n const details = element[REMOVAL_FLAG];\n\n if (details && details.setForRemoval) {\n // this will prevent it from removing it twice\n element[REMOVAL_FLAG] = NULL_REMOVAL_STATE;\n\n if (details.namespaceId) {\n this.destroyInnerAnimations(element);\n\n const ns = this._fetchNamespace(details.namespaceId);\n\n if (ns) {\n ns.clearElementCache(element);\n }\n }\n\n this._onRemovalComplete(element, details.setForRemoval);\n }\n\n if ((_element$classList = element.classList) !== null && _element$classList !== void 0 && _element$classList.contains(DISABLED_CLASSNAME)) {\n this.markElementAsDisabled(element, false);\n }\n\n this.driver.query(element, DISABLED_SELECTOR, true).forEach(node => {\n this.markElementAsDisabled(node, false);\n });\n }\n\n flush(microtaskId = -1) {\n let players = [];\n\n if (this.newHostElements.size) {\n this.newHostElements.forEach((ns, element) => this._balanceNamespaceList(ns, element));\n this.newHostElements.clear();\n }\n\n if (this.totalAnimations && this.collectedEnterElements.length) {\n for (let i = 0; i < this.collectedEnterElements.length; i++) {\n const elm = this.collectedEnterElements[i];\n addClass(elm, STAR_CLASSNAME);\n }\n }\n\n if (this._namespaceList.length && (this.totalQueuedPlayers || this.collectedLeaveElements.length)) {\n const cleanupFns = [];\n\n try {\n players = this._flushAnimations(cleanupFns, microtaskId);\n } finally {\n for (let i = 0; i < cleanupFns.length; i++) {\n cleanupFns[i]();\n }\n }\n } else {\n for (let i = 0; i < this.collectedLeaveElements.length; i++) {\n const element = this.collectedLeaveElements[i];\n this.processLeaveNode(element);\n }\n }\n\n this.totalQueuedPlayers = 0;\n this.collectedEnterElements.length = 0;\n this.collectedLeaveElements.length = 0;\n\n this._flushFns.forEach(fn => fn());\n\n this._flushFns = [];\n\n if (this._whenQuietFns.length) {\n // we move these over to a variable so that\n // if any new callbacks are registered in another\n // flush they do not populate the existing set\n const quietFns = this._whenQuietFns;\n this._whenQuietFns = [];\n\n if (players.length) {\n optimizeGroupPlayer(players).onDone(() => {\n quietFns.forEach(fn => fn());\n });\n } else {\n quietFns.forEach(fn => fn());\n }\n }\n }\n\n reportError(errors) {\n throw triggerTransitionsFailed(errors);\n }\n\n _flushAnimations(cleanupFns, microtaskId) {\n const subTimelines = new ElementInstructionMap();\n const skippedPlayers = [];\n const skippedPlayersMap = new Map();\n const queuedInstructions = [];\n const queriedElements = new Map();\n const allPreStyleElements = new Map();\n const allPostStyleElements = new Map();\n const disabledElementsSet = new Set();\n this.disabledNodes.forEach(node => {\n disabledElementsSet.add(node);\n const nodesThatAreDisabled = this.driver.query(node, QUEUED_SELECTOR, true);\n\n for (let i = 0; i < nodesThatAreDisabled.length; i++) {\n disabledElementsSet.add(nodesThatAreDisabled[i]);\n }\n });\n const bodyNode = this.bodyNode;\n const allTriggerElements = Array.from(this.statesByElement.keys());\n const enterNodeMap = buildRootMap(allTriggerElements, this.collectedEnterElements); // this must occur before the instructions are built below such that\n // the :enter queries match the elements (since the timeline queries\n // are fired during instruction building).\n\n const enterNodeMapIds = new Map();\n let i = 0;\n enterNodeMap.forEach((nodes, root) => {\n const className = ENTER_CLASSNAME + i++;\n enterNodeMapIds.set(root, className);\n nodes.forEach(node => addClass(node, className));\n });\n const allLeaveNodes = [];\n const mergedLeaveNodes = new Set();\n const leaveNodesWithoutAnimations = new Set();\n\n for (let i = 0; i < this.collectedLeaveElements.length; i++) {\n const element = this.collectedLeaveElements[i];\n const details = element[REMOVAL_FLAG];\n\n if (details && details.setForRemoval) {\n allLeaveNodes.push(element);\n mergedLeaveNodes.add(element);\n\n if (details.hasAnimation) {\n this.driver.query(element, STAR_SELECTOR, true).forEach(elm => mergedLeaveNodes.add(elm));\n } else {\n leaveNodesWithoutAnimations.add(element);\n }\n }\n }\n\n const leaveNodeMapIds = new Map();\n const leaveNodeMap = buildRootMap(allTriggerElements, Array.from(mergedLeaveNodes));\n leaveNodeMap.forEach((nodes, root) => {\n const className = LEAVE_CLASSNAME + i++;\n leaveNodeMapIds.set(root, className);\n nodes.forEach(node => addClass(node, className));\n });\n cleanupFns.push(() => {\n enterNodeMap.forEach((nodes, root) => {\n const className = enterNodeMapIds.get(root);\n nodes.forEach(node => removeClass(node, className));\n });\n leaveNodeMap.forEach((nodes, root) => {\n const className = leaveNodeMapIds.get(root);\n nodes.forEach(node => removeClass(node, className));\n });\n allLeaveNodes.forEach(element => {\n this.processLeaveNode(element);\n });\n });\n const allPlayers = [];\n const erroneousTransitions = [];\n\n for (let i = this._namespaceList.length - 1; i >= 0; i--) {\n const ns = this._namespaceList[i];\n ns.drainQueuedTransitions(microtaskId).forEach(entry => {\n const player = entry.player;\n const element = entry.element;\n allPlayers.push(player);\n\n if (this.collectedEnterElements.length) {\n const details = element[REMOVAL_FLAG]; // animations for move operations (elements being removed and reinserted,\n // e.g. when the order of an *ngFor list changes) are currently not supported\n\n if (details && details.setForMove) {\n if (details.previousTriggersValues && details.previousTriggersValues.has(entry.triggerName)) {\n const previousValue = details.previousTriggersValues.get(entry.triggerName); // we need to restore the previous trigger value since the element has\n // only been moved and hasn't actually left the DOM\n\n const triggersWithStates = this.statesByElement.get(entry.element);\n\n if (triggersWithStates && triggersWithStates.has(entry.triggerName)) {\n const state = triggersWithStates.get(entry.triggerName);\n state.value = previousValue;\n triggersWithStates.set(entry.triggerName, state);\n }\n }\n\n player.destroy();\n return;\n }\n }\n\n const nodeIsOrphaned = !bodyNode || !this.driver.containsElement(bodyNode, element);\n const leaveClassName = leaveNodeMapIds.get(element);\n const enterClassName = enterNodeMapIds.get(element);\n\n const instruction = this._buildInstruction(entry, subTimelines, enterClassName, leaveClassName, nodeIsOrphaned);\n\n if (instruction.errors && instruction.errors.length) {\n erroneousTransitions.push(instruction);\n return;\n } // even though the element may not be in the DOM, it may still\n // be added at a later point (due to the mechanics of content\n // projection and/or dynamic component insertion) therefore it's\n // important to still style the element.\n\n\n if (nodeIsOrphaned) {\n player.onStart(() => eraseStyles(element, instruction.fromStyles));\n player.onDestroy(() => setStyles(element, instruction.toStyles));\n skippedPlayers.push(player);\n return;\n } // if an unmatched transition is queued and ready to go\n // then it SHOULD NOT render an animation and cancel the\n // previously running animations.\n\n\n if (entry.isFallbackTransition) {\n player.onStart(() => eraseStyles(element, instruction.fromStyles));\n player.onDestroy(() => setStyles(element, instruction.toStyles));\n skippedPlayers.push(player);\n return;\n } // this means that if a parent animation uses this animation as a sub-trigger\n // then it will instruct the timeline builder not to add a player delay, but\n // instead stretch the first keyframe gap until the animation starts. This is\n // important in order to prevent extra initialization styles from being\n // required by the user for the animation.\n\n\n const timelines = [];\n instruction.timelines.forEach(tl => {\n tl.stretchStartingKeyframe = true;\n\n if (!this.disabledNodes.has(tl.element)) {\n timelines.push(tl);\n }\n });\n instruction.timelines = timelines;\n subTimelines.append(element, instruction.timelines);\n const tuple = {\n instruction,\n player,\n element\n };\n queuedInstructions.push(tuple);\n instruction.queriedElements.forEach(element => getOrSetDefaultValue(queriedElements, element, []).push(player));\n instruction.preStyleProps.forEach((stringMap, element) => {\n if (stringMap.size) {\n let setVal = allPreStyleElements.get(element);\n\n if (!setVal) {\n allPreStyleElements.set(element, setVal = new Set());\n }\n\n stringMap.forEach((_, prop) => setVal.add(prop));\n }\n });\n instruction.postStyleProps.forEach((stringMap, element) => {\n let setVal = allPostStyleElements.get(element);\n\n if (!setVal) {\n allPostStyleElements.set(element, setVal = new Set());\n }\n\n stringMap.forEach((_, prop) => setVal.add(prop));\n });\n });\n }\n\n if (erroneousTransitions.length) {\n const errors = [];\n erroneousTransitions.forEach(instruction => {\n errors.push(transitionFailed(instruction.triggerName, instruction.errors));\n });\n allPlayers.forEach(player => player.destroy());\n this.reportError(errors);\n }\n\n const allPreviousPlayersMap = new Map(); // this map tells us which element in the DOM tree is contained by\n // which animation. Further down this map will get populated once\n // the players are built and in doing so we can use it to efficiently\n // figure out if a sub player is skipped due to a parent player having priority.\n\n const animationElementMap = new Map();\n queuedInstructions.forEach(entry => {\n const element = entry.element;\n\n if (subTimelines.has(element)) {\n animationElementMap.set(element, element);\n\n this._beforeAnimationBuild(entry.player.namespaceId, entry.instruction, allPreviousPlayersMap);\n }\n });\n skippedPlayers.forEach(player => {\n const element = player.element;\n\n const previousPlayers = this._getPreviousPlayers(element, false, player.namespaceId, player.triggerName, null);\n\n previousPlayers.forEach(prevPlayer => {\n getOrSetDefaultValue(allPreviousPlayersMap, element, []).push(prevPlayer);\n prevPlayer.destroy();\n });\n }); // this is a special case for nodes that will be removed either by\n // having their own leave animations or by being queried in a container\n // that will be removed once a parent animation is complete. The idea\n // here is that * styles must be identical to ! styles because of\n // backwards compatibility (* is also filled in by default in many places).\n // Otherwise * styles will return an empty value or \"auto\" since the element\n // passed to getComputedStyle will not be visible (since * === destination)\n\n const replaceNodes = allLeaveNodes.filter(node => {\n return replacePostStylesAsPre(node, allPreStyleElements, allPostStyleElements);\n }); // POST STAGE: fill the * styles\n\n const postStylesMap = new Map();\n const allLeaveQueriedNodes = cloakAndComputeStyles(postStylesMap, this.driver, leaveNodesWithoutAnimations, allPostStyleElements, AUTO_STYLE);\n allLeaveQueriedNodes.forEach(node => {\n if (replacePostStylesAsPre(node, allPreStyleElements, allPostStyleElements)) {\n replaceNodes.push(node);\n }\n }); // PRE STAGE: fill the ! styles\n\n const preStylesMap = new Map();\n enterNodeMap.forEach((nodes, root) => {\n cloakAndComputeStyles(preStylesMap, this.driver, new Set(nodes), allPreStyleElements, ɵPRE_STYLE);\n });\n replaceNodes.forEach(node => {\n var _post$entries, _pre$entries;\n\n const post = postStylesMap.get(node);\n const pre = preStylesMap.get(node);\n postStylesMap.set(node, new Map([...Array.from((_post$entries = post === null || post === void 0 ? void 0 : post.entries()) !== null && _post$entries !== void 0 ? _post$entries : []), ...Array.from((_pre$entries = pre === null || pre === void 0 ? void 0 : pre.entries()) !== null && _pre$entries !== void 0 ? _pre$entries : [])]));\n });\n const rootPlayers = [];\n const subPlayers = [];\n const NO_PARENT_ANIMATION_ELEMENT_DETECTED = {};\n queuedInstructions.forEach(entry => {\n const {\n element,\n player,\n instruction\n } = entry; // this means that it was never consumed by a parent animation which\n // means that it is independent and therefore should be set for animation\n\n if (subTimelines.has(element)) {\n if (disabledElementsSet.has(element)) {\n player.onDestroy(() => setStyles(element, instruction.toStyles));\n player.disabled = true;\n player.overrideTotalTime(instruction.totalTime);\n skippedPlayers.push(player);\n return;\n } // this will flow up the DOM and query the map to figure out\n // if a parent animation has priority over it. In the situation\n // that a parent is detected then it will cancel the loop. If\n // nothing is detected, or it takes a few hops to find a parent,\n // then it will fill in the missing nodes and signal them as having\n // a detected parent (or a NO_PARENT value via a special constant).\n\n\n let parentWithAnimation = NO_PARENT_ANIMATION_ELEMENT_DETECTED;\n\n if (animationElementMap.size > 1) {\n let elm = element;\n const parentsToAdd = [];\n\n while (elm = elm.parentNode) {\n const detectedParent = animationElementMap.get(elm);\n\n if (detectedParent) {\n parentWithAnimation = detectedParent;\n break;\n }\n\n parentsToAdd.push(elm);\n }\n\n parentsToAdd.forEach(parent => animationElementMap.set(parent, parentWithAnimation));\n }\n\n const innerPlayer = this._buildAnimation(player.namespaceId, instruction, allPreviousPlayersMap, skippedPlayersMap, preStylesMap, postStylesMap);\n\n player.setRealPlayer(innerPlayer);\n\n if (parentWithAnimation === NO_PARENT_ANIMATION_ELEMENT_DETECTED) {\n rootPlayers.push(player);\n } else {\n const parentPlayers = this.playersByElement.get(parentWithAnimation);\n\n if (parentPlayers && parentPlayers.length) {\n player.parentPlayer = optimizeGroupPlayer(parentPlayers);\n }\n\n skippedPlayers.push(player);\n }\n } else {\n eraseStyles(element, instruction.fromStyles);\n player.onDestroy(() => setStyles(element, instruction.toStyles)); // there still might be a ancestor player animating this\n // element therefore we will still add it as a sub player\n // even if its animation may be disabled\n\n subPlayers.push(player);\n\n if (disabledElementsSet.has(element)) {\n skippedPlayers.push(player);\n }\n }\n }); // find all of the sub players' corresponding inner animation players\n\n subPlayers.forEach(player => {\n // even if no players are found for a sub animation it\n // will still complete itself after the next tick since it's Noop\n const playersForElement = skippedPlayersMap.get(player.element);\n\n if (playersForElement && playersForElement.length) {\n const innerPlayer = optimizeGroupPlayer(playersForElement);\n player.setRealPlayer(innerPlayer);\n }\n }); // the reason why we don't actually play the animation is\n // because all that a skipped player is designed to do is to\n // fire the start/done transition callback events\n\n skippedPlayers.forEach(player => {\n if (player.parentPlayer) {\n player.syncPlayerEvents(player.parentPlayer);\n } else {\n player.destroy();\n }\n }); // run through all of the queued removals and see if they\n // were picked up by a query. If not then perform the removal\n // operation right away unless a parent animation is ongoing.\n\n for (let i = 0; i < allLeaveNodes.length; i++) {\n const element = allLeaveNodes[i];\n const details = element[REMOVAL_FLAG];\n removeClass(element, LEAVE_CLASSNAME); // this means the element has a removal animation that is being\n // taken care of and therefore the inner elements will hang around\n // until that animation is over (or the parent queried animation)\n\n if (details && details.hasAnimation) continue;\n let players = []; // if this element is queried or if it contains queried children\n // then we want for the element not to be removed from the page\n // until the queried animations have finished\n\n if (queriedElements.size) {\n let queriedPlayerResults = queriedElements.get(element);\n\n if (queriedPlayerResults && queriedPlayerResults.length) {\n players.push(...queriedPlayerResults);\n }\n\n let queriedInnerElements = this.driver.query(element, NG_ANIMATING_SELECTOR, true);\n\n for (let j = 0; j < queriedInnerElements.length; j++) {\n let queriedPlayers = queriedElements.get(queriedInnerElements[j]);\n\n if (queriedPlayers && queriedPlayers.length) {\n players.push(...queriedPlayers);\n }\n }\n }\n\n const activePlayers = players.filter(p => !p.destroyed);\n\n if (activePlayers.length) {\n removeNodesAfterAnimationDone(this, element, activePlayers);\n } else {\n this.processLeaveNode(element);\n }\n } // this is required so the cleanup method doesn't remove them\n\n\n allLeaveNodes.length = 0;\n rootPlayers.forEach(player => {\n this.players.push(player);\n player.onDone(() => {\n player.destroy();\n const index = this.players.indexOf(player);\n this.players.splice(index, 1);\n });\n player.play();\n });\n return rootPlayers;\n }\n\n elementContainsData(namespaceId, element) {\n let containsData = false;\n const details = element[REMOVAL_FLAG];\n if (details && details.setForRemoval) containsData = true;\n if (this.playersByElement.has(element)) containsData = true;\n if (this.playersByQueriedElement.has(element)) containsData = true;\n if (this.statesByElement.has(element)) containsData = true;\n return this._fetchNamespace(namespaceId).elementContainsData(element) || containsData;\n }\n\n afterFlush(callback) {\n this._flushFns.push(callback);\n }\n\n afterFlushAnimationsDone(callback) {\n this._whenQuietFns.push(callback);\n }\n\n _getPreviousPlayers(element, isQueriedElement, namespaceId, triggerName, toStateValue) {\n let players = [];\n\n if (isQueriedElement) {\n const queriedElementPlayers = this.playersByQueriedElement.get(element);\n\n if (queriedElementPlayers) {\n players = queriedElementPlayers;\n }\n } else {\n const elementPlayers = this.playersByElement.get(element);\n\n if (elementPlayers) {\n const isRemovalAnimation = !toStateValue || toStateValue == VOID_VALUE;\n elementPlayers.forEach(player => {\n if (player.queued) return;\n if (!isRemovalAnimation && player.triggerName != triggerName) return;\n players.push(player);\n });\n }\n }\n\n if (namespaceId || triggerName) {\n players = players.filter(player => {\n if (namespaceId && namespaceId != player.namespaceId) return false;\n if (triggerName && triggerName != player.triggerName) return false;\n return true;\n });\n }\n\n return players;\n }\n\n _beforeAnimationBuild(namespaceId, instruction, allPreviousPlayersMap) {\n const triggerName = instruction.triggerName;\n const rootElement = instruction.element; // when a removal animation occurs, ALL previous players are collected\n // and destroyed (even if they are outside of the current namespace)\n\n const targetNameSpaceId = instruction.isRemovalTransition ? undefined : namespaceId;\n const targetTriggerName = instruction.isRemovalTransition ? undefined : triggerName;\n\n for (const timelineInstruction of instruction.timelines) {\n const element = timelineInstruction.element;\n const isQueriedElement = element !== rootElement;\n const players = getOrSetDefaultValue(allPreviousPlayersMap, element, []);\n\n const previousPlayers = this._getPreviousPlayers(element, isQueriedElement, targetNameSpaceId, targetTriggerName, instruction.toState);\n\n previousPlayers.forEach(player => {\n const realPlayer = player.getRealPlayer();\n\n if (realPlayer.beforeDestroy) {\n realPlayer.beforeDestroy();\n }\n\n player.destroy();\n players.push(player);\n });\n } // this needs to be done so that the PRE/POST styles can be\n // computed properly without interfering with the previous animation\n\n\n eraseStyles(rootElement, instruction.fromStyles);\n }\n\n _buildAnimation(namespaceId, instruction, allPreviousPlayersMap, skippedPlayersMap, preStylesMap, postStylesMap) {\n const triggerName = instruction.triggerName;\n const rootElement = instruction.element; // we first run this so that the previous animation player\n // data can be passed into the successive animation players\n\n const allQueriedPlayers = [];\n const allConsumedElements = new Set();\n const allSubElements = new Set();\n const allNewPlayers = instruction.timelines.map(timelineInstruction => {\n const element = timelineInstruction.element;\n allConsumedElements.add(element); // FIXME (matsko): make sure to-be-removed animations are removed properly\n\n const details = element[REMOVAL_FLAG];\n if (details && details.removedBeforeQueried) return new NoopAnimationPlayer(timelineInstruction.duration, timelineInstruction.delay);\n const isQueriedElement = element !== rootElement;\n const previousPlayers = flattenGroupPlayers((allPreviousPlayersMap.get(element) || EMPTY_PLAYER_ARRAY).map(p => p.getRealPlayer())).filter(p => {\n // the `element` is not apart of the AnimationPlayer definition, but\n // Mock/WebAnimations\n // use the element within their implementation. This will be added in Angular5 to\n // AnimationPlayer\n const pp = p;\n return pp.element ? pp.element === element : false;\n });\n const preStyles = preStylesMap.get(element);\n const postStyles = postStylesMap.get(element);\n const keyframes = normalizeKeyframes$1(this.driver, this._normalizer, element, timelineInstruction.keyframes, preStyles, postStyles);\n\n const player = this._buildPlayer(timelineInstruction, keyframes, previousPlayers); // this means that this particular player belongs to a sub trigger. It is\n // important that we match this player up with the corresponding (@trigger.listener)\n\n\n if (timelineInstruction.subTimeline && skippedPlayersMap) {\n allSubElements.add(element);\n }\n\n if (isQueriedElement) {\n const wrappedPlayer = new TransitionAnimationPlayer(namespaceId, triggerName, element);\n wrappedPlayer.setRealPlayer(player);\n allQueriedPlayers.push(wrappedPlayer);\n }\n\n return player;\n });\n allQueriedPlayers.forEach(player => {\n getOrSetDefaultValue(this.playersByQueriedElement, player.element, []).push(player);\n player.onDone(() => deleteOrUnsetInMap(this.playersByQueriedElement, player.element, player));\n });\n allConsumedElements.forEach(element => addClass(element, NG_ANIMATING_CLASSNAME));\n const player = optimizeGroupPlayer(allNewPlayers);\n player.onDestroy(() => {\n allConsumedElements.forEach(element => removeClass(element, NG_ANIMATING_CLASSNAME));\n setStyles(rootElement, instruction.toStyles);\n }); // this basically makes all of the callbacks for sub element animations\n // be dependent on the upper players for when they finish\n\n allSubElements.forEach(element => {\n getOrSetDefaultValue(skippedPlayersMap, element, []).push(player);\n });\n return player;\n }\n\n _buildPlayer(instruction, keyframes, previousPlayers) {\n if (keyframes.length > 0) {\n return this.driver.animate(instruction.element, keyframes, instruction.duration, instruction.delay, instruction.easing, previousPlayers);\n } // special case for when an empty transition|definition is provided\n // ... there is no point in rendering an empty animation\n\n\n return new NoopAnimationPlayer(instruction.duration, instruction.delay);\n }\n\n}\n\nclass TransitionAnimationPlayer {\n constructor(namespaceId, triggerName, element) {\n this.namespaceId = namespaceId;\n this.triggerName = triggerName;\n this.element = element;\n this._player = new NoopAnimationPlayer();\n this._containsRealPlayer = false;\n this._queuedCallbacks = new Map();\n this.destroyed = false;\n this.markedForDestroy = false;\n this.disabled = false;\n this.queued = true;\n this.totalTime = 0;\n }\n\n setRealPlayer(player) {\n if (this._containsRealPlayer) return;\n this._player = player;\n\n this._queuedCallbacks.forEach((callbacks, phase) => {\n callbacks.forEach(callback => listenOnPlayer(player, phase, undefined, callback));\n });\n\n this._queuedCallbacks.clear();\n\n this._containsRealPlayer = true;\n this.overrideTotalTime(player.totalTime);\n this.queued = false;\n }\n\n getRealPlayer() {\n return this._player;\n }\n\n overrideTotalTime(totalTime) {\n this.totalTime = totalTime;\n }\n\n syncPlayerEvents(player) {\n const p = this._player;\n\n if (p.triggerCallback) {\n player.onStart(() => p.triggerCallback('start'));\n }\n\n player.onDone(() => this.finish());\n player.onDestroy(() => this.destroy());\n }\n\n _queueEvent(name, callback) {\n getOrSetDefaultValue(this._queuedCallbacks, name, []).push(callback);\n }\n\n onDone(fn) {\n if (this.queued) {\n this._queueEvent('done', fn);\n }\n\n this._player.onDone(fn);\n }\n\n onStart(fn) {\n if (this.queued) {\n this._queueEvent('start', fn);\n }\n\n this._player.onStart(fn);\n }\n\n onDestroy(fn) {\n if (this.queued) {\n this._queueEvent('destroy', fn);\n }\n\n this._player.onDestroy(fn);\n }\n\n init() {\n this._player.init();\n }\n\n hasStarted() {\n return this.queued ? false : this._player.hasStarted();\n }\n\n play() {\n !this.queued && this._player.play();\n }\n\n pause() {\n !this.queued && this._player.pause();\n }\n\n restart() {\n !this.queued && this._player.restart();\n }\n\n finish() {\n this._player.finish();\n }\n\n destroy() {\n this.destroyed = true;\n\n this._player.destroy();\n }\n\n reset() {\n !this.queued && this._player.reset();\n }\n\n setPosition(p) {\n if (!this.queued) {\n this._player.setPosition(p);\n }\n }\n\n getPosition() {\n return this.queued ? 0 : this._player.getPosition();\n }\n /** @internal */\n\n\n triggerCallback(phaseName) {\n const p = this._player;\n\n if (p.triggerCallback) {\n p.triggerCallback(phaseName);\n }\n }\n\n}\n\nfunction deleteOrUnsetInMap(map, key, value) {\n let currentValues = map.get(key);\n\n if (currentValues) {\n if (currentValues.length) {\n const index = currentValues.indexOf(value);\n currentValues.splice(index, 1);\n }\n\n if (currentValues.length == 0) {\n map.delete(key);\n }\n }\n\n return currentValues;\n}\n\nfunction normalizeTriggerValue(value) {\n // we use `!= null` here because it's the most simple\n // way to test against a \"falsy\" value without mixing\n // in empty strings or a zero value. DO NOT OPTIMIZE.\n return value != null ? value : null;\n}\n\nfunction isElementNode(node) {\n return node && node['nodeType'] === 1;\n}\n\nfunction isTriggerEventValid(eventName) {\n return eventName == 'start' || eventName == 'done';\n}\n\nfunction cloakElement(element, value) {\n const oldValue = element.style.display;\n element.style.display = value != null ? value : 'none';\n return oldValue;\n}\n\nfunction cloakAndComputeStyles(valuesMap, driver, elements, elementPropsMap, defaultStyle) {\n const cloakVals = [];\n elements.forEach(element => cloakVals.push(cloakElement(element)));\n const failedElements = [];\n elementPropsMap.forEach((props, element) => {\n const styles = new Map();\n props.forEach(prop => {\n const value = driver.computeStyle(element, prop, defaultStyle);\n styles.set(prop, value); // there is no easy way to detect this because a sub element could be removed\n // by a parent animation element being detached.\n\n if (!value || value.length == 0) {\n element[REMOVAL_FLAG] = NULL_REMOVED_QUERIED_STATE;\n failedElements.push(element);\n }\n });\n valuesMap.set(element, styles);\n }); // we use a index variable here since Set.forEach(a, i) does not return\n // an index value for the closure (but instead just the value)\n\n let i = 0;\n elements.forEach(element => cloakElement(element, cloakVals[i++]));\n return failedElements;\n}\n/*\nSince the Angular renderer code will return a collection of inserted\nnodes in all areas of a DOM tree, it's up to this algorithm to figure\nout which nodes are roots for each animation @trigger.\n\nBy placing each inserted node into a Set and traversing upwards, it\nis possible to find the @trigger elements and well any direct *star\ninsertion nodes, if a @trigger root is found then the enter element\nis placed into the Map[@trigger] spot.\n */\n\n\nfunction buildRootMap(roots, nodes) {\n const rootMap = new Map();\n roots.forEach(root => rootMap.set(root, []));\n if (nodes.length == 0) return rootMap;\n const NULL_NODE = 1;\n const nodeSet = new Set(nodes);\n const localRootMap = new Map();\n\n function getRoot(node) {\n if (!node) return NULL_NODE;\n let root = localRootMap.get(node);\n if (root) return root;\n const parent = node.parentNode;\n\n if (rootMap.has(parent)) {\n // ngIf inside @trigger\n root = parent;\n } else if (nodeSet.has(parent)) {\n // ngIf inside ngIf\n root = NULL_NODE;\n } else {\n // recurse upwards\n root = getRoot(parent);\n }\n\n localRootMap.set(node, root);\n return root;\n }\n\n nodes.forEach(node => {\n const root = getRoot(node);\n\n if (root !== NULL_NODE) {\n rootMap.get(root).push(node);\n }\n });\n return rootMap;\n}\n\nfunction addClass(element, className) {\n var _element$classList2;\n\n (_element$classList2 = element.classList) === null || _element$classList2 === void 0 ? void 0 : _element$classList2.add(className);\n}\n\nfunction removeClass(element, className) {\n var _element$classList3;\n\n (_element$classList3 = element.classList) === null || _element$classList3 === void 0 ? void 0 : _element$classList3.remove(className);\n}\n\nfunction removeNodesAfterAnimationDone(engine, element, players) {\n optimizeGroupPlayer(players).onDone(() => engine.processLeaveNode(element));\n}\n\nfunction flattenGroupPlayers(players) {\n const finalPlayers = [];\n\n _flattenGroupPlayersRecur(players, finalPlayers);\n\n return finalPlayers;\n}\n\nfunction _flattenGroupPlayersRecur(players, finalPlayers) {\n for (let i = 0; i < players.length; i++) {\n const player = players[i];\n\n if (player instanceof ɵAnimationGroupPlayer) {\n _flattenGroupPlayersRecur(player.players, finalPlayers);\n } else {\n finalPlayers.push(player);\n }\n }\n}\n\nfunction objEquals(a, b) {\n const k1 = Object.keys(a);\n const k2 = Object.keys(b);\n if (k1.length != k2.length) return false;\n\n for (let i = 0; i < k1.length; i++) {\n const prop = k1[i];\n if (!b.hasOwnProperty(prop) || a[prop] !== b[prop]) return false;\n }\n\n return true;\n}\n\nfunction replacePostStylesAsPre(element, allPreStyleElements, allPostStyleElements) {\n const postEntry = allPostStyleElements.get(element);\n if (!postEntry) return false;\n let preEntry = allPreStyleElements.get(element);\n\n if (preEntry) {\n postEntry.forEach(data => preEntry.add(data));\n } else {\n allPreStyleElements.set(element, postEntry);\n }\n\n allPostStyleElements.delete(element);\n return true;\n}\n\nclass AnimationEngine {\n constructor(bodyNode, _driver, _normalizer) {\n this.bodyNode = bodyNode;\n this._driver = _driver;\n this._normalizer = _normalizer;\n this._triggerCache = {}; // this method is designed to be overridden by the code that uses this engine\n\n this.onRemovalComplete = (element, context) => {};\n\n this._transitionEngine = new TransitionAnimationEngine(bodyNode, _driver, _normalizer);\n this._timelineEngine = new TimelineAnimationEngine(bodyNode, _driver, _normalizer);\n\n this._transitionEngine.onRemovalComplete = (element, context) => this.onRemovalComplete(element, context);\n }\n\n registerTrigger(componentId, namespaceId, hostElement, name, metadata) {\n const cacheKey = componentId + '-' + name;\n let trigger = this._triggerCache[cacheKey];\n\n if (!trigger) {\n const errors = [];\n const warnings = [];\n const ast = buildAnimationAst(this._driver, metadata, errors, warnings);\n\n if (errors.length) {\n throw triggerBuildFailed(name, errors);\n }\n\n if (warnings.length) {\n warnTriggerBuild(name, warnings);\n }\n\n trigger = buildTrigger(name, ast, this._normalizer);\n this._triggerCache[cacheKey] = trigger;\n }\n\n this._transitionEngine.registerTrigger(namespaceId, name, trigger);\n }\n\n register(namespaceId, hostElement) {\n this._transitionEngine.register(namespaceId, hostElement);\n }\n\n destroy(namespaceId, context) {\n this._transitionEngine.destroy(namespaceId, context);\n }\n\n onInsert(namespaceId, element, parent, insertBefore) {\n this._transitionEngine.insertNode(namespaceId, element, parent, insertBefore);\n }\n\n onRemove(namespaceId, element, context, isHostElement) {\n this._transitionEngine.removeNode(namespaceId, element, isHostElement || false, context);\n }\n\n disableAnimations(element, disable) {\n this._transitionEngine.markElementAsDisabled(element, disable);\n }\n\n process(namespaceId, element, property, value) {\n if (property.charAt(0) == '@') {\n const [id, action] = parseTimelineCommand(property);\n const args = value;\n\n this._timelineEngine.command(id, element, action, args);\n } else {\n this._transitionEngine.trigger(namespaceId, element, property, value);\n }\n }\n\n listen(namespaceId, element, eventName, eventPhase, callback) {\n // @@listen\n if (eventName.charAt(0) == '@') {\n const [id, action] = parseTimelineCommand(eventName);\n return this._timelineEngine.listen(id, element, action, callback);\n }\n\n return this._transitionEngine.listen(namespaceId, element, eventName, eventPhase, callback);\n }\n\n flush(microtaskId = -1) {\n this._transitionEngine.flush(microtaskId);\n }\n\n get players() {\n return this._transitionEngine.players.concat(this._timelineEngine.players);\n }\n\n whenRenderingDone() {\n return this._transitionEngine.whenRenderingDone();\n }\n\n}\n/**\n * Returns an instance of `SpecialCasedStyles` if and when any special (non animateable) styles are\n * detected.\n *\n * In CSS there exist properties that cannot be animated within a keyframe animation\n * (whether it be via CSS keyframes or web-animations) and the animation implementation\n * will ignore them. This function is designed to detect those special cased styles and\n * return a container that will be executed at the start and end of the animation.\n *\n * @returns an instance of `SpecialCasedStyles` if any special styles are detected otherwise `null`\n */\n\n\nfunction packageNonAnimatableStyles(element, styles) {\n let startStyles = null;\n let endStyles = null;\n\n if (Array.isArray(styles) && styles.length) {\n startStyles = filterNonAnimatableStyles(styles[0]);\n\n if (styles.length > 1) {\n endStyles = filterNonAnimatableStyles(styles[styles.length - 1]);\n }\n } else if (styles instanceof Map) {\n startStyles = filterNonAnimatableStyles(styles);\n }\n\n return startStyles || endStyles ? new SpecialCasedStyles(element, startStyles, endStyles) : null;\n}\n/**\n * Designed to be executed during a keyframe-based animation to apply any special-cased styles.\n *\n * When started (when the `start()` method is run) then the provided `startStyles`\n * will be applied. When finished (when the `finish()` method is called) the\n * `endStyles` will be applied as well any any starting styles. Finally when\n * `destroy()` is called then all styles will be removed.\n */\n\n\nlet SpecialCasedStyles = /*#__PURE__*/(() => {\n class SpecialCasedStyles {\n constructor(_element, _startStyles, _endStyles) {\n this._element = _element;\n this._startStyles = _startStyles;\n this._endStyles = _endStyles;\n this._state = 0\n /* SpecialCasedStylesState.Pending */\n ;\n let initialStyles = SpecialCasedStyles.initialStylesByElement.get(_element);\n\n if (!initialStyles) {\n SpecialCasedStyles.initialStylesByElement.set(_element, initialStyles = new Map());\n }\n\n this._initialStyles = initialStyles;\n }\n\n start() {\n if (this._state < 1\n /* SpecialCasedStylesState.Started */\n ) {\n if (this._startStyles) {\n setStyles(this._element, this._startStyles, this._initialStyles);\n }\n\n this._state = 1\n /* SpecialCasedStylesState.Started */\n ;\n }\n }\n\n finish() {\n this.start();\n\n if (this._state < 2\n /* SpecialCasedStylesState.Finished */\n ) {\n setStyles(this._element, this._initialStyles);\n\n if (this._endStyles) {\n setStyles(this._element, this._endStyles);\n this._endStyles = null;\n }\n\n this._state = 1\n /* SpecialCasedStylesState.Started */\n ;\n }\n }\n\n destroy() {\n this.finish();\n\n if (this._state < 3\n /* SpecialCasedStylesState.Destroyed */\n ) {\n SpecialCasedStyles.initialStylesByElement.delete(this._element);\n\n if (this._startStyles) {\n eraseStyles(this._element, this._startStyles);\n this._endStyles = null;\n }\n\n if (this._endStyles) {\n eraseStyles(this._element, this._endStyles);\n this._endStyles = null;\n }\n\n setStyles(this._element, this._initialStyles);\n this._state = 3\n /* SpecialCasedStylesState.Destroyed */\n ;\n }\n }\n\n }\n\n SpecialCasedStyles.initialStylesByElement = /* @__PURE__ */new WeakMap();\n return SpecialCasedStyles;\n})();\n\nfunction filterNonAnimatableStyles(styles) {\n let result = null;\n styles.forEach((val, prop) => {\n if (isNonAnimatableStyle(prop)) {\n result = result || new Map();\n result.set(prop, val);\n }\n });\n return result;\n}\n\nfunction isNonAnimatableStyle(prop) {\n return prop === 'display' || prop === 'position';\n}\n\nclass WebAnimationsPlayer {\n constructor(element, keyframes, options, _specialStyles) {\n this.element = element;\n this.keyframes = keyframes;\n this.options = options;\n this._specialStyles = _specialStyles;\n this._onDoneFns = [];\n this._onStartFns = [];\n this._onDestroyFns = [];\n this._initialized = false;\n this._finished = false;\n this._started = false;\n this._destroyed = false; // the following original fns are persistent copies of the _onStartFns and _onDoneFns\n // and are used to reset the fns to their original values upon reset()\n // (since the _onStartFns and _onDoneFns get deleted after they are called)\n\n this._originalOnDoneFns = [];\n this._originalOnStartFns = [];\n this.time = 0;\n this.parentPlayer = null;\n this.currentSnapshot = new Map();\n this._duration = options['duration'];\n this._delay = options['delay'] || 0;\n this.time = this._duration + this._delay;\n }\n\n _onFinish() {\n if (!this._finished) {\n this._finished = true;\n\n this._onDoneFns.forEach(fn => fn());\n\n this._onDoneFns = [];\n }\n }\n\n init() {\n this._buildPlayer();\n\n this._preparePlayerBeforeStart();\n }\n\n _buildPlayer() {\n if (this._initialized) return;\n this._initialized = true;\n const keyframes = this.keyframes;\n this.domPlayer = this._triggerWebAnimation(this.element, keyframes, this.options);\n this._finalKeyframe = keyframes.length ? keyframes[keyframes.length - 1] : new Map();\n this.domPlayer.addEventListener('finish', () => this._onFinish());\n }\n\n _preparePlayerBeforeStart() {\n // this is required so that the player doesn't start to animate right away\n if (this._delay) {\n this._resetDomPlayerState();\n } else {\n this.domPlayer.pause();\n }\n }\n\n _convertKeyframesToObject(keyframes) {\n const kfs = [];\n keyframes.forEach(frame => {\n kfs.push(Object.fromEntries(frame));\n });\n return kfs;\n }\n /** @internal */\n\n\n _triggerWebAnimation(element, keyframes, options) {\n // jscompiler doesn't seem to know animate is a native property because it's not fully\n // supported yet across common browsers (we polyfill it for Edge/Safari) [CL #143630929]\n return element['animate'](this._convertKeyframesToObject(keyframes), options);\n }\n\n onStart(fn) {\n this._originalOnStartFns.push(fn);\n\n this._onStartFns.push(fn);\n }\n\n onDone(fn) {\n this._originalOnDoneFns.push(fn);\n\n this._onDoneFns.push(fn);\n }\n\n onDestroy(fn) {\n this._onDestroyFns.push(fn);\n }\n\n play() {\n this._buildPlayer();\n\n if (!this.hasStarted()) {\n this._onStartFns.forEach(fn => fn());\n\n this._onStartFns = [];\n this._started = true;\n\n if (this._specialStyles) {\n this._specialStyles.start();\n }\n }\n\n this.domPlayer.play();\n }\n\n pause() {\n this.init();\n this.domPlayer.pause();\n }\n\n finish() {\n this.init();\n\n if (this._specialStyles) {\n this._specialStyles.finish();\n }\n\n this._onFinish();\n\n this.domPlayer.finish();\n }\n\n reset() {\n this._resetDomPlayerState();\n\n this._destroyed = false;\n this._finished = false;\n this._started = false;\n this._onStartFns = this._originalOnStartFns;\n this._onDoneFns = this._originalOnDoneFns;\n }\n\n _resetDomPlayerState() {\n if (this.domPlayer) {\n this.domPlayer.cancel();\n }\n }\n\n restart() {\n this.reset();\n this.play();\n }\n\n hasStarted() {\n return this._started;\n }\n\n destroy() {\n if (!this._destroyed) {\n this._destroyed = true;\n\n this._resetDomPlayerState();\n\n this._onFinish();\n\n if (this._specialStyles) {\n this._specialStyles.destroy();\n }\n\n this._onDestroyFns.forEach(fn => fn());\n\n this._onDestroyFns = [];\n }\n }\n\n setPosition(p) {\n if (this.domPlayer === undefined) {\n this.init();\n }\n\n this.domPlayer.currentTime = p * this.time;\n }\n\n getPosition() {\n return this.domPlayer.currentTime / this.time;\n }\n\n get totalTime() {\n return this._delay + this._duration;\n }\n\n beforeDestroy() {\n const styles = new Map();\n\n if (this.hasStarted()) {\n // note: this code is invoked only when the `play` function was called prior to this\n // (thus `hasStarted` returns true), this implies that the code that initializes\n // `_finalKeyframe` has also been executed and the non-null assertion can be safely used here\n const finalKeyframe = this._finalKeyframe;\n finalKeyframe.forEach((val, prop) => {\n if (prop !== 'offset') {\n styles.set(prop, this._finished ? val : computeStyle(this.element, prop));\n }\n });\n }\n\n this.currentSnapshot = styles;\n }\n /** @internal */\n\n\n triggerCallback(phaseName) {\n const methods = phaseName === 'start' ? this._onStartFns : this._onDoneFns;\n methods.forEach(fn => fn());\n methods.length = 0;\n }\n\n}\n\nclass WebAnimationsDriver {\n validateStyleProperty(prop) {\n // Perform actual validation in dev mode only, in prod mode this check is a noop.\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n return validateStyleProperty(prop);\n }\n\n return true;\n }\n\n validateAnimatableStyleProperty(prop) {\n // Perform actual validation in dev mode only, in prod mode this check is a noop.\n if (typeof ngDevMode === 'undefined' || ngDevMode) {\n const cssProp = camelCaseToDashCase(prop);\n return validateWebAnimatableStyleProperty(cssProp);\n }\n\n return true;\n }\n\n matchesElement(_element, _selector) {\n // This method is deprecated and no longer in use so we return false.\n return false;\n }\n\n containsElement(elm1, elm2) {\n return containsElement(elm1, elm2);\n }\n\n getParentElement(element) {\n return getParentElement(element);\n }\n\n query(element, selector, multi) {\n return invokeQuery(element, selector, multi);\n }\n\n computeStyle(element, prop, defaultValue) {\n return window.getComputedStyle(element)[prop];\n }\n\n animate(element, keyframes, duration, delay, easing, previousPlayers = []) {\n const fill = delay == 0 ? 'both' : 'forwards';\n const playerOptions = {\n duration,\n delay,\n fill\n }; // we check for this to avoid having a null|undefined value be present\n // for the easing (which results in an error for certain browsers #9752)\n\n if (easing) {\n playerOptions['easing'] = easing;\n }\n\n const previousStyles = new Map();\n const previousWebAnimationPlayers = previousPlayers.filter(player => player instanceof WebAnimationsPlayer);\n\n if (allowPreviousPlayerStylesMerge(duration, delay)) {\n previousWebAnimationPlayers.forEach(player => {\n player.currentSnapshot.forEach((val, prop) => previousStyles.set(prop, val));\n });\n }\n\n let _keyframes = normalizeKeyframes(keyframes).map(styles => copyStyles(styles));\n\n _keyframes = balancePreviousStylesIntoKeyframes(element, _keyframes, previousStyles);\n const specialStyles = packageNonAnimatableStyles(element, _keyframes);\n return new WebAnimationsPlayer(element, _keyframes, playerOptions, specialStyles);\n }\n\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Generated bundle index. Do not edit.\n */\n\n\nexport { AnimationDriver, Animation as ɵAnimation, AnimationEngine as ɵAnimationEngine, AnimationStyleNormalizer as ɵAnimationStyleNormalizer, NoopAnimationDriver as ɵNoopAnimationDriver, NoopAnimationStyleNormalizer as ɵNoopAnimationStyleNormalizer, WebAnimationsDriver as ɵWebAnimationsDriver, WebAnimationsPlayer as ɵWebAnimationsPlayer, WebAnimationsStyleNormalizer as ɵWebAnimationsStyleNormalizer, allowPreviousPlayerStylesMerge as ɵallowPreviousPlayerStylesMerge, containsElement as ɵcontainsElement, getParentElement as ɵgetParentElement, invokeQuery as ɵinvokeQuery, normalizeKeyframes as ɵnormalizeKeyframes, validateStyleProperty as ɵvalidateStyleProperty }; //# sourceMappingURL=browser.mjs.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/232896b0ac94dc4c308b28e6b9248c0e.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/232896b0ac94dc4c308b28e6b9248c0e.json
deleted file mode 100644
index ef6b36a2..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/232896b0ac94dc4c308b28e6b9248c0e.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { mergeMap } from './mergeMap';\nimport { identity } from '../util/identity';\nexport function mergeAll(concurrent = Infinity) {\n return mergeMap(identity, concurrent);\n} //# sourceMappingURL=mergeAll.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/23914479387e00b98986a4de82f6951d.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/23914479387e00b98986a4de82f6951d.json
deleted file mode 100644
index 564b52d0..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/23914479387e00b98986a4de82f6951d.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { Observable } from '../Observable';\nimport { executeSchedule } from '../util/executeSchedule';\nexport function scheduleAsyncIterable(input, scheduler) {\n if (!input) {\n throw new Error('Iterable cannot be null');\n }\n\n return new Observable(subscriber => {\n executeSchedule(subscriber, scheduler, () => {\n const iterator = input[Symbol.asyncIterator]();\n executeSchedule(subscriber, scheduler, () => {\n iterator.next().then(result => {\n if (result.done) {\n subscriber.complete();\n } else {\n subscriber.next(result.value);\n }\n });\n }, 0, true);\n });\n });\n} //# sourceMappingURL=scheduleAsyncIterable.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/23d186a3f5fdeb4bc185eed2fe54284d.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/23d186a3f5fdeb4bc185eed2fe54284d.json
deleted file mode 100644
index eddd119e..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/23d186a3f5fdeb4bc185eed2fe54284d.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { __asyncValues, __awaiter } from \"tslib\";\nimport { isArrayLike } from '../util/isArrayLike';\nimport { isPromise } from '../util/isPromise';\nimport { Observable } from '../Observable';\nimport { isInteropObservable } from '../util/isInteropObservable';\nimport { isAsyncIterable } from '../util/isAsyncIterable';\nimport { createInvalidObservableTypeError } from '../util/throwUnobservableError';\nimport { isIterable } from '../util/isIterable';\nimport { isReadableStreamLike, readableStreamLikeToAsyncGenerator } from '../util/isReadableStreamLike';\nimport { isFunction } from '../util/isFunction';\nimport { reportUnhandledError } from '../util/reportUnhandledError';\nimport { observable as Symbol_observable } from '../symbol/observable';\nexport function innerFrom(input) {\n if (input instanceof Observable) {\n return input;\n }\n\n if (input != null) {\n if (isInteropObservable(input)) {\n return fromInteropObservable(input);\n }\n\n if (isArrayLike(input)) {\n return fromArrayLike(input);\n }\n\n if (isPromise(input)) {\n return fromPromise(input);\n }\n\n if (isAsyncIterable(input)) {\n return fromAsyncIterable(input);\n }\n\n if (isIterable(input)) {\n return fromIterable(input);\n }\n\n if (isReadableStreamLike(input)) {\n return fromReadableStreamLike(input);\n }\n }\n\n throw createInvalidObservableTypeError(input);\n}\nexport function fromInteropObservable(obj) {\n return new Observable(subscriber => {\n const obs = obj[Symbol_observable]();\n\n if (isFunction(obs.subscribe)) {\n return obs.subscribe(subscriber);\n }\n\n throw new TypeError('Provided object does not correctly implement Symbol.observable');\n });\n}\nexport function fromArrayLike(array) {\n return new Observable(subscriber => {\n for (let i = 0; i < array.length && !subscriber.closed; i++) {\n subscriber.next(array[i]);\n }\n\n subscriber.complete();\n });\n}\nexport function fromPromise(promise) {\n return new Observable(subscriber => {\n promise.then(value => {\n if (!subscriber.closed) {\n subscriber.next(value);\n subscriber.complete();\n }\n }, err => subscriber.error(err)).then(null, reportUnhandledError);\n });\n}\nexport function fromIterable(iterable) {\n return new Observable(subscriber => {\n for (const value of iterable) {\n subscriber.next(value);\n\n if (subscriber.closed) {\n return;\n }\n }\n\n subscriber.complete();\n });\n}\nexport function fromAsyncIterable(asyncIterable) {\n return new Observable(subscriber => {\n process(asyncIterable, subscriber).catch(err => subscriber.error(err));\n });\n}\nexport function fromReadableStreamLike(readableStream) {\n return fromAsyncIterable(readableStreamLikeToAsyncGenerator(readableStream));\n}\n\nfunction process(asyncIterable, subscriber) {\n var asyncIterable_1, asyncIterable_1_1;\n\n var e_1, _a;\n\n return __awaiter(this, void 0, void 0, function* () {\n try {\n for (asyncIterable_1 = __asyncValues(asyncIterable); asyncIterable_1_1 = yield asyncIterable_1.next(), !asyncIterable_1_1.done;) {\n const value = asyncIterable_1_1.value;\n subscriber.next(value);\n\n if (subscriber.closed) {\n return;\n }\n }\n } catch (e_1_1) {\n e_1 = {\n error: e_1_1\n };\n } finally {\n try {\n if (asyncIterable_1_1 && !asyncIterable_1_1.done && (_a = asyncIterable_1.return)) yield _a.call(asyncIterable_1);\n } finally {\n if (e_1) throw e_1.error;\n }\n }\n\n subscriber.complete();\n });\n} //# sourceMappingURL=innerFrom.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/244e3d8711aebbebb815322f8ca979a7.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/244e3d8711aebbebb815322f8ca979a7.json
deleted file mode 100644
index 4eaf56b9..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/244e3d8711aebbebb815322f8ca979a7.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { coerceNumberProperty, coerceElement, coerceBooleanProperty } from '@angular/cdk/coercion';\nimport * as i0 from '@angular/core';\nimport { InjectionToken, forwardRef, Directive, Input, Injectable, Optional, Inject, Component, ViewEncapsulation, ChangeDetectionStrategy, Output, ViewChild, SkipSelf, NgModule } from '@angular/core';\nimport { Subject, of, Observable, fromEvent, animationFrameScheduler, asapScheduler, Subscription, isObservable } from 'rxjs';\nimport { distinctUntilChanged, auditTime, filter, takeUntil, startWith, pairwise, switchMap, shareReplay } from 'rxjs/operators';\nimport * as i1 from '@angular/cdk/platform';\nimport { getRtlScrollAxisType, supportsScrollBehavior, PlatformModule } from '@angular/cdk/platform';\nimport { DOCUMENT } from '@angular/common';\nimport * as i2 from '@angular/cdk/bidi';\nimport { BidiModule } from '@angular/cdk/bidi';\nimport * as i2$1 from '@angular/cdk/collections';\nimport { isDataSource, ArrayDataSource, _VIEW_REPEATER_STRATEGY, _RecycleViewRepeaterStrategy } from '@angular/cdk/collections';\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/** The injection token used to specify the virtual scrolling strategy. */\n\nconst _c0 = [\"contentWrapper\"];\nconst _c1 = [\"*\"];\nconst VIRTUAL_SCROLL_STRATEGY = /*#__PURE__*/new InjectionToken('VIRTUAL_SCROLL_STRATEGY');\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/** Virtual scrolling strategy for lists with items of known fixed size. */\n\nclass FixedSizeVirtualScrollStrategy {\n /**\n * @param itemSize The size of the items in the virtually scrolling list.\n * @param minBufferPx The minimum amount of buffer (in pixels) before needing to render more\n * @param maxBufferPx The amount of buffer (in pixels) to render when rendering more.\n */\n constructor(itemSize, minBufferPx, maxBufferPx) {\n this._scrolledIndexChange = new Subject();\n /** @docs-private Implemented as part of VirtualScrollStrategy. */\n\n this.scrolledIndexChange = this._scrolledIndexChange.pipe(distinctUntilChanged());\n /** The attached viewport. */\n\n this._viewport = null;\n this._itemSize = itemSize;\n this._minBufferPx = minBufferPx;\n this._maxBufferPx = maxBufferPx;\n }\n /**\n * Attaches this scroll strategy to a viewport.\n * @param viewport The viewport to attach this strategy to.\n */\n\n\n attach(viewport) {\n this._viewport = viewport;\n\n this._updateTotalContentSize();\n\n this._updateRenderedRange();\n }\n /** Detaches this scroll strategy from the currently attached viewport. */\n\n\n detach() {\n this._scrolledIndexChange.complete();\n\n this._viewport = null;\n }\n /**\n * Update the item size and buffer size.\n * @param itemSize The size of the items in the virtually scrolling list.\n * @param minBufferPx The minimum amount of buffer (in pixels) before needing to render more\n * @param maxBufferPx The amount of buffer (in pixels) to render when rendering more.\n */\n\n\n updateItemAndBufferSize(itemSize, minBufferPx, maxBufferPx) {\n if (maxBufferPx < minBufferPx && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n throw Error('CDK virtual scroll: maxBufferPx must be greater than or equal to minBufferPx');\n }\n\n this._itemSize = itemSize;\n this._minBufferPx = minBufferPx;\n this._maxBufferPx = maxBufferPx;\n\n this._updateTotalContentSize();\n\n this._updateRenderedRange();\n }\n /** @docs-private Implemented as part of VirtualScrollStrategy. */\n\n\n onContentScrolled() {\n this._updateRenderedRange();\n }\n /** @docs-private Implemented as part of VirtualScrollStrategy. */\n\n\n onDataLengthChanged() {\n this._updateTotalContentSize();\n\n this._updateRenderedRange();\n }\n /** @docs-private Implemented as part of VirtualScrollStrategy. */\n\n\n onContentRendered() {\n /* no-op */\n }\n /** @docs-private Implemented as part of VirtualScrollStrategy. */\n\n\n onRenderedOffsetChanged() {\n /* no-op */\n }\n /**\n * Scroll to the offset for the given index.\n * @param index The index of the element to scroll to.\n * @param behavior The ScrollBehavior to use when scrolling.\n */\n\n\n scrollToIndex(index, behavior) {\n if (this._viewport) {\n this._viewport.scrollToOffset(index * this._itemSize, behavior);\n }\n }\n /** Update the viewport's total content size. */\n\n\n _updateTotalContentSize() {\n if (!this._viewport) {\n return;\n }\n\n this._viewport.setTotalContentSize(this._viewport.getDataLength() * this._itemSize);\n }\n /** Update the viewport's rendered range. */\n\n\n _updateRenderedRange() {\n if (!this._viewport) {\n return;\n }\n\n const renderedRange = this._viewport.getRenderedRange();\n\n const newRange = {\n start: renderedRange.start,\n end: renderedRange.end\n };\n\n const viewportSize = this._viewport.getViewportSize();\n\n const dataLength = this._viewport.getDataLength();\n\n let scrollOffset = this._viewport.measureScrollOffset(); // Prevent NaN as result when dividing by zero.\n\n\n let firstVisibleIndex = this._itemSize > 0 ? scrollOffset / this._itemSize : 0; // If user scrolls to the bottom of the list and data changes to a smaller list\n\n if (newRange.end > dataLength) {\n // We have to recalculate the first visible index based on new data length and viewport size.\n const maxVisibleItems = Math.ceil(viewportSize / this._itemSize);\n const newVisibleIndex = Math.max(0, Math.min(firstVisibleIndex, dataLength - maxVisibleItems)); // If first visible index changed we must update scroll offset to handle start/end buffers\n // Current range must also be adjusted to cover the new position (bottom of new list).\n\n if (firstVisibleIndex != newVisibleIndex) {\n firstVisibleIndex = newVisibleIndex;\n scrollOffset = newVisibleIndex * this._itemSize;\n newRange.start = Math.floor(firstVisibleIndex);\n }\n\n newRange.end = Math.max(0, Math.min(dataLength, newRange.start + maxVisibleItems));\n }\n\n const startBuffer = scrollOffset - newRange.start * this._itemSize;\n\n if (startBuffer < this._minBufferPx && newRange.start != 0) {\n const expandStart = Math.ceil((this._maxBufferPx - startBuffer) / this._itemSize);\n newRange.start = Math.max(0, newRange.start - expandStart);\n newRange.end = Math.min(dataLength, Math.ceil(firstVisibleIndex + (viewportSize + this._minBufferPx) / this._itemSize));\n } else {\n const endBuffer = newRange.end * this._itemSize - (scrollOffset + viewportSize);\n\n if (endBuffer < this._minBufferPx && newRange.end != dataLength) {\n const expandEnd = Math.ceil((this._maxBufferPx - endBuffer) / this._itemSize);\n\n if (expandEnd > 0) {\n newRange.end = Math.min(dataLength, newRange.end + expandEnd);\n newRange.start = Math.max(0, Math.floor(firstVisibleIndex - this._minBufferPx / this._itemSize));\n }\n }\n }\n\n this._viewport.setRenderedRange(newRange);\n\n this._viewport.setRenderedContentOffset(this._itemSize * newRange.start);\n\n this._scrolledIndexChange.next(Math.floor(firstVisibleIndex));\n }\n\n}\n/**\n * Provider factory for `FixedSizeVirtualScrollStrategy` that simply extracts the already created\n * `FixedSizeVirtualScrollStrategy` from the given directive.\n * @param fixedSizeDir The instance of `CdkFixedSizeVirtualScroll` to extract the\n * `FixedSizeVirtualScrollStrategy` from.\n */\n\n\nfunction _fixedSizeVirtualScrollStrategyFactory(fixedSizeDir) {\n return fixedSizeDir._scrollStrategy;\n}\n/** A virtual scroll strategy that supports fixed-size items. */\n\n\nlet CdkFixedSizeVirtualScroll = /*#__PURE__*/(() => {\n class CdkFixedSizeVirtualScroll {\n constructor() {\n this._itemSize = 20;\n this._minBufferPx = 100;\n this._maxBufferPx = 200;\n /** The scroll strategy used by this directive. */\n\n this._scrollStrategy = new FixedSizeVirtualScrollStrategy(this.itemSize, this.minBufferPx, this.maxBufferPx);\n }\n /** The size of the items in the list (in pixels). */\n\n\n get itemSize() {\n return this._itemSize;\n }\n\n set itemSize(value) {\n this._itemSize = coerceNumberProperty(value);\n }\n /**\n * The minimum amount of buffer rendered beyond the viewport (in pixels).\n * If the amount of buffer dips below this number, more items will be rendered. Defaults to 100px.\n */\n\n\n get minBufferPx() {\n return this._minBufferPx;\n }\n\n set minBufferPx(value) {\n this._minBufferPx = coerceNumberProperty(value);\n }\n /**\n * The number of pixels worth of buffer to render for when rendering new items. Defaults to 200px.\n */\n\n\n get maxBufferPx() {\n return this._maxBufferPx;\n }\n\n set maxBufferPx(value) {\n this._maxBufferPx = coerceNumberProperty(value);\n }\n\n ngOnChanges() {\n this._scrollStrategy.updateItemAndBufferSize(this.itemSize, this.minBufferPx, this.maxBufferPx);\n }\n\n }\n\n CdkFixedSizeVirtualScroll.ɵfac = function CdkFixedSizeVirtualScroll_Factory(t) {\n return new (t || CdkFixedSizeVirtualScroll)();\n };\n\n CdkFixedSizeVirtualScroll.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: CdkFixedSizeVirtualScroll,\n selectors: [[\"cdk-virtual-scroll-viewport\", \"itemSize\", \"\"]],\n inputs: {\n itemSize: \"itemSize\",\n minBufferPx: \"minBufferPx\",\n maxBufferPx: \"maxBufferPx\"\n },\n features: [i0.ɵɵProvidersFeature([{\n provide: VIRTUAL_SCROLL_STRATEGY,\n useFactory: _fixedSizeVirtualScrollStrategyFactory,\n deps: [forwardRef(() => CdkFixedSizeVirtualScroll)]\n }]), i0.ɵɵNgOnChangesFeature]\n });\n return CdkFixedSizeVirtualScroll;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/** Time in ms to throttle the scrolling events by default. */\n\n\nconst DEFAULT_SCROLL_TIME = 20;\n/**\n * Service contained all registered Scrollable references and emits an event when any one of the\n * Scrollable references emit a scrolled event.\n */\n\nlet ScrollDispatcher = /*#__PURE__*/(() => {\n class ScrollDispatcher {\n constructor(_ngZone, _platform, document) {\n this._ngZone = _ngZone;\n this._platform = _platform;\n /** Subject for notifying that a registered scrollable reference element has been scrolled. */\n\n this._scrolled = new Subject();\n /** Keeps track of the global `scroll` and `resize` subscriptions. */\n\n this._globalSubscription = null;\n /** Keeps track of the amount of subscriptions to `scrolled`. Used for cleaning up afterwards. */\n\n this._scrolledCount = 0;\n /**\n * Map of all the scrollable references that are registered with the service and their\n * scroll event subscriptions.\n */\n\n this.scrollContainers = new Map();\n this._document = document;\n }\n /**\n * Registers a scrollable instance with the service and listens for its scrolled events. When the\n * scrollable is scrolled, the service emits the event to its scrolled observable.\n * @param scrollable Scrollable instance to be registered.\n */\n\n\n register(scrollable) {\n if (!this.scrollContainers.has(scrollable)) {\n this.scrollContainers.set(scrollable, scrollable.elementScrolled().subscribe(() => this._scrolled.next(scrollable)));\n }\n }\n /**\n * Deregisters a Scrollable reference and unsubscribes from its scroll event observable.\n * @param scrollable Scrollable instance to be deregistered.\n */\n\n\n deregister(scrollable) {\n const scrollableReference = this.scrollContainers.get(scrollable);\n\n if (scrollableReference) {\n scrollableReference.unsubscribe();\n this.scrollContainers.delete(scrollable);\n }\n }\n /**\n * Returns an observable that emits an event whenever any of the registered Scrollable\n * references (or window, document, or body) fire a scrolled event. Can provide a time in ms\n * to override the default \"throttle\" time.\n *\n * **Note:** in order to avoid hitting change detection for every scroll event,\n * all of the events emitted from this stream will be run outside the Angular zone.\n * If you need to update any data bindings as a result of a scroll event, you have\n * to run the callback using `NgZone.run`.\n */\n\n\n scrolled(auditTimeInMs = DEFAULT_SCROLL_TIME) {\n if (!this._platform.isBrowser) {\n return of();\n }\n\n return new Observable(observer => {\n if (!this._globalSubscription) {\n this._addGlobalListener();\n } // In the case of a 0ms delay, use an observable without auditTime\n // since it does add a perceptible delay in processing overhead.\n\n\n const subscription = auditTimeInMs > 0 ? this._scrolled.pipe(auditTime(auditTimeInMs)).subscribe(observer) : this._scrolled.subscribe(observer);\n this._scrolledCount++;\n return () => {\n subscription.unsubscribe();\n this._scrolledCount--;\n\n if (!this._scrolledCount) {\n this._removeGlobalListener();\n }\n };\n });\n }\n\n ngOnDestroy() {\n this._removeGlobalListener();\n\n this.scrollContainers.forEach((_, container) => this.deregister(container));\n\n this._scrolled.complete();\n }\n /**\n * Returns an observable that emits whenever any of the\n * scrollable ancestors of an element are scrolled.\n * @param elementOrElementRef Element whose ancestors to listen for.\n * @param auditTimeInMs Time to throttle the scroll events.\n */\n\n\n ancestorScrolled(elementOrElementRef, auditTimeInMs) {\n const ancestors = this.getAncestorScrollContainers(elementOrElementRef);\n return this.scrolled(auditTimeInMs).pipe(filter(target => {\n return !target || ancestors.indexOf(target) > -1;\n }));\n }\n /** Returns all registered Scrollables that contain the provided element. */\n\n\n getAncestorScrollContainers(elementOrElementRef) {\n const scrollingContainers = [];\n this.scrollContainers.forEach((_subscription, scrollable) => {\n if (this._scrollableContainsElement(scrollable, elementOrElementRef)) {\n scrollingContainers.push(scrollable);\n }\n });\n return scrollingContainers;\n }\n /** Use defaultView of injected document if available or fallback to global window reference */\n\n\n _getWindow() {\n return this._document.defaultView || window;\n }\n /** Returns true if the element is contained within the provided Scrollable. */\n\n\n _scrollableContainsElement(scrollable, elementOrElementRef) {\n let element = coerceElement(elementOrElementRef);\n let scrollableElement = scrollable.getElementRef().nativeElement; // Traverse through the element parents until we reach null, checking if any of the elements\n // are the scrollable's element.\n\n do {\n if (element == scrollableElement) {\n return true;\n }\n } while (element = element.parentElement);\n\n return false;\n }\n /** Sets up the global scroll listeners. */\n\n\n _addGlobalListener() {\n this._globalSubscription = this._ngZone.runOutsideAngular(() => {\n const window = this._getWindow();\n\n return fromEvent(window.document, 'scroll').subscribe(() => this._scrolled.next());\n });\n }\n /** Cleans up the global scroll listener. */\n\n\n _removeGlobalListener() {\n if (this._globalSubscription) {\n this._globalSubscription.unsubscribe();\n\n this._globalSubscription = null;\n }\n }\n\n }\n\n ScrollDispatcher.ɵfac = function ScrollDispatcher_Factory(t) {\n return new (t || ScrollDispatcher)(i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(i1.Platform), i0.ɵɵinject(DOCUMENT, 8));\n };\n\n ScrollDispatcher.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: ScrollDispatcher,\n factory: ScrollDispatcher.ɵfac,\n providedIn: 'root'\n });\n return ScrollDispatcher;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Sends an event when the directive's element is scrolled. Registers itself with the\n * ScrollDispatcher service to include itself as part of its collection of scrolling events that it\n * can be listened to through the service.\n */\n\n\nlet CdkScrollable = /*#__PURE__*/(() => {\n class CdkScrollable {\n constructor(elementRef, scrollDispatcher, ngZone, dir) {\n this.elementRef = elementRef;\n this.scrollDispatcher = scrollDispatcher;\n this.ngZone = ngZone;\n this.dir = dir;\n this._destroyed = new Subject();\n this._elementScrolled = new Observable(observer => this.ngZone.runOutsideAngular(() => fromEvent(this.elementRef.nativeElement, 'scroll').pipe(takeUntil(this._destroyed)).subscribe(observer)));\n }\n\n ngOnInit() {\n this.scrollDispatcher.register(this);\n }\n\n ngOnDestroy() {\n this.scrollDispatcher.deregister(this);\n\n this._destroyed.next();\n\n this._destroyed.complete();\n }\n /** Returns observable that emits when a scroll event is fired on the host element. */\n\n\n elementScrolled() {\n return this._elementScrolled;\n }\n /** Gets the ElementRef for the viewport. */\n\n\n getElementRef() {\n return this.elementRef;\n }\n /**\n * Scrolls to the specified offsets. This is a normalized version of the browser's native scrollTo\n * method, since browsers are not consistent about what scrollLeft means in RTL. For this method\n * left and right always refer to the left and right side of the scrolling container irrespective\n * of the layout direction. start and end refer to left and right in an LTR context and vice-versa\n * in an RTL context.\n * @param options specified the offsets to scroll to.\n */\n\n\n scrollTo(options) {\n const el = this.elementRef.nativeElement;\n const isRtl = this.dir && this.dir.value == 'rtl'; // Rewrite start & end offsets as right or left offsets.\n\n if (options.left == null) {\n options.left = isRtl ? options.end : options.start;\n }\n\n if (options.right == null) {\n options.right = isRtl ? options.start : options.end;\n } // Rewrite the bottom offset as a top offset.\n\n\n if (options.bottom != null) {\n options.top = el.scrollHeight - el.clientHeight - options.bottom;\n } // Rewrite the right offset as a left offset.\n\n\n if (isRtl && getRtlScrollAxisType() != 0\n /* NORMAL */\n ) {\n if (options.left != null) {\n options.right = el.scrollWidth - el.clientWidth - options.left;\n }\n\n if (getRtlScrollAxisType() == 2\n /* INVERTED */\n ) {\n options.left = options.right;\n } else if (getRtlScrollAxisType() == 1\n /* NEGATED */\n ) {\n options.left = options.right ? -options.right : options.right;\n }\n } else {\n if (options.right != null) {\n options.left = el.scrollWidth - el.clientWidth - options.right;\n }\n }\n\n this._applyScrollToOptions(options);\n }\n\n _applyScrollToOptions(options) {\n const el = this.elementRef.nativeElement;\n\n if (supportsScrollBehavior()) {\n el.scrollTo(options);\n } else {\n if (options.top != null) {\n el.scrollTop = options.top;\n }\n\n if (options.left != null) {\n el.scrollLeft = options.left;\n }\n }\n }\n /**\n * Measures the scroll offset relative to the specified edge of the viewport. This method can be\n * used instead of directly checking scrollLeft or scrollTop, since browsers are not consistent\n * about what scrollLeft means in RTL. The values returned by this method are normalized such that\n * left and right always refer to the left and right side of the scrolling container irrespective\n * of the layout direction. start and end refer to left and right in an LTR context and vice-versa\n * in an RTL context.\n * @param from The edge to measure from.\n */\n\n\n measureScrollOffset(from) {\n const LEFT = 'left';\n const RIGHT = 'right';\n const el = this.elementRef.nativeElement;\n\n if (from == 'top') {\n return el.scrollTop;\n }\n\n if (from == 'bottom') {\n return el.scrollHeight - el.clientHeight - el.scrollTop;\n } // Rewrite start & end as left or right offsets.\n\n\n const isRtl = this.dir && this.dir.value == 'rtl';\n\n if (from == 'start') {\n from = isRtl ? RIGHT : LEFT;\n } else if (from == 'end') {\n from = isRtl ? LEFT : RIGHT;\n }\n\n if (isRtl && getRtlScrollAxisType() == 2\n /* INVERTED */\n ) {\n // For INVERTED, scrollLeft is (scrollWidth - clientWidth) when scrolled all the way left and\n // 0 when scrolled all the way right.\n if (from == LEFT) {\n return el.scrollWidth - el.clientWidth - el.scrollLeft;\n } else {\n return el.scrollLeft;\n }\n } else if (isRtl && getRtlScrollAxisType() == 1\n /* NEGATED */\n ) {\n // For NEGATED, scrollLeft is -(scrollWidth - clientWidth) when scrolled all the way left and\n // 0 when scrolled all the way right.\n if (from == LEFT) {\n return el.scrollLeft + el.scrollWidth - el.clientWidth;\n } else {\n return -el.scrollLeft;\n }\n } else {\n // For NORMAL, as well as non-RTL contexts, scrollLeft is 0 when scrolled all the way left and\n // (scrollWidth - clientWidth) when scrolled all the way right.\n if (from == LEFT) {\n return el.scrollLeft;\n } else {\n return el.scrollWidth - el.clientWidth - el.scrollLeft;\n }\n }\n }\n\n }\n\n CdkScrollable.ɵfac = function CdkScrollable_Factory(t) {\n return new (t || CdkScrollable)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(ScrollDispatcher), i0.ɵɵdirectiveInject(i0.NgZone), i0.ɵɵdirectiveInject(i2.Directionality, 8));\n };\n\n CdkScrollable.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: CdkScrollable,\n selectors: [[\"\", \"cdk-scrollable\", \"\"], [\"\", \"cdkScrollable\", \"\"]]\n });\n return CdkScrollable;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/** Time in ms to throttle the resize events by default. */\n\n\nconst DEFAULT_RESIZE_TIME = 20;\n/**\n * Simple utility for getting the bounds of the browser viewport.\n * @docs-private\n */\n\nlet ViewportRuler = /*#__PURE__*/(() => {\n class ViewportRuler {\n constructor(_platform, ngZone, document) {\n this._platform = _platform;\n /** Stream of viewport change events. */\n\n this._change = new Subject();\n /** Event listener that will be used to handle the viewport change events. */\n\n this._changeListener = event => {\n this._change.next(event);\n };\n\n this._document = document;\n ngZone.runOutsideAngular(() => {\n if (_platform.isBrowser) {\n const window = this._getWindow(); // Note that bind the events ourselves, rather than going through something like RxJS's\n // `fromEvent` so that we can ensure that they're bound outside of the NgZone.\n\n\n window.addEventListener('resize', this._changeListener);\n window.addEventListener('orientationchange', this._changeListener);\n } // Clear the cached position so that the viewport is re-measured next time it is required.\n // We don't need to keep track of the subscription, because it is completed on destroy.\n\n\n this.change().subscribe(() => this._viewportSize = null);\n });\n }\n\n ngOnDestroy() {\n if (this._platform.isBrowser) {\n const window = this._getWindow();\n\n window.removeEventListener('resize', this._changeListener);\n window.removeEventListener('orientationchange', this._changeListener);\n }\n\n this._change.complete();\n }\n /** Returns the viewport's width and height. */\n\n\n getViewportSize() {\n if (!this._viewportSize) {\n this._updateViewportSize();\n }\n\n const output = {\n width: this._viewportSize.width,\n height: this._viewportSize.height\n }; // If we're not on a browser, don't cache the size since it'll be mocked out anyway.\n\n if (!this._platform.isBrowser) {\n this._viewportSize = null;\n }\n\n return output;\n }\n /** Gets a ClientRect for the viewport's bounds. */\n\n\n getViewportRect() {\n // Use the document element's bounding rect rather than the window scroll properties\n // (e.g. pageYOffset, scrollY) due to in issue in Chrome and IE where window scroll\n // properties and client coordinates (boundingClientRect, clientX/Y, etc.) are in different\n // conceptual viewports. Under most circumstances these viewports are equivalent, but they\n // can disagree when the page is pinch-zoomed (on devices that support touch).\n // See https://bugs.chromium.org/p/chromium/issues/detail?id=489206#c4\n // We use the documentElement instead of the body because, by default (without a css reset)\n // browsers typically give the document body an 8px margin, which is not included in\n // getBoundingClientRect().\n const scrollPosition = this.getViewportScrollPosition();\n const {\n width,\n height\n } = this.getViewportSize();\n return {\n top: scrollPosition.top,\n left: scrollPosition.left,\n bottom: scrollPosition.top + height,\n right: scrollPosition.left + width,\n height,\n width\n };\n }\n /** Gets the (top, left) scroll position of the viewport. */\n\n\n getViewportScrollPosition() {\n // While we can get a reference to the fake document\n // during SSR, it doesn't have getBoundingClientRect.\n if (!this._platform.isBrowser) {\n return {\n top: 0,\n left: 0\n };\n } // The top-left-corner of the viewport is determined by the scroll position of the document\n // body, normally just (scrollLeft, scrollTop). However, Chrome and Firefox disagree about\n // whether `document.body` or `document.documentElement` is the scrolled element, so reading\n // `scrollTop` and `scrollLeft` is inconsistent. However, using the bounding rect of\n // `document.documentElement` works consistently, where the `top` and `left` values will\n // equal negative the scroll position.\n\n\n const document = this._document;\n\n const window = this._getWindow();\n\n const documentElement = document.documentElement;\n const documentRect = documentElement.getBoundingClientRect();\n const top = -documentRect.top || document.body.scrollTop || window.scrollY || documentElement.scrollTop || 0;\n const left = -documentRect.left || document.body.scrollLeft || window.scrollX || documentElement.scrollLeft || 0;\n return {\n top,\n left\n };\n }\n /**\n * Returns a stream that emits whenever the size of the viewport changes.\n * This stream emits outside of the Angular zone.\n * @param throttleTime Time in milliseconds to throttle the stream.\n */\n\n\n change(throttleTime = DEFAULT_RESIZE_TIME) {\n return throttleTime > 0 ? this._change.pipe(auditTime(throttleTime)) : this._change;\n }\n /** Use defaultView of injected document if available or fallback to global window reference */\n\n\n _getWindow() {\n return this._document.defaultView || window;\n }\n /** Updates the cached viewport size. */\n\n\n _updateViewportSize() {\n const window = this._getWindow();\n\n this._viewportSize = this._platform.isBrowser ? {\n width: window.innerWidth,\n height: window.innerHeight\n } : {\n width: 0,\n height: 0\n };\n }\n\n }\n\n ViewportRuler.ɵfac = function ViewportRuler_Factory(t) {\n return new (t || ViewportRuler)(i0.ɵɵinject(i1.Platform), i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(DOCUMENT, 8));\n };\n\n ViewportRuler.ɵprov = /* @__PURE__ */i0.ɵɵdefineInjectable({\n token: ViewportRuler,\n factory: ViewportRuler.ɵfac,\n providedIn: 'root'\n });\n return ViewportRuler;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/** Checks if the given ranges are equal. */\n\n\nfunction rangesEqual(r1, r2) {\n return r1.start == r2.start && r1.end == r2.end;\n}\n/**\n * Scheduler to be used for scroll events. Needs to fall back to\n * something that doesn't rely on requestAnimationFrame on environments\n * that don't support it (e.g. server-side rendering).\n */\n\n\nconst SCROLL_SCHEDULER = typeof requestAnimationFrame !== 'undefined' ? animationFrameScheduler : asapScheduler;\n/** A viewport that virtualizes its scrolling with the help of `CdkVirtualForOf`. */\n\nlet CdkVirtualScrollViewport = /*#__PURE__*/(() => {\n class CdkVirtualScrollViewport extends CdkScrollable {\n constructor(elementRef, _changeDetectorRef, ngZone, _scrollStrategy, dir, scrollDispatcher, viewportRuler) {\n super(elementRef, scrollDispatcher, ngZone, dir);\n this.elementRef = elementRef;\n this._changeDetectorRef = _changeDetectorRef;\n this._scrollStrategy = _scrollStrategy;\n /** Emits when the viewport is detached from a CdkVirtualForOf. */\n\n this._detachedSubject = new Subject();\n /** Emits when the rendered range changes. */\n\n this._renderedRangeSubject = new Subject();\n this._orientation = 'vertical';\n this._appendOnly = false; // Note: we don't use the typical EventEmitter here because we need to subscribe to the scroll\n // strategy lazily (i.e. only if the user is actually listening to the events). We do this because\n // depending on how the strategy calculates the scrolled index, it may come at a cost to\n // performance.\n\n /** Emits when the index of the first element visible in the viewport changes. */\n\n this.scrolledIndexChange = new Observable(observer => this._scrollStrategy.scrolledIndexChange.subscribe(index => Promise.resolve().then(() => this.ngZone.run(() => observer.next(index)))));\n /** A stream that emits whenever the rendered range changes. */\n\n this.renderedRangeStream = this._renderedRangeSubject;\n /**\n * The total size of all content (in pixels), including content that is not currently rendered.\n */\n\n this._totalContentSize = 0;\n /** A string representing the `style.width` property value to be used for the spacer element. */\n\n this._totalContentWidth = '';\n /** A string representing the `style.height` property value to be used for the spacer element. */\n\n this._totalContentHeight = '';\n /** The currently rendered range of indices. */\n\n this._renderedRange = {\n start: 0,\n end: 0\n };\n /** The length of the data bound to this viewport (in number of items). */\n\n this._dataLength = 0;\n /** The size of the viewport (in pixels). */\n\n this._viewportSize = 0;\n /** The last rendered content offset that was set. */\n\n this._renderedContentOffset = 0;\n /**\n * Whether the last rendered content offset was to the end of the content (and therefore needs to\n * be rewritten as an offset to the start of the content).\n */\n\n this._renderedContentOffsetNeedsRewrite = false;\n /** Whether there is a pending change detection cycle. */\n\n this._isChangeDetectionPending = false;\n /** A list of functions to run after the next change detection cycle. */\n\n this._runAfterChangeDetection = [];\n /** Subscription to changes in the viewport size. */\n\n this._viewportChanges = Subscription.EMPTY;\n\n if (!_scrollStrategy && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n throw Error('Error: cdk-virtual-scroll-viewport requires the \"itemSize\" property to be set.');\n }\n\n this._viewportChanges = viewportRuler.change().subscribe(() => {\n this.checkViewportSize();\n });\n }\n /** The direction the viewport scrolls. */\n\n\n get orientation() {\n return this._orientation;\n }\n\n set orientation(orientation) {\n if (this._orientation !== orientation) {\n this._orientation = orientation;\n\n this._calculateSpacerSize();\n }\n }\n /**\n * Whether rendered items should persist in the DOM after scrolling out of view. By default, items\n * will be removed.\n */\n\n\n get appendOnly() {\n return this._appendOnly;\n }\n\n set appendOnly(value) {\n this._appendOnly = coerceBooleanProperty(value);\n }\n\n ngOnInit() {\n super.ngOnInit(); // It's still too early to measure the viewport at this point. Deferring with a promise allows\n // the Viewport to be rendered with the correct size before we measure. We run this outside the\n // zone to avoid causing more change detection cycles. We handle the change detection loop\n // ourselves instead.\n\n this.ngZone.runOutsideAngular(() => Promise.resolve().then(() => {\n this._measureViewportSize();\n\n this._scrollStrategy.attach(this);\n\n this.elementScrolled().pipe( // Start off with a fake scroll event so we properly detect our initial position.\n startWith(null), // Collect multiple events into one until the next animation frame. This way if\n // there are multiple scroll events in the same frame we only need to recheck\n // our layout once.\n auditTime(0, SCROLL_SCHEDULER)).subscribe(() => this._scrollStrategy.onContentScrolled());\n\n this._markChangeDetectionNeeded();\n }));\n }\n\n ngOnDestroy() {\n this.detach();\n\n this._scrollStrategy.detach(); // Complete all subjects\n\n\n this._renderedRangeSubject.complete();\n\n this._detachedSubject.complete();\n\n this._viewportChanges.unsubscribe();\n\n super.ngOnDestroy();\n }\n /** Attaches a `CdkVirtualScrollRepeater` to this viewport. */\n\n\n attach(forOf) {\n if (this._forOf && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n throw Error('CdkVirtualScrollViewport is already attached.');\n } // Subscribe to the data stream of the CdkVirtualForOf to keep track of when the data length\n // changes. Run outside the zone to avoid triggering change detection, since we're managing the\n // change detection loop ourselves.\n\n\n this.ngZone.runOutsideAngular(() => {\n this._forOf = forOf;\n\n this._forOf.dataStream.pipe(takeUntil(this._detachedSubject)).subscribe(data => {\n const newLength = data.length;\n\n if (newLength !== this._dataLength) {\n this._dataLength = newLength;\n\n this._scrollStrategy.onDataLengthChanged();\n }\n\n this._doChangeDetection();\n });\n });\n }\n /** Detaches the current `CdkVirtualForOf`. */\n\n\n detach() {\n this._forOf = null;\n\n this._detachedSubject.next();\n }\n /** Gets the length of the data bound to this viewport (in number of items). */\n\n\n getDataLength() {\n return this._dataLength;\n }\n /** Gets the size of the viewport (in pixels). */\n\n\n getViewportSize() {\n return this._viewportSize;\n } // TODO(mmalerba): This is technically out of sync with what's really rendered until a render\n // cycle happens. I'm being careful to only call it after the render cycle is complete and before\n // setting it to something else, but its error prone and should probably be split into\n // `pendingRange` and `renderedRange`, the latter reflecting whats actually in the DOM.\n\n /** Get the current rendered range of items. */\n\n\n getRenderedRange() {\n return this._renderedRange;\n }\n /**\n * Sets the total size of all content (in pixels), including content that is not currently\n * rendered.\n */\n\n\n setTotalContentSize(size) {\n if (this._totalContentSize !== size) {\n this._totalContentSize = size;\n\n this._calculateSpacerSize();\n\n this._markChangeDetectionNeeded();\n }\n }\n /** Sets the currently rendered range of indices. */\n\n\n setRenderedRange(range) {\n if (!rangesEqual(this._renderedRange, range)) {\n if (this.appendOnly) {\n range = {\n start: 0,\n end: Math.max(this._renderedRange.end, range.end)\n };\n }\n\n this._renderedRangeSubject.next(this._renderedRange = range);\n\n this._markChangeDetectionNeeded(() => this._scrollStrategy.onContentRendered());\n }\n }\n /**\n * Gets the offset from the start of the viewport to the start of the rendered data (in pixels).\n */\n\n\n getOffsetToRenderedContentStart() {\n return this._renderedContentOffsetNeedsRewrite ? null : this._renderedContentOffset;\n }\n /**\n * Sets the offset from the start of the viewport to either the start or end of the rendered data\n * (in pixels).\n */\n\n\n setRenderedContentOffset(offset, to = 'to-start') {\n // For a horizontal viewport in a right-to-left language we need to translate along the x-axis\n // in the negative direction.\n const isRtl = this.dir && this.dir.value == 'rtl';\n const isHorizontal = this.orientation == 'horizontal';\n const axis = isHorizontal ? 'X' : 'Y';\n const axisDirection = isHorizontal && isRtl ? -1 : 1;\n let transform = `translate${axis}(${Number(axisDirection * offset)}px)`; // in appendOnly, we always start from the top\n\n offset = this.appendOnly && to === 'to-start' ? 0 : offset;\n this._renderedContentOffset = offset;\n\n if (to === 'to-end') {\n transform += ` translate${axis}(-100%)`; // The viewport should rewrite this as a `to-start` offset on the next render cycle. Otherwise\n // elements will appear to expand in the wrong direction (e.g. `mat-expansion-panel` would\n // expand upward).\n\n this._renderedContentOffsetNeedsRewrite = true;\n }\n\n if (this._renderedContentTransform != transform) {\n // We know this value is safe because we parse `offset` with `Number()` before passing it\n // into the string.\n this._renderedContentTransform = transform;\n\n this._markChangeDetectionNeeded(() => {\n if (this._renderedContentOffsetNeedsRewrite) {\n this._renderedContentOffset -= this.measureRenderedContentSize();\n this._renderedContentOffsetNeedsRewrite = false;\n this.setRenderedContentOffset(this._renderedContentOffset);\n } else {\n this._scrollStrategy.onRenderedOffsetChanged();\n }\n });\n }\n }\n /**\n * Scrolls to the given offset from the start of the viewport. Please note that this is not always\n * the same as setting `scrollTop` or `scrollLeft`. In a horizontal viewport with right-to-left\n * direction, this would be the equivalent of setting a fictional `scrollRight` property.\n * @param offset The offset to scroll to.\n * @param behavior The ScrollBehavior to use when scrolling. Default is behavior is `auto`.\n */\n\n\n scrollToOffset(offset, behavior = 'auto') {\n const options = {\n behavior\n };\n\n if (this.orientation === 'horizontal') {\n options.start = offset;\n } else {\n options.top = offset;\n }\n\n this.scrollTo(options);\n }\n /**\n * Scrolls to the offset for the given index.\n * @param index The index of the element to scroll to.\n * @param behavior The ScrollBehavior to use when scrolling. Default is behavior is `auto`.\n */\n\n\n scrollToIndex(index, behavior = 'auto') {\n this._scrollStrategy.scrollToIndex(index, behavior);\n }\n /**\n * Gets the current scroll offset from the start of the viewport (in pixels).\n * @param from The edge to measure the offset from. Defaults to 'top' in vertical mode and 'start'\n * in horizontal mode.\n */\n\n\n measureScrollOffset(from) {\n return from ? super.measureScrollOffset(from) : super.measureScrollOffset(this.orientation === 'horizontal' ? 'start' : 'top');\n }\n /** Measure the combined size of all of the rendered items. */\n\n\n measureRenderedContentSize() {\n const contentEl = this._contentWrapper.nativeElement;\n return this.orientation === 'horizontal' ? contentEl.offsetWidth : contentEl.offsetHeight;\n }\n /**\n * Measure the total combined size of the given range. Throws if the range includes items that are\n * not rendered.\n */\n\n\n measureRangeSize(range) {\n if (!this._forOf) {\n return 0;\n }\n\n return this._forOf.measureRangeSize(range, this.orientation);\n }\n /** Update the viewport dimensions and re-render. */\n\n\n checkViewportSize() {\n // TODO: Cleanup later when add logic for handling content resize\n this._measureViewportSize();\n\n this._scrollStrategy.onDataLengthChanged();\n }\n /** Measure the viewport size. */\n\n\n _measureViewportSize() {\n const viewportEl = this.elementRef.nativeElement;\n this._viewportSize = this.orientation === 'horizontal' ? viewportEl.clientWidth : viewportEl.clientHeight;\n }\n /** Queue up change detection to run. */\n\n\n _markChangeDetectionNeeded(runAfter) {\n if (runAfter) {\n this._runAfterChangeDetection.push(runAfter);\n } // Use a Promise to batch together calls to `_doChangeDetection`. This way if we set a bunch of\n // properties sequentially we only have to run `_doChangeDetection` once at the end.\n\n\n if (!this._isChangeDetectionPending) {\n this._isChangeDetectionPending = true;\n this.ngZone.runOutsideAngular(() => Promise.resolve().then(() => {\n this._doChangeDetection();\n }));\n }\n }\n /** Run change detection. */\n\n\n _doChangeDetection() {\n this._isChangeDetectionPending = false; // Apply the content transform. The transform can't be set via an Angular binding because\n // bypassSecurityTrustStyle is banned in Google. However the value is safe, it's composed of\n // string literals, a variable that can only be 'X' or 'Y', and user input that is run through\n // the `Number` function first to coerce it to a numeric value.\n\n this._contentWrapper.nativeElement.style.transform = this._renderedContentTransform; // Apply changes to Angular bindings. Note: We must call `markForCheck` to run change detection\n // from the root, since the repeated items are content projected in. Calling `detectChanges`\n // instead does not properly check the projected content.\n\n this.ngZone.run(() => this._changeDetectorRef.markForCheck());\n const runAfterChangeDetection = this._runAfterChangeDetection;\n this._runAfterChangeDetection = [];\n\n for (const fn of runAfterChangeDetection) {\n fn();\n }\n }\n /** Calculates the `style.width` and `style.height` for the spacer element. */\n\n\n _calculateSpacerSize() {\n this._totalContentHeight = this.orientation === 'horizontal' ? '' : `${this._totalContentSize}px`;\n this._totalContentWidth = this.orientation === 'horizontal' ? `${this._totalContentSize}px` : '';\n }\n\n }\n\n CdkVirtualScrollViewport.ɵfac = function CdkVirtualScrollViewport_Factory(t) {\n return new (t || CdkVirtualScrollViewport)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.NgZone), i0.ɵɵdirectiveInject(VIRTUAL_SCROLL_STRATEGY, 8), i0.ɵɵdirectiveInject(i2.Directionality, 8), i0.ɵɵdirectiveInject(ScrollDispatcher), i0.ɵɵdirectiveInject(ViewportRuler));\n };\n\n CdkVirtualScrollViewport.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: CdkVirtualScrollViewport,\n selectors: [[\"cdk-virtual-scroll-viewport\"]],\n viewQuery: function CdkVirtualScrollViewport_Query(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵviewQuery(_c0, 7);\n }\n\n if (rf & 2) {\n let _t;\n\n i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx._contentWrapper = _t.first);\n }\n },\n hostAttrs: [1, \"cdk-virtual-scroll-viewport\"],\n hostVars: 4,\n hostBindings: function CdkVirtualScrollViewport_HostBindings(rf, ctx) {\n if (rf & 2) {\n i0.ɵɵclassProp(\"cdk-virtual-scroll-orientation-horizontal\", ctx.orientation === \"horizontal\")(\"cdk-virtual-scroll-orientation-vertical\", ctx.orientation !== \"horizontal\");\n }\n },\n inputs: {\n orientation: \"orientation\",\n appendOnly: \"appendOnly\"\n },\n outputs: {\n scrolledIndexChange: \"scrolledIndexChange\"\n },\n features: [i0.ɵɵProvidersFeature([{\n provide: CdkScrollable,\n useExisting: CdkVirtualScrollViewport\n }]), i0.ɵɵInheritDefinitionFeature],\n ngContentSelectors: _c1,\n decls: 4,\n vars: 4,\n consts: [[1, \"cdk-virtual-scroll-content-wrapper\"], [\"contentWrapper\", \"\"], [1, \"cdk-virtual-scroll-spacer\"]],\n template: function CdkVirtualScrollViewport_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵprojectionDef();\n i0.ɵɵelementStart(0, \"div\", 0, 1);\n i0.ɵɵprojection(2);\n i0.ɵɵelementEnd();\n i0.ɵɵelement(3, \"div\", 2);\n }\n\n if (rf & 2) {\n i0.ɵɵadvance(3);\n i0.ɵɵstyleProp(\"width\", ctx._totalContentWidth)(\"height\", ctx._totalContentHeight);\n }\n },\n styles: [\"cdk-virtual-scroll-viewport{display:block;position:relative;overflow:auto;contain:strict;transform:translateZ(0);will-change:scroll-position;-webkit-overflow-scrolling:touch}.cdk-virtual-scroll-content-wrapper{position:absolute;top:0;left:0;contain:content}[dir=rtl] .cdk-virtual-scroll-content-wrapper{right:0;left:auto}.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper{min-height:100%}.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>dl:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>ol:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>table:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>ul:not([cdkVirtualFor]){padding-left:0;padding-right:0;margin-left:0;margin-right:0;border-left-width:0;border-right-width:0;outline:none}.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper{min-width:100%}.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>dl:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>ol:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>table:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>ul:not([cdkVirtualFor]){padding-top:0;padding-bottom:0;margin-top:0;margin-bottom:0;border-top-width:0;border-bottom-width:0;outline:none}.cdk-virtual-scroll-spacer{position:absolute;top:0;left:0;height:1px;width:1px;transform-origin:0 0}[dir=rtl] .cdk-virtual-scroll-spacer{right:0;left:auto;transform-origin:100% 0}\\n\"],\n encapsulation: 2,\n changeDetection: 0\n });\n return CdkVirtualScrollViewport;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/** Helper to extract the offset of a DOM Node in a certain direction. */\n\n\nfunction getOffset(orientation, direction, node) {\n const el = node;\n\n if (!el.getBoundingClientRect) {\n return 0;\n }\n\n const rect = el.getBoundingClientRect();\n\n if (orientation === 'horizontal') {\n return direction === 'start' ? rect.left : rect.right;\n }\n\n return direction === 'start' ? rect.top : rect.bottom;\n}\n/**\n * A directive similar to `ngForOf` to be used for rendering data inside a virtual scrolling\n * container.\n */\n\n\nlet CdkVirtualForOf = /*#__PURE__*/(() => {\n class CdkVirtualForOf {\n constructor(\n /** The view container to add items to. */\n _viewContainerRef,\n /** The template to use when stamping out new items. */\n _template,\n /** The set of available differs. */\n _differs,\n /** The strategy used to render items in the virtual scroll viewport. */\n _viewRepeater,\n /** The virtual scrolling viewport that these items are being rendered in. */\n _viewport, ngZone) {\n this._viewContainerRef = _viewContainerRef;\n this._template = _template;\n this._differs = _differs;\n this._viewRepeater = _viewRepeater;\n this._viewport = _viewport;\n /** Emits when the rendered view of the data changes. */\n\n this.viewChange = new Subject();\n /** Subject that emits when a new DataSource instance is given. */\n\n this._dataSourceChanges = new Subject();\n /** Emits whenever the data in the current DataSource changes. */\n\n this.dataStream = this._dataSourceChanges.pipe( // Start off with null `DataSource`.\n startWith(null), // Bundle up the previous and current data sources so we can work with both.\n pairwise(), // Use `_changeDataSource` to disconnect from the previous data source and connect to the\n // new one, passing back a stream of data changes which we run through `switchMap` to give\n // us a data stream that emits the latest data from whatever the current `DataSource` is.\n switchMap(([prev, cur]) => this._changeDataSource(prev, cur)), // Replay the last emitted data when someone subscribes.\n shareReplay(1));\n /** The differ used to calculate changes to the data. */\n\n this._differ = null;\n /** Whether the rendered data should be updated during the next ngDoCheck cycle. */\n\n this._needsUpdate = false;\n this._destroyed = new Subject();\n this.dataStream.subscribe(data => {\n this._data = data;\n\n this._onRenderedDataChange();\n });\n\n this._viewport.renderedRangeStream.pipe(takeUntil(this._destroyed)).subscribe(range => {\n this._renderedRange = range;\n ngZone.run(() => this.viewChange.next(this._renderedRange));\n\n this._onRenderedDataChange();\n });\n\n this._viewport.attach(this);\n }\n /** The DataSource to display. */\n\n\n get cdkVirtualForOf() {\n return this._cdkVirtualForOf;\n }\n\n set cdkVirtualForOf(value) {\n this._cdkVirtualForOf = value;\n\n if (isDataSource(value)) {\n this._dataSourceChanges.next(value);\n } else {\n // If value is an an NgIterable, convert it to an array.\n this._dataSourceChanges.next(new ArrayDataSource(isObservable(value) ? value : Array.from(value || [])));\n }\n }\n /**\n * The `TrackByFunction` to use for tracking changes. The `TrackByFunction` takes the index and\n * the item and produces a value to be used as the item's identity when tracking changes.\n */\n\n\n get cdkVirtualForTrackBy() {\n return this._cdkVirtualForTrackBy;\n }\n\n set cdkVirtualForTrackBy(fn) {\n this._needsUpdate = true;\n this._cdkVirtualForTrackBy = fn ? (index, item) => fn(index + (this._renderedRange ? this._renderedRange.start : 0), item) : undefined;\n }\n /** The template used to stamp out new elements. */\n\n\n set cdkVirtualForTemplate(value) {\n if (value) {\n this._needsUpdate = true;\n this._template = value;\n }\n }\n /**\n * The size of the cache used to store templates that are not being used for re-use later.\n * Setting the cache size to `0` will disable caching. Defaults to 20 templates.\n */\n\n\n get cdkVirtualForTemplateCacheSize() {\n return this._viewRepeater.viewCacheSize;\n }\n\n set cdkVirtualForTemplateCacheSize(size) {\n this._viewRepeater.viewCacheSize = coerceNumberProperty(size);\n }\n /**\n * Measures the combined size (width for horizontal orientation, height for vertical) of all items\n * in the specified range. Throws an error if the range includes items that are not currently\n * rendered.\n */\n\n\n measureRangeSize(range, orientation) {\n if (range.start >= range.end) {\n return 0;\n }\n\n if ((range.start < this._renderedRange.start || range.end > this._renderedRange.end) && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n throw Error(`Error: attempted to measure an item that isn't rendered.`);\n } // The index into the list of rendered views for the first item in the range.\n\n\n const renderedStartIndex = range.start - this._renderedRange.start; // The length of the range we're measuring.\n\n const rangeLen = range.end - range.start; // Loop over all the views, find the first and land node and compute the size by subtracting\n // the top of the first node from the bottom of the last one.\n\n let firstNode;\n let lastNode; // Find the first node by starting from the beginning and going forwards.\n\n for (let i = 0; i < rangeLen; i++) {\n const view = this._viewContainerRef.get(i + renderedStartIndex);\n\n if (view && view.rootNodes.length) {\n firstNode = lastNode = view.rootNodes[0];\n break;\n }\n } // Find the last node by starting from the end and going backwards.\n\n\n for (let i = rangeLen - 1; i > -1; i--) {\n const view = this._viewContainerRef.get(i + renderedStartIndex);\n\n if (view && view.rootNodes.length) {\n lastNode = view.rootNodes[view.rootNodes.length - 1];\n break;\n }\n }\n\n return firstNode && lastNode ? getOffset(orientation, 'end', lastNode) - getOffset(orientation, 'start', firstNode) : 0;\n }\n\n ngDoCheck() {\n if (this._differ && this._needsUpdate) {\n // TODO(mmalerba): We should differentiate needs update due to scrolling and a new portion of\n // this list being rendered (can use simpler algorithm) vs needs update due to data actually\n // changing (need to do this diff).\n const changes = this._differ.diff(this._renderedItems);\n\n if (!changes) {\n this._updateContext();\n } else {\n this._applyChanges(changes);\n }\n\n this._needsUpdate = false;\n }\n }\n\n ngOnDestroy() {\n this._viewport.detach();\n\n this._dataSourceChanges.next(undefined);\n\n this._dataSourceChanges.complete();\n\n this.viewChange.complete();\n\n this._destroyed.next();\n\n this._destroyed.complete();\n\n this._viewRepeater.detach();\n }\n /** React to scroll state changes in the viewport. */\n\n\n _onRenderedDataChange() {\n if (!this._renderedRange) {\n return;\n }\n\n this._renderedItems = this._data.slice(this._renderedRange.start, this._renderedRange.end);\n\n if (!this._differ) {\n // Use a wrapper function for the `trackBy` so any new values are\n // picked up automatically without having to recreate the differ.\n this._differ = this._differs.find(this._renderedItems).create((index, item) => {\n return this.cdkVirtualForTrackBy ? this.cdkVirtualForTrackBy(index, item) : item;\n });\n }\n\n this._needsUpdate = true;\n }\n /** Swap out one `DataSource` for another. */\n\n\n _changeDataSource(oldDs, newDs) {\n if (oldDs) {\n oldDs.disconnect(this);\n }\n\n this._needsUpdate = true;\n return newDs ? newDs.connect(this) : of();\n }\n /** Update the `CdkVirtualForOfContext` for all views. */\n\n\n _updateContext() {\n const count = this._data.length;\n let i = this._viewContainerRef.length;\n\n while (i--) {\n const view = this._viewContainerRef.get(i);\n\n view.context.index = this._renderedRange.start + i;\n view.context.count = count;\n\n this._updateComputedContextProperties(view.context);\n\n view.detectChanges();\n }\n }\n /** Apply changes to the DOM. */\n\n\n _applyChanges(changes) {\n this._viewRepeater.applyChanges(changes, this._viewContainerRef, (record, _adjustedPreviousIndex, currentIndex) => this._getEmbeddedViewArgs(record, currentIndex), record => record.item); // Update $implicit for any items that had an identity change.\n\n\n changes.forEachIdentityChange(record => {\n const view = this._viewContainerRef.get(record.currentIndex);\n\n view.context.$implicit = record.item;\n }); // Update the context variables on all items.\n\n const count = this._data.length;\n let i = this._viewContainerRef.length;\n\n while (i--) {\n const view = this._viewContainerRef.get(i);\n\n view.context.index = this._renderedRange.start + i;\n view.context.count = count;\n\n this._updateComputedContextProperties(view.context);\n }\n }\n /** Update the computed properties on the `CdkVirtualForOfContext`. */\n\n\n _updateComputedContextProperties(context) {\n context.first = context.index === 0;\n context.last = context.index === context.count - 1;\n context.even = context.index % 2 === 0;\n context.odd = !context.even;\n }\n\n _getEmbeddedViewArgs(record, index) {\n // Note that it's important that we insert the item directly at the proper index,\n // rather than inserting it and the moving it in place, because if there's a directive\n // on the same node that injects the `ViewContainerRef`, Angular will insert another\n // comment node which can throw off the move when it's being repeated for all items.\n return {\n templateRef: this._template,\n context: {\n $implicit: record.item,\n // It's guaranteed that the iterable is not \"undefined\" or \"null\" because we only\n // generate views for elements if the \"cdkVirtualForOf\" iterable has elements.\n cdkVirtualForOf: this._cdkVirtualForOf,\n index: -1,\n count: -1,\n first: false,\n last: false,\n odd: false,\n even: false\n },\n index\n };\n }\n\n }\n\n CdkVirtualForOf.ɵfac = function CdkVirtualForOf_Factory(t) {\n return new (t || CdkVirtualForOf)(i0.ɵɵdirectiveInject(i0.ViewContainerRef), i0.ɵɵdirectiveInject(i0.TemplateRef), i0.ɵɵdirectiveInject(i0.IterableDiffers), i0.ɵɵdirectiveInject(_VIEW_REPEATER_STRATEGY), i0.ɵɵdirectiveInject(CdkVirtualScrollViewport, 4), i0.ɵɵdirectiveInject(i0.NgZone));\n };\n\n CdkVirtualForOf.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: CdkVirtualForOf,\n selectors: [[\"\", \"cdkVirtualFor\", \"\", \"cdkVirtualForOf\", \"\"]],\n inputs: {\n cdkVirtualForOf: \"cdkVirtualForOf\",\n cdkVirtualForTrackBy: \"cdkVirtualForTrackBy\",\n cdkVirtualForTemplate: \"cdkVirtualForTemplate\",\n cdkVirtualForTemplateCacheSize: \"cdkVirtualForTemplateCacheSize\"\n },\n features: [i0.ɵɵProvidersFeature([{\n provide: _VIEW_REPEATER_STRATEGY,\n useClass: _RecycleViewRepeaterStrategy\n }])]\n });\n return CdkVirtualForOf;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nlet CdkScrollableModule = /*#__PURE__*/(() => {\n class CdkScrollableModule {}\n\n CdkScrollableModule.ɵfac = function CdkScrollableModule_Factory(t) {\n return new (t || CdkScrollableModule)();\n };\n\n CdkScrollableModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: CdkScrollableModule\n });\n CdkScrollableModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({});\n return CdkScrollableModule;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @docs-primary-export\n */\n\n\nlet ScrollingModule = /*#__PURE__*/(() => {\n class ScrollingModule {}\n\n ScrollingModule.ɵfac = function ScrollingModule_Factory(t) {\n return new (t || ScrollingModule)();\n };\n\n ScrollingModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: ScrollingModule\n });\n ScrollingModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n imports: [[BidiModule, PlatformModule, CdkScrollableModule], BidiModule, CdkScrollableModule]\n });\n return ScrollingModule;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Generated bundle index. Do not edit.\n */\n\n\nexport { CdkFixedSizeVirtualScroll, CdkScrollable, CdkScrollableModule, CdkVirtualForOf, CdkVirtualScrollViewport, DEFAULT_RESIZE_TIME, DEFAULT_SCROLL_TIME, FixedSizeVirtualScrollStrategy, ScrollDispatcher, ScrollingModule, VIRTUAL_SCROLL_STRATEGY, ViewportRuler, _fixedSizeVirtualScrollStrategyFactory }; //# sourceMappingURL=scrolling.mjs.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/25674fff68c9c0ed9ef690fad7a663cd.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/25674fff68c9c0ed9ef690fad7a663cd.json
deleted file mode 100644
index c39035c3..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/25674fff68c9c0ed9ef690fad7a663cd.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { createErrorClass } from './createErrorClass';\nexport const EmptyError = createErrorClass(_super => function EmptyErrorImpl() {\n _super(this);\n\n this.name = 'EmptyError';\n this.message = 'no elements in sequence';\n}); //# sourceMappingURL=EmptyError.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/25ce8822902d6ce6b59eabf6b62dddb2.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/25ce8822902d6ce6b59eabf6b62dddb2.json
deleted file mode 100644
index 48a4599b..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/25ce8822902d6ce6b59eabf6b62dddb2.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { innerFrom } from '../observable/innerFrom';\nimport { executeSchedule } from '../util/executeSchedule';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nexport function mergeInternals(source, subscriber, project, concurrent, onBeforeNext, expand, innerSubScheduler, additionalFinalizer) {\n const buffer = [];\n let active = 0;\n let index = 0;\n let isComplete = false;\n\n const checkComplete = () => {\n if (isComplete && !buffer.length && !active) {\n subscriber.complete();\n }\n };\n\n const outerNext = value => active < concurrent ? doInnerSub(value) : buffer.push(value);\n\n const doInnerSub = value => {\n expand && subscriber.next(value);\n active++;\n let innerComplete = false;\n innerFrom(project(value, index++)).subscribe(createOperatorSubscriber(subscriber, innerValue => {\n onBeforeNext === null || onBeforeNext === void 0 ? void 0 : onBeforeNext(innerValue);\n\n if (expand) {\n outerNext(innerValue);\n } else {\n subscriber.next(innerValue);\n }\n }, () => {\n innerComplete = true;\n }, undefined, () => {\n if (innerComplete) {\n try {\n active--;\n\n while (buffer.length && active < concurrent) {\n const bufferedValue = buffer.shift();\n\n if (innerSubScheduler) {\n executeSchedule(subscriber, innerSubScheduler, () => doInnerSub(bufferedValue));\n } else {\n doInnerSub(bufferedValue);\n }\n }\n\n checkComplete();\n } catch (err) {\n subscriber.error(err);\n }\n }\n }));\n };\n\n source.subscribe(createOperatorSubscriber(subscriber, outerNext, () => {\n isComplete = true;\n checkComplete();\n }));\n return () => {\n additionalFinalizer === null || additionalFinalizer === void 0 ? void 0 : additionalFinalizer();\n };\n} //# sourceMappingURL=mergeInternals.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/262b8608aa86a500542609ef01534687.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/262b8608aa86a500542609ef01534687.json
deleted file mode 100644
index 0698e246..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/262b8608aa86a500542609ef01534687.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"const {\n isArray\n} = Array;\nconst {\n getPrototypeOf,\n prototype: objectProto,\n keys: getKeys\n} = Object;\nexport function argsArgArrayOrObject(args) {\n if (args.length === 1) {\n const first = args[0];\n\n if (isArray(first)) {\n return {\n args: first,\n keys: null\n };\n }\n\n if (isPOJO(first)) {\n const keys = getKeys(first);\n return {\n args: keys.map(key => first[key]),\n keys\n };\n }\n }\n\n return {\n args: args,\n keys: null\n };\n}\n\nfunction isPOJO(obj) {\n return obj && typeof obj === 'object' && getPrototypeOf(obj) === objectProto;\n} //# sourceMappingURL=argsArgArrayOrObject.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/27e659525cab9d3580b5c6ec530ab8c4.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/27e659525cab9d3580b5c6ec530ab8c4.json
deleted file mode 100644
index 22df9687..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/27e659525cab9d3580b5c6ec530ab8c4.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"// The error overlay is inspired (and mostly copied) from Create React App (https://github.com/facebookincubator/create-react-app)\n// They, in turn, got inspired by webpack-hot-middleware (https://github.com/glenjamin/webpack-hot-middleware).\nimport ansiHTML from \"ansi-html-community\";\nimport { encode } from \"html-entities\";\nvar colors = {\n reset: [\"transparent\", \"transparent\"],\n black: \"181818\",\n red: \"E36049\",\n green: \"B3CB74\",\n yellow: \"FFD080\",\n blue: \"7CAFC2\",\n magenta: \"7FACCA\",\n cyan: \"C3C2EF\",\n lightgrey: \"EBE7E3\",\n darkgrey: \"6D7891\"\n};\n/** @type {HTMLIFrameElement | null | undefined} */\n\nvar iframeContainerElement;\n/** @type {HTMLDivElement | null | undefined} */\n\nvar containerElement;\n/** @type {Array<(element: HTMLDivElement) => void>} */\n\nvar onLoadQueue = [];\n/** @type {TrustedTypePolicy | undefined} */\n\nvar overlayTrustedTypesPolicy;\nansiHTML.setColors(colors);\n/**\n * @param {string | null} trustedTypesPolicyName\n */\n\nfunction createContainer(trustedTypesPolicyName) {\n // Enable Trusted Types if they are available in the current browser.\n if (window.trustedTypes) {\n overlayTrustedTypesPolicy = window.trustedTypes.createPolicy(trustedTypesPolicyName || \"webpack-dev-server#overlay\", {\n createHTML: function createHTML(value) {\n return value;\n }\n });\n }\n\n iframeContainerElement = document.createElement(\"iframe\");\n iframeContainerElement.id = \"webpack-dev-server-client-overlay\";\n iframeContainerElement.src = \"about:blank\";\n iframeContainerElement.style.position = \"fixed\";\n iframeContainerElement.style.left = 0;\n iframeContainerElement.style.top = 0;\n iframeContainerElement.style.right = 0;\n iframeContainerElement.style.bottom = 0;\n iframeContainerElement.style.width = \"100vw\";\n iframeContainerElement.style.height = \"100vh\";\n iframeContainerElement.style.border = \"none\";\n iframeContainerElement.style.zIndex = 9999999999;\n\n iframeContainerElement.onload = function () {\n containerElement =\n /** @type {Document} */\n\n /** @type {HTMLIFrameElement} */\n iframeContainerElement.contentDocument.createElement(\"div\");\n containerElement.id = \"webpack-dev-server-client-overlay-div\";\n containerElement.style.position = \"fixed\";\n containerElement.style.boxSizing = \"border-box\";\n containerElement.style.left = 0;\n containerElement.style.top = 0;\n containerElement.style.right = 0;\n containerElement.style.bottom = 0;\n containerElement.style.width = \"100vw\";\n containerElement.style.height = \"100vh\";\n containerElement.style.backgroundColor = \"rgba(0, 0, 0, 0.85)\";\n containerElement.style.color = \"#E8E8E8\";\n containerElement.style.fontFamily = \"Menlo, Consolas, monospace\";\n containerElement.style.fontSize = \"large\";\n containerElement.style.padding = \"2rem\";\n containerElement.style.lineHeight = \"1.2\";\n containerElement.style.whiteSpace = \"pre-wrap\";\n containerElement.style.overflow = \"auto\";\n var headerElement = document.createElement(\"span\");\n headerElement.innerText = \"Compiled with problems:\";\n var closeButtonElement = document.createElement(\"button\");\n closeButtonElement.innerText = \"X\";\n closeButtonElement.style.background = \"transparent\";\n closeButtonElement.style.border = \"none\";\n closeButtonElement.style.fontSize = \"20px\";\n closeButtonElement.style.fontWeight = \"bold\";\n closeButtonElement.style.color = \"white\";\n closeButtonElement.style.cursor = \"pointer\";\n closeButtonElement.style.cssFloat = \"right\"; // @ts-ignore\n\n closeButtonElement.style.styleFloat = \"right\";\n closeButtonElement.addEventListener(\"click\", function () {\n hide();\n });\n containerElement.appendChild(headerElement);\n containerElement.appendChild(closeButtonElement);\n containerElement.appendChild(document.createElement(\"br\"));\n containerElement.appendChild(document.createElement(\"br\"));\n /** @type {Document} */\n\n /** @type {HTMLIFrameElement} */\n\n iframeContainerElement.contentDocument.body.appendChild(containerElement);\n onLoadQueue.forEach(function (onLoad) {\n onLoad(\n /** @type {HTMLDivElement} */\n containerElement);\n });\n onLoadQueue = [];\n /** @type {HTMLIFrameElement} */\n\n iframeContainerElement.onload = null;\n };\n\n document.body.appendChild(iframeContainerElement);\n}\n/**\n * @param {(element: HTMLDivElement) => void} callback\n * @param {string | null} trustedTypesPolicyName\n */\n\n\nfunction ensureOverlayExists(callback, trustedTypesPolicyName) {\n if (containerElement) {\n // Everything is ready, call the callback right away.\n callback(containerElement);\n return;\n }\n\n onLoadQueue.push(callback);\n\n if (iframeContainerElement) {\n return;\n }\n\n createContainer(trustedTypesPolicyName);\n} // Successful compilation.\n\n\nfunction hide() {\n if (!iframeContainerElement) {\n return;\n } // Clean up and reset internal state.\n\n\n document.body.removeChild(iframeContainerElement);\n iframeContainerElement = null;\n containerElement = null;\n}\n/**\n * @param {string} type\n * @param {string | { file?: string, moduleName?: string, loc?: string, message?: string }} item\n * @returns {{ header: string, body: string }}\n */\n\n\nfunction formatProblem(type, item) {\n var header = type === \"warning\" ? \"WARNING\" : \"ERROR\";\n var body = \"\";\n\n if (typeof item === \"string\") {\n body += item;\n } else {\n var file = item.file || \"\"; // eslint-disable-next-line no-nested-ternary\n\n var moduleName = item.moduleName ? item.moduleName.indexOf(\"!\") !== -1 ? \"\".concat(item.moduleName.replace(/^(\\s|\\S)*!/, \"\"), \" (\").concat(item.moduleName, \")\") : \"\".concat(item.moduleName) : \"\";\n var loc = item.loc;\n header += \"\".concat(moduleName || file ? \" in \".concat(moduleName ? \"\".concat(moduleName).concat(file ? \" (\".concat(file, \")\") : \"\") : file).concat(loc ? \" \".concat(loc) : \"\") : \"\");\n body += item.message || \"\";\n }\n\n return {\n header: header,\n body: body\n };\n} // Compilation with errors (e.g. syntax error or missing modules).\n\n/**\n * @param {string} type\n * @param {Array} messages\n * @param {string | null} trustedTypesPolicyName\n */\n\n\nfunction show(type, messages, trustedTypesPolicyName) {\n ensureOverlayExists(function () {\n messages.forEach(function (message) {\n var entryElement = document.createElement(\"div\");\n var typeElement = document.createElement(\"span\");\n\n var _formatProblem = formatProblem(type, message),\n header = _formatProblem.header,\n body = _formatProblem.body;\n\n typeElement.innerText = header;\n typeElement.style.color = \"#\".concat(colors.red); // Make it look similar to our terminal.\n\n var text = ansiHTML(encode(body));\n var messageTextNode = document.createElement(\"div\");\n messageTextNode.innerHTML = overlayTrustedTypesPolicy ? overlayTrustedTypesPolicy.createHTML(text) : text;\n entryElement.appendChild(typeElement);\n entryElement.appendChild(document.createElement(\"br\"));\n entryElement.appendChild(document.createElement(\"br\"));\n entryElement.appendChild(messageTextNode);\n entryElement.appendChild(document.createElement(\"br\"));\n entryElement.appendChild(document.createElement(\"br\"));\n /** @type {HTMLDivElement} */\n\n containerElement.appendChild(entryElement);\n });\n }, trustedTypesPolicyName);\n}\n\nexport { formatProblem, show, hide };","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/27ea4aaec0975b9a3a177f457523370c.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/27ea4aaec0975b9a3a177f457523370c.json
deleted file mode 100644
index 02cff301..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/27ea4aaec0975b9a3a177f457523370c.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"export function arrRemove(arr, item) {\n if (arr) {\n const index = arr.indexOf(item);\n 0 <= index && arr.splice(index, 1);\n }\n} //# sourceMappingURL=arrRemove.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/2873c502412e0279bcdd37804bde642c.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/2873c502412e0279bcdd37804bde642c.json
deleted file mode 100644
index 4d180b95..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/2873c502412e0279bcdd37804bde642c.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"export { Observable } from './internal/Observable';\nexport { ConnectableObservable } from './internal/observable/ConnectableObservable';\nexport { observable } from './internal/symbol/observable';\nexport { animationFrames } from './internal/observable/dom/animationFrames';\nexport { Subject } from './internal/Subject';\nexport { BehaviorSubject } from './internal/BehaviorSubject';\nexport { ReplaySubject } from './internal/ReplaySubject';\nexport { AsyncSubject } from './internal/AsyncSubject';\nexport { asap, asapScheduler } from './internal/scheduler/asap';\nexport { async, asyncScheduler } from './internal/scheduler/async';\nexport { queue, queueScheduler } from './internal/scheduler/queue';\nexport { animationFrame, animationFrameScheduler } from './internal/scheduler/animationFrame';\nexport { VirtualTimeScheduler, VirtualAction } from './internal/scheduler/VirtualTimeScheduler';\nexport { Scheduler } from './internal/Scheduler';\nexport { Subscription } from './internal/Subscription';\nexport { Subscriber } from './internal/Subscriber';\nexport { Notification, NotificationKind } from './internal/Notification';\nexport { pipe } from './internal/util/pipe';\nexport { noop } from './internal/util/noop';\nexport { identity } from './internal/util/identity';\nexport { isObservable } from './internal/util/isObservable';\nexport { lastValueFrom } from './internal/lastValueFrom';\nexport { firstValueFrom } from './internal/firstValueFrom';\nexport { ArgumentOutOfRangeError } from './internal/util/ArgumentOutOfRangeError';\nexport { EmptyError } from './internal/util/EmptyError';\nexport { NotFoundError } from './internal/util/NotFoundError';\nexport { ObjectUnsubscribedError } from './internal/util/ObjectUnsubscribedError';\nexport { SequenceError } from './internal/util/SequenceError';\nexport { TimeoutError } from './internal/operators/timeout';\nexport { UnsubscriptionError } from './internal/util/UnsubscriptionError';\nexport { bindCallback } from './internal/observable/bindCallback';\nexport { bindNodeCallback } from './internal/observable/bindNodeCallback';\nexport { combineLatest } from './internal/observable/combineLatest';\nexport { concat } from './internal/observable/concat';\nexport { connectable } from './internal/observable/connectable';\nexport { defer } from './internal/observable/defer';\nexport { empty } from './internal/observable/empty';\nexport { forkJoin } from './internal/observable/forkJoin';\nexport { from } from './internal/observable/from';\nexport { fromEvent } from './internal/observable/fromEvent';\nexport { fromEventPattern } from './internal/observable/fromEventPattern';\nexport { generate } from './internal/observable/generate';\nexport { iif } from './internal/observable/iif';\nexport { interval } from './internal/observable/interval';\nexport { merge } from './internal/observable/merge';\nexport { never } from './internal/observable/never';\nexport { of } from './internal/observable/of';\nexport { onErrorResumeNext } from './internal/observable/onErrorResumeNext';\nexport { pairs } from './internal/observable/pairs';\nexport { partition } from './internal/observable/partition';\nexport { race } from './internal/observable/race';\nexport { range } from './internal/observable/range';\nexport { throwError } from './internal/observable/throwError';\nexport { timer } from './internal/observable/timer';\nexport { using } from './internal/observable/using';\nexport { zip } from './internal/observable/zip';\nexport { scheduled } from './internal/scheduled/scheduled';\nexport { EMPTY } from './internal/observable/empty';\nexport { NEVER } from './internal/observable/never';\nexport * from './internal/types';\nexport { config } from './internal/config';\nexport { audit } from './internal/operators/audit';\nexport { auditTime } from './internal/operators/auditTime';\nexport { buffer } from './internal/operators/buffer';\nexport { bufferCount } from './internal/operators/bufferCount';\nexport { bufferTime } from './internal/operators/bufferTime';\nexport { bufferToggle } from './internal/operators/bufferToggle';\nexport { bufferWhen } from './internal/operators/bufferWhen';\nexport { catchError } from './internal/operators/catchError';\nexport { combineAll } from './internal/operators/combineAll';\nexport { combineLatestAll } from './internal/operators/combineLatestAll';\nexport { combineLatestWith } from './internal/operators/combineLatestWith';\nexport { concatAll } from './internal/operators/concatAll';\nexport { concatMap } from './internal/operators/concatMap';\nexport { concatMapTo } from './internal/operators/concatMapTo';\nexport { concatWith } from './internal/operators/concatWith';\nexport { connect } from './internal/operators/connect';\nexport { count } from './internal/operators/count';\nexport { debounce } from './internal/operators/debounce';\nexport { debounceTime } from './internal/operators/debounceTime';\nexport { defaultIfEmpty } from './internal/operators/defaultIfEmpty';\nexport { delay } from './internal/operators/delay';\nexport { delayWhen } from './internal/operators/delayWhen';\nexport { dematerialize } from './internal/operators/dematerialize';\nexport { distinct } from './internal/operators/distinct';\nexport { distinctUntilChanged } from './internal/operators/distinctUntilChanged';\nexport { distinctUntilKeyChanged } from './internal/operators/distinctUntilKeyChanged';\nexport { elementAt } from './internal/operators/elementAt';\nexport { endWith } from './internal/operators/endWith';\nexport { every } from './internal/operators/every';\nexport { exhaust } from './internal/operators/exhaust';\nexport { exhaustAll } from './internal/operators/exhaustAll';\nexport { exhaustMap } from './internal/operators/exhaustMap';\nexport { expand } from './internal/operators/expand';\nexport { filter } from './internal/operators/filter';\nexport { finalize } from './internal/operators/finalize';\nexport { find } from './internal/operators/find';\nexport { findIndex } from './internal/operators/findIndex';\nexport { first } from './internal/operators/first';\nexport { groupBy } from './internal/operators/groupBy';\nexport { ignoreElements } from './internal/operators/ignoreElements';\nexport { isEmpty } from './internal/operators/isEmpty';\nexport { last } from './internal/operators/last';\nexport { map } from './internal/operators/map';\nexport { mapTo } from './internal/operators/mapTo';\nexport { materialize } from './internal/operators/materialize';\nexport { max } from './internal/operators/max';\nexport { mergeAll } from './internal/operators/mergeAll';\nexport { flatMap } from './internal/operators/flatMap';\nexport { mergeMap } from './internal/operators/mergeMap';\nexport { mergeMapTo } from './internal/operators/mergeMapTo';\nexport { mergeScan } from './internal/operators/mergeScan';\nexport { mergeWith } from './internal/operators/mergeWith';\nexport { min } from './internal/operators/min';\nexport { multicast } from './internal/operators/multicast';\nexport { observeOn } from './internal/operators/observeOn';\nexport { pairwise } from './internal/operators/pairwise';\nexport { pluck } from './internal/operators/pluck';\nexport { publish } from './internal/operators/publish';\nexport { publishBehavior } from './internal/operators/publishBehavior';\nexport { publishLast } from './internal/operators/publishLast';\nexport { publishReplay } from './internal/operators/publishReplay';\nexport { raceWith } from './internal/operators/raceWith';\nexport { reduce } from './internal/operators/reduce';\nexport { repeat } from './internal/operators/repeat';\nexport { repeatWhen } from './internal/operators/repeatWhen';\nexport { retry } from './internal/operators/retry';\nexport { retryWhen } from './internal/operators/retryWhen';\nexport { refCount } from './internal/operators/refCount';\nexport { sample } from './internal/operators/sample';\nexport { sampleTime } from './internal/operators/sampleTime';\nexport { scan } from './internal/operators/scan';\nexport { sequenceEqual } from './internal/operators/sequenceEqual';\nexport { share } from './internal/operators/share';\nexport { shareReplay } from './internal/operators/shareReplay';\nexport { single } from './internal/operators/single';\nexport { skip } from './internal/operators/skip';\nexport { skipLast } from './internal/operators/skipLast';\nexport { skipUntil } from './internal/operators/skipUntil';\nexport { skipWhile } from './internal/operators/skipWhile';\nexport { startWith } from './internal/operators/startWith';\nexport { subscribeOn } from './internal/operators/subscribeOn';\nexport { switchAll } from './internal/operators/switchAll';\nexport { switchMap } from './internal/operators/switchMap';\nexport { switchMapTo } from './internal/operators/switchMapTo';\nexport { switchScan } from './internal/operators/switchScan';\nexport { take } from './internal/operators/take';\nexport { takeLast } from './internal/operators/takeLast';\nexport { takeUntil } from './internal/operators/takeUntil';\nexport { takeWhile } from './internal/operators/takeWhile';\nexport { tap } from './internal/operators/tap';\nexport { throttle } from './internal/operators/throttle';\nexport { throttleTime } from './internal/operators/throttleTime';\nexport { throwIfEmpty } from './internal/operators/throwIfEmpty';\nexport { timeInterval } from './internal/operators/timeInterval';\nexport { timeout } from './internal/operators/timeout';\nexport { timeoutWith } from './internal/operators/timeoutWith';\nexport { timestamp } from './internal/operators/timestamp';\nexport { toArray } from './internal/operators/toArray';\nexport { window } from './internal/operators/window';\nexport { windowCount } from './internal/operators/windowCount';\nexport { windowTime } from './internal/operators/windowTime';\nexport { windowToggle } from './internal/operators/windowToggle';\nexport { windowWhen } from './internal/operators/windowWhen';\nexport { withLatestFrom } from './internal/operators/withLatestFrom';\nexport { zipAll } from './internal/operators/zipAll';\nexport { zipWith } from './internal/operators/zipWith'; //# sourceMappingURL=index.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/29ab3819f81fd20123a715fa6fbf32ea.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/29ab3819f81fd20123a715fa6fbf32ea.json
deleted file mode 100644
index 6181eacd..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/29ab3819f81fd20123a715fa6fbf32ea.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { innerFrom } from '../observable/innerFrom';\nimport { identity } from '../util/identity';\nimport { noop } from '../util/noop';\nimport { popResultSelector } from '../util/args';\nexport function withLatestFrom(...inputs) {\n const project = popResultSelector(inputs);\n return operate((source, subscriber) => {\n const len = inputs.length;\n const otherValues = new Array(len);\n let hasValue = inputs.map(() => false);\n let ready = false;\n\n for (let i = 0; i < len; i++) {\n innerFrom(inputs[i]).subscribe(createOperatorSubscriber(subscriber, value => {\n otherValues[i] = value;\n\n if (!ready && !hasValue[i]) {\n hasValue[i] = true;\n (ready = hasValue.every(identity)) && (hasValue = null);\n }\n }, noop));\n }\n\n source.subscribe(createOperatorSubscriber(subscriber, value => {\n if (ready) {\n const values = [value, ...otherValues];\n subscriber.next(project ? project(...values) : values);\n }\n }));\n });\n} //# sourceMappingURL=withLatestFrom.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/2aa9eada412b86c552bf7276622f1d5b.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/2aa9eada412b86c552bf7276622f1d5b.json
deleted file mode 100644
index c41312c9..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/2aa9eada412b86c552bf7276622f1d5b.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"export function identity(x) {\n return x;\n} //# sourceMappingURL=identity.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/2c3b21fbe980b76735cdd79ea61cc8d5.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/2c3b21fbe980b76735cdd79ea61cc8d5.json
deleted file mode 100644
index 21ccfcf5..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/2c3b21fbe980b76735cdd79ea61cc8d5.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { defer } from './defer';\nexport function iif(condition, trueResult, falseResult) {\n return defer(() => condition() ? trueResult : falseResult);\n} //# sourceMappingURL=iif.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/2c7726e15e32b6873f94d8f0a62bc669.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/2c7726e15e32b6873f94d8f0a62bc669.json
deleted file mode 100644
index 25db6329..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/2c7726e15e32b6873f94d8f0a62bc669.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { isFunction } from './isFunction';\nexport function hasLift(source) {\n return isFunction(source === null || source === void 0 ? void 0 : source.lift);\n}\nexport function operate(init) {\n return source => {\n if (hasLift(source)) {\n return source.lift(function (liftedSource) {\n try {\n return init(liftedSource, this);\n } catch (err) {\n this.error(err);\n }\n });\n }\n\n throw new TypeError('Unable to lift unknown Observable type');\n };\n} //# sourceMappingURL=lift.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/2c98e472b84ea443e82322a809c43c99.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/2c98e472b84ea443e82322a809c43c99.json
deleted file mode 100644
index 64e00770..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/2c98e472b84ea443e82322a809c43c99.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { Scheduler } from '../Scheduler';\nexport class AsyncScheduler extends Scheduler {\n constructor(SchedulerAction, now = Scheduler.now) {\n super(SchedulerAction, now);\n this.actions = [];\n this._active = false;\n }\n\n flush(action) {\n const {\n actions\n } = this;\n\n if (this._active) {\n actions.push(action);\n return;\n }\n\n let error;\n this._active = true;\n\n do {\n if (error = action.execute(action.state, action.delay)) {\n break;\n }\n } while (action = actions.shift());\n\n this._active = false;\n\n if (error) {\n while (action = actions.shift()) {\n action.unsubscribe();\n }\n\n throw error;\n }\n }\n\n} //# sourceMappingURL=AsyncScheduler.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/2cbb49559bfd8ebbec21fc9bf591c9ed.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/2cbb49559bfd8ebbec21fc9bf591c9ed.json
deleted file mode 100644
index e9d13c56..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/2cbb49559bfd8ebbec21fc9bf591c9ed.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { operate } from '../util/lift';\nimport { createFind } from './find';\nexport function findIndex(predicate, thisArg) {\n return operate(createFind(predicate, thisArg, 'index'));\n} //# sourceMappingURL=findIndex.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/2dec38a69775715f624c5c2635e020f4.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/2dec38a69775715f624c5c2635e020f4.json
deleted file mode 100644
index 12e129c6..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/2dec38a69775715f624c5c2635e020f4.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { createOperatorSubscriber } from './OperatorSubscriber';\nexport function scanInternals(accumulator, seed, hasSeed, emitOnNext, emitBeforeComplete) {\n return (source, subscriber) => {\n let hasState = hasSeed;\n let state = seed;\n let index = 0;\n source.subscribe(createOperatorSubscriber(subscriber, value => {\n const i = index++;\n state = hasState ? accumulator(state, value, i) : (hasState = true, value);\n emitOnNext && subscriber.next(state);\n }, emitBeforeComplete && (() => {\n hasState && subscriber.next(state);\n subscriber.complete();\n })));\n };\n} //# sourceMappingURL=scanInternals.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/2e4fff6f23c09e9ef4d2842bcf95930d.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/2e4fff6f23c09e9ef4d2842bcf95930d.json
deleted file mode 100644
index 2f9af612..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/2e4fff6f23c09e9ef4d2842bcf95930d.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { isFunction } from '../util/isFunction';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { identity } from '../util/identity';\nexport function tap(observerOrNext, error, complete) {\n const tapObserver = isFunction(observerOrNext) || error || complete ? {\n next: observerOrNext,\n error,\n complete\n } : observerOrNext;\n return tapObserver ? operate((source, subscriber) => {\n var _a;\n\n (_a = tapObserver.subscribe) === null || _a === void 0 ? void 0 : _a.call(tapObserver);\n let isUnsub = true;\n source.subscribe(createOperatorSubscriber(subscriber, value => {\n var _a;\n\n (_a = tapObserver.next) === null || _a === void 0 ? void 0 : _a.call(tapObserver, value);\n subscriber.next(value);\n }, () => {\n var _a;\n\n isUnsub = false;\n (_a = tapObserver.complete) === null || _a === void 0 ? void 0 : _a.call(tapObserver);\n subscriber.complete();\n }, err => {\n var _a;\n\n isUnsub = false;\n (_a = tapObserver.error) === null || _a === void 0 ? void 0 : _a.call(tapObserver, err);\n subscriber.error(err);\n }, () => {\n var _a, _b;\n\n if (isUnsub) {\n (_a = tapObserver.unsubscribe) === null || _a === void 0 ? void 0 : _a.call(tapObserver);\n }\n\n (_b = tapObserver.finalize) === null || _b === void 0 ? void 0 : _b.call(tapObserver);\n }));\n }) : identity;\n} //# sourceMappingURL=tap.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/2e956ebaa13c78b713ed5d40e4dd487f.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/2e956ebaa13c78b713ed5d40e4dd487f.json
deleted file mode 100644
index 2fe7d799..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/2e956ebaa13c78b713ed5d40e4dd487f.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { AsyncScheduler } from './AsyncScheduler';\nexport class AnimationFrameScheduler extends AsyncScheduler {\n flush(action) {\n this._active = true;\n const flushId = this._scheduled;\n this._scheduled = undefined;\n const {\n actions\n } = this;\n let error;\n action = action || actions.shift();\n\n do {\n if (error = action.execute(action.state, action.delay)) {\n break;\n }\n } while ((action = actions[0]) && action.id === flushId && actions.shift());\n\n this._active = false;\n\n if (error) {\n while ((action = actions[0]) && action.id === flushId && actions.shift()) {\n action.unsubscribe();\n }\n\n throw error;\n }\n }\n\n} //# sourceMappingURL=AnimationFrameScheduler.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/2fe238e76115e87110d51eef842d3e08.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/2fe238e76115e87110d51eef842d3e08.json
deleted file mode 100644
index 810e0d18..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/2fe238e76115e87110d51eef842d3e08.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"var EventEmitter = require(\"events\");\n\nmodule.exports = new EventEmitter();","map":null,"metadata":{},"sourceType":"script"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/302f76052bd8c3c2ffc3f3077aaf5907.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/302f76052bd8c3c2ffc3f3077aaf5907.json
deleted file mode 100644
index 78355bd4..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/302f76052bd8c3c2ffc3f3077aaf5907.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { __asyncGenerator, __await } from \"tslib\";\nimport { isFunction } from './isFunction';\nexport function readableStreamLikeToAsyncGenerator(readableStream) {\n return __asyncGenerator(this, arguments, function* readableStreamLikeToAsyncGenerator_1() {\n const reader = readableStream.getReader();\n\n try {\n while (true) {\n const {\n value,\n done\n } = yield __await(reader.read());\n\n if (done) {\n return yield __await(void 0);\n }\n\n yield yield __await(value);\n }\n } finally {\n reader.releaseLock();\n }\n });\n}\nexport function isReadableStreamLike(obj) {\n return isFunction(obj === null || obj === void 0 ? void 0 : obj.getReader);\n} //# sourceMappingURL=isReadableStreamLike.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/34e950f363203f63d234e3fd7f0b7b0f.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/34e950f363203f63d234e3fd7f0b7b0f.json
deleted file mode 100644
index a30e7c97..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/34e950f363203f63d234e3fd7f0b7b0f.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { EMPTY } from '../observable/empty';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { innerFrom } from '../observable/innerFrom';\nimport { timer } from '../observable/timer';\nexport function repeat(countOrConfig) {\n let count = Infinity;\n let delay;\n\n if (countOrConfig != null) {\n if (typeof countOrConfig === 'object') {\n ({\n count = Infinity,\n delay\n } = countOrConfig);\n } else {\n count = countOrConfig;\n }\n }\n\n return count <= 0 ? () => EMPTY : operate((source, subscriber) => {\n let soFar = 0;\n let sourceSub;\n\n const resubscribe = () => {\n sourceSub === null || sourceSub === void 0 ? void 0 : sourceSub.unsubscribe();\n sourceSub = null;\n\n if (delay != null) {\n const notifier = typeof delay === 'number' ? timer(delay) : innerFrom(delay(soFar));\n const notifierSubscriber = createOperatorSubscriber(subscriber, () => {\n notifierSubscriber.unsubscribe();\n subscribeToSource();\n });\n notifier.subscribe(notifierSubscriber);\n } else {\n subscribeToSource();\n }\n };\n\n const subscribeToSource = () => {\n let syncUnsub = false;\n sourceSub = source.subscribe(createOperatorSubscriber(subscriber, undefined, () => {\n if (++soFar < count) {\n if (sourceSub) {\n resubscribe();\n } else {\n syncUnsub = true;\n }\n } else {\n subscriber.complete();\n }\n }));\n\n if (syncUnsub) {\n resubscribe();\n }\n };\n\n subscribeToSource();\n });\n} //# sourceMappingURL=repeat.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/3533a8f2159614c2838719e614e1f033.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/3533a8f2159614c2838719e614e1f033.json
deleted file mode 100644
index 4288f18a..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/3533a8f2159614c2838719e614e1f033.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { Observable } from '../Observable';\nimport { isFunction } from '../util/isFunction';\nimport { mapOneOrManyArgs } from '../util/mapOneOrManyArgs';\nexport function fromEventPattern(addHandler, removeHandler, resultSelector) {\n if (resultSelector) {\n return fromEventPattern(addHandler, removeHandler).pipe(mapOneOrManyArgs(resultSelector));\n }\n\n return new Observable(subscriber => {\n const handler = (...e) => subscriber.next(e.length === 1 ? e[0] : e);\n\n const retValue = addHandler(handler);\n return isFunction(removeHandler) ? () => removeHandler(handler, retValue) : undefined;\n });\n} //# sourceMappingURL=fromEventPattern.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/36618594cfd36f6eafd5ad3377372627.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/36618594cfd36f6eafd5ad3377372627.json
deleted file mode 100644
index 1af809de..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/36618594cfd36f6eafd5ad3377372627.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { operate } from '../util/lift';\nimport { noop } from '../util/noop';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nexport function buffer(closingNotifier) {\n return operate((source, subscriber) => {\n let currentBuffer = [];\n source.subscribe(createOperatorSubscriber(subscriber, value => currentBuffer.push(value), () => {\n subscriber.next(currentBuffer);\n subscriber.complete();\n }));\n closingNotifier.subscribe(createOperatorSubscriber(subscriber, () => {\n const b = currentBuffer;\n currentBuffer = [];\n subscriber.next(b);\n }, noop));\n return () => {\n currentBuffer = null;\n };\n });\n} //# sourceMappingURL=buffer.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/375650546b2eb3c537ad368e0d6a7d6c.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/375650546b2eb3c537ad368e0d6a7d6c.json
deleted file mode 100644
index 8f14c650..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/375650546b2eb3c537ad368e0d6a7d6c.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nconst MAC_ENTER = 3;\nconst BACKSPACE = 8;\nconst TAB = 9;\nconst NUM_CENTER = 12;\nconst ENTER = 13;\nconst SHIFT = 16;\nconst CONTROL = 17;\nconst ALT = 18;\nconst PAUSE = 19;\nconst CAPS_LOCK = 20;\nconst ESCAPE = 27;\nconst SPACE = 32;\nconst PAGE_UP = 33;\nconst PAGE_DOWN = 34;\nconst END = 35;\nconst HOME = 36;\nconst LEFT_ARROW = 37;\nconst UP_ARROW = 38;\nconst RIGHT_ARROW = 39;\nconst DOWN_ARROW = 40;\nconst PLUS_SIGN = 43;\nconst PRINT_SCREEN = 44;\nconst INSERT = 45;\nconst DELETE = 46;\nconst ZERO = 48;\nconst ONE = 49;\nconst TWO = 50;\nconst THREE = 51;\nconst FOUR = 52;\nconst FIVE = 53;\nconst SIX = 54;\nconst SEVEN = 55;\nconst EIGHT = 56;\nconst NINE = 57;\nconst FF_SEMICOLON = 59; // Firefox (Gecko) fires this for semicolon instead of 186\n\nconst FF_EQUALS = 61; // Firefox (Gecko) fires this for equals instead of 187\n\nconst QUESTION_MARK = 63;\nconst AT_SIGN = 64;\nconst A = 65;\nconst B = 66;\nconst C = 67;\nconst D = 68;\nconst E = 69;\nconst F = 70;\nconst G = 71;\nconst H = 72;\nconst I = 73;\nconst J = 74;\nconst K = 75;\nconst L = 76;\nconst M = 77;\nconst N = 78;\nconst O = 79;\nconst P = 80;\nconst Q = 81;\nconst R = 82;\nconst S = 83;\nconst T = 84;\nconst U = 85;\nconst V = 86;\nconst W = 87;\nconst X = 88;\nconst Y = 89;\nconst Z = 90;\nconst META = 91; // WIN_KEY_LEFT\n\nconst MAC_WK_CMD_LEFT = 91;\nconst MAC_WK_CMD_RIGHT = 93;\nconst CONTEXT_MENU = 93;\nconst NUMPAD_ZERO = 96;\nconst NUMPAD_ONE = 97;\nconst NUMPAD_TWO = 98;\nconst NUMPAD_THREE = 99;\nconst NUMPAD_FOUR = 100;\nconst NUMPAD_FIVE = 101;\nconst NUMPAD_SIX = 102;\nconst NUMPAD_SEVEN = 103;\nconst NUMPAD_EIGHT = 104;\nconst NUMPAD_NINE = 105;\nconst NUMPAD_MULTIPLY = 106;\nconst NUMPAD_PLUS = 107;\nconst NUMPAD_MINUS = 109;\nconst NUMPAD_PERIOD = 110;\nconst NUMPAD_DIVIDE = 111;\nconst F1 = 112;\nconst F2 = 113;\nconst F3 = 114;\nconst F4 = 115;\nconst F5 = 116;\nconst F6 = 117;\nconst F7 = 118;\nconst F8 = 119;\nconst F9 = 120;\nconst F10 = 121;\nconst F11 = 122;\nconst F12 = 123;\nconst NUM_LOCK = 144;\nconst SCROLL_LOCK = 145;\nconst FIRST_MEDIA = 166;\nconst FF_MINUS = 173;\nconst MUTE = 173; // Firefox (Gecko) fires 181 for MUTE\n\nconst VOLUME_DOWN = 174; // Firefox (Gecko) fires 182 for VOLUME_DOWN\n\nconst VOLUME_UP = 175; // Firefox (Gecko) fires 183 for VOLUME_UP\n\nconst FF_MUTE = 181;\nconst FF_VOLUME_DOWN = 182;\nconst LAST_MEDIA = 183;\nconst FF_VOLUME_UP = 183;\nconst SEMICOLON = 186; // Firefox (Gecko) fires 59 for SEMICOLON\n\nconst EQUALS = 187; // Firefox (Gecko) fires 61 for EQUALS\n\nconst COMMA = 188;\nconst DASH = 189; // Firefox (Gecko) fires 173 for DASH/MINUS\n\nconst PERIOD = 190;\nconst SLASH = 191;\nconst APOSTROPHE = 192;\nconst TILDE = 192;\nconst OPEN_SQUARE_BRACKET = 219;\nconst BACKSLASH = 220;\nconst CLOSE_SQUARE_BRACKET = 221;\nconst SINGLE_QUOTE = 222;\nconst MAC_META = 224;\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Checks whether a modifier key is pressed.\n * @param event Event to be checked.\n */\n\nfunction hasModifierKey(event, ...modifiers) {\n if (modifiers.length) {\n return modifiers.some(modifier => event[modifier]);\n }\n\n return event.altKey || event.shiftKey || event.ctrlKey || event.metaKey;\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Generated bundle index. Do not edit.\n */\n\n\nexport { A, ALT, APOSTROPHE, AT_SIGN, B, BACKSLASH, BACKSPACE, C, CAPS_LOCK, CLOSE_SQUARE_BRACKET, COMMA, CONTEXT_MENU, CONTROL, D, DASH, DELETE, DOWN_ARROW, E, EIGHT, END, ENTER, EQUALS, ESCAPE, F, F1, F10, F11, F12, F2, F3, F4, F5, F6, F7, F8, F9, FF_EQUALS, FF_MINUS, FF_MUTE, FF_SEMICOLON, FF_VOLUME_DOWN, FF_VOLUME_UP, FIRST_MEDIA, FIVE, FOUR, G, H, HOME, I, INSERT, J, K, L, LAST_MEDIA, LEFT_ARROW, M, MAC_ENTER, MAC_META, MAC_WK_CMD_LEFT, MAC_WK_CMD_RIGHT, META, MUTE, N, NINE, NUMPAD_DIVIDE, NUMPAD_EIGHT, NUMPAD_FIVE, NUMPAD_FOUR, NUMPAD_MINUS, NUMPAD_MULTIPLY, NUMPAD_NINE, NUMPAD_ONE, NUMPAD_PERIOD, NUMPAD_PLUS, NUMPAD_SEVEN, NUMPAD_SIX, NUMPAD_THREE, NUMPAD_TWO, NUMPAD_ZERO, NUM_CENTER, NUM_LOCK, O, ONE, OPEN_SQUARE_BRACKET, P, PAGE_DOWN, PAGE_UP, PAUSE, PERIOD, PLUS_SIGN, PRINT_SCREEN, Q, QUESTION_MARK, R, RIGHT_ARROW, S, SCROLL_LOCK, SEMICOLON, SEVEN, SHIFT, SINGLE_QUOTE, SIX, SLASH, SPACE, T, TAB, THREE, TILDE, TWO, U, UP_ARROW, V, VOLUME_DOWN, VOLUME_UP, W, X, Y, Z, ZERO, hasModifierKey }; //# sourceMappingURL=keycodes.mjs.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/3885fb2e9f3497f0198f8e5f6034c05e.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/3885fb2e9f3497f0198f8e5f6034c05e.json
deleted file mode 100644
index 8ba7b796..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/3885fb2e9f3497f0198f8e5f6034c05e.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nexport function sequenceEqual(compareTo, comparator = (a, b) => a === b) {\n return operate((source, subscriber) => {\n const aState = createState();\n const bState = createState();\n\n const emit = isEqual => {\n subscriber.next(isEqual);\n subscriber.complete();\n };\n\n const createSubscriber = (selfState, otherState) => {\n const sequenceEqualSubscriber = createOperatorSubscriber(subscriber, a => {\n const {\n buffer,\n complete\n } = otherState;\n\n if (buffer.length === 0) {\n complete ? emit(false) : selfState.buffer.push(a);\n } else {\n !comparator(a, buffer.shift()) && emit(false);\n }\n }, () => {\n selfState.complete = true;\n const {\n complete,\n buffer\n } = otherState;\n complete && emit(buffer.length === 0);\n sequenceEqualSubscriber === null || sequenceEqualSubscriber === void 0 ? void 0 : sequenceEqualSubscriber.unsubscribe();\n });\n return sequenceEqualSubscriber;\n };\n\n source.subscribe(createSubscriber(aState, bState));\n compareTo.subscribe(createSubscriber(bState, aState));\n });\n}\n\nfunction createState() {\n return {\n buffer: [],\n complete: false\n };\n} //# sourceMappingURL=sequenceEqual.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/39ba0f88c1add86e970d08c02ba104e8.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/39ba0f88c1add86e970d08c02ba104e8.json
deleted file mode 100644
index 1859afc9..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/39ba0f88c1add86e970d08c02ba104e8.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { Subject } from '../Subject';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { noop } from '../util/noop';\nexport function window(windowBoundaries) {\n return operate((source, subscriber) => {\n let windowSubject = new Subject();\n subscriber.next(windowSubject.asObservable());\n\n const errorHandler = err => {\n windowSubject.error(err);\n subscriber.error(err);\n };\n\n source.subscribe(createOperatorSubscriber(subscriber, value => windowSubject === null || windowSubject === void 0 ? void 0 : windowSubject.next(value), () => {\n windowSubject.complete();\n subscriber.complete();\n }, errorHandler));\n windowBoundaries.subscribe(createOperatorSubscriber(subscriber, () => {\n windowSubject.complete();\n subscriber.next(windowSubject = new Subject());\n }, noop, errorHandler));\n return () => {\n windowSubject === null || windowSubject === void 0 ? void 0 : windowSubject.unsubscribe();\n windowSubject = null;\n };\n });\n} //# sourceMappingURL=window.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/3a6695ac1d09de2ed936fd1b55cd01f5.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/3a6695ac1d09de2ed936fd1b55cd01f5.json
deleted file mode 100644
index 651d6e69..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/3a6695ac1d09de2ed936fd1b55cd01f5.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { Observable } from '../Observable';\nimport { innerFrom } from './innerFrom';\nimport { argsOrArgArray } from '../util/argsOrArgArray';\nimport { EMPTY } from './empty';\nimport { createOperatorSubscriber } from '../operators/OperatorSubscriber';\nimport { popResultSelector } from '../util/args';\nexport function zip(...args) {\n const resultSelector = popResultSelector(args);\n const sources = argsOrArgArray(args);\n return sources.length ? new Observable(subscriber => {\n let buffers = sources.map(() => []);\n let completed = sources.map(() => false);\n subscriber.add(() => {\n buffers = completed = null;\n });\n\n for (let sourceIndex = 0; !subscriber.closed && sourceIndex < sources.length; sourceIndex++) {\n innerFrom(sources[sourceIndex]).subscribe(createOperatorSubscriber(subscriber, value => {\n buffers[sourceIndex].push(value);\n\n if (buffers.every(buffer => buffer.length)) {\n const result = buffers.map(buffer => buffer.shift());\n subscriber.next(resultSelector ? resultSelector(...result) : result);\n\n if (buffers.some((buffer, i) => !buffer.length && completed[i])) {\n subscriber.complete();\n }\n }\n }, () => {\n completed[sourceIndex] = true;\n !buffers[sourceIndex].length && subscriber.complete();\n }));\n }\n\n return () => {\n buffers = completed = null;\n };\n }) : EMPTY;\n} //# sourceMappingURL=zip.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/3b8c29b5a0faeee96c1ea555b950b2ff.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/3b8c29b5a0faeee96c1ea555b950b2ff.json
deleted file mode 100644
index eef5239d..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/3b8c29b5a0faeee96c1ea555b950b2ff.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import hotEmitter from \"webpack/hot/emitter.js\";\nimport { log } from \"./log.js\";\n/** @typedef {import(\"../index\").Options} Options\n/** @typedef {import(\"../index\").Status} Status\n\n/**\n * @param {Options} options\n * @param {Status} status\n */\n\nfunction reloadApp(_ref, status) {\n var hot = _ref.hot,\n liveReload = _ref.liveReload;\n\n if (status.isUnloading) {\n return;\n }\n\n var currentHash = status.currentHash,\n previousHash = status.previousHash;\n var isInitial = currentHash.indexOf(\n /** @type {string} */\n previousHash) >= 0;\n\n if (isInitial) {\n return;\n }\n /**\n * @param {Window} rootWindow\n * @param {number} intervalId\n */\n\n\n function applyReload(rootWindow, intervalId) {\n clearInterval(intervalId);\n log.info(\"App updated. Reloading...\");\n rootWindow.location.reload();\n }\n\n var search = self.location.search.toLowerCase();\n var allowToHot = search.indexOf(\"webpack-dev-server-hot=false\") === -1;\n var allowToLiveReload = search.indexOf(\"webpack-dev-server-live-reload=false\") === -1;\n\n if (hot && allowToHot) {\n log.info(\"App hot update...\");\n hotEmitter.emit(\"webpackHotUpdate\", status.currentHash);\n\n if (typeof self !== \"undefined\" && self.window) {\n // broadcast update to window\n self.postMessage(\"webpackHotUpdate\".concat(status.currentHash), \"*\");\n }\n } // allow refreshing the page only if liveReload isn't disabled\n else if (liveReload && allowToLiveReload) {\n var rootWindow = self; // use parent window for reload (in case we're in an iframe with no valid src)\n\n var intervalId = self.setInterval(function () {\n if (rootWindow.location.protocol !== \"about:\") {\n // reload immediately if protocol is valid\n applyReload(rootWindow, intervalId);\n } else {\n rootWindow = rootWindow.parent;\n\n if (rootWindow.parent === rootWindow) {\n // if parent equals current window we've reached the root which would continue forever, so trigger a reload anyways\n applyReload(rootWindow, intervalId);\n }\n }\n });\n }\n}\n\nexport default reloadApp;","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/3e7edf27e8e083baf6ec26d09c7f8e5d.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/3e7edf27e8e083baf6ec26d09c7f8e5d.json
deleted file mode 100644
index 7904becb..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/3e7edf27e8e083baf6ec26d09c7f8e5d.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"\"use strict\";\n\nvar __assign = this && this.__assign || function () {\n __assign = Object.assign || function (t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n\n return t;\n };\n\n return __assign.apply(this, arguments);\n};\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar named_references_1 = require(\"./named-references\");\n\nvar numeric_unicode_map_1 = require(\"./numeric-unicode-map\");\n\nvar surrogate_pairs_1 = require(\"./surrogate-pairs\");\n\nvar allNamedReferences = __assign(__assign({}, named_references_1.namedReferences), {\n all: named_references_1.namedReferences.html5\n});\n\nvar encodeRegExps = {\n specialChars: /[<>'\"&]/g,\n nonAscii: /(?:[<>'\"&\\u0080-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])/g,\n nonAsciiPrintable: /(?:[<>'\"&\\x01-\\x08\\x11-\\x15\\x17-\\x1F\\x7f-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])/g,\n extensive: /(?:[\\x01-\\x0c\\x0e-\\x1f\\x21-\\x2c\\x2e-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\x7d\\x7f-\\uD7FF\\uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF])/g\n};\nvar defaultEncodeOptions = {\n mode: 'specialChars',\n level: 'all',\n numeric: 'decimal'\n};\n/** Encodes all the necessary (specified by `level`) characters in the text */\n\nfunction encode(text, _a) {\n var _b = _a === void 0 ? defaultEncodeOptions : _a,\n _c = _b.mode,\n mode = _c === void 0 ? 'specialChars' : _c,\n _d = _b.numeric,\n numeric = _d === void 0 ? 'decimal' : _d,\n _e = _b.level,\n level = _e === void 0 ? 'all' : _e;\n\n if (!text) {\n return '';\n }\n\n var encodeRegExp = encodeRegExps[mode];\n var references = allNamedReferences[level].characters;\n var isHex = numeric === 'hexadecimal';\n encodeRegExp.lastIndex = 0;\n\n var _b = encodeRegExp.exec(text);\n\n var _c;\n\n if (_b) {\n _c = '';\n var _d = 0;\n\n do {\n if (_d !== _b.index) {\n _c += text.substring(_d, _b.index);\n }\n\n var _e = _b[0];\n var result_1 = references[_e];\n\n if (!result_1) {\n var code_1 = _e.length > 1 ? surrogate_pairs_1.getCodePoint(_e, 0) : _e.charCodeAt(0);\n result_1 = (isHex ? '' + code_1.toString(16) : '' + code_1) + ';';\n }\n\n _c += result_1;\n _d = _b.index + _e.length;\n } while (_b = encodeRegExp.exec(text));\n\n if (_d !== text.length) {\n _c += text.substring(_d);\n }\n } else {\n _c = text;\n }\n\n return _c;\n}\n\nexports.encode = encode;\nvar defaultDecodeOptions = {\n scope: 'body',\n level: 'all'\n};\nvar strict = /&(?:#\\d+|#[xX][\\da-fA-F]+|[0-9a-zA-Z]+);/g;\nvar attribute = /&(?:#\\d+|#[xX][\\da-fA-F]+|[0-9a-zA-Z]+)[;=]?/g;\nvar baseDecodeRegExps = {\n xml: {\n strict: strict,\n attribute: attribute,\n body: named_references_1.bodyRegExps.xml\n },\n html4: {\n strict: strict,\n attribute: attribute,\n body: named_references_1.bodyRegExps.html4\n },\n html5: {\n strict: strict,\n attribute: attribute,\n body: named_references_1.bodyRegExps.html5\n }\n};\n\nvar decodeRegExps = __assign(__assign({}, baseDecodeRegExps), {\n all: baseDecodeRegExps.html5\n});\n\nvar fromCharCode = String.fromCharCode;\nvar outOfBoundsChar = fromCharCode(65533);\nvar defaultDecodeEntityOptions = {\n level: 'all'\n};\n/** Decodes a single entity */\n\nfunction decodeEntity(entity, _a) {\n var _b = (_a === void 0 ? defaultDecodeEntityOptions : _a).level,\n level = _b === void 0 ? 'all' : _b;\n\n if (!entity) {\n return '';\n }\n\n var _b = entity;\n var decodeEntityLastChar_1 = entity[entity.length - 1];\n\n if (false && decodeEntityLastChar_1 === '=') {\n _b = entity;\n } else if (false && decodeEntityLastChar_1 !== ';') {\n _b = entity;\n } else {\n var decodeResultByReference_1 = allNamedReferences[level].entities[entity];\n\n if (decodeResultByReference_1) {\n _b = decodeResultByReference_1;\n } else if (entity[0] === '&' && entity[1] === '#') {\n var decodeSecondChar_1 = entity[2];\n var decodeCode_1 = decodeSecondChar_1 == 'x' || decodeSecondChar_1 == 'X' ? parseInt(entity.substr(3), 16) : parseInt(entity.substr(2));\n _b = decodeCode_1 >= 0x10ffff ? outOfBoundsChar : decodeCode_1 > 65535 ? surrogate_pairs_1.fromCodePoint(decodeCode_1) : fromCharCode(numeric_unicode_map_1.numericUnicodeMap[decodeCode_1] || decodeCode_1);\n }\n }\n\n return _b;\n}\n\nexports.decodeEntity = decodeEntity;\n/** Decodes all entities in the text */\n\nfunction decode(text, _a) {\n var decodeSecondChar_1 = _a === void 0 ? defaultDecodeOptions : _a,\n decodeCode_1 = decodeSecondChar_1.level,\n level = decodeCode_1 === void 0 ? 'all' : decodeCode_1,\n _b = decodeSecondChar_1.scope,\n scope = _b === void 0 ? level === 'xml' ? 'strict' : 'body' : _b;\n\n if (!text) {\n return '';\n }\n\n var decodeRegExp = decodeRegExps[level][scope];\n var references = allNamedReferences[level].entities;\n var isAttribute = scope === 'attribute';\n var isStrict = scope === 'strict';\n decodeRegExp.lastIndex = 0;\n var replaceMatch_1 = decodeRegExp.exec(text);\n var replaceResult_1;\n\n if (replaceMatch_1) {\n replaceResult_1 = '';\n var replaceLastIndex_1 = 0;\n\n do {\n if (replaceLastIndex_1 !== replaceMatch_1.index) {\n replaceResult_1 += text.substring(replaceLastIndex_1, replaceMatch_1.index);\n }\n\n var replaceInput_1 = replaceMatch_1[0];\n var decodeResult_1 = replaceInput_1;\n var decodeEntityLastChar_2 = replaceInput_1[replaceInput_1.length - 1];\n\n if (isAttribute && decodeEntityLastChar_2 === '=') {\n decodeResult_1 = replaceInput_1;\n } else if (isStrict && decodeEntityLastChar_2 !== ';') {\n decodeResult_1 = replaceInput_1;\n } else {\n var decodeResultByReference_2 = references[replaceInput_1];\n\n if (decodeResultByReference_2) {\n decodeResult_1 = decodeResultByReference_2;\n } else if (replaceInput_1[0] === '&' && replaceInput_1[1] === '#') {\n var decodeSecondChar_2 = replaceInput_1[2];\n var decodeCode_2 = decodeSecondChar_2 == 'x' || decodeSecondChar_2 == 'X' ? parseInt(replaceInput_1.substr(3), 16) : parseInt(replaceInput_1.substr(2));\n decodeResult_1 = decodeCode_2 >= 0x10ffff ? outOfBoundsChar : decodeCode_2 > 65535 ? surrogate_pairs_1.fromCodePoint(decodeCode_2) : fromCharCode(numeric_unicode_map_1.numericUnicodeMap[decodeCode_2] || decodeCode_2);\n }\n }\n\n replaceResult_1 += decodeResult_1;\n replaceLastIndex_1 = replaceMatch_1.index + replaceInput_1.length;\n } while (replaceMatch_1 = decodeRegExp.exec(text));\n\n if (replaceLastIndex_1 !== text.length) {\n replaceResult_1 += text.substring(replaceLastIndex_1);\n }\n } else {\n replaceResult_1 = text;\n }\n\n return replaceResult_1;\n}\n\nexports.decode = decode;","map":null,"metadata":{},"sourceType":"script"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/3f74ec3a6aabc59cb6f3e03cb6164c28.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/3f74ec3a6aabc59cb6f3e03cb6164c28.json
deleted file mode 100644
index f7b262a6..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/3f74ec3a6aabc59cb6f3e03cb6164c28.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { innerFrom } from '../observable/innerFrom';\nimport { observeOn } from '../operators/observeOn';\nimport { subscribeOn } from '../operators/subscribeOn';\nexport function scheduleObservable(input, scheduler) {\n return innerFrom(input).pipe(subscribeOn(scheduler), observeOn(scheduler));\n} //# sourceMappingURL=scheduleObservable.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/4014b81db2954b433d2e06b94ae49f4f.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/4014b81db2954b433d2e06b94ae49f4f.json
deleted file mode 100644
index e6ca4f68..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/4014b81db2954b433d2e06b94ae49f4f.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { innerFrom } from '../observable/innerFrom';\nimport { noop } from '../util/noop';\nexport function skipUntil(notifier) {\n return operate((source, subscriber) => {\n let taking = false;\n const skipSubscriber = createOperatorSubscriber(subscriber, () => {\n skipSubscriber === null || skipSubscriber === void 0 ? void 0 : skipSubscriber.unsubscribe();\n taking = true;\n }, noop);\n innerFrom(notifier).subscribe(skipSubscriber);\n source.subscribe(createOperatorSubscriber(subscriber, value => taking && subscriber.next(value)));\n });\n} //# sourceMappingURL=skipUntil.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/40d43fcb4cb4f99268a038f11d2330b2.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/40d43fcb4cb4f99268a038f11d2330b2.json
deleted file mode 100644
index fef4b838..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/40d43fcb4cb4f99268a038f11d2330b2.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { map } from \"../operators/map\";\nconst {\n isArray\n} = Array;\n\nfunction callOrApply(fn, args) {\n return isArray(args) ? fn(...args) : fn(args);\n}\n\nexport function mapOneOrManyArgs(fn) {\n return map(args => callOrApply(fn, args));\n} //# sourceMappingURL=mapOneOrManyArgs.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/41039690521490226720fada9ae32249.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/41039690521490226720fada9ae32249.json
deleted file mode 100644
index e6275ba3..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/41039690521490226720fada9ae32249.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"/**\n * @param {{ protocol?: string, auth?: string, hostname?: string, port?: string, pathname?: string, search?: string, hash?: string, slashes?: boolean }} objURL\n * @returns {string}\n */\nfunction format(objURL) {\n var protocol = objURL.protocol || \"\";\n\n if (protocol && protocol.substr(-1) !== \":\") {\n protocol += \":\";\n }\n\n var auth = objURL.auth || \"\";\n\n if (auth) {\n auth = encodeURIComponent(auth);\n auth = auth.replace(/%3A/i, \":\");\n auth += \"@\";\n }\n\n var host = \"\";\n\n if (objURL.hostname) {\n host = auth + (objURL.hostname.indexOf(\":\") === -1 ? objURL.hostname : \"[\".concat(objURL.hostname, \"]\"));\n\n if (objURL.port) {\n host += \":\".concat(objURL.port);\n }\n }\n\n var pathname = objURL.pathname || \"\";\n\n if (objURL.slashes) {\n host = \"//\".concat(host || \"\");\n\n if (pathname && pathname.charAt(0) !== \"/\") {\n pathname = \"/\".concat(pathname);\n }\n } else if (!host) {\n host = \"\";\n }\n\n var search = objURL.search || \"\";\n\n if (search && search.charAt(0) !== \"?\") {\n search = \"?\".concat(search);\n }\n\n var hash = objURL.hash || \"\";\n\n if (hash && hash.charAt(0) !== \"#\") {\n hash = \"#\".concat(hash);\n }\n\n pathname = pathname.replace(/[?#]/g,\n /**\n * @param {string} match\n * @returns {string}\n */\n function (match) {\n return encodeURIComponent(match);\n });\n search = search.replace(\"#\", \"%23\");\n return \"\".concat(protocol).concat(host).concat(pathname).concat(search).concat(hash);\n}\n/**\n * @param {URL & { fromCurrentScript?: boolean }} parsedURL\n * @returns {string}\n */\n\n\nfunction createSocketURL(parsedURL) {\n var hostname = parsedURL.hostname; // Node.js module parses it as `::`\n // `new URL(urlString, [baseURLString])` parses it as '[::]'\n\n var isInAddrAny = hostname === \"0.0.0.0\" || hostname === \"::\" || hostname === \"[::]\"; // why do we need this check?\n // hostname n/a for file protocol (example, when using electron, ionic)\n // see: https://github.com/webpack/webpack-dev-server/pull/384\n\n if (isInAddrAny && self.location.hostname && self.location.protocol.indexOf(\"http\") === 0) {\n hostname = self.location.hostname;\n }\n\n var socketURLProtocol = parsedURL.protocol || self.location.protocol; // When https is used in the app, secure web sockets are always necessary because the browser doesn't accept non-secure web sockets.\n\n if (socketURLProtocol === \"auto:\" || hostname && isInAddrAny && self.location.protocol === \"https:\") {\n socketURLProtocol = self.location.protocol;\n }\n\n socketURLProtocol = socketURLProtocol.replace(/^(?:http|.+-extension|file)/i, \"ws\");\n var socketURLAuth = \"\"; // `new URL(urlString, [baseURLstring])` doesn't have `auth` property\n // Parse authentication credentials in case we need them\n\n if (parsedURL.username) {\n socketURLAuth = parsedURL.username; // Since HTTP basic authentication does not allow empty username,\n // we only include password if the username is not empty.\n\n if (parsedURL.password) {\n // Result: :\n socketURLAuth = socketURLAuth.concat(\":\", parsedURL.password);\n }\n } // In case the host is a raw IPv6 address, it can be enclosed in\n // the brackets as the brackets are needed in the final URL string.\n // Need to remove those as url.format blindly adds its own set of brackets\n // if the host string contains colons. That would lead to non-working\n // double brackets (e.g. [[::]]) host\n //\n // All of these web socket url params are optionally passed in through resourceQuery,\n // so we need to fall back to the default if they are not provided\n\n\n var socketURLHostname = (hostname || self.location.hostname || \"localhost\").replace(/^\\[(.*)\\]$/, \"$1\");\n var socketURLPort = parsedURL.port;\n\n if (!socketURLPort || socketURLPort === \"0\") {\n socketURLPort = self.location.port;\n } // If path is provided it'll be passed in via the resourceQuery as a\n // query param so it has to be parsed out of the querystring in order for the\n // client to open the socket to the correct location.\n\n\n var socketURLPathname = \"/ws\";\n\n if (parsedURL.pathname && !parsedURL.fromCurrentScript) {\n socketURLPathname = parsedURL.pathname;\n }\n\n return format({\n protocol: socketURLProtocol,\n auth: socketURLAuth,\n hostname: socketURLHostname,\n port: socketURLPort,\n pathname: socketURLPathname,\n slashes: true\n });\n}\n\nexport default createSocketURL;","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/41ea88779dd902a914648c95680256bb.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/41ea88779dd902a914648c95680256bb.json
deleted file mode 100644
index bb8b73c1..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/41ea88779dd902a914648c95680256bb.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { isFunction } from './util/isFunction';\nimport { isSubscription, Subscription } from './Subscription';\nimport { config } from './config';\nimport { reportUnhandledError } from './util/reportUnhandledError';\nimport { noop } from './util/noop';\nimport { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';\nimport { timeoutProvider } from './scheduler/timeoutProvider';\nimport { captureError } from './util/errorContext';\nexport class Subscriber extends Subscription {\n constructor(destination) {\n super();\n this.isStopped = false;\n\n if (destination) {\n this.destination = destination;\n\n if (isSubscription(destination)) {\n destination.add(this);\n }\n } else {\n this.destination = EMPTY_OBSERVER;\n }\n }\n\n static create(next, error, complete) {\n return new SafeSubscriber(next, error, complete);\n }\n\n next(value) {\n if (this.isStopped) {\n handleStoppedNotification(nextNotification(value), this);\n } else {\n this._next(value);\n }\n }\n\n error(err) {\n if (this.isStopped) {\n handleStoppedNotification(errorNotification(err), this);\n } else {\n this.isStopped = true;\n\n this._error(err);\n }\n }\n\n complete() {\n if (this.isStopped) {\n handleStoppedNotification(COMPLETE_NOTIFICATION, this);\n } else {\n this.isStopped = true;\n\n this._complete();\n }\n }\n\n unsubscribe() {\n if (!this.closed) {\n this.isStopped = true;\n super.unsubscribe();\n this.destination = null;\n }\n }\n\n _next(value) {\n this.destination.next(value);\n }\n\n _error(err) {\n try {\n this.destination.error(err);\n } finally {\n this.unsubscribe();\n }\n }\n\n _complete() {\n try {\n this.destination.complete();\n } finally {\n this.unsubscribe();\n }\n }\n\n}\nconst _bind = Function.prototype.bind;\n\nfunction bind(fn, thisArg) {\n return _bind.call(fn, thisArg);\n}\n\nclass ConsumerObserver {\n constructor(partialObserver) {\n this.partialObserver = partialObserver;\n }\n\n next(value) {\n const {\n partialObserver\n } = this;\n\n if (partialObserver.next) {\n try {\n partialObserver.next(value);\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n\n error(err) {\n const {\n partialObserver\n } = this;\n\n if (partialObserver.error) {\n try {\n partialObserver.error(err);\n } catch (error) {\n handleUnhandledError(error);\n }\n } else {\n handleUnhandledError(err);\n }\n }\n\n complete() {\n const {\n partialObserver\n } = this;\n\n if (partialObserver.complete) {\n try {\n partialObserver.complete();\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n\n}\n\nexport class SafeSubscriber extends Subscriber {\n constructor(observerOrNext, error, complete) {\n super();\n let partialObserver;\n\n if (isFunction(observerOrNext) || !observerOrNext) {\n partialObserver = {\n next: observerOrNext !== null && observerOrNext !== void 0 ? observerOrNext : undefined,\n error: error !== null && error !== void 0 ? error : undefined,\n complete: complete !== null && complete !== void 0 ? complete : undefined\n };\n } else {\n let context;\n\n if (this && config.useDeprecatedNextContext) {\n context = Object.create(observerOrNext);\n\n context.unsubscribe = () => this.unsubscribe();\n\n partialObserver = {\n next: observerOrNext.next && bind(observerOrNext.next, context),\n error: observerOrNext.error && bind(observerOrNext.error, context),\n complete: observerOrNext.complete && bind(observerOrNext.complete, context)\n };\n } else {\n partialObserver = observerOrNext;\n }\n }\n\n this.destination = new ConsumerObserver(partialObserver);\n }\n\n}\n\nfunction handleUnhandledError(error) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n captureError(error);\n } else {\n reportUnhandledError(error);\n }\n}\n\nfunction defaultErrorHandler(err) {\n throw err;\n}\n\nfunction handleStoppedNotification(notification, subscriber) {\n const {\n onStoppedNotification\n } = config;\n onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));\n}\n\nexport const EMPTY_OBSERVER = {\n closed: true,\n next: noop,\n error: defaultErrorHandler,\n complete: noop\n}; //# sourceMappingURL=Subscriber.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/43d49a0b42daaaab7545f0642510bc7d.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/43d49a0b42daaaab7545f0642510bc7d.json
deleted file mode 100644
index 685301cc..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/43d49a0b42daaaab7545f0642510bc7d.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { innerFrom } from '../observable/innerFrom';\nimport { noop } from '../util/noop';\nexport function takeUntil(notifier) {\n return operate((source, subscriber) => {\n innerFrom(notifier).subscribe(createOperatorSubscriber(subscriber, () => subscriber.complete(), noop));\n !subscriber.closed && source.subscribe(subscriber);\n });\n} //# sourceMappingURL=takeUntil.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/44ba430a416237df50e48cae32792fac.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/44ba430a416237df50e48cae32792fac.json
deleted file mode 100644
index 545c2a14..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/44ba430a416237df50e48cae32792fac.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import * as i0 from \"@angular/core\";\nimport * as i1 from \"ng2-pdfjs-viewer\";\nconst _c0 = [\"bigPdfViewer\"];\nexport let BigComponent = /*#__PURE__*/(() => {\n class BigComponent {\n constructor() {}\n\n ngOnInit() {}\n\n testBeforePrint() {\n console.log('testBeforePrint() successfully called');\n console.log(this.bigPdfViewer.page);\n this.bigPdfViewer.page = 3;\n console.log(this.bigPdfViewer.page);\n }\n\n testAfterPrint() {\n console.log('testAfterPrint() successfully called');\n }\n\n testPagesLoaded(count) {\n console.log('testPagesLoaded() successfully called. Total pages # : ' + count);\n }\n\n testPageChange(pageNumber) {\n console.log('testPageChange() successfully called. Current page # : ' + pageNumber);\n }\n\n }\n\n BigComponent.ɵfac = function BigComponent_Factory(t) {\n return new (t || BigComponent)();\n };\n\n BigComponent.ɵcmp = /*@__PURE__*/i0.ɵɵdefineComponent({\n type: BigComponent,\n selectors: [[\"app-big\"]],\n viewQuery: function BigComponent_Query(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵviewQuery(_c0, 7);\n }\n\n if (rf & 2) {\n let _t;\n\n i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.bigPdfViewer = _t.first);\n }\n },\n decls: 3,\n vars: 0,\n consts: [[1, \"h-100\"], [\"pdfSrc\", \"gre_research_validity_data.pdf\", \"downloadFileName\", \"mySample\", \"zoom\", \"auto\", \"viewerId\", \"MyID\", 3, \"onDocumentLoad\", \"onPageChange\", \"onBeforePrint\", \"onAfterPrint\"], [\"bigPdfViewer\", \"\"]],\n template: function BigComponent_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵelementStart(0, \"div\", 0)(1, \"ng2-pdfjs-viewer\", 1, 2);\n i0.ɵɵlistener(\"onDocumentLoad\", function BigComponent_Template_ng2_pdfjs_viewer_onDocumentLoad_1_listener($event) {\n return ctx.testPagesLoaded($event);\n })(\"onPageChange\", function BigComponent_Template_ng2_pdfjs_viewer_onPageChange_1_listener($event) {\n return ctx.testPageChange($event);\n })(\"onBeforePrint\", function BigComponent_Template_ng2_pdfjs_viewer_onBeforePrint_1_listener() {\n return ctx.testBeforePrint();\n })(\"onAfterPrint\", function BigComponent_Template_ng2_pdfjs_viewer_onAfterPrint_1_listener() {\n return ctx.testAfterPrint();\n });\n i0.ɵɵelementEnd()();\n }\n },\n dependencies: [i1.PdfJsViewerComponent],\n styles: [\".h-100[_ngcontent-%COMP%]{height:100%}\"]\n });\n return BigComponent;\n})();","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/44cf9e44daf59a94d26b0baf111268d0.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/44cf9e44daf59a94d26b0baf111268d0.json
deleted file mode 100644
index fc2c9bc4..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/44cf9e44daf59a94d26b0baf111268d0.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import * as i0 from '@angular/core';\nimport { Directive, Component, ChangeDetectionStrategy, ViewEncapsulation, Inject, ContentChildren, NgModule } from '@angular/core';\nimport { mixinColor, MatCommonModule } from '@angular/material/core';\nimport * as i1 from '@angular/cdk/platform';\nimport { DOCUMENT } from '@angular/common';\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n// Boilerplate for applying mixins to MatToolbar.\n\n/** @docs-private */\n\nconst _c0 = [\"*\", [[\"mat-toolbar-row\"]]];\nconst _c1 = [\"*\", \"mat-toolbar-row\"];\n\nconst _MatToolbarBase = /*#__PURE__*/mixinColor(class {\n constructor(_elementRef) {\n this._elementRef = _elementRef;\n }\n\n});\n\nlet MatToolbarRow = /*#__PURE__*/(() => {\n class MatToolbarRow {}\n\n MatToolbarRow.ɵfac = function MatToolbarRow_Factory(t) {\n return new (t || MatToolbarRow)();\n };\n\n MatToolbarRow.ɵdir = /* @__PURE__ */i0.ɵɵdefineDirective({\n type: MatToolbarRow,\n selectors: [[\"mat-toolbar-row\"]],\n hostAttrs: [1, \"mat-toolbar-row\"],\n exportAs: [\"matToolbarRow\"]\n });\n return MatToolbarRow;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n\nlet MatToolbar = /*#__PURE__*/(() => {\n class MatToolbar extends _MatToolbarBase {\n constructor(elementRef, _platform, document) {\n super(elementRef);\n this._platform = _platform; // TODO: make the document a required param when doing breaking changes.\n\n this._document = document;\n }\n\n ngAfterViewInit() {\n if (this._platform.isBrowser) {\n this._checkToolbarMixedModes();\n\n this._toolbarRows.changes.subscribe(() => this._checkToolbarMixedModes());\n }\n }\n /**\n * Throws an exception when developers are attempting to combine the different toolbar row modes.\n */\n\n\n _checkToolbarMixedModes() {\n if (this._toolbarRows.length && (typeof ngDevMode === 'undefined' || ngDevMode)) {\n // Check if there are any other DOM nodes that can display content but aren't inside of\n // a element.\n const isCombinedUsage = Array.from(this._elementRef.nativeElement.childNodes).filter(node => !(node.classList && node.classList.contains('mat-toolbar-row'))).filter(node => node.nodeType !== (this._document ? this._document.COMMENT_NODE : 8)).some(node => !!(node.textContent && node.textContent.trim()));\n\n if (isCombinedUsage) {\n throwToolbarMixedModesError();\n }\n }\n }\n\n }\n\n MatToolbar.ɵfac = function MatToolbar_Factory(t) {\n return new (t || MatToolbar)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i1.Platform), i0.ɵɵdirectiveInject(DOCUMENT));\n };\n\n MatToolbar.ɵcmp = /* @__PURE__ */i0.ɵɵdefineComponent({\n type: MatToolbar,\n selectors: [[\"mat-toolbar\"]],\n contentQueries: function MatToolbar_ContentQueries(rf, ctx, dirIndex) {\n if (rf & 1) {\n i0.ɵɵcontentQuery(dirIndex, MatToolbarRow, 5);\n }\n\n if (rf & 2) {\n let _t;\n\n i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx._toolbarRows = _t);\n }\n },\n hostAttrs: [1, \"mat-toolbar\"],\n hostVars: 4,\n hostBindings: function MatToolbar_HostBindings(rf, ctx) {\n if (rf & 2) {\n i0.ɵɵclassProp(\"mat-toolbar-multiple-rows\", ctx._toolbarRows.length > 0)(\"mat-toolbar-single-row\", ctx._toolbarRows.length === 0);\n }\n },\n inputs: {\n color: \"color\"\n },\n exportAs: [\"matToolbar\"],\n features: [i0.ɵɵInheritDefinitionFeature],\n ngContentSelectors: _c1,\n decls: 2,\n vars: 0,\n template: function MatToolbar_Template(rf, ctx) {\n if (rf & 1) {\n i0.ɵɵprojectionDef(_c0);\n i0.ɵɵprojection(0);\n i0.ɵɵprojection(1, 1);\n }\n },\n styles: [\".cdk-high-contrast-active .mat-toolbar{outline:solid 1px}.mat-toolbar-row,.mat-toolbar-single-row{display:flex;box-sizing:border-box;padding:0 16px;width:100%;flex-direction:row;align-items:center;white-space:nowrap}.mat-toolbar-multiple-rows{display:flex;box-sizing:border-box;flex-direction:column;width:100%}\\n\"],\n encapsulation: 2,\n changeDetection: 0\n });\n return MatToolbar;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * Throws an exception when attempting to combine the different toolbar row modes.\n * @docs-private\n */\n\n\nfunction throwToolbarMixedModesError() {\n throw Error('MatToolbar: Attempting to combine different toolbar modes. ' + 'Either specify multiple `` elements explicitly or just place content ' + 'inside of a `` for a single row.');\n}\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n\nlet MatToolbarModule = /*#__PURE__*/(() => {\n class MatToolbarModule {}\n\n MatToolbarModule.ɵfac = function MatToolbarModule_Factory(t) {\n return new (t || MatToolbarModule)();\n };\n\n MatToolbarModule.ɵmod = /* @__PURE__ */i0.ɵɵdefineNgModule({\n type: MatToolbarModule\n });\n MatToolbarModule.ɵinj = /* @__PURE__ */i0.ɵɵdefineInjector({\n imports: [[MatCommonModule], MatCommonModule]\n });\n return MatToolbarModule;\n})();\n\n/*#__PURE__*/\n(function () {\n (typeof ngDevMode === \"undefined\" || ngDevMode) && void 0;\n})();\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n/**\n * Generated bundle index. Do not edit.\n */\n\n\nexport { MatToolbar, MatToolbarModule, MatToolbarRow, throwToolbarMixedModesError }; //# sourceMappingURL=toolbar.mjs.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/45b8bce05fed7bc54ac48b1ddc863d14.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/45b8bce05fed7bc54ac48b1ddc863d14.json
deleted file mode 100644
index 5a4dd1a8..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/45b8bce05fed7bc54ac48b1ddc863d14.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { reduce } from './reduce';\nimport { isFunction } from '../util/isFunction';\nexport function min(comparer) {\n return reduce(isFunction(comparer) ? (x, y) => comparer(x, y) < 0 ? x : y : (x, y) => x < y ? x : y);\n} //# sourceMappingURL=min.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/46175dd7bf5a9fd13cc966779a7c1358.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/46175dd7bf5a9fd13cc966779a7c1358.json
deleted file mode 100644
index 155d5429..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/46175dd7bf5a9fd13cc966779a7c1358.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { from } from './from';\nexport function pairs(obj, scheduler) {\n return from(Object.entries(obj), scheduler);\n} //# sourceMappingURL=pairs.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/4682909628f6b8b576359f4a16d4659d.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/4682909628f6b8b576359f4a16d4659d.json
deleted file mode 100644
index b0d810f5..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/4682909628f6b8b576359f4a16d4659d.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"export const isArrayLike = x => x && typeof x.length === 'number' && typeof x !== 'function'; //# sourceMappingURL=isArrayLike.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/46a8a47e59cec44abb216b43d215fb0c.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/46a8a47e59cec44abb216b43d215fb0c.json
deleted file mode 100644
index 34b3b9af..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/46a8a47e59cec44abb216b43d215fb0c.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { Observable } from '../Observable';\nimport { innerFrom } from './innerFrom';\nexport function defer(observableFactory) {\n return new Observable(subscriber => {\n innerFrom(observableFactory()).subscribe(subscriber);\n });\n} //# sourceMappingURL=defer.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/4747928c7885445f4852a698ea1d5705.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/4747928c7885445f4852a698ea1d5705.json
deleted file mode 100644
index 8610c4ee..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/4747928c7885445f4852a698ea1d5705.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { innerFrom } from '../observable/innerFrom';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nexport function switchMap(project, resultSelector) {\n return operate((source, subscriber) => {\n let innerSubscriber = null;\n let index = 0;\n let isComplete = false;\n\n const checkComplete = () => isComplete && !innerSubscriber && subscriber.complete();\n\n source.subscribe(createOperatorSubscriber(subscriber, value => {\n innerSubscriber === null || innerSubscriber === void 0 ? void 0 : innerSubscriber.unsubscribe();\n let innerIndex = 0;\n const outerIndex = index++;\n innerFrom(project(value, outerIndex)).subscribe(innerSubscriber = createOperatorSubscriber(subscriber, innerValue => subscriber.next(resultSelector ? resultSelector(value, innerValue, outerIndex, innerIndex++) : innerValue), () => {\n innerSubscriber = null;\n checkComplete();\n }));\n }, () => {\n isComplete = true;\n checkComplete();\n }));\n });\n} //# sourceMappingURL=switchMap.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/47737f18f8ec66cbce91368ae645aee0.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/47737f18f8ec66cbce91368ae645aee0.json
deleted file mode 100644
index fa00442b..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/47737f18f8ec66cbce91368ae645aee0.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"export function isFunction(value) {\n return typeof value === 'function';\n} //# sourceMappingURL=isFunction.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/480a15ec21cbe3bb849e6d898eaa0ab6.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/480a15ec21cbe3bb849e6d898eaa0ab6.json
deleted file mode 100644
index 3fa61b0c..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/480a15ec21cbe3bb849e6d898eaa0ab6.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import { operate } from '../util/lift';\nimport { mergeInternals } from './mergeInternals';\nexport function expand(project, concurrent = Infinity, scheduler) {\n concurrent = (concurrent || 0) < 1 ? Infinity : concurrent;\n return operate((source, subscriber) => mergeInternals(source, subscriber, project, concurrent, undefined, true, scheduler));\n} //# sourceMappingURL=expand.js.map","map":null,"metadata":{},"sourceType":"module"}
\ No newline at end of file
diff --git a/SampleApp/.angular/cache/14.2.3/babel-webpack/4851390672e65323b646777d4167ef4c.json b/SampleApp/.angular/cache/14.2.3/babel-webpack/4851390672e65323b646777d4167ef4c.json
deleted file mode 100644
index 5aa54878..00000000
--- a/SampleApp/.angular/cache/14.2.3/babel-webpack/4851390672e65323b646777d4167ef4c.json
+++ /dev/null
@@ -1 +0,0 @@
-{"ast":null,"code":"import getCurrentScriptSource from \"./getCurrentScriptSource.js\";\n/**\n * @param {string} resourceQuery\n * @returns {{ [key: string]: string | boolean }}\n */\n\nfunction parseURL(resourceQuery) {\n /** @type {{ [key: string]: string }} */\n var options = {};\n\n if (typeof resourceQuery === \"string\" && resourceQuery !== \"\") {\n var searchParams = resourceQuery.slice(1).split(\"&\");\n\n for (var i = 0; i < searchParams.length; i++) {\n var pair = searchParams[i].split(\"=\");\n options[pair[0]] = decodeURIComponent(pair[1]);\n }\n } else {\n // Else, get the url from the